diff --git a/README.md b/README.md index 32d9795..3432340 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,13 @@ ## Требования -- VPS с **Docker** и **Docker Compose v2** — команда **`docker compose`** (плагин `docker-compose-plugin`). - **Не подходит** старый **`docker-compose`** 1.x из Ubuntu — на новых образах будет ошибка **`ContainerConfig` / KeyError**. -- Установка плагина: `sudo apt-get update && sudo apt-get install -y docker-compose-plugin` -- Также нужны **curl** и при первой установке — **git** -- Активная подписка и **ключ** (GitHub PAT с `read:packages`), см. закрытый пост Boosty +- VPS с установленным **Docker** и запущенным демоном. +- Командная строка должна понимать **`docker compose`** (Compose v2). + Если пакета **`docker-compose-plugin`** нет в ваших APT‑репозиториях, **`quick-install.sh`** по умолчанию **скачивает официальный CLI‑плагин** Compose v2 с GitHub Releases в **`/usr/local/lib/docker/cli-plugins/`** (переменные **`COMPOSE_CLI_VERSION`** / **`DISABLE_STANDALONE_COMPOSE_DOWNLOAD=1`** — см. `scripts/lib-compose-v2.sh`). +- Альтернатива: добавить **[репозиторий Docker CE](https://docs.docker.com/engine/install/ubuntu/)** и поставить **`docker-compose-plugin`** из apt. +- **Не использовать** одноимённый устаревший **`docker-compose` 1.x** (Python): на образах GHCR будет **`ContainerConfig` / KeyError**. +- Нужны **curl** и при первой установке — **git** +- Подписка и **ключ** (GitHub PAT с `read:packages`), см. закрытый пост Boosty ## Одна команда — FREE → PRO (спросит только ключ) @@ -25,6 +27,8 @@ curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia-web-pro-deploy 3. Подставляет **`AWG_CONTAINER`** автоматически, если на сервере уже есть `amnezia-awg` или `amnezia-awg2`. 4. Клонирует/обновляет **`/opt/amnezia-web-pro-deploy`**, тянет тег из [`PRO_IMAGE_TAG`](PRO_IMAGE_TAG), запрашивает **ключ PAT** (ввод с **`/dev/tty`**). +Перед всем этим, если **`docker compose`** отсутствует, установщик **подтягивает** модуль Compose v2 (см. выше). + Отключить снос FREE (редко нужно): `SKIP_REMOVE_FREE=1 curl … | sudo -E bash`. Если **нет интерактива** на stdin: @@ -48,21 +52,18 @@ HOST_PORT=8081 curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia ### `KeyError: 'ContainerConfig'` и в трассировке указан **`docker-compose` 1.29.x** (`/usr/lib/python3/...`) -Старый **Docker Compose v1** из пакета `docker-compose` **непонимает** образы из GHCR с современным OCI-манифестом без поля **`ContainerConfig`**. Нужна **Compose v2** — команда **`docker compose`** (пакет-плагин). +Старый **Docker Compose v1** из пакета `docker-compose` **непонимает** образы из GHCR с современным OCI-манифестом без поля **`ContainerConfig`**. Нужна **Compose v2** — **`docker compose`**. -```bash -sudo apt-get update -sudo apt-get install -y docker-compose-plugin -docker compose version -``` - -Затем обновите файлы установки (**на ветке `main` уже запрещён fallback на 1.x**): +На актуальной ветке **`main`** установщики **не дергают legacy `docker-compose` 1.x**, а поднимают Compose v2 через APT (**если пакет виден**) либо **официальный CLI‑плагин с GitHub**. ```bash sudo git -C /opt/amnezia-web-pro-deploy fetch origin main sudo git -C /opt/amnezia-web-pro-deploy reset --hard origin/main +curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia-web-pro-deploy/main/quick-install.sh | sudo bash ``` +Вручную: **`docker-compose-plugin`** из [репозитория Docker CE](https://docs.docker.com/engine/install/ubuntu/) или шаг из справки в **`scripts/lib-compose-v2.sh`**. + Если после неудачного `up` образовался полубитый контейнер: ```bash @@ -72,6 +73,21 @@ sudo bash /opt/amnezia-web-pro-deploy/scripts/install.sh Если файл **`.env` удалён или пуст**, снова запустите **`quick-install.sh`** — он заново попросит PAT. +### `Unable to locate package docker-compose-plugin` (Ubuntu без репозитория Docker) + +Пакет поставляет официальный репозиторий Docker CE на Ubuntu/Debian. Если его подключать не хотите или `apt-get` всё равно пишет, что пакета нет: + +1. Просто снова запустите обновлённый **`quick-install.sh`** после `git pull` репозитория установки — он попытается **скачать плагин Compose v2 напрямую** с GitHub (нужны `curl` и исходящий HTTPS до `github.com`). + +Либо отдельно: + +```bash +sudo curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia-web-pro-deploy/main/scripts/lib-compose-v2.sh -o /tmp/lib-compose-v2.sh +sudo bash -c 'source /tmp/lib-compose-v2.sh && ensure_compose_v2' +sudo rm -f /tmp/lib-compose-v2.sh +docker compose version +``` + ## Ручной способ (git + .env) ```bash diff --git a/docs/BOOSTY_SUBSCRIBERS_POST.md b/docs/BOOSTY_SUBSCRIBERS_POST.md index b55ee8a..ff0b04d 100644 --- a/docs/BOOSTY_SUBSCRIBERS_POST.md +++ b/docs/BOOSTY_SUBSCRIBERS_POST.md @@ -10,15 +10,14 @@ ### Установка одной командой -На VPS установите Docker и Compose v2, затем выполните **от root**: +На VPS установите **Docker Engine** (`docker.io` / пакеты Docker CE) и утилиты **`curl`**, **`git`**, затем выполните **от root**: ```bash -sudo apt-get update && sudo apt-get install -y curl git docker-compose-plugin -docker compose version +sudo apt-get update && sudo apt-get install -y curl git docker.io curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia-web-pro-deploy/main/quick-install.sh | sudo bash ``` -Нужен именно **`docker compose`** (плагин v2). Старый пакет **`docker-compose`** 1.x из Ubuntu ломает установку (**ContainerConfig**). +Нужна именно команда **`docker compose`** (Compose v2). Если пакет **`docker-compose-plugin`** недоступен в ваших репозиториях APT, **обновлённый `quick-install.sh` сам ставит официальный плагин** с GitHub в `/usr/local/lib/docker/cli-plugins/` (можно отключить: см. файл `scripts/lib-compose-v2.sh` в репозитории установки). Старый пакет **`docker-compose`** 1.x из Ubuntu **не использовать** — на новых образах будет ошибка **ContainerConfig**. Установщик **снимает FREE-панель** (типовой `amnezia_web`: контейнеры `amnezia-admin`, лендинг, образы и `/opt/amnezia-admin`). **Контейнер AmneziaWG/VPN не удаляется.** Затем ставится PRO и запрашивается ключ ниже. diff --git a/quick-install.sh b/quick-install.sh index 23176b8..078631a 100755 --- a/quick-install.sh +++ b/quick-install.sh @@ -41,13 +41,16 @@ if ! docker info >/dev/null 2>&1; then fi if ! docker compose version >/dev/null 2>&1; then - echo "Ошибка: нужен Docker Compose v2 — команда «docker compose»." >&2 - echo "Старый «docker-compose» 1.x из apt даёт ошибку ContainerConfig на новых образах." >&2 - echo "" >&2 - echo "Установите плагин и повторите:" >&2 - echo " sudo apt-get update && sudo apt-get install -y docker-compose-plugin" >&2 - echo " docker compose version" >&2 - exit 1 + _lib="$(mktemp)" + if ! curl -fsSL "${RAW_BASE}/scripts/lib-compose-v2.sh" -o "${_lib}"; then + echo "Не удалось скачать вспомогательный файл Compose v2 (${RAW_BASE}/scripts/lib-compose-v2.sh)." >&2 + rm -f "${_lib}" + exit 1 + fi + # shellcheck disable=SC1090 + source "${_lib}" + rm -f "${_lib}" + ensure_compose_v2 || exit 1 fi # Снимаем FREE-панель (amnezia_web / install.sh): контейнеры + локальный образ + каталог сборки. diff --git a/scripts/install.sh b/scripts/install.sh index d3b7b33..007eaa6 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -5,6 +5,8 @@ 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}" +# shellcheck disable=SC1091 +source "${ROOT_DIR}/scripts/lib-compose-v2.sh" need_root() { if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then @@ -24,23 +26,10 @@ need_docker() { } } -# Не используем legacy docker-compose 1.x (Python): KeyError ContainerConfig на новых образах. -need_compose_v2() { - if docker compose version >/dev/null 2>&1; then - COMPOSE=(docker compose) - return 0 - fi - echo "Ошибка: нужен Docker Compose v2 — команда «docker compose», не старый «docker-compose» 1.x из apt." >&2 - echo "" >&2 - echo "Установка плагина (Ubuntu/Debian):" >&2 - echo " sudo apt-get update && sudo apt-get install -y docker-compose-plugin" >&2 - echo "Проверка: docker compose version" >&2 - exit 1 -} - need_root need_docker -need_compose_v2 +ensure_compose_v2 || exit 1 +COMPOSE=(docker compose) if [[ ! -f "${ENV_FILE}" ]]; then echo "Создайте файл .env из .env.example и вставьте GHCR_* из закрытого поста Boosty:" diff --git a/scripts/lib-compose-v2.sh b/scripts/lib-compose-v2.sh new file mode 100644 index 0000000..a4d48a9 --- /dev/null +++ b/scripts/lib-compose-v2.sh @@ -0,0 +1,123 @@ +#!/usr/bin/env bash +# Функции для проверки и установки Docker Compose v2 («docker compose»). +# Файл предназначен для source из quick-install (через curl) и из install/update. + +compose_plugin_download_name_for_arch() { + case "$(uname -m)" in + x86_64 | amd64) + printf '%s' docker-compose-linux-x86_64 + ;; + aarch64 | arm64) + printf '%s' docker-compose-linux-aarch64 + ;; + armv7l) + printf '%s' docker-compose-linux-armv7 + ;; + *) + printf '%s' '' + ;; + esac +} + +compose_v2_ok() { + docker compose version >/dev/null 2>&1 +} + +print_compose_v2_help_text() { + cat <<'EOF' + +Нужен Docker Compose v2 — команда «docker compose». + +• Быстро (если хотите ставить только плагин, без нашего автозагрузчика): + + sudo mkdir -p /usr/local/lib/docker/cli-plugins + ARCH=$(uname -m) + case "$ARCH" in x86_64|amd64) N=docker-compose-linux-x86_64 ;; aarch64|arm64) N=docker-compose-linux-aarch64 ;; *) echo "Архитектура не поддерживается: $ARCH"; exit 1 ;; esac + sudo curl -fsSL "https://github.com/docker/compose/releases/download/v2.36.0/${N}" -o /usr/local/lib/docker/cli-plugins/docker-compose + sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose + docker compose version + +• Если удобнее через репозиторий Docker CE (Ubuntu): + + см. https://docs.docker.com/engine/install/ubuntu/ + + После добавления repo: sudo apt-get update && sudo apt-get install -y docker-compose-plugin + +• Принудительно отключить авто‑скачивание плагина из quick-install/install: + + DISABLE_STANDALONE_COMPOSE_DOWNLOAD=1 + +• Версия релиза GitHub задаётся переменной COMPOSE_CLI_VERSION (по умолчанию v2.36.0). +EOF +} + +try_apt_install_docker_compose_plugin() { + command -v apt-get >/dev/null 2>&1 || return 1 + if ! apt-cache show docker-compose-plugin >/dev/null 2>&1; then + return 1 + fi + local cand="" + cand="$(apt-cache policy docker-compose-plugin 2>/dev/null | awk '/^ Candidate:/ {print $2; exit}')" + if [[ -z "${cand}" || "${cand}" == "(none)" ]]; then + return 1 + fi + + echo "→ APT: устанавливаю docker-compose-plugin..." >&2 + DEBIAN_FRONTEND=noninteractive apt-get update -qq || + DEBIAN_FRONTEND=noninteractive apt-get update + DEBIAN_FRONTEND=noninteractive apt-get install -y docker-compose-plugin +} + +install_compose_v2_cli_plugin_standalone() { + local name version url plugin_dir tmp target + + name="$(compose_plugin_download_name_for_arch)" + if [[ -z "${name}" ]]; then + echo "Ошибка: архитектура $(uname -m) не поддерживается авто‑установкой Compose v2." >&2 + return 1 + fi + + version="${COMPOSE_CLI_VERSION:-v2.36.0}" + url="https://github.com/docker/compose/releases/download/${version}/${name}" + plugin_dir="${COMPOSE_CLI_PLUGIN_DIR:-/usr/local/lib/docker/cli-plugins}" + target="${plugin_dir}/docker-compose" + tmp="${target}.tmp.$$" + + echo "→ Скачиваю Docker Compose ${version} → ${target}" >&2 + mkdir -p "${plugin_dir}" + curl -fsSL "${url}" -o "${tmp}" + chmod +x "${tmp}" + mv -f "${tmp}" "${target}" +} + +# Требует root для APT/записи в /usr/local (у standalone). +ensure_compose_v2() { + if compose_v2_ok; then + return 0 + fi + + echo "Не найдена команда «docker compose» (Compose v2)." >&2 + echo "Старый «docker-compose» 1.x из apt здесь не подходит (ошибка ContainerConfig на новых образах)." >&2 + + if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then + print_compose_v2_help_text >&2 + return 1 + fi + + if try_apt_install_docker_compose_plugin && compose_v2_ok; then + docker compose version | head -n1 >&2 + return 0 + fi + + if [[ "${DISABLE_STANDALONE_COMPOSE_DOWNLOAD:-}" == "1" ]]; then + print_compose_v2_help_text >&2 + return 1 + fi + + if ! install_compose_v2_cli_plugin_standalone || ! compose_v2_ok; then + print_compose_v2_help_text >&2 + return 1 + fi + + docker compose version | head -n1 >&2 +} diff --git a/scripts/update.sh b/scripts/update.sh index 49d4787..3fe85f4 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -3,19 +3,16 @@ 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" +# shellcheck disable=SC1091 +source "${ROOT_DIR}/scripts/lib-compose-v2.sh" if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then echo "Запустите от root." exit 1 fi -if docker compose version >/dev/null 2>&1; then - COMPOSE=(docker compose) -else - echo "Ошибка: нужен Docker Compose v2 («docker compose»). Старый docker-compose 1.x не поддерживается." >&2 - echo " sudo apt-get update && sudo apt-get install -y docker-compose-plugin" >&2 - exit 1 -fi +ensure_compose_v2 || exit 1 +COMPOSE=(docker compose) set -a # shellcheck disable=SC1090