Add reverse proxy SSL guides for Caddy, Nginx, and Traefik.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
orohi
2026-07-29 03:55:37 +03:00
co-authored by Cursor
parent b1e31430b5
commit 93bbbf8ce8
12 changed files with 434 additions and 1 deletions
+147 -1
View File
@@ -7,10 +7,11 @@
- Go 1.23 (веб-админка)
- PostgreSQL 17
- Docker Compose
- Reverse proxy + SSL: **Caddy** / **Nginx** / **Traefik**
## Быстрый старт (Dokploy / Docker)
1. Скопируйте `.env.example``.env` и задайте пароли.
1. Скопируйте `.env.example``.env` и задайте пароли + `DOMAIN`.
2. В Dokploy создайте приложение типа **Docker Compose**, укажите этот репозиторий.
3. Deploy — поднимутся сервисы `app` и `postgres`.
@@ -30,6 +31,151 @@ docker compose up -d --build
При первом запуске админ создаётся автоматически из этих переменных.
---
## Reverse proxy + SSL (Let's Encrypt)
Примеры лежат в `deploy/`. Сеть Docker: `vpn-panel-net`.
### Что нужно до выпуска сертификата
1. **DNS**: A (и при необходимости AAAA) запись `DOMAIN` → публичный IP сервера.
2. **Порты**: `80` и `443` открыты на firewall / security group (TCP; для Caddy HTTP/3 ещё `443/udp`).
3. **Домен в `.env`**:
```env
DOMAIN=panel.example.com
ACME_EMAIL=admin@example.com
```
4. **Не светить панель наружу на `:8080`** — только через proxy:
```bash
docker compose -f docker-compose.yml -f deploy/compose.behind-proxy.yml up -d
```
Либо в Dokploy / compose закомментируйте `ports` у `app`, оставьте доступ по внутренней сети `app:8080`.
5. Прокси обязан передавать заголовки `Host`, `X-Forwarded-Proto`, `X-Forwarded-For` (уже есть в примерах).
> Let's Encrypt не выпустит сертификат на `localhost` / приватный IP. Нужен реальный домен с публичным DNS.
---
### Вариант A — Caddy (самый простой, SSL автоматом)
Caddy сам получает и продлевает сертификат.
1. В `deploy/caddy/Caddyfile` домен берётся из `{$DOMAIN:...}` (или задайте в `.env`).
2. Запуск вместе с панелью:
```bash
# из корня репозитория
docker compose \
-f docker-compose.yml \
-f deploy/compose.behind-proxy.yml \
-f deploy/caddy/docker-compose.caddy.yml \
up -d --build
```
3. Откройте `https://panel.example.com`.
Файлы: `deploy/caddy/Caddyfile`, `deploy/caddy/docker-compose.caddy.yml`.
---
### Вариант B — Nginx + Certbot
1. Подставьте свой домен в `deploy/nginx/nginx.conf` (`server_name` и пути к сертификатам).
2. Поднимите стек (сначала HTTP + ACME webroot):
```bash
docker compose \
-f docker-compose.yml \
-f deploy/compose.behind-proxy.yml \
-f deploy/nginx/docker-compose.nginx.yml \
up -d --build
```
3. Выпустите сертификат:
```bash
docker compose -f deploy/nginx/docker-compose.nginx.yml run --rm certbot certonly \
--webroot -w /var/www/certbot \
-d panel.example.com \
--email admin@example.com \
--agree-tos --no-eff-email
```
4. В `deploy/nginx/nginx.conf`:
- раскомментируйте блок `server { listen 443 ... }`;
- включите `return 301 https://$host$request_uri;` в HTTP-сервере;
- закомментируйте временный `location /` на порту 80 (оставьте только ACME).
5. Перезагрузите nginx:
```bash
docker compose -f docker-compose.yml -f deploy/nginx/docker-compose.nginx.yml exec nginx nginx -s reload
```
Продление: контейнер `certbot` крутит `renew` раз в 12 часов; после renew — `nginx -s reload`.
Файлы: `deploy/nginx/`.
---
### Вариант C — Traefik (свой или Dokploy)
#### C1. Свой Traefik из репозитория
```bash
docker compose \
-f docker-compose.yml \
-f deploy/compose.behind-proxy.yml \
-f deploy/traefik/docker-compose.traefik.yml \
up -d --build
```
В `.env`: `DOMAIN`, `ACME_EMAIL`. Сертификат выпускается HTTP-challenge на entrypoint `web`.
#### C2. Dokploy (встроенный Traefik)
Dokploy уже поднимает Traefik — **не** добавляйте `deploy/traefik/docker-compose.traefik.yml`.
1. В Dokploy укажите домен для сервиса `app`.
2. Либо добавьте labels к `app` (см. `deploy/traefik/labels.example.yml`):
```yaml
labels:
- traefik.enable=true
- traefik.http.routers.vpn-panel.rule=Host(`panel.example.com`)
- traefik.http.routers.vpn-panel.entrypoints=websecure
- traefik.http.routers.vpn-panel.tls=true
- traefik.http.routers.vpn-panel.tls.certresolver=letsencrypt
- traefik.http.services.vpn-panel.loadbalancer.server.port=8080
```
Имя `certresolver` в Dokploy часто `letsencrypt` — проверьте в настройках (или `TRAEFIK_CERT_RESOLVER` в `.env`).
3. Не публикуйте порт `8080` наружу в UI Dokploy, если трафик идёт только через Traefik.
---
### Чеклист после включения HTTPS
| Проверка | Ожидание |
|---|---|
| `https://DOMAIN/` | Главная панель |
| `https://DOMAIN/health` | `ok` |
| HTTP → HTTPS | Редирект 301 (Caddy/Traefik по умолчанию; Nginx — после шага 4) |
| Сертификат | Валидный LE, не self-signed |
| Порт `8080` снаружи | Закрыт |
### Типичные ошибки
| Симптом | Причина |
|---|---|
| ACME timeout / pending | DNS ещё не указывает на сервер, или закрыт порт 80 |
| 502 Bad Gateway | Proxy не в сети `vpn-panel-net` / сервис `app` не запущен |
| Редирект-петля | За приложением HTTPS, а `X-Forwarded-Proto` не передаётся |
| Certbot: no such file | Домен в путях `nginx.conf` не совпадает с `-d` |
---
## Протоколы (seed)
WireGuard, OpenVPN, VLESS, VMess, Trojan, Shadowsocks, Hysteria2 — можно включать/выключать в админке.