mirror of
https://github.com/andrey271192/amnezia-web-pro-deploy.git
synced 2026-09-20 13:50:06 +00:00
feat: install Compose v2 when apt plugin is missing
Add lib-compose-v2.sh: try docker-compose-plugin from APT only if indexed, otherwise download official CLI plugin from GitHub Releases. quick-install bootstraps via curl before clone; install/update reuse the helper from repo. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
42
README.md
42
README.md
@@ -4,11 +4,13 @@
|
|||||||
|
|
||||||
## Требования
|
## Требования
|
||||||
|
|
||||||
- VPS с **Docker** и **Docker Compose v2** — команда **`docker compose`** (плагин `docker-compose-plugin`).
|
- VPS с установленным **Docker** и запущенным демоном.
|
||||||
**Не подходит** старый **`docker-compose`** 1.x из Ubuntu — на новых образах будет ошибка **`ContainerConfig` / KeyError**.
|
- Командная строка должна понимать **`docker compose`** (Compose v2).
|
||||||
- Установка плагина: `sudo apt-get update && sudo apt-get install -y docker-compose-plugin`
|
Если пакета **`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`).
|
||||||
- Также нужны **curl** и при первой установке — **git**
|
- Альтернатива: добавить **[репозиторий Docker CE](https://docs.docker.com/engine/install/ubuntu/)** и поставить **`docker-compose-plugin`** из apt.
|
||||||
- Активная подписка и **ключ** (GitHub PAT с `read:packages`), см. закрытый пост Boosty
|
- **Не использовать** одноимённый устаревший **`docker-compose` 1.x** (Python): на образах GHCR будет **`ContainerConfig` / KeyError**.
|
||||||
|
- Нужны **curl** и при первой установке — **git**
|
||||||
|
- Подписка и **ключ** (GitHub PAT с `read:packages`), см. закрытый пост Boosty
|
||||||
|
|
||||||
## Одна команда — FREE → PRO (спросит только ключ)
|
## Одна команда — FREE → PRO (спросит только ключ)
|
||||||
|
|
||||||
@@ -25,6 +27,8 @@ curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia-web-pro-deploy
|
|||||||
3. Подставляет **`AWG_CONTAINER`** автоматически, если на сервере уже есть `amnezia-awg` или `amnezia-awg2`.
|
3. Подставляет **`AWG_CONTAINER`** автоматически, если на сервере уже есть `amnezia-awg` или `amnezia-awg2`.
|
||||||
4. Клонирует/обновляет **`/opt/amnezia-web-pro-deploy`**, тянет тег из [`PRO_IMAGE_TAG`](PRO_IMAGE_TAG), запрашивает **ключ PAT** (ввод с **`/dev/tty`**).
|
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`.
|
Отключить снос FREE (редко нужно): `SKIP_REMOVE_FREE=1 curl … | sudo -E bash`.
|
||||||
|
|
||||||
Если **нет интерактива** на stdin:
|
Если **нет интерактива** на 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/...`)
|
### `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
|
На актуальной ветке **`main`** установщики **не дергают legacy `docker-compose` 1.x**, а поднимают Compose v2 через APT (**если пакет виден**) либо **официальный CLI‑плагин с GitHub**.
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y docker-compose-plugin
|
|
||||||
docker compose version
|
|
||||||
```
|
|
||||||
|
|
||||||
Затем обновите файлы установки (**на ветке `main` уже запрещён fallback на 1.x**):
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo git -C /opt/amnezia-web-pro-deploy fetch origin main
|
sudo git -C /opt/amnezia-web-pro-deploy fetch origin main
|
||||||
sudo git -C /opt/amnezia-web-pro-deploy reset --hard 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` образовался полубитый контейнер:
|
Если после неудачного `up` образовался полубитый контейнер:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -72,6 +73,21 @@ sudo bash /opt/amnezia-web-pro-deploy/scripts/install.sh
|
|||||||
|
|
||||||
Если файл **`.env` удалён или пуст**, снова запустите **`quick-install.sh`** — он заново попросит PAT.
|
Если файл **`.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)
|
## Ручной способ (git + .env)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -10,15 +10,14 @@
|
|||||||
|
|
||||||
### Установка одной командой
|
### Установка одной командой
|
||||||
|
|
||||||
На VPS установите Docker и Compose v2, затем выполните **от root**:
|
На VPS установите **Docker Engine** (`docker.io` / пакеты Docker CE) и утилиты **`curl`**, **`git`**, затем выполните **от root**:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get update && sudo apt-get install -y curl git docker-compose-plugin
|
sudo apt-get update && sudo apt-get install -y curl git docker.io
|
||||||
docker compose version
|
|
||||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia-web-pro-deploy/main/quick-install.sh | sudo bash
|
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 и запрашивается ключ ниже.
|
Установщик **снимает FREE-панель** (типовой `amnezia_web`: контейнеры `amnezia-admin`, лендинг, образы и `/opt/amnezia-admin`). **Контейнер AmneziaWG/VPN не удаляется.** Затем ставится PRO и запрашивается ключ ниже.
|
||||||
|
|
||||||
|
|||||||
@@ -41,14 +41,17 @@ if ! docker info >/dev/null 2>&1; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if ! docker compose version >/dev/null 2>&1; then
|
if ! docker compose version >/dev/null 2>&1; then
|
||||||
echo "Ошибка: нужен Docker Compose v2 — команда «docker compose»." >&2
|
_lib="$(mktemp)"
|
||||||
echo "Старый «docker-compose» 1.x из apt даёт ошибку ContainerConfig на новых образах." >&2
|
if ! curl -fsSL "${RAW_BASE}/scripts/lib-compose-v2.sh" -o "${_lib}"; then
|
||||||
echo "" >&2
|
echo "Не удалось скачать вспомогательный файл Compose v2 (${RAW_BASE}/scripts/lib-compose-v2.sh)." >&2
|
||||||
echo "Установите плагин и повторите:" >&2
|
rm -f "${_lib}"
|
||||||
echo " sudo apt-get update && sudo apt-get install -y docker-compose-plugin" >&2
|
|
||||||
echo " docker compose version" >&2
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "${_lib}"
|
||||||
|
rm -f "${_lib}"
|
||||||
|
ensure_compose_v2 || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Снимаем FREE-панель (amnezia_web / install.sh): контейнеры + локальный образ + каталог сборки.
|
# Снимаем FREE-панель (amnezia_web / install.sh): контейнеры + локальный образ + каталог сборки.
|
||||||
# VPN/AWG контейнеры (amnezia-awg, amnezia-awg2 и т.д.) не останавливаем.
|
# VPN/AWG контейнеры (amnezia-awg, amnezia-awg2 и т.д.) не останавливаем.
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ set -euo pipefail
|
|||||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
COMPOSE_FILE="${ROOT_DIR}/docker-compose.yml"
|
COMPOSE_FILE="${ROOT_DIR}/docker-compose.yml"
|
||||||
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
|
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "${ROOT_DIR}/scripts/lib-compose-v2.sh"
|
||||||
|
|
||||||
need_root() {
|
need_root() {
|
||||||
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
|
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_root
|
||||||
need_docker
|
need_docker
|
||||||
need_compose_v2
|
ensure_compose_v2 || exit 1
|
||||||
|
COMPOSE=(docker compose)
|
||||||
|
|
||||||
if [[ ! -f "${ENV_FILE}" ]]; then
|
if [[ ! -f "${ENV_FILE}" ]]; then
|
||||||
echo "Создайте файл .env из .env.example и вставьте GHCR_* из закрытого поста Boosty:"
|
echo "Создайте файл .env из .env.example и вставьте GHCR_* из закрытого поста Boosty:"
|
||||||
|
|||||||
123
scripts/lib-compose-v2.sh
Normal file
123
scripts/lib-compose-v2.sh
Normal file
@@ -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
|
||||||
|
}
|
||||||
@@ -3,19 +3,16 @@ set -euo pipefail
|
|||||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
|
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
|
||||||
COMPOSE_FILE="${ROOT_DIR}/docker-compose.yml"
|
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
|
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
|
||||||
echo "Запустите от root."
|
echo "Запустите от root."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if docker compose version >/dev/null 2>&1; then
|
ensure_compose_v2 || exit 1
|
||||||
COMPOSE=(docker compose)
|
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
|
|
||||||
|
|
||||||
set -a
|
set -a
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
|
|||||||
Reference in New Issue
Block a user