# VPN Panel Админ-панель VPN на Go + PostgreSQL 17. Готово к деплою в **Dokploy** через Docker Compose. ## Стек - Go 1.23 (веб-админка) - PostgreSQL 17 - Docker Compose - Reverse proxy + SSL: **Caddy** / **Nginx** / **Traefik** ## Быстрый старт (Dokploy / Docker) 1. Скопируйте `.env.example` → `.env` и задайте пароли + `DOMAIN`. 2. В Dokploy создайте приложение типа **Docker Compose**, укажите этот репозиторий. 3. Deploy — поднимутся сервисы `app` и `postgres`. ```bash docker compose up -d --build ``` Панель: `http://localhost:8080` ## Авторизация админа (из `.env`) | Переменная | Значение по умолчанию | |---|---| | `ADMIN_EMAIL` | `admin@panel.local` | | `ADMIN_PASSWORD` | `Admin123!ChangeMe` | | `ADMIN_NAME` | `Administrator` | При первом запуске админ создаётся автоматически из этих переменных. --- ## 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 — можно включать/выключать в админке. ## Локальная разработка без Docker ```bash # нужен локальный Postgres 17 и .env с POSTGRES_HOST=localhost go mod tidy go run ./cmd/server ``` ## Эндпоинты - `/` — главная - `/login` — вход - `/admin` — дашборд - `/admin/protocols` — протоколы - `/health` — healthcheck