Add Go rewrite with Postgres 17 and Dokploy Docker Compose
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+150
@@ -0,0 +1,150 @@
|
||||
# Amnezia VPN Share Panel (Go)
|
||||
|
||||
Полный переезд панели совместного доступа к Amnezia VPN с PHP на Go
|
||||
(модуль `amnezia-share`). Приложение — единый статически собранный бинарник:
|
||||
HTTP-сервер, сессии, CSRF, шаблоны и вся бизнес-логика (гостевые
|
||||
share-ссылки, личный кабинет, админка) внутри одного процесса + PostgreSQL.
|
||||
|
||||
## Состав репозитория
|
||||
|
||||
```
|
||||
Go/
|
||||
├── cmd/
|
||||
│ ├── server/ — основной HTTP-сервер (слушает APP_PORT)
|
||||
│ └── cleanup/ — разовая задача очистки просроченных share-ссылок
|
||||
├── internal/
|
||||
│ ├── config/ — чтение переменных окружения
|
||||
│ ├── db/ — подключение к БД + миграции
|
||||
│ ├── models/ — доменные структуры (ShareLink, Member, ServerInfo, ...)
|
||||
│ ├── panel/ — клиент Amnezia Web Panel API
|
||||
│ ├── settings/ — key-value настройки в БД (URL панели, токен, лейблы и т.д.)
|
||||
│ ├── auth/ — вход администратора, Pocket ID (OIDC)
|
||||
│ ├── member/ — личный кабинет (регистрация, подписка, конфиги)
|
||||
│ ├── share/ — гостевые share-ссылки, коды продления, сборка бандлов
|
||||
│ ├── i18n/ — переводы RU/EN
|
||||
│ └── web/ — HTTP-слой: App, роуты, middleware, шаблоны
|
||||
│ └── handlers/ — обработчики, сгруппированные по разделам
|
||||
├── web/
|
||||
│ ├── templates/ — HTML-шаблоны (layouts, share, cabinet, admin, auth)
|
||||
│ └── static/ — CSS/иконки (Bootstrap 5 подключается через CDN)
|
||||
├── migrations/ — SQL-схема (идемпотентные CREATE TABLE IF NOT EXISTS)
|
||||
├── Dockerfile
|
||||
├── docker-compose.yml
|
||||
└── .env.example
|
||||
```
|
||||
|
||||
## Запуск локально (без Docker)
|
||||
|
||||
Требуется Go 1.22+ и PostgreSQL 14+.
|
||||
|
||||
```bash
|
||||
cd Go
|
||||
cp .env.example .env # заполните пароли/секреты
|
||||
go mod tidy
|
||||
go build ./...
|
||||
DATABASE_URL="postgres://vpn_admin:vpn_admin@127.0.0.1:5432/vpn_admin?sslmode=disable" \
|
||||
APP_SESSION_SECRET="локальный-дев-секрет-минимум-32-символа" \
|
||||
go run ./cmd/server
|
||||
```
|
||||
|
||||
Сервер поднимется на `http://127.0.0.1:30000`. При первом запуске
|
||||
(таблица администраторов пуста) корень `/` перенаправит на `/install` —
|
||||
форму создания единственного администратора. Дальше вход через `/login`.
|
||||
|
||||
Миграции (`migrations/001_schema.sql`) применяются автоматически при
|
||||
старте `cmd/server` и `cmd/cleanup` — отдельно накатывать их не нужно.
|
||||
|
||||
## Запуск через Docker Compose / Dokploy
|
||||
|
||||
```bash
|
||||
cd Go
|
||||
cp .env.example .env
|
||||
# отредактируйте .env: POSTGRES_PASSWORD, APP_SESSION_SECRET (32+ символов)
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Сервисы:
|
||||
|
||||
- **app** — веб-приложение, слушает `30000:30000` (в Dokploy пробросьте
|
||||
этот порт через ваш прокси/домен).
|
||||
- **db** — PostgreSQL 17, доступен только внутри docker-сети `amnezia`
|
||||
(порт 5432 наружу не публикуется; не открывайте его в проде).
|
||||
- **cleanup** — тот же образ, в цикле раз в 5 минут запускает
|
||||
`/app/cleanup`, который удаляет истёкшие share-ссылки и их конфиги
|
||||
на панели Amnezia.
|
||||
|
||||
Проверка живости: `GET /health` → `{"ok":true,"db":true,"time":"..."}`.
|
||||
Этот же путь используют healthcheck-и в docker-compose.
|
||||
|
||||
### Переменные окружения
|
||||
|
||||
| Переменная | Назначение | По умолчанию |
|
||||
|---|---|---|
|
||||
| `APP_PORT` | порт HTTP-сервера | `30000` |
|
||||
| `APP_BASE_URL` | префикс пути, если приложение висит не на корне домена (например `vpn`) | пусто |
|
||||
| `APP_SESSION_SECRET` | секрет сессий (используется как соль для CSRF/токенов); задайте случайную строку 32+ символов | — |
|
||||
| `APP_HTTP_BUDGET_SEC` | таймаут на HTTP-запросы к панели Amnezia в рамках одного запроса | `52` |
|
||||
| `DATABASE_URL` | строка подключения к PostgreSQL | `postgres://vpn_admin:vpn_admin@127.0.0.1:5432/vpn_admin?sslmode=disable` |
|
||||
| `AMNEZIA_PANEL_URL`, `AMNEZIA_API_TOKEN` | адрес и токен панели Amnezia (можно также задать в `/admin/settings`) | пусто |
|
||||
| `AMNEZIA_SERVER_LABELS_JSON` | JSON `{"1":"Германия"}` — переопределение названий серверов через окружение | пусто |
|
||||
| `MIGRATIONS_DIR` | путь к папке с SQL-миграциями | `migrations` |
|
||||
| `WEB_DIR` | путь к папке `templates/` и `static/` | `web` |
|
||||
|
||||
Настройки панели, Pocket ID, режим техработ, лейблы/флаги/скорости
|
||||
серверов и лимиты личного кабинета по умолчанию удобнее менять прямо в
|
||||
админке (`/admin/settings`, `/admin/servers`) — они хранятся в таблице
|
||||
`site_settings` и переживают перезапуск контейнера.
|
||||
|
||||
## Основные маршруты
|
||||
|
||||
Гостевые:
|
||||
|
||||
- `GET /` — редирект на `/admin`, `/install` или `/login` в зависимости от состояния.
|
||||
- `GET/POST /install` — создание единственного администратора (доступно, пока админов нет).
|
||||
- `GET/POST /login`, `GET /login?oidc=1`, `GET /oidc/callback`, `GET /logout` — вход администратора (пароль или Pocket ID SSO).
|
||||
- `GET/POST /share?k=ТОКЕН` — гостевая страница share-ссылки: выбор сервера/протокола, создание/перенос/продление конфига, скачивание. POST с заголовком `X-Share-Async: 1` отвечает JSON.
|
||||
- `GET /share/servers?k=`, `GET /share/download?k=&cre=&part=conf|vpn|zip`.
|
||||
- `GET /faq`, `GET /rules`, `GET /status` — статические страницы + пинг серверов.
|
||||
- `GET/POST /cabinet`, `/cabinet/login`, `/cabinet/register`, `/cabinet/logout`, `/cabinet/servers`, `/cabinet/download` — личный кабинет.
|
||||
|
||||
Администрирование (требует входа):
|
||||
|
||||
- `GET /admin` — дашборд.
|
||||
- `GET/POST /admin/links` — управление share-ссылками (создание, продление, список серверов, удаление конфигов).
|
||||
- `GET/POST /admin/renewal` — коды продления (для гостевых ссылок и/или личного кабинета).
|
||||
- `GET/POST /admin/configs` — обзор всех выданных конфигов с фильтрами и удалением.
|
||||
- `GET/POST /admin/servers` — метки, протоколы, флаги, скорость и отключение серверов панели.
|
||||
- `GET/POST /admin/settings` — URL/токен панели, Pocket ID, техработы, лимиты кабинета, проверка соединения.
|
||||
|
||||
Статика: `/static/*` раздаётся из `WEB_DIR/static`.
|
||||
|
||||
## Миграция с PHP-версии
|
||||
|
||||
- Схема БД совместима: `migrations/001_schema.sql` использует
|
||||
`CREATE TABLE IF NOT EXISTS` — можно указать Go-приложению ту же базу,
|
||||
на которой уже работала PHP-панель, без потери данных.
|
||||
- Ключи в таблице настроек (`site_settings`) переиспользованы 1:1
|
||||
(`amnezia_panel_url`, `amnezia_api_token`, `amnezia_server_labels_json`,
|
||||
`share_maintenance_mode`, `pocket_id_*` и т.д.) — значения, заданные в
|
||||
PHP-админке, подхватятся автоматически.
|
||||
- Cookie для языка (`share_lang`) и сессии называются иначе
|
||||
(`amnezia_session`), поэтому после переключения все пользователи один
|
||||
раз залогинятся заново — это нормально.
|
||||
- Разовый крон-скрипт очистки истёкших ссылок (`cleanup_share.php`)
|
||||
заменён на бинарник `cmd/cleanup`, который в docker-compose запускается
|
||||
в цикле каждые 5 минут отдельным контейнером.
|
||||
- Файлы конфигов больше не пишутся на диск — тело ответа панели
|
||||
сохраняется в БД (`share_creations.response_json`) и конфиги
|
||||
собираются "на лету" при скачивании, как и в PHP-версии.
|
||||
|
||||
## Тесты
|
||||
|
||||
```bash
|
||||
go build ./...
|
||||
go test ./...
|
||||
```
|
||||
|
||||
`internal/web` и `internal/web/handlers` содержат smoke-тесты, которые
|
||||
парсят все HTML-шаблоны и рендерят каждую страницу с реалистичными
|
||||
данными без подключения к базе — это ловит опечатки в шаблонах ещё на
|
||||
этапе CI, до реального деплоя.
|
||||
Reference in New Issue
Block a user