-
Notifications
You must be signed in to change notification settings - Fork 377
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New tutorial - "Setup custom domain with S3-compatible object storage"
- Loading branch information
1 parent
1cd6ac6
commit 987c680
Showing
1 changed file
with
233 additions
and
0 deletions.
There are no files selected for viewing
233 changes: 233 additions & 0 deletions
233
tutorials/hetzner-object-storage-custom-domain/01.en.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
--- | ||
SPDX-License-Identifier: MIT | ||
path: "/tutorials/hetzner-object-storage-custom-domain" | ||
slug: "hetzner-object-storage-custom-domain" | ||
date: "2025-01-05" | ||
title: "Setup custom domain with S3-compatible object storage" | ||
short_description: "This tutorial explains how to setup custom domain for S3-compatible object storage using reverse proxy." | ||
tags: ["Custom domain", "Reverse proxy", "Object Storage"] | ||
author: "Ivan Zaitsev" | ||
author_link: "https://github.com/ivan-zaitsev" | ||
author_img: "https://avatars.githubusercontent.com/u/15122759" | ||
author_description: "" | ||
language: "en" | ||
available_languages: ["en"] | ||
header_img: "header-7" | ||
cta: "cloud" | ||
--- | ||
|
||
## Introduction | ||
|
||
This tutorial will guide you to setup custom domain for S3-compatible object storage using reverse proxy. | ||
The advantages of custom domain is to enable seamless integration with existing infrastructure or services under a unified domain. | ||
|
||
A custom domain can be configured in various ways, such as using a CNAME record or a reverse proxy. | ||
This tutorial focuses on configuring a custom domain using a reverse proxy. | ||
|
||
**Prerequisites** | ||
|
||
* A server (e.g. with [Hetzner Cloud](https://www.hetzner.com/cloud/)) | ||
* A S3-compatible bucket (e.g. with [Hetzner](https://www.hetzner.com)) | ||
* A domain you want to use (e.g. `storage.example.com`). | ||
|
||
## Step 1 - Create Object Storage Bucket | ||
|
||
Create a S3-compatible bucket. | ||
With Hetzner, see the getting started "[Creating a Bucket](https://docs.hetzner.com/storage/object-storage/getting-started/creating-a-bucket)". | ||
Make sure it is set to public access permissions. No much benefit of using custom domain for private buckets. | ||
|
||
Create S3 credentials to access your bucket. | ||
With Hetzner, see the getting started "[Generating S3 keys](https://docs.hetzner.com/storage/object-storage/getting-started/generating-s3-keys)". | ||
|
||
## Step 2 - Create Server | ||
|
||
Create a new server. | ||
With Hetzner, see the getting started "[Creating a Server](https://docs.hetzner.com/cloud/servers/getting-started/creating-a-server)"). | ||
To install Docker and Docker Compose, follow the [official Docker documentation](https://docs.docker.com/engine/install/). | ||
|
||
## Step 3 - Deploy Caddy | ||
|
||
SSH to your server `ssh root@<server-ip>`. | ||
|
||
Create a directory for your Docker Compose files and folders for the persistent storage of the Caddy container: | ||
|
||
```bash | ||
mkdir -p /opt/caddy | ||
``` | ||
|
||
### Step 3.1 - Create docker deployment and configuration files | ||
|
||
`vim /opt/caddy/compose.yaml` | ||
|
||
```yaml | ||
services: | ||
caddy: | ||
container_name: caddy | ||
image: caddy:latest | ||
restart: unless-stopped | ||
ports: | ||
- 80:80 | ||
- 443:443 | ||
volumes: | ||
- ./caddy/Caddyfile:/etc/caddy/Caddyfile | ||
- ./caddy/certs:/certs | ||
- ./caddy/config:/config | ||
- ./caddy/data:/data | ||
- ./caddy/sites:/srv | ||
``` | ||
`vim /opt/caddy/Caddyfile` | ||
|
||
```text | ||
storage.example.com { | ||
tls { | ||
issuer acme { | ||
dir https://acme-v02.api.letsencrypt.org/directory | ||
} | ||
} | ||
} | ||
storage.example.com:443 { | ||
reverse_proxy https://fsn1.your-objectstorage.com { | ||
header_up Host {http.reverse_proxy.upstream.hostport} | ||
header_up X-Forwarded-Host {host} | ||
} | ||
} | ||
``` | ||
|
||
### Step 3.2 - Start Caddy | ||
|
||
```bash | ||
cd /opt/caddy | ||
docker compose up -d | ||
``` | ||
|
||
**Note:** | ||
|
||
The request url would be `https://storage.example.com/bucket-name/object.txt`. I | ||
It is equivalent to `https://fsn1.your-objectstorage.com/bucket-name/object.txt`. | ||
|
||
### Step 3.3 - Create kubernetes deployment and configuration files (Optional) | ||
|
||
Assuming you already have configured kubernetes, gateway api. | ||
|
||
```yaml | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
name: caddy-storage | ||
namespace: caddy | ||
spec: | ||
type: ClusterIP | ||
selector: | ||
service: caddy-storage | ||
ports: | ||
- name: http | ||
protocol: TCP | ||
port: 80 | ||
targetPort: 80 | ||
--- | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: caddy-storage | ||
namespace: caddy | ||
spec: | ||
replicas: 1 | ||
revisionHistoryLimit: 3 | ||
selector: | ||
matchLabels: | ||
service: caddy-storage | ||
template: | ||
metadata: | ||
labels: | ||
service: caddy-storage | ||
spec: | ||
containers: | ||
- image: "caddy:latest" | ||
name: caddy | ||
ports: | ||
- name: http | ||
protocol: TCP | ||
containerPort: 80 | ||
volumeMounts: | ||
- name: config-volume | ||
mountPath: /etc/caddy | ||
volumes: | ||
- name: config-volume | ||
configMap: | ||
name: caddy-storage-config | ||
--- | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: caddy-storage-config | ||
namespace: caddy | ||
data: | ||
Caddyfile: | | ||
storage.example.com:80 { | ||
reverse_proxy https://fsn1.your-objectstorage.com { | ||
header_up Host {http.reverse_proxy.upstream.hostport} | ||
header_up X-Forwarded-Host {host} | ||
} | ||
} | ||
--- | ||
apiVersion: gateway.networking.k8s.io/v1 | ||
kind: HTTPRoute | ||
metadata: | ||
name: caddy-storage-route | ||
namespace: caddy | ||
spec: | ||
parentRefs: | ||
- name: kubernetes-gateway | ||
namespace: istio-gateway | ||
hostnames: | ||
- "storage.example.com" | ||
rules: | ||
- matches: | ||
- path: | ||
type: PathPrefix | ||
value: / | ||
backendRefs: | ||
- name: caddy-storage | ||
port: 80 | ||
weight: 100 | ||
``` | ||
|
||
##### License: MIT | ||
|
||
<!-- | ||
|
||
Contributor's Certificate of Origin | ||
|
||
By making a contribution to this project, I certify that: | ||
|
||
(a) The contribution was created in whole or in part by me and I have | ||
the right to submit it under the license indicated in the file; or | ||
|
||
(b) The contribution is based upon previous work that, to the best of my | ||
knowledge, is covered under an appropriate license and I have the | ||
right under that license to submit that work with modifications, | ||
whether created in whole or in part by me, under the same license | ||
(unless I am permitted to submit under a different license), as | ||
indicated in the file; or | ||
|
||
(c) The contribution was provided directly to me by some other person | ||
who certified (a), (b) or (c) and I have not modified it. | ||
|
||
(d) I understand and agree that this project and the contribution are | ||
public and that a record of the contribution (including all personal | ||
information I submit with it, including my sign-off) is maintained | ||
indefinitely and may be redistributed consistent with this project | ||
or the license(s) involved. | ||
|
||
Signed-off-by: Ivan Zaitsev, https://github.com/ivan-zaitsev | ||
|
||
--> |