feat(replication): ORCH-10b Bundled-тираж — bundle-compose всего стека + bootstrap-скрипт
Закрывает Type B эпика ORCH-10 (по ADR-001 ORCH-103, D1–D11): - deploy/bundled/docker-compose.yml — самодостаточный compose всего стека (орк + watchdog + Gitea 1.22.6 + зеркало upstream Plane CE v0.23.1, ~14 контейнеров); project name orchestrator-bundle (узнаваемый префикс), container_name не пиннится, staging-контура нет; одна bridge-сеть, машинный трафик — сервис-DNS, наружу только человеческие порты; GITEA__webhook__ALLOWED_HOST_LIST=orchestrator; все образы пиннованы неподвижными тегами. Корневой compose/Dockerfile/src/** — байт-в-байт. - deploy/bundled/.env.example — конфиг-канон bundle (плейсхолдеры, ни одного дефолтного пароля; key-set-sync интерполяций держит тест). - scripts/bootstrap_bundle.py — python stdlib-only, режимы plan/apply/verify, step-движок check→ensure, exit 0/2/1: preflight (fail-fast до мутаций) → секреты (gen_secrets.py + stdlib secrets, без перетирания) → up+готовность → init Gitea автоматом → init Plane (manual-step с API-верификацией) → онбординг строго onboard_project.py apply+verify → token-remote клон → сборка .env/.env.watchdog (единственный писатель, права 600) → health. Delete-операций нет вообще (D9), секреты не печатаются (NFR-3). - CHANGELOG.md, CLAUDE.md (абзац Type B), .gitignore (deploy/bundled/repos/). Док BUNDLED_SETUP.md, REPLICATION §1, arch README, adr-0038 и три структурных тест-модуля (TC-01…TC-11) — в предыдущих коммитах ветки; полный регресс 1844 passed, ruff по файлам задачи чистый. Refs: ORCH-103 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
61
deploy/bundled/.env.example
Normal file
61
deploy/bundled/.env.example
Normal file
@@ -0,0 +1,61 @@
|
||||
# deploy/bundled/.env — конфиг bundle-ИНФРЫ (ORCH-103, ADR-001 D2).
|
||||
# Канонический example: 100% ключей интерполяции deploy/bundled/docker-compose.yml
|
||||
# (key-set-sync держит tests/test_bundle_compose.py) + ключи init-кред, которые
|
||||
# заполняет bootstrap. Создание: cp .env.example .env (или это сделает
|
||||
# scripts/bootstrap_bundle.py apply); права 600.
|
||||
#
|
||||
# ⚠️ СЕМАНТИКА ФАЙЛА-НОСИТЕЛЯ (TR-8): этот файл читает ТОЛЬКО compose-интерполяция
|
||||
# bundle (авто-чтение .env из project dir deploy/bundled/). Runtime-конфиг самого
|
||||
# оркестратора и watchdog — КОРНЕВЫЕ .env / .env.watchdog (каноны Lite 1:1:
|
||||
# .env.example / .env.watchdog.example, карта — docs/operations/REPLICATION.md §2).
|
||||
# Единственный писатель всех live-файлов — scripts/bootstrap_bundle.py: дублируемые
|
||||
# ключи (uid/gid, HOME, пути Claude CLI) когерентны механически, не дисциплиной.
|
||||
#
|
||||
# DO NOT COMMIT реальный deploy/bundled/.env (покрыт неякорным `.env` в .gitignore).
|
||||
# Секреты: НИ ОДНОГО дефолтного пароля — пустые значения ниже генерирует bootstrap
|
||||
# (stdlib secrets) и никогда не печатает (NFR-3); повторный запуск НЕ перетирает
|
||||
# существующие значения без явного --force-secrets.
|
||||
|
||||
# --- Публичная точка инсталляции -------------------------------------------
|
||||
# Хост, по которому браузер оператора открывает Plane/Gitea и по которому
|
||||
# строятся публичные ссылки (ORCH_GITEA_PUBLIC_URL / ORCH_PLANE_WEB_URL / WEB_URL
|
||||
# Plane / ROOT_URL Gitea). HTTPS/домены/reverse-proxy заказчика — вне bundle.
|
||||
BUNDLE_PUBLIC_HOST=localhost
|
||||
|
||||
# --- Карта публикуемых портов (D4: только человеческие точки) ---------------
|
||||
# Конфликт порта на хосте → отказ preflight bootstrap ДО любых мутаций (BR-7).
|
||||
BUNDLE_ORCH_PORT=8500
|
||||
BUNDLE_PLANE_PORT=8080
|
||||
BUNDLE_GITEA_HTTP_PORT=3000
|
||||
|
||||
# --- Идентичность контейнера орка (реюз имён ORCH-101: один факт = одно имя) --
|
||||
# uid:gid владельца deploy/bundled/repos (инвариант ORCH-040); docker-gid хоста
|
||||
# («МИНА 1», узнать: getent group docker). Заполняет bootstrap из id -u/-g/getent.
|
||||
ORCH_RUN_UID=1000
|
||||
ORCH_RUN_GID=1000
|
||||
ORCH_DOCKER_GID=999
|
||||
# HOME всех акторов в контейнере (группа ORCH-040 двигается одной переменной).
|
||||
ORCH_AGENT_HOME_DIR=/home/orchestrator
|
||||
|
||||
# --- LLM-предусловие хоста заказчика (bundle НЕ поставляет Claude CLI) -------
|
||||
# Пути дистрибутива claude-code/node и кред CLI на хосте (канон — LITE_SETUP §7).
|
||||
ORCH_HOST_CLAUDE_CODE_DIR=/usr/lib/node_modules/@anthropic-ai/claude-code
|
||||
ORCH_HOST_NODE_BIN=/usr/bin/node
|
||||
ORCH_HOST_CLAUDE_DIR=~/.claude
|
||||
ORCH_HOST_CLAUDE_JSON=~/.claude.json
|
||||
|
||||
# --- Внутренние креды Plane CE-стека (upstream-имена; значения — bootstrap) --
|
||||
POSTGRES_USER=plane
|
||||
POSTGRES_PASSWORD=
|
||||
POSTGRES_DB=plane
|
||||
SECRET_KEY=
|
||||
RABBITMQ_DEFAULT_USER=plane
|
||||
RABBITMQ_DEFAULT_PASS=
|
||||
RABBITMQ_DEFAULT_VHOST=plane
|
||||
MINIO_ROOT_USER=plane-minio-admin
|
||||
MINIO_ROOT_PASSWORD=
|
||||
|
||||
# --- Init-креды Gitea (D6: один пользователь-бот = админ, владелец репо,
|
||||
# носитель API-токена; создаёт bootstrap через `gitea admin user create`) --
|
||||
GITEA_ADMIN_USERNAME=orchestrator-bot
|
||||
GITEA_ADMIN_PASSWORD=
|
||||
338
deploy/bundled/docker-compose.yml
Normal file
338
deploy/bundled/docker-compose.yml
Normal file
@@ -0,0 +1,338 @@
|
||||
# ORCH-103 (Type B Bundled, ADR-001 D1–D4): самодостаточный compose ВСЕГО стека
|
||||
# для тиража «под ключ» на хост заказчика: orchestrator + orchestrator-watchdog +
|
||||
# Gitea + Plane CE (зеркало официального selfhost-référence makeplane/plane
|
||||
# v0.23.1: имена сервисов и env-контракт — upstream, анти-дрейф к их докам; наши
|
||||
# отличия от référence: пиннинг неподвижными тегами литералом вместо ${APP_RELEASE}
|
||||
# (NFR-6, держится tests/test_bundle_compose.py), убраны replicas/platform/SENTRY,
|
||||
# секреты БЕЗ дефолтных значений — их генерирует scripts/bootstrap_bundle.py).
|
||||
#
|
||||
# Этот файл НЕ исполняется в нашем прод-контуре (корневой docker-compose.yml —
|
||||
# байт-в-байт, заморожен анти-дрейфом ORCH-102); активация — только явный запуск
|
||||
# оператором на целевом хосте (паттерн ORCH-009, kill-switch не нужен).
|
||||
#
|
||||
# Конфиг-слои (D2): интерполяции ${VAR} читаются compose'ом из deploy/bundled/.env
|
||||
# (авто-чтение из project dir — без --env-file-футгана); канон ключей —
|
||||
# deploy/bundled/.env.example (key-set-sync держит тест). Runtime-конфиг орка и
|
||||
# watchdog — КОРНЕВЫЕ .env / .env.watchdog (канон Lite 1:1, REPLICATION §2);
|
||||
# их единственный писатель — bootstrap_bundle.py.
|
||||
#
|
||||
# Сеть (D4): одна bridge-сеть проекта; машинный трафик — строго сервис-DNS
|
||||
# (Plane→орк http://orchestrator:8500/webhook/plane, Gitea→орк .../webhook/gitea,
|
||||
# орк→Plane http://proxy, орк→Gitea http://gitea:3000); network_mode: host НЕ
|
||||
# используется (ssh-деплой-контур нашего хоста в bundle структурно спит —
|
||||
# ORCH_DEPLOY_SSH_HOST пуст). Наружу публикуются ТОЛЬКО человеческие порты
|
||||
# (орк/Plane proxy/Gitea web); postgres/redis/mq/minio не публикуются.
|
||||
#
|
||||
# Project name = узнаваемый префикс томов/контейнеров orchestrator-bundle_* (D1);
|
||||
# container_name сознательно НЕ пиннится ни у кого — bundle и Lite/корневой
|
||||
# compose не сталкиваются по именам на одном хосте.
|
||||
name: orchestrator-bundle
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: orchestrator-bundle
|
||||
driver: bridge
|
||||
|
||||
# Env-контракт Plane CE — upstream-имена (référence v0.23.1). Значения секретов
|
||||
# (POSTGRES_PASSWORD/SECRET_KEY/RABBITMQ_DEFAULT_PASS/MINIO_ROOT_PASSWORD) живут
|
||||
# ТОЛЬКО в deploy/bundled/.env (генерирует bootstrap); дефолтных паролей нет.
|
||||
x-plane-env: &plane-env
|
||||
environment:
|
||||
- WEB_URL=http://${BUNDLE_PUBLIC_HOST:-localhost}:${BUNDLE_PLANE_PORT:-8080}
|
||||
- DEBUG=0
|
||||
- CORS_ALLOWED_ORIGINS=http://${BUNDLE_PUBLIC_HOST:-localhost}:${BUNDLE_PLANE_PORT:-8080}
|
||||
- GUNICORN_WORKERS=1
|
||||
# db (upstream-имена; host/port — фиксированные сервис-DNS этого файла)
|
||||
- PGHOST=plane-db
|
||||
- PGDATABASE=${POSTGRES_DB:-plane}
|
||||
- POSTGRES_USER=${POSTGRES_USER:-plane}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- POSTGRES_DB=${POSTGRES_DB:-plane}
|
||||
- POSTGRES_PORT=5432
|
||||
- PGDATA=/var/lib/postgresql/data
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-plane}:${POSTGRES_PASSWORD}@plane-db:5432/${POSTGRES_DB:-plane}
|
||||
# redis
|
||||
- REDIS_HOST=plane-redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_URL=redis://plane-redis:6379/
|
||||
# rabbitmq
|
||||
- RABBITMQ_HOST=plane-mq
|
||||
- RABBITMQ_PORT=5672
|
||||
- RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER:-plane}
|
||||
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS}
|
||||
- RABBITMQ_DEFAULT_VHOST=${RABBITMQ_DEFAULT_VHOST:-plane}
|
||||
- RABBITMQ_VHOST=${RABBITMQ_DEFAULT_VHOST:-plane}
|
||||
- AMQP_URL=amqp://${RABBITMQ_DEFAULT_USER:-plane}:${RABBITMQ_DEFAULT_PASS}@plane-mq:5672/${RABBITMQ_DEFAULT_VHOST:-plane}
|
||||
# application secret (генерирует bootstrap; дефолта сознательно НЕТ)
|
||||
- SECRET_KEY=${SECRET_KEY}
|
||||
# datastore (minio)
|
||||
- USE_MINIO=1
|
||||
- AWS_REGION=
|
||||
- AWS_ACCESS_KEY_ID=${MINIO_ROOT_USER:-plane-minio-admin}
|
||||
- AWS_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD}
|
||||
- AWS_S3_ENDPOINT_URL=http://plane-minio:9000
|
||||
- AWS_S3_BUCKET_NAME=uploads
|
||||
- MINIO_ROOT_USER=${MINIO_ROOT_USER:-plane-minio-admin}
|
||||
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
|
||||
- BUCKET_NAME=uploads
|
||||
- FILE_SIZE_LIMIT=5242880
|
||||
# live server
|
||||
- API_BASE_URL=http://api:8000
|
||||
# proxy
|
||||
- NGINX_PORT=80
|
||||
|
||||
services:
|
||||
# ── Платформа: орк + sidecar-watchdog (образы собираются из этого же чекаута;
|
||||
# корневой Dockerfile / watchdog/Dockerfile — без правок, NFR-1) ──────────
|
||||
orchestrator:
|
||||
build:
|
||||
context: ../..
|
||||
# ORCH-101 (D5): uid/gid/home двигаются ОДНОЙ группой с user: и таргетами
|
||||
# маунтов ниже (инвариант ORCH-040). Дефолты bundle нейтральны (D2).
|
||||
args:
|
||||
APP_UID: ${ORCH_RUN_UID:-1000}
|
||||
APP_GID: ${ORCH_RUN_GID:-1000}
|
||||
APP_HOME: ${ORCH_AGENT_HOME_DIR:-/home/orchestrator}
|
||||
restart: unless-stopped
|
||||
user: "${ORCH_RUN_UID:-1000}:${ORCH_RUN_GID:-1000}"
|
||||
init: true
|
||||
command: ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8500"]
|
||||
ports:
|
||||
# человеческая точка: операторский smoke `curl /health` (D4)
|
||||
- "${BUNDLE_ORCH_PORT:-8500}:8500"
|
||||
volumes:
|
||||
# данные/репозитории — bind ВНУТРИ project dir (uid-причины ORCH-040;
|
||||
# покрыты .gitignore: неякорный data/ + deploy/bundled/repos/)
|
||||
- ./data:/app/data
|
||||
- ./repos:/repos
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
# LLM-предусловие хоста заказчика (bundle его НЕ поставляет, BRD §1.3)
|
||||
- ${ORCH_HOST_CLAUDE_CODE_DIR:-/usr/lib/node_modules/@anthropic-ai/claude-code}:/opt/claude-code:ro
|
||||
- ${ORCH_HOST_NODE_BIN:-/usr/bin/node}:/usr/bin/node:ro
|
||||
- ${ORCH_HOST_CLAUDE_DIR:-~/.claude}:${ORCH_AGENT_HOME_DIR:-/home/orchestrator}/.claude
|
||||
- ${ORCH_HOST_CLAUDE_JSON:-~/.claude.json}:${ORCH_AGENT_HOME_DIR:-/home/orchestrator}/.claude.json:ro
|
||||
# ssh-контур в bundle сознательно НЕ вводится (ADR D8): git-доступ агентов
|
||||
# — HTTP token-remote, деплой-хуки нашего хоста структурно спят.
|
||||
# runtime-конфиг орка собирает bootstrap (шаг 8); required:false — первый
|
||||
# `up -d` поднимает стек ДО сборки конфига (AC-1), орк жив без него.
|
||||
env_file:
|
||||
- path: ../../.env
|
||||
required: false
|
||||
environment:
|
||||
- ORCH_REPOS_DIR=/repos
|
||||
group_add:
|
||||
- "${ORCH_DOCKER_GID:-999}"
|
||||
|
||||
orchestrator-watchdog:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: watchdog/Dockerfile
|
||||
restart: unless-stopped
|
||||
init: true
|
||||
mem_limit: 128m
|
||||
mem_reservation: 32m
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ./repos:/repos:ro
|
||||
- ./data:/app/data:ro
|
||||
env_file:
|
||||
- path: ../../.env.watchdog
|
||||
required: false
|
||||
environment:
|
||||
# bundle-сеть ≠ host-network Lite: метрики — по сервис-DNS; имя контейнера
|
||||
# орка детерминировано project name (container_name не пиннится, D1).
|
||||
# environment перекрывает env_file → когерентность механическая (TR-8).
|
||||
- WATCHDOG_METRICS_URL=http://orchestrator:8500/metrics
|
||||
- WATCHDOG_CONTAINERS=orchestrator-bundle-orchestrator-1
|
||||
group_add:
|
||||
- "${ORCH_DOCKER_GID:-999}"
|
||||
|
||||
# ── Gitea (D6): официальный образ, НЕ rootless; init полностью автоматом —
|
||||
# bootstrap создаёт админа/токен через `gitea admin ...` CLI в контейнере.
|
||||
# Branch protection на main НЕ настраивается (норматив D10 ORCH-009/INV-4).
|
||||
gitea:
|
||||
image: gitea/gitea:1.22.6
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${BUNDLE_GITEA_HTTP_PORT:-3000}:3000"
|
||||
environment:
|
||||
- GITEA__database__DB_TYPE=sqlite3
|
||||
- GITEA__security__INSTALL_LOCK=true
|
||||
- GITEA__server__DOMAIN=${BUNDLE_PUBLIC_HOST:-localhost}
|
||||
- GITEA__server__ROOT_URL=http://${BUNDLE_PUBLIC_HOST:-localhost}:${BUNDLE_GITEA_HTTP_PORT:-3000}/
|
||||
# ssh-контур не вводится (D8): порт не публикуется, ssh выключен.
|
||||
- GITEA__server__DISABLE_SSH=true
|
||||
- GITEA__service__DISABLE_REGISTRATION=true
|
||||
# МИНА TR-4 (D4): Gitea по умолчанию режет webhook'и в приватные адреса —
|
||||
# без этой строки «задача не появилась» гарантирован.
|
||||
- GITEA__webhook__ALLOWED_HOST_LIST=orchestrator
|
||||
volumes:
|
||||
- gitea-data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-fsS", "http://localhost:3000/api/healthz"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
|
||||
# ── Plane CE — зеркало upstream selfhost-référence v0.23.1 (D3) ────────────
|
||||
web:
|
||||
<<: *plane-env
|
||||
image: makeplane/plane-frontend:v0.23.1
|
||||
restart: unless-stopped
|
||||
command: node web/server.js web
|
||||
depends_on:
|
||||
- api
|
||||
- worker
|
||||
|
||||
space:
|
||||
<<: *plane-env
|
||||
image: makeplane/plane-space:v0.23.1
|
||||
restart: unless-stopped
|
||||
command: node space/server.js space
|
||||
depends_on:
|
||||
- api
|
||||
- worker
|
||||
- web
|
||||
|
||||
admin:
|
||||
<<: *plane-env
|
||||
image: makeplane/plane-admin:v0.23.1
|
||||
restart: unless-stopped
|
||||
command: node admin/server.js admin
|
||||
depends_on:
|
||||
- api
|
||||
- web
|
||||
|
||||
live:
|
||||
<<: *plane-env
|
||||
image: makeplane/plane-live:v0.23.1
|
||||
restart: unless-stopped
|
||||
command: node live/dist/server.js live
|
||||
depends_on:
|
||||
- api
|
||||
- web
|
||||
|
||||
api:
|
||||
<<: *plane-env
|
||||
image: makeplane/plane-backend:v0.23.1
|
||||
restart: unless-stopped
|
||||
command: ./bin/docker-entrypoint-api.sh
|
||||
volumes:
|
||||
- logs_api:/code/plane/logs
|
||||
depends_on:
|
||||
- plane-db
|
||||
- plane-redis
|
||||
- plane-mq
|
||||
|
||||
worker:
|
||||
<<: *plane-env
|
||||
image: makeplane/plane-backend:v0.23.1
|
||||
restart: unless-stopped
|
||||
command: ./bin/docker-entrypoint-worker.sh
|
||||
volumes:
|
||||
- logs_worker:/code/plane/logs
|
||||
depends_on:
|
||||
- api
|
||||
- plane-db
|
||||
- plane-redis
|
||||
- plane-mq
|
||||
|
||||
beat-worker:
|
||||
<<: *plane-env
|
||||
image: makeplane/plane-backend:v0.23.1
|
||||
restart: unless-stopped
|
||||
command: ./bin/docker-entrypoint-beat.sh
|
||||
volumes:
|
||||
- logs_beat-worker:/code/plane/logs
|
||||
depends_on:
|
||||
- api
|
||||
- plane-db
|
||||
- plane-redis
|
||||
- plane-mq
|
||||
|
||||
migrator:
|
||||
<<: *plane-env
|
||||
image: makeplane/plane-backend:v0.23.1
|
||||
restart: "no"
|
||||
command: ./bin/docker-entrypoint-migrator.sh
|
||||
volumes:
|
||||
- logs_migrator:/code/plane/logs
|
||||
depends_on:
|
||||
- plane-db
|
||||
- plane-redis
|
||||
|
||||
plane-db:
|
||||
<<: *plane-env
|
||||
image: postgres:15.7-alpine
|
||||
restart: unless-stopped
|
||||
command: postgres -c 'max_connections=1000'
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
|
||||
plane-redis:
|
||||
<<: *plane-env
|
||||
image: valkey/valkey:7.2.5-alpine
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- redisdata:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "valkey-cli", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
|
||||
plane-mq:
|
||||
<<: *plane-env
|
||||
image: rabbitmq:3.13.6-management-alpine
|
||||
restart: always
|
||||
volumes:
|
||||
- rabbitmq_data:/var/lib/rabbitmq
|
||||
healthcheck:
|
||||
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 12
|
||||
|
||||
plane-minio:
|
||||
<<: *plane-env
|
||||
# upstream-référence держит latest — bundle пиннит неподвижный тег (NFR-6)
|
||||
image: minio/minio:RELEASE.2024-05-28T17-19-04Z
|
||||
restart: unless-stopped
|
||||
command: server /export --console-address ":9090"
|
||||
volumes:
|
||||
- uploads:/export
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-fsS", "http://localhost:9000/minio/health/live"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
|
||||
proxy:
|
||||
<<: *plane-env
|
||||
image: makeplane/plane-proxy:v0.23.1
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
# человеческая точка: UI Plane в браузере оператора (D4)
|
||||
- "${BUNDLE_PLANE_PORT:-8080}:80"
|
||||
depends_on:
|
||||
- web
|
||||
- api
|
||||
- space
|
||||
|
||||
# Состояние Plane/Gitea — именованные тома проекта (префикс orchestrator-bundle_,
|
||||
# D1/D2); preflight bootstrap детектирует «грязный хост» по этому префиксу.
|
||||
volumes:
|
||||
pgdata:
|
||||
redisdata:
|
||||
uploads:
|
||||
logs_api:
|
||||
logs_worker:
|
||||
logs_beat-worker:
|
||||
logs_migrator:
|
||||
rabbitmq_data:
|
||||
gitea-data:
|
||||
Reference in New Issue
Block a user