init
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
# Cloudflare API Token (Requires Zone:DNS:Edit permission)
|
||||||
|
CLOUDFLARE_API_TOKEN=your_cloudflare_api_token_here
|
||||||
|
ACME_EMAIL=[email protected]
|
||||||
|
|
||||||
|
# Cloudflare Tunnel Token (From Cloudflare Zero Trust Dashboard -> Networks -> Tunnels)
|
||||||
|
CLOUDFLARE_TUNNEL_TOKEN=your_cloudflare_tunnel_token_here
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Local environment variables
|
||||||
|
.env
|
||||||
|
|
||||||
|
# Caddy persistent storage and configurations
|
||||||
|
data/
|
||||||
|
config/
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
{
|
||||||
|
email {$ACME_EMAIL:[email protected]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Reusable TLS block using Cloudflare DNS-01 ACME challenge (Let's Encrypt / ZeroSSL)
|
||||||
|
(cloudflare_tls) {
|
||||||
|
tls {
|
||||||
|
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Synotrip (PHP 8.3 / MariaDB / Redis)
|
||||||
|
synotrip.kucial.com {
|
||||||
|
import cloudflare_tls
|
||||||
|
reverse_proxy host.docker.internal:3200
|
||||||
|
}
|
||||||
|
|
||||||
|
npm.kucial.com {
|
||||||
|
import cloudflare_tls
|
||||||
|
reverse_proxy host.docker.internal:4873
|
||||||
|
}
|
||||||
|
|
||||||
|
# Blog (PHP 8.3 / MariaDB)
|
||||||
|
blog.kucial.com {
|
||||||
|
import cloudflare_tls
|
||||||
|
reverse_proxy host.docker.internal:3201
|
||||||
|
}
|
||||||
|
|
||||||
|
gig-api.kucial.com {
|
||||||
|
import cloudflare_tls
|
||||||
|
reverse_proxy host.docker.internal:8088
|
||||||
|
}
|
||||||
|
|
||||||
|
gig-static.kucial.com {
|
||||||
|
import cloudflare_tls
|
||||||
|
reverse_proxy host.docker.internal:8088
|
||||||
|
}
|
||||||
|
|
||||||
|
gig-db.kucial.com {
|
||||||
|
import cloudflare_tls
|
||||||
|
reverse_proxy host.docker.internal:3100
|
||||||
|
}
|
||||||
|
|
||||||
|
gig-web.kucial.com {
|
||||||
|
import cloudflare_tls
|
||||||
|
reverse_proxy host.docker.internal:3101
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Gitea on Z2Pro
|
||||||
|
gitea.kucial.com {
|
||||||
|
import cloudflare_tls
|
||||||
|
reverse_proxy 192.168.50.228:8081
|
||||||
|
}
|
||||||
|
|
||||||
|
*.ddev.kucial.com {
|
||||||
|
tls {
|
||||||
|
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
|
||||||
|
}
|
||||||
|
|
||||||
|
@api host gig-api.ddev.kucial.com
|
||||||
|
handle @api {
|
||||||
|
reverse_proxy https://192.168.50.160:443 {
|
||||||
|
header_up Host gig-platform.ddev.site
|
||||||
|
transport http {
|
||||||
|
tls_server_name gig-platform.ddev.site
|
||||||
|
# The public device-facing certificate is still fully trusted.
|
||||||
|
# This applies only to the fixed, private Caddy-to-DDEV hop.
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@socket host gig-socket.ddev.kucial.com
|
||||||
|
handle @socket {
|
||||||
|
reverse_proxy http://192.168.50.160:6001 {
|
||||||
|
header_up Host gig-platform.ddev.site
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@static host gig-static.ddev.kucial.com
|
||||||
|
handle @static {
|
||||||
|
reverse_proxy https://192.168.50.160:443 {
|
||||||
|
header_up Host gig-platform.ddev.site
|
||||||
|
transport http {
|
||||||
|
tls_server_name gig-platform.ddev.site
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
respond 404
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
FROM caddy:builder AS builder
|
||||||
|
|
||||||
|
RUN xcaddy build \
|
||||||
|
--with github.com/caddy-dns/cloudflare
|
||||||
|
|
||||||
|
FROM caddy:latest
|
||||||
|
|
||||||
|
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# Caddy Dual TLS + Cloudflare Tunnel Setup
|
||||||
|
|
||||||
|
This architecture provides **End-to-End Dual TLS Encryption**:
|
||||||
|
1. **Edge TLS (Cloudflare Edge Certificate):** Cloudflare terminates HTTPS for public visitors on the internet.
|
||||||
|
2. **Origin TLS (Let's Encrypt / ACME Certificate):** Caddy automatically requests and renews valid SSL/TLS certificates using the Cloudflare DNS-01 ACME challenge plugin.
|
||||||
|
3. **Tunnel Transport:** Cloudflare Tunnel (`cloudflared`) connects to Caddy over **`HTTPS://caddy:443`** with strict origin TLS verification.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 File Structure
|
||||||
|
|
||||||
|
- [`Dockerfile`](file:///Users/kongkx/services/caddy/Dockerfile): Builds Caddy with `github.com/caddy-dns/cloudflare` using `xcaddy`.
|
||||||
|
- [`docker-compose.yml`](file:///Users/kongkx/services/caddy/docker-compose.yml): Runs `caddy` and `cloudflared` on the shared Docker bridge network.
|
||||||
|
- [`Caddyfile`](file:///Users/kongkx/services/caddy/Caddyfile): Configures `synotrip.kucial.com` & `blog.kucial.com` with DNS-01 TLS challenge.
|
||||||
|
- [`.env`](file:///Users/kongkx/services/caddy/.env): Stores `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_TUNNEL_TOKEN`.
|
||||||
|
- [`data/`](file:///Users/kongkx/services/caddy/data): Persistent volume storing Caddy's Let's Encrypt certificates.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Setup & Cloudflare Dashboard Configuration
|
||||||
|
|
||||||
|
### 1. In [`.env`](file:///Users/kongkx/services/caddy/.env)
|
||||||
|
- `CLOUDFLARE_API_TOKEN`: Token with `Zone:DNS:Edit` permission (allows Caddy to complete the DNS-01 challenge).
|
||||||
|
- `CLOUDFLARE_TUNNEL_TOKEN`: Token from Cloudflare Zero Trust Tunnels.
|
||||||
|
|
||||||
|
### 2. In Cloudflare Zero Trust Dashboard (Public Hostnames)
|
||||||
|
Add your subdomains under your Tunnel's **Public Hostnames**:
|
||||||
|
|
||||||
|
| Public Hostname | Service Type | URL | Origin Server Name (under Additional Settings -> TLS) |
|
||||||
|
| :--- | :--- | :--- | :--- |
|
||||||
|
| `synotrip.kucial.com` | `HTTPS` | `caddy:443` | `synotrip.kucial.com` |
|
||||||
|
| `blog.kucial.com` | `HTTPS` | `caddy:443` | `blog.kucial.com` |
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Setting **Origin Server Name** tells `cloudflared` which SNI hostname to send to Caddy during the TLS handshake, allowing Caddy to serve the matching Let's Encrypt certificate.
|
||||||
|
|
||||||
|
### 3. Start Services
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Zero-Downtime Reload
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
services:
|
||||||
|
caddy:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: caddy
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
- "443:443/udp" # HTTP/3 (QUIC)
|
||||||
|
environment:
|
||||||
|
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
volumes:
|
||||||
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||||
|
- ./data:/data
|
||||||
|
- ./config:/config
|
||||||
|
- ./site:/srv
|
||||||
|
|
||||||
|
cloudflared:
|
||||||
|
image: cloudflare/cloudflared:latest
|
||||||
|
container_name: cloudflared
|
||||||
|
restart: unless-stopped
|
||||||
|
command: tunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN}
|
||||||
|
environment:
|
||||||
|
- TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
depends_on:
|
||||||
|
- caddy
|
||||||
|
|
||||||
Reference in New Issue
Block a user