feat: cloudflared container with optional WireGuard egress
- Dockerfile.cloudflared builds cloudflared (official static binary) on Alpine with wireguard-tools
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
*.key
|
||||
*.crt
|
||||
certs/
|
||||
wg/
|
||||
|
||||
# --- Run-time data / uploads ---
|
||||
uploads/
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# Сборка контейнера cloudflared с опциональным WireGuard.
|
||||
# Официальный образ cloudflare/cloudflared — distroless (без оболочки/apk), поэтому:
|
||||
# 1) берём из него статичный бинарник cloudflared;
|
||||
# 2) саму сборку делаем на Alpine, где ставим wireguard-tools.
|
||||
# Если в wg/wg0.conf нет конфига — VPN не поднимается, туннель запускается как обычно.
|
||||
FROM cloudflare/cloudflared:latest AS cf
|
||||
|
||||
FROM alpine:3.20
|
||||
RUN apk add --no-cache wireguard-tools iproute2
|
||||
COPY --from=cf /usr/local/bin/cloudflared /usr/bin/cloudflared
|
||||
COPY start-cloudflared.sh /start-cloudflared.sh
|
||||
ENTRYPOINT ["/bin/sh", "/start-cloudflared.sh"]
|
||||
@@ -182,7 +182,26 @@ docker exec whatido-tailscale-1 tailscale funnel status
|
||||
docker compose logs cloudflared | grep trycloud
|
||||
```
|
||||
|
||||
Адрес меняется при каждом перезапуске контейнера `cloudflared`. Для постоянного адреса используйте именованный туннель (замените `command` сервиса `cloudflared` в `docker-compose.yml` на `["tunnel", "run", "--token", "${CLOUDFLARE_TUNNEL_TOKEN}"]`, токен — из Cloudflare Zero Trust **Networks → Tunnels**) или схему через Tailscale выше.
|
||||
### Опциональный WireGuard для эгресса Cloudflare
|
||||
|
||||
`cloudflared` собирается из `Dockerfile.cloudflared`, в который добавлена поддержка **опционального WireGuard** — полезно, когда Cloudflare не работает с прямого IP хоста, и исход туннеля нужно пустить через VPN.
|
||||
|
||||
- Положите рабочий конфиг провайдера в `wg/wg0.conf` (папка `wg/` монтируется в контейнер как `/etc/wireguard`). Пример-заглушка уже лежит в `wg/wg0.conf` — замените значения на свои.
|
||||
- Если `wg/wg0.conf` есть → контейнер **сначала поднимает WireGuard, дожидается handshake и только потом запускает туннель** (весь эгресс Cloudflare идёт через VPN).
|
||||
- Если `wg0.conf` нет или папка пустая → VPN не включается, туннель стартует сразу, как в базовой схеме.
|
||||
|
||||
Проверка:
|
||||
|
||||
```bash
|
||||
docker compose logs -f cloudflared # в идеале сначала "WireGuard is up", затем URL
|
||||
docker compose exec cloudflared wg show # есть handshake — VPN поднят
|
||||
```
|
||||
|
||||
Примечания:
|
||||
- `wg/wg0.conf` содержит приватный ключ, поэтому папка `wg/` добавлена в `.gitignore` (в репозиторий не попадёт).
|
||||
- При полном туннеле (`AllowedIPs = 0.0.0.0/0`) существующий маршрут docker-сети сохраняется, поэтому `cloudflared` по-прежнему достаёт `app` локально, а наружу уходит через wg0. Если вдруг `app` станет недоступен из-за VPN — переключите `CLOUDFLARE_TUNNEL_URL` в `.env` на docker-шлюз (`http://<gateway-ip>:3003`).
|
||||
|
||||
Адрес Quick Tunnel меняется при каждом перезапуске контейнера `cloudflared`. Для постоянного адреса используйте именованный туннель (для этого в `start-cloudflared.sh` замените последнюю команду на `exec cloudflared --no-autoupdate tunnel run --token "$CLOUDFLARE_TUNNEL_TOKEN"` и задайте токен; токен — из Cloudflare Zero Trust **Networks → Tunnels**) или схему через Tailscale выше.
|
||||
|
||||
## Структура данных
|
||||
|
||||
|
||||
+13
-8
@@ -68,22 +68,27 @@ services:
|
||||
# Публикация наружу через Cloudflare Tunnel (cloudflared), Quick Tunnel:
|
||||
# случайный публичный URL *.trycloudflare.com, который печатается в логах:
|
||||
# docker compose logs -f cloudflared
|
||||
# ВАЖНО: официальный образ cloudflare/cloudflared НЕ содержит /bin/sh,
|
||||
# поэтому логика передаётся аргументами в command (entrypoint образа = cloudflared),
|
||||
# а не скриптом.
|
||||
# Для именованного туннеля на свой домен замените command ниже на:
|
||||
# command: ["tunnel", "run", "--token", "${CLOUDFLARE_TUNNEL_TOKEN}"]
|
||||
# (токен получается в Cloudflare Zero Trust -> Networks -> Tunnels).
|
||||
# Сборка из Dockerfile.cloudflared добавляет опциональный WireGuard:
|
||||
# если в wg/wg0.conf лежит конфиг — контейнер сначала поднимает VPN и
|
||||
# только потом запускает туннель (исход Cloudflare через VPN). Без конфига
|
||||
# туннель стартует сразу, как в базовой схеме.
|
||||
cloudflared:
|
||||
image: cloudflare/cloudflared:latest
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.cloudflared
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
volumes:
|
||||
- ./wg:/etc/wireguard:ro
|
||||
environment:
|
||||
TZ: Europe/Moscow
|
||||
command: ["tunnel", "--url", "${CLOUDFLARE_TUNNEL_URL:-http://app:3003}"]
|
||||
CLOUDFLARE_TUNNEL_URL: ${CLOUDFLARE_TUNNEL_URL:-http://app:3003}
|
||||
depends_on:
|
||||
- app
|
||||
|
||||
|
||||
|
||||
text-corrector:
|
||||
image: ghcr.io/ggml-org/llama.cpp:server
|
||||
container_name: text-corrector
|
||||
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Опциональный WireGuard: если в wg/wg0.conf лежит конфиг — поднимаем VPN
|
||||
# и только после установки handshake запускаем туннель. Без конфига —
|
||||
# cloudflared стартует сразу, как в базовой схеме Quick Tunnel.
|
||||
if [ -f /etc/wireguard/wg0.conf ]; then
|
||||
echo "WireGuard config found, bringing up wg0..."
|
||||
wg-quick up wg0
|
||||
echo "Waiting for WireGuard handshake..."
|
||||
# Формат `wg show wg0 latest-handshakes`: "<pubkey> <epoch-ts>"; 0 = handshake ещё не было.
|
||||
until wg show wg0 latest-handshakes | awk '{ if ($2 != 0) found=1 } END { exit !found }'; do
|
||||
sleep 2
|
||||
done
|
||||
echo "WireGuard is up, starting Cloudflare tunnel through VPN..."
|
||||
else
|
||||
echo "No WireGuard config, starting Cloudflare tunnel directly..."
|
||||
fi
|
||||
|
||||
exec cloudflared --no-autoupdate tunnel --url "$CLOUDFLARE_TUNNEL_URL"
|
||||
Reference in New Issue
Block a user