feat: add offline docker bundle for enterprise clean releases
This commit is contained in:
21
.env.enterprise-clean.example
Normal file
21
.env.enterprise-clean.example
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Offline / air-gapped compose profile for enterprise clean release.
|
||||||
|
|
||||||
|
BACKEND_IMAGE=ss-tools-backend:v1.0.0-rc2
|
||||||
|
FRONTEND_IMAGE=ss-tools-frontend:v1.0.0-rc2
|
||||||
|
POSTGRES_IMAGE=postgres:16-alpine
|
||||||
|
|
||||||
|
POSTGRES_DB=ss_tools
|
||||||
|
POSTGRES_USER=postgres
|
||||||
|
POSTGRES_PASSWORD=change-me
|
||||||
|
|
||||||
|
BACKEND_HOST_PORT=8001
|
||||||
|
FRONTEND_HOST_PORT=8000
|
||||||
|
POSTGRES_HOST_PORT=5432
|
||||||
|
|
||||||
|
ENABLE_BELIEF_STATE_LOGGING=true
|
||||||
|
TASK_LOG_LEVEL=INFO
|
||||||
|
|
||||||
|
STORAGE_ROOT=./storage
|
||||||
|
|
||||||
|
OPENAI_API_KEY=
|
||||||
|
ANTHROPIC_API_KEY=
|
||||||
27
README.md
27
README.md
@@ -250,19 +250,19 @@ cd /home/busya/dev/ss-tools
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Собрать образы в подключённом контуре
|
# 1. Собрать образы в подключённом контуре
|
||||||
docker compose -f docker-compose.yml build
|
./scripts/build_offline_docker_bundle.sh v1.0.0-rc2
|
||||||
|
|
||||||
# 2. Экспортировать их в tar-архивы
|
# 2. Передать dist/docker/* в изолированный контур
|
||||||
docker save ss-tools-backend:TAG -o dist/docker/backend.TAG.tar
|
# 3. Импортировать образы локально
|
||||||
docker save ss-tools-frontend:TAG -o dist/docker/frontend.TAG.tar
|
docker load -i dist/docker/backend.v1.0.0-rc2.tar
|
||||||
|
docker load -i dist/docker/frontend.v1.0.0-rc2.tar
|
||||||
|
docker load -i dist/docker/postgres.v1.0.0-rc2.tar
|
||||||
|
|
||||||
# 3. Передать bundle в изолированный контур
|
# 4. Подготовить env из шаблона
|
||||||
# 4. Импортировать образы локально
|
cp dist/docker/.env.enterprise-clean.example .env.enterprise-clean
|
||||||
docker load -i dist/docker/backend.TAG.tar
|
|
||||||
docker load -i dist/docker/frontend.TAG.tar
|
|
||||||
|
|
||||||
# 5. Запустить только локальные образы
|
# 5. Запустить только локальные образы
|
||||||
docker compose -f docker-compose.enterprise-clean.yml up -d
|
docker compose --env-file .env.enterprise-clean -f dist/docker/docker-compose.enterprise-clean.yml up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
Ограничения для production-grade offline release:
|
Ограничения для production-grade offline release:
|
||||||
@@ -272,10 +272,10 @@ docker compose -f docker-compose.enterprise-clean.yml up -d
|
|||||||
- clean/compliance manifest должен включать docker image digests как часть evidence package.
|
- clean/compliance manifest должен включать docker image digests как часть evidence package.
|
||||||
|
|
||||||
Практический план внедрения:
|
Практический план внедрения:
|
||||||
- добавить pinned Docker image tags и отдельный `enterprise-clean` compose profile;
|
- pinned Docker image tags и отдельный `enterprise-clean` compose profile добавлены;
|
||||||
- подготовить `make release-docker-bundle` или shell script для `build -> save -> checksum`;
|
- shell script `scripts/build_offline_docker_bundle.sh` добавлен для `build -> save -> checksum`;
|
||||||
- включить docker image digests в clean-release manifest;
|
- следующим шагом стоит включить docker image digests в clean-release manifest;
|
||||||
- добавить smoke-check, что compose-файлы не содержат внешних registry references вне allowlist.
|
- следующим шагом стоит добавить smoke-check, что compose-файлы не содержат внешних registry references вне allowlist.
|
||||||
|
|
||||||
## 📖 Документация
|
## 📖 Документация
|
||||||
|
|
||||||
@@ -371,4 +371,3 @@ pip install -r requirements.txt --upgrade
|
|||||||
cd frontend
|
cd frontend
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
57
docker-compose.enterprise-clean.yml
Normal file
57
docker-compose.enterprise-clean.yml
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: ${POSTGRES_IMAGE:?Set POSTGRES_IMAGE in .env.enterprise-clean}
|
||||||
|
pull_policy: never
|
||||||
|
container_name: ss_tools_db
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:-ss_tools}
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env.enterprise-clean}
|
||||||
|
ports:
|
||||||
|
- "${POSTGRES_HOST_PORT:-5432}:5432"
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-ss_tools}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
backend:
|
||||||
|
image: ${BACKEND_IMAGE:?Set BACKEND_IMAGE in .env.enterprise-clean}
|
||||||
|
pull_policy: never
|
||||||
|
container_name: ss_tools_backend
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-ss_tools}
|
||||||
|
TASKS_DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-ss_tools}
|
||||||
|
AUTH_DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-ss_tools}
|
||||||
|
BACKEND_PORT: 8000
|
||||||
|
ENABLE_BELIEF_STATE_LOGGING: ${ENABLE_BELIEF_STATE_LOGGING:-true}
|
||||||
|
TASK_LOG_LEVEL: ${TASK_LOG_LEVEL:-INFO}
|
||||||
|
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
|
||||||
|
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
|
||||||
|
ports:
|
||||||
|
- "${BACKEND_HOST_PORT:-8001}:8000"
|
||||||
|
volumes:
|
||||||
|
- ./config.json:/app/config.json:ro
|
||||||
|
- ./backups:/app/backups
|
||||||
|
- ./backend/git_repos:/app/backend/git_repos
|
||||||
|
- ${STORAGE_ROOT:-./storage}:/app/storage
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
image: ${FRONTEND_IMAGE:?Set FRONTEND_IMAGE in .env.enterprise-clean}
|
||||||
|
pull_policy: never
|
||||||
|
container_name: ss_tools_frontend
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
ports:
|
||||||
|
- "${FRONTEND_HOST_PORT:-8000}:80"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
- [Требования](#требования)
|
- [Требования](#требования)
|
||||||
- [Установка через Docker](#установка-через-docker)
|
- [Установка через Docker](#установка-через-docker)
|
||||||
|
- [Offline Docker Bundle](#offline-docker-bundle)
|
||||||
- [Локальная установка](#локальная-установка)
|
- [Локальная установка](#локальная-установка)
|
||||||
- [Первая настройка](#первая-настройка)
|
- [Первая настройка](#первая-настройка)
|
||||||
- [Конфигурация окружений](#конфигурация-окружений)
|
- [Конфигурация окружений](#конфигурация-окружений)
|
||||||
@@ -143,6 +144,59 @@ createdb ss_tools
|
|||||||
psql -U postgres -d ss_tools
|
psql -U postgres -d ss_tools
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Offline Docker Bundle
|
||||||
|
|
||||||
|
Этот режим предназначен для enterprise clean-развёртывания в контуре без доступа к внешнему интернету.
|
||||||
|
|
||||||
|
### 1. Сборка bundle в подключённом контуре
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/busya/dev/ss-tools
|
||||||
|
./scripts/build_offline_docker_bundle.sh v1.0.0-rc2
|
||||||
|
```
|
||||||
|
|
||||||
|
Результат появится в `dist/docker/`:
|
||||||
|
- `backend.v1.0.0-rc2.tar`
|
||||||
|
- `frontend.v1.0.0-rc2.tar`
|
||||||
|
- `postgres.v1.0.0-rc2.tar`
|
||||||
|
- `sha256sums.v1.0.0-rc2.txt`
|
||||||
|
- `manifest.v1.0.0-rc2.txt`
|
||||||
|
- `docker-compose.enterprise-clean.yml`
|
||||||
|
- `.env.enterprise-clean.example`
|
||||||
|
|
||||||
|
### 2. Перенос bundle в изолированный контур
|
||||||
|
|
||||||
|
Передайте каталог `dist/docker/` во внутреннюю сеть любым утверждённым способом.
|
||||||
|
|
||||||
|
### 3. Импорт образов
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker load -i backend.v1.0.0-rc2.tar
|
||||||
|
docker load -i frontend.v1.0.0-rc2.tar
|
||||||
|
docker load -i postgres.v1.0.0-rc2.tar
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Подготовка конфигурации
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.enterprise-clean.example .env.enterprise-clean
|
||||||
|
```
|
||||||
|
|
||||||
|
Минимально проверьте:
|
||||||
|
- `BACKEND_IMAGE`
|
||||||
|
- `FRONTEND_IMAGE`
|
||||||
|
- `POSTGRES_IMAGE`
|
||||||
|
- `POSTGRES_PASSWORD`
|
||||||
|
- `STORAGE_ROOT`
|
||||||
|
|
||||||
|
### 5. Запуск в offline-контуре
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --env-file .env.enterprise-clean -f docker-compose.enterprise-clean.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Compose-файл использует `pull_policy: never`, поэтому runtime не должен обращаться к внешним registry.
|
||||||
|
|
||||||
## Первая настройка
|
## Первая настройка
|
||||||
|
|
||||||
### 1. Инициализация базы данных
|
### 1. Инициализация базы данных
|
||||||
|
|||||||
58
scripts/build_offline_docker_bundle.sh
Executable file
58
scripts/build_offline_docker_bundle.sh
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# [DEF:scripts.build_offline_docker_bundle:Module]
|
||||||
|
# @PURPOSE: Build and export an offline Docker bundle for enterprise-clean releases.
|
||||||
|
# [/DEF:scripts.build_offline_docker_bundle:Module]
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
DIST_ROOT="${PROJECT_ROOT}/dist/docker"
|
||||||
|
|
||||||
|
TAG="${1:-v1.0.0-rc2}"
|
||||||
|
POSTGRES_IMAGE="${POSTGRES_IMAGE:-postgres:16-alpine}"
|
||||||
|
BACKEND_IMAGE="ss-tools-backend:${TAG}"
|
||||||
|
FRONTEND_IMAGE="ss-tools-frontend:${TAG}"
|
||||||
|
|
||||||
|
mkdir -p "${DIST_ROOT}"
|
||||||
|
|
||||||
|
cd "${PROJECT_ROOT}"
|
||||||
|
|
||||||
|
echo "[offline-bundle] building backend image ${BACKEND_IMAGE}"
|
||||||
|
docker build -f docker/backend.Dockerfile -t "${BACKEND_IMAGE}" .
|
||||||
|
|
||||||
|
echo "[offline-bundle] building frontend image ${FRONTEND_IMAGE}"
|
||||||
|
docker build -f docker/frontend.Dockerfile -t "${FRONTEND_IMAGE}" .
|
||||||
|
|
||||||
|
echo "[offline-bundle] pulling postgres image ${POSTGRES_IMAGE}"
|
||||||
|
docker pull "${POSTGRES_IMAGE}"
|
||||||
|
|
||||||
|
echo "[offline-bundle] exporting tar archives"
|
||||||
|
docker save -o "${DIST_ROOT}/backend.${TAG}.tar" "${BACKEND_IMAGE}"
|
||||||
|
docker save -o "${DIST_ROOT}/frontend.${TAG}.tar" "${FRONTEND_IMAGE}"
|
||||||
|
docker save -o "${DIST_ROOT}/postgres.${TAG}.tar" "${POSTGRES_IMAGE}"
|
||||||
|
|
||||||
|
echo "[offline-bundle] calculating checksums"
|
||||||
|
(
|
||||||
|
cd "${DIST_ROOT}"
|
||||||
|
sha256sum "backend.${TAG}.tar" "frontend.${TAG}.tar" "postgres.${TAG}.tar" > "sha256sums.${TAG}.txt"
|
||||||
|
)
|
||||||
|
|
||||||
|
cat > "${DIST_ROOT}/manifest.${TAG}.txt" <<EOF
|
||||||
|
release_tag=${TAG}
|
||||||
|
backend_image=${BACKEND_IMAGE}
|
||||||
|
frontend_image=${FRONTEND_IMAGE}
|
||||||
|
postgres_image=${POSTGRES_IMAGE}
|
||||||
|
compose_file=docker-compose.enterprise-clean.yml
|
||||||
|
env_template=.env.enterprise-clean.example
|
||||||
|
generated_at_utc=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cp "${PROJECT_ROOT}/docker-compose.enterprise-clean.yml" "${DIST_ROOT}/docker-compose.enterprise-clean.yml"
|
||||||
|
cp "${PROJECT_ROOT}/.env.enterprise-clean.example" "${DIST_ROOT}/.env.enterprise-clean.example"
|
||||||
|
|
||||||
|
echo "[offline-bundle] bundle created in ${DIST_ROOT}"
|
||||||
|
echo "[offline-bundle] next step:"
|
||||||
|
echo " docker load -i ${DIST_ROOT}/backend.${TAG}.tar"
|
||||||
|
echo " docker load -i ${DIST_ROOT}/frontend.${TAG}.tar"
|
||||||
|
echo " docker load -i ${DIST_ROOT}/postgres.${TAG}.tar"
|
||||||
Reference in New Issue
Block a user