commit a031e9c579c3d8c1f574071c26b0fa061f1b9f67 Author: Андрей Бобырев Date: Thu May 14 23:18:43 2026 +0300 Initial public deploy bundle (GHCR + Boosty) Co-authored-by: Cursor diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..8223bdf --- /dev/null +++ b/.env.example @@ -0,0 +1,17 @@ +# Скопируйте в .env и заполните значения из закрытого поста Boosty (только для подписчиков). + +# Образ из GHCR (пример; ваш продавец подставит точное значение) +GHCR_IMAGE=ghcr.io/andrey271192/amnezia-admin-pro +IMAGE_TAG=v1.0.0 + +# Учётные данные только для docker pull (read-only PAT / Fine-grained token) +GHCR_USERNAME=your_github_username_or_bot +GHCR_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx + +# Опционально +HOST_PORT=8080 +CONTAINER_NAME=amnezia-admin-pro +AWG_CONTAINER=amnezia-awg2 + +# Первый пароль панели (рекомендуется задать явно). Иначе смотрите логи контейнера / доку Pro. +# ADMIN_PASSWORD= diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2334d82 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +*.log diff --git a/README.md b/README.md new file mode 100644 index 0000000..5a0046f --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# Amnezia Admin Pro — установка (Docker / GHCR) + +Публичный репозиторий **только с инструкциями и compose**. Сам образ приложения — **приватный** на GitHub Container Registry; учётные данные для `docker pull` выдаются **активным подписчикам** (например, в закрытом посте на Boosty). + +## Требования + +- VPS с Docker и Docker Compose v2 (`docker compose`) +- Подписка и значения `GHCR_*` из материалов для подписчиков + +## Быстрый старт + +```bash +git clone https://github.com/andrey271192/amnezia-web-pro-deploy.git +cd amnezia-web-pro-deploy +cp .env.example .env +# заполните GHCR_IMAGE, IMAGE_TAG, GHCR_USERNAME, GHCR_TOKEN (из закрытого поста Boosty) +sudo bash scripts/install.sh +``` + +## Публикация на GitHub (для автора) + +1. Создайте на GitHub новый репозиторий **`amnezia-web-pro-deploy`**, тип **Public** (без автогенерации README, если заливаете уже готовые файлы). +2. В каталоге с этим проектом: + +```bash +cd amnezia-web-pro-deploy +git init +git add -A +git commit -m "Initial public deploy bundle" +git branch -M main +git remote add origin https://github.com/andrey271192/amnezia-web-pro-deploy.git +git push -u origin main +``` + +Если GitHub при создании репозитория уже добавил коммит — сделайте `git pull origin main --allow-unrelated-histories`, затем push. + +## Обновление + +После объявления нового тега образа обновите `IMAGE_TAG` в `.env` и выполните: + +```bash +sudo bash scripts/update.sh +``` + +## Шаблон поста для Boosty + +См. [docs/BOOSTY_SUBSCRIBERS_POST.md](docs/BOOSTY_SUBSCRIBERS_POST.md). + +## Безопасность + +- Файл `.env` с токеном не должен попадать в issue, чаты и скриншоты. +- При утечке токена автор перевыпускает его в GitHub; подписчикам выдаётся новый токен в обновлённом посте. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c2b3227 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,25 @@ +services: + panel: + image: ${GHCR_IMAGE}:${IMAGE_TAG} + container_name: ${CONTAINER_NAME:-amnezia-admin-pro} + restart: unless-stopped + ports: + - "${HOST_PORT:-8080}:3980" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - amnezia-admin-pro-data:/data + environment: + AWG_CONTAINER: ${AWG_CONTAINER:-amnezia-awg2} + TZ: ${TZ:-} + AWG_PROFILES: ${AWG_PROFILES:-} + TIME_SYNC_SSH_HOST: ${TIME_SYNC_SSH_HOST:-} + TIME_SYNC_DISABLED: ${TIME_SYNC_DISABLED:-} + WARP_DIR: ${WARP_DIR:-} + WARP_CONF_PATH: ${WARP_CONF_PATH:-} + WARP_CLIENTS_LIST: ${WARP_CLIENTS_LIST:-} + AMNEZIA_START_SCRIPT: ${AMNEZIA_START_SCRIPT:-} + ADMIN_PASSWORD: ${ADMIN_PASSWORD:-} + ALLOW_DEFAULT_PASSWORD: ${ALLOW_DEFAULT_PASSWORD:-} + +volumes: + amnezia-admin-pro-data: diff --git a/docs/BOOSTY_SUBSCRIBERS_POST.md b/docs/BOOSTY_SUBSCRIBERS_POST.md new file mode 100644 index 0000000..c1c17d9 --- /dev/null +++ b/docs/BOOSTY_SUBSCRIBERS_POST.md @@ -0,0 +1,60 @@ +# Шаблон закрытого поста Boosty (только для подписчиков) + +Скопируйте в Boosty и замените плейсхолдеры. + +--- + +## Amnezia Admin — Pro (Docker) + +Спасибо за поддержку. Исходный код Pro не распространяется — доступ только к готовому образу в GitHub Container Registry. + +### 1) Открытая инструкция и файлы + +Репозиторий установки (публичный): +https://github.com/andrey271192/amnezia-web-pro-deploy + +На VPS (Ubuntu/Debian, установлен Docker): + +```bash +sudo apt-get update && sudo apt-get install -y git +git clone https://github.com/andrey271192/amnezia-web-pro-deploy.git +cd amnezia-web-pro-deploy +cp .env.example .env +nano .env +``` + +### 2) Заполните `.env` значениями ниже + +| Переменная | Значение для подписчиков | +|------------|--------------------------| +| `GHCR_IMAGE` | `ghcr.io/andrey271192/amnezia-admin-pro` | +| `IMAGE_TAG` | `v1.0.0` *(или актуальный тег из объявления)* | +| `GHCR_USERNAME` | **`REPLACE_ME_USERNAME`** | +| `GHCR_TOKEN` | **`REPLACE_ME_TOKEN`** | + +⚠️ Не выкладывайте `.env` и токен в открытый доступ. Не коммитьте их в git. + +### 3) Установка одной командой + +```bash +sudo bash scripts/install.sh +``` + +Панель: `http://ВАШ_IP:8080` (порт меняется через `HOST_PORT` в `.env`). + +### 4) Обновление до новой версии + +В посте при новом релизе будет указан новый `IMAGE_TAG`. В `.env` замените `IMAGE_TAG`, затем: + +```bash +cd amnezia-web-pro-deploy +sudo bash scripts/update.sh +``` + +### 5) Если подписка закончилась + +Доступ к закрытым материалам Boosty пропадает; pull-токен может быть отозван при ротации — новые установки и обновления станут недоступны без активной подписки. + +--- + +**Поддержка:** напишите автору в личные сообщения на Boosty (вопросы по установке и обновлению). diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 0000000..3ef52bb --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# Установка Pro с приватного GHCR (без исходников). Публичный репозиторий — только этот скрипт и compose. +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +COMPOSE_FILE="${ROOT_DIR}/docker-compose.yml" +ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}" + +need_root() { + if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then + echo "Запустите от root: sudo bash scripts/install.sh" + exit 1 + fi +} + +need_docker() { + command -v docker >/dev/null 2>&1 || { + echo "Нужен Docker." + exit 1 + } + docker info >/dev/null 2>&1 || { + echo "Docker daemon недоступен." + exit 1 + } +} + +need_compose() { + if docker compose version >/dev/null 2>&1; then + COMPOSE=(docker compose) + return + fi + if command -v docker-compose >/dev/null 2>&1; then + COMPOSE=(docker-compose) + return + fi + echo "Нужен Docker Compose v2 (docker compose)." + exit 1 +} + +need_root +need_docker +need_compose + +if [[ ! -f "${ENV_FILE}" ]]; then + echo "Создайте файл .env из .env.example и вставьте GHCR_* из закрытого поста Boosty:" + echo " cp .env.example .env && nano .env" + exit 1 +fi + +set -a +# shellcheck disable=SC1090 +source "${ENV_FILE}" +set +a + +: "${GHCR_IMAGE:?Укажите GHCR_IMAGE в .env}" +: "${IMAGE_TAG:?Укажите IMAGE_TAG в .env}" +: "${GHCR_USERNAME:?Укажите GHCR_USERNAME в .env}" +: "${GHCR_TOKEN:?Укажите GHCR_TOKEN в .env}" + +echo "→ docker login ghcr.io ..." +printf '%s\n' "${GHCR_TOKEN}" | docker login ghcr.io -u "${GHCR_USERNAME}" --password-stdin + +echo "→ pull ${GHCR_IMAGE}:${IMAGE_TAG}" +"${COMPOSE[@]}" -f "${COMPOSE_FILE}" --env-file "${ENV_FILE}" pull + +echo "→ up -d" +"${COMPOSE[@]}" -f "${COMPOSE_FILE}" --env-file "${ENV_FILE}" up -d + +IP="$(hostname -I 2>/dev/null | awk '{print $1}' || true)" +echo "" +echo "=== Готово ===" +echo "Панель: http://${IP:-YOUR_SERVER_IP}:${HOST_PORT:-8080}" +echo "Обновление: sudo bash ${ROOT_DIR}/scripts/update.sh" diff --git a/scripts/update.sh b/scripts/update.sh new file mode 100755 index 0000000..f84f17f --- /dev/null +++ b/scripts/update.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}" +COMPOSE_FILE="${ROOT_DIR}/docker-compose.yml" + +if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then + echo "Запустите от root." + exit 1 +fi + +if docker compose version >/dev/null 2>&1; then + COMPOSE=(docker compose) +elif command -v docker-compose >/dev/null 2>&1; then + COMPOSE=(docker-compose) +else + echo "Нужен docker compose." + exit 1 +fi + +set -a +# shellcheck disable=SC1090 +source "${ENV_FILE}" +set +a + +printf '%s\n' "${GHCR_TOKEN}" | docker login ghcr.io -u "${GHCR_USERNAME}" --password-stdin +"${COMPOSE[@]}" -f "${COMPOSE_FILE}" --env-file "${ENV_FILE}" pull +"${COMPOSE[@]}" -f "${COMPOSE_FILE}" --env-file "${ENV_FILE}" up -d + +echo "Обновлено."