diff --git a/Dockerfile b/Dockerfile index 7a6aa89..84176c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,6 +26,8 @@ FROM python:3.12-slim WORKDIR /app +LABEL org.opencontainers.image.source="https://github.com/3252a8/remnawave-minishop" + RUN useradd -u 10001 -m appuser COPY --from=python-builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages diff --git a/README.md b/README.md index 2217c3a..a3881a6 100644 --- a/README.md +++ b/README.md @@ -468,13 +468,13 @@ cd /opt/remnawave/nginx && docker compose down && docker compose up -d && docker Файлы `Dockerfile` и `docker-compose.yml` уже настроены для локальной сборки и запуска проекта. -Если нужен запуск из готового образа, используйте `docker-compose-remote-server.yml` как шаблон и укажите свой `image:` вместо локальной сборки. +Если нужен запуск из готового образа, используйте `docker-compose-remote-server.yml` как шаблон и укажите свой `image:` вместо локальной сборки. По умолчанию он тянет `ghcr.io/3252a8/remnawave-minishop:latest`, а для закрепления версии можно задать `IMAGE_TAG=3.1.0`. -Этот репозиторий больше не публикует образы автоматически через GitHub Actions. В GHCR сохранён только тег `3.0.0`; `latest` и `0.1.0` больше не используются. +В GHCR доступны теги `3.1.0` и `latest`. Чтобы использовать сохранённый образ, можно запустить: ```bash -IMAGE_TAG=3.0.0 docker compose -f docker-compose-remote-server.yml up -d +IMAGE_TAG=3.1.0 docker compose -f docker-compose-remote-server.yml up -d ``` ### Вариант с Caddy @@ -558,4 +558,4 @@ docker compose -f docker-compose-caddy.yml up -d --build ``` ## ❤️ Поддержка -- Crypto: `USDT/Other ERC-20 0xeD506D44aae634fEc0E01C8835744fBedb7B2a44 (Ethereum/Polygon/Gnosis)` \ No newline at end of file +- Crypto: `USDT/Other ERC-20 0xeD506D44aae634fEc0E01C8835744fBedb7B2a44 (Ethereum/Polygon/Gnosis)` diff --git a/docker-compose-caddy.yml b/docker-compose-caddy.yml index 3fe359c..a5faacd 100644 --- a/docker-compose-caddy.yml +++ b/docker-compose-caddy.yml @@ -1,6 +1,6 @@ services: remnawave-minishop: - build: . + image: ghcr.io/3252a8/remnawave-minishop:${IMAGE_TAG:-latest} container_name: remnawave-minishop hostname: remnawave-minishop env_file: diff --git a/docker-compose-remote-server.yml b/docker-compose-remote-server.yml index 9b9fd9b..6fe31c6 100644 --- a/docker-compose-remote-server.yml +++ b/docker-compose-remote-server.yml @@ -1,6 +1,6 @@ services: remnawave-minishop: - image: ghcr.io/3252a8/remnawave-tg-shop:${IMAGE_TAG:-3.0.0} + image: ghcr.io/3252a8/remnawave-minishop:${IMAGE_TAG:-latest} container_name: remnawave-minishop hostname: remnawave-minishop env_file: diff --git a/docker-compose.yml b/docker-compose.yml index 71bddab..9829ff6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ services: remnawave-minishop: - build: . + image: ghcr.io/3252a8/remnawave-minishop:${IMAGE_TAG:-latest} container_name: remnawave-minishop hostname: remnawave-minishop env_file: diff --git a/docs/migration-to-minishop.md b/docs/migration-to-minishop.md index ef81d6d..77bd822 100644 --- a/docs/migration-to-minishop.md +++ b/docs/migration-to-minishop.md @@ -59,8 +59,10 @@ ASSUME_YES=1 \ 1. **Останавливает текущий стек**: проверяет известные контейнеры старой и новой схемы и останавливает их, если они запущены. 2. **Переключает `origin`**, если задана переменная `NEW_ORIGIN_URL`, иначе оставляет как есть. 3. **Подтягивает целевую ветку** (`git fetch` + `git switch` + `git pull --ff-only`). Прерывается, если в рабочем дереве есть незакоммиченные изменения. -4. **Переносит тома** `remnawave-tg-shop-*` → `remnawave-minishop-*` через одноразовый `alpine`-контейнер. Если новый том уже непустой, копирование пропускается. Заодно правится `POSTGRES_HOST` в `.env` (с бэкапом в `.env.bak`). -5. **Стартует новый стек** (`docker compose -f $COMPOSE_FILE up -d --remove-orphans`, а для локальной сборки ещё и `--build`) и печатает `docker compose ps`. +4. **Обновляет `.env`** и правит `POSTGRES_HOST`, если он ещё указывает на старый контейнер. +5. **Подготавливает новый стек в режиме `--no-start`**, чтобы Compose сам создал тома и не ругался на уже существующий volume. +6. **Переносит тома** `remnawave-tg-shop-*` → `remnawave-minishop-*` через одноразовый `alpine`-контейнер. Если новый том уже непустой, копирование пропускается. +7. **Стартует новый стек** (`docker compose -f $COMPOSE_FILE up -d --remove-orphans`, а для локальной сборки ещё и `--build`) и печатает `docker compose ps`. Скрипт идемпотентен: повторный запуск ничего не сломает, просто пропустит уже выполненные шаги. @@ -84,27 +86,38 @@ docker volume rm remnawave-tg-shop-caddy-data remnawave-tg-shop-caddy-config 2>/ git pull --ff-only origin main ``` -2. **Перенесите том БД в новое имя:** +2. **Обновите `.env`:** + + ```bash + sed -i.bak 's/^POSTGRES_HOST=remnawave-tg-shop-db$/POSTGRES_HOST=remnawave-minishop-db/' .env + ``` + +3. **Подготовьте новый стек без запуска:** + + ```bash + # Локальная сборка + docker compose up --no-start --build + + # Или Caddy-вариант + docker compose -f docker-compose-caddy.yml up --no-start --build + + # Или готовый образ + docker compose -f docker-compose-remote-server.yml up --no-start + ``` + +4. **Перенесите том БД в новое имя:** ```bash - docker volume create remnawave-minishop-db-data docker run --rm \ -v remnawave-tg-shop-db-data:/from:ro \ -v remnawave-minishop-db-data:/to \ alpine sh -c "cd /from && cp -a . /to" ``` -3. **Обновите `.env`:** - - ```bash - sed -i.bak 's/^POSTGRES_HOST=remnawave-tg-shop-db$/POSTGRES_HOST=remnawave-minishop-db/' .env - ``` - -4. **(Только для Caddy)** перенесите тома Caddy с TLS-сертификатами и состоянием ACME: +5. **(Только для Caddy)** перенесите тома Caddy с TLS-сертификатами и состоянием ACME: ```bash for v in caddy-data caddy-config; do - docker volume create "remnawave-minishop-$v" docker run --rm \ -v "remnawave-tg-shop-$v":/from:ro \ -v "remnawave-minishop-$v":/to \ @@ -112,7 +125,7 @@ docker volume rm remnawave-tg-shop-caddy-data remnawave-tg-shop-caddy-config 2>/ done ``` -5. **Запустите новый стек:** +6. **Запустите новый стек:** ```bash docker compose up -d @@ -122,14 +135,14 @@ docker volume rm remnawave-tg-shop-caddy-data remnawave-tg-shop-caddy-config 2>/ docker compose -f docker-compose-remote-server.yml up -d ``` -6. **Проверьте:** +7. **Проверьте:** ```bash docker compose ps docker compose logs -f remnawave-minishop ``` -7. **(Опционально) удалите старые тома**, когда убедитесь, что новый стек стабилен: +8. **(Опционально) удалите старые тома**, когда убедитесь, что новый стек стабилен: ```bash docker volume rm remnawave-tg-shop-db-data diff --git a/scripts/migrate_to_minishop.sh b/scripts/migrate_to_minishop.sh index 08a6eea..e8b8eab 100644 --- a/scripts/migrate_to_minishop.sh +++ b/scripts/migrate_to_minishop.sh @@ -95,7 +95,10 @@ copy_volume() { return 1 fi - docker volume create "$target" >/dev/null + if ! volume_exists "$target"; then + die "Целевой том \`$target\` не создан Compose. Сначала нужно подготовить новый стек в режиме \`--no-start\`." + fi + docker run --rm -v "$source:/from:ro" -v "$target:/to" alpine sh -c 'cd /from && cp -a . /to/' } @@ -197,6 +200,7 @@ main() { if is_old_postgres_host; then summary+=( "обновить \`POSTGRES_HOST\` в \`.env\`" ) fi + summary+=( "подготовить новый стек через Compose в режиме \`--no-start\`" ) summary+=( "запустить compose-файл \`$(basename "$compose_file")\`" ) if [[ "$assume_yes" != "1" ]]; then @@ -260,7 +264,17 @@ main() { log " - локальная ветка уже совпадает с удалённой, \`git pull\` не нужен" fi - log "4. Переношу тома" + log "4. Обновляю \`.env\`" + update_postgres_host + + log "5. Подготавливаю новый стек через Compose" + if ((compose_has_build)); then + run "${compose_cmd[@]}" -f "$compose_file" up --no-start --build + else + run "${compose_cmd[@]}" -f "$compose_file" up --no-start + fi + + log "6. Переношу тома" if copy_volume "$OLD_DB_VOLUME" "$NEW_DB_VOLUME"; then log " - БД перенесена в \`$NEW_DB_VOLUME\`" fi @@ -274,10 +288,7 @@ main() { done fi - log "5. Обновляю \`.env\`" - update_postgres_host - - log "6. Запускаю новый стек" + log "7. Запускаю новый стек" if ((compose_has_build)); then up_args=(up -d --build --remove-orphans) else