iac/docker-compose.yaml

429 lines
18 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

services:
k3s-server:
image: rancher/k3s:v1.36.2-k3s1
container_name: k3s-server
command:
- server
- --tls-san=127.0.0.1
- --tls-san=k3s-server
- --tls-san=${K3S_API_HOST:-127.0.0.1} # внешний IP/домен для доступа к apiserver извне
- --disable=traefik
privileged: true
cgroup: host # kubelet в cgroup v2 (Ubuntu 22.04+/RedOS)
restart: unless-stopped
environment:
K3S_TOKEN: ${K3S_TOKEN:-supersecrettoken}
K3S_KUBECONFIG_OUTPUT: /output/kubeconfig.yaml
K3S_KUBECONFIG_MODE: "644"
#ports:
# - "6443:6443" # kube-apiserver — доступен извне; ОБЯЗАТЕЛЬНО ограничь фаерволом до доверенных IP
# - "80:80" # ingress http — задействуются после установки ingress-контроллера
# - "443:443" # ingress https
volumes:
- k3s-server-data:/var/lib/rancher/k3s # etcd/state, образы, манифесты — только named volume
- ./k3s:/output:z # отсюда забираем контекст k8s (:z — SELinux label для RedOS)
tmpfs:
- /run
- /var/run
ulimits:
nproc: 65535
nofile:
soft: 65535
hard: 65535
healthcheck:
test: ["CMD", "kubectl", "get", "--raw=/readyz"]
interval: 10s
timeout: 5s
retries: 30
start_period: 30s
k3s-worker:
image: rancher/k3s:v1.36.2-k3s1
container_name: k3s-worker
command:
- agent
privileged: true
cgroup: host # kubelet в cgroup v2 (Ubuntu 22.04+/RedOS)
restart: unless-stopped
depends_on:
k3s-server:
condition: service_healthy
environment:
K3S_URL: https://k3s-server:6443
K3S_TOKEN: ${K3S_TOKEN:-supersecrettoken}
volumes:
- k3s-worker-data:/var/lib/rancher/k3s
tmpfs:
- /run
- /var/run
ulimits:
nproc: 65535
nofile:
soft: 65535
hard: 65535
gitea:
image: gitea/gitea:1.22
container_name: gitea
restart: unless-stopped
environment:
USER_UID: 1000
USER_GID: 1000
GITEA__server__ROOT_URL: ${GITEA_ROOT_URL:-http://localhost:3000/}
GITEA__server__SSH_PORT: ${GITEA_SSH_PORT:-2222}
ports:
- "3000:3000" # web UI (80/443 заняты k3s)
- "${GITEA_SSH_PORT:-2222}:22" # git over ssh
volumes:
- ./gitea-data:/data:z # :z — SELinux label для RedOS
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:3000/api/healthz"]
interval: 10s
timeout: 5s
retries: 12
start_period: 20s
# ---------------------------------------------------------------------------
# Инфраструктурные зависимости apps/django (sarex-backend).
# Django деплоится в k3s и ходит сюда — про связность k3s→compose см. README.
# Креды/версии взяты из sarex-backend/docker-compose.yaml и apps/django/.env.example.
# ---------------------------------------------------------------------------
postgres:
image: postgres:12-alpine
container_name: postgres
restart: unless-stopped
environment:
# суперпользователь (администрирование)
POSTGRES_DB: ${SAREX_POSTGRES_DB:-sarex_db}
POSTGRES_USER: ${SAREX_POSTGRES_USER:-sarex}
POSTGRES_PASSWORD: ${SAREX_POSTGRES_PASSWORD:-sarex}
# роли приложений с паролями — читаются init-скриптом 00-init.sh
DJANGO_DB: ${SAREX_POSTGRES_DB:-sarex_db}
DJANGO_DB_USER: ${SAREX_DJANGO_DB_USER:-django}
DJANGO_DB_PASSWORD: ${SAREX_DJANGO_DB_PASSWORD:-django-secret}
PROC_DB: ${SAREX_PROCESSING_DB:-workflow_db}
PROC_DB_USER: ${SAREX_PROCESSING_DB_USER:-processing}
PROC_DB_PASSWORD: ${SAREX_PROCESSING_DB_PASSWORD:-processing-secret}
volumes:
- sarex-postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${SAREX_POSTGRES_USER:-sarex} -d ${SAREX_POSTGRES_DB:-sarex_db}"]
interval: 10s
timeout: 5s
retries: 12
start_period: 10s
# Одноразовый init: на каждое приложение заводит роль (LOGIN+пароль) и базу
# данных с этим владельцем. Идемпотентно (по образцу minio-init).
postgres-init:
image: postgres:12-alpine
depends_on:
postgres:
condition: service_healthy
entrypoint:
- /bin/sh
- -c
- |
set -e
until psql -h postgres -U "$$SUPER_USER" -d "$$SUPER_DB" -c 'SELECT 1' >/dev/null 2>&1; do
echo 'waiting for postgres...'; sleep 2;
done
q() { psql -v ON_ERROR_STOP=1 -h postgres -U "$$SUPER_USER" -d "$$SUPER_DB" "$$@"; }
# provision <db> <user> <password>
provision() {
q -tc "SELECT 1 FROM pg_roles WHERE rolname='$$2'" | grep -q 1 \
|| q -c "CREATE ROLE \"$$2\" LOGIN PASSWORD '$$3'"
q -c "ALTER ROLE \"$$2\" WITH LOGIN PASSWORD '$$3'"
q -tc "SELECT 1 FROM pg_database WHERE datname='$$1'" | grep -q 1 \
|| q -c "CREATE DATABASE \"$$1\" OWNER \"$$2\""
q -c "ALTER DATABASE \"$$1\" OWNER TO \"$$2\""
q -c "GRANT ALL PRIVILEGES ON DATABASE \"$$1\" TO \"$$2\""
echo "db $$1 + user $$2 ready"
}
provision "$$DJANGO_DB" "$$DJANGO_USER" "$$DJANGO_PASSWORD"
provision "$$PROC_DB" "$$PROC_USER" "$$PROC_PASSWORD"
provision "$$BIM_DB" "$$BIM_USER" "$$BIM_PASSWORD"
provision "$$WORKSPACE_DB" "$$WORKSPACE_USER" "$$WORKSPACE_PASSWORD"
environment:
PGPASSWORD: ${SAREX_POSTGRES_PASSWORD:-sarex}
SUPER_USER: ${SAREX_POSTGRES_USER:-sarex}
SUPER_DB: ${SAREX_POSTGRES_DB:-sarex_db}
# django (использует основную базу SAREX_POSTGRES_DB)
DJANGO_DB: ${SAREX_POSTGRES_DB:-sarex_db}
DJANGO_USER: ${SAREX_DJANGO_DB_USER:-django}
DJANGO_PASSWORD: ${SAREX_DJANGO_DB_PASSWORD:-django-secret}
# processing
PROC_DB: ${SAREX_PROCESSING_DB:-workflow_db}
PROC_USER: ${SAREX_PROCESSING_DB_USER:-processing}
PROC_PASSWORD: ${SAREX_PROCESSING_DB_PASSWORD:-processing-secret}
# bim
BIM_DB: ${SAREX_BIM_DB:-bim_db}
BIM_USER: ${SAREX_BIM_DB_USER:-bim}
BIM_PASSWORD: ${SAREX_BIM_DB_PASSWORD:-bim-secret}
# workspace
WORKSPACE_DB: ${SAREX_WORKSPACE_DB:-workspace_db}
WORKSPACE_USER: ${SAREX_WORKSPACE_DB_USER:-workspace}
WORKSPACE_PASSWORD: ${SAREX_WORKSPACE_DB_PASSWORD:-workspace-secret}
restart: "no"
redis:
image: cr.yandex/crp3ccidau046kdj8g9q/redis:7.0.10
container_name: redis
restart: unless-stopped
command: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
volumes:
- sarex-redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 12
start_period: 5s
rabbitmq:
image: cr.yandex/crp3ccidau046kdj8g9q/rabbimtq:3.11.23
container_name: rabbitmq
restart: unless-stopped
environment:
RABBITMQ_VHOST: ${SAREX_RABBITMQ_VHOST:-api}
RABBITMQ_USERNAME: ${SAREX_RABBITMQ_USER:-rabbit}
RABBITMQ_PASSWORD: ${SAREX_RABBITMQ_PASSWORD:-rabbit}
RABBITMQ_DISK_FREE_ABSOLUTE_LIMIT: 200MB
volumes:
- sarex-rabbitmq-data:/bitnami/rabbitmq/mnesia
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
interval: 15s
timeout: 10s
retries: 12
start_period: 30s
minio:
image: cr.yandex/crp3ccidau046kdj8g9q/minio:250724
container_name: minio
restart: unless-stopped
command: ["server", "/data", "--console-address", ":9001"]
environment:
MINIO_ROOT_USER: ${SAREX_MINIO_ROOT_USER:-minioadmin}
MINIO_ROOT_PASSWORD: ${SAREX_MINIO_ROOT_PASSWORD:-minioadmin}
# Консоль отдаётся через верхний nginx с корня minio-домена
MINIO_BROWSER_REDIRECT_URL: ${SAREX_MINIO_CONSOLE_URL:-https://minio.sarex.local}
volumes:
- sarex-minio-data:/data
# Одноразовый init: ждёт MinIO и на каждое приложение заводит бакет +
# отдельного пользователя со scoped-политикой (доступ только к своему бакету).
minio-init:
image: cr.yandex/crp3ccidau046kdj8g9q/mc:250724
depends_on:
- minio
entrypoint:
- /bin/sh
- -c
- |
until mc alias set local http://minio:9000 "$$MINIO_ROOT_USER" "$$MINIO_ROOT_PASSWORD"; do
echo 'waiting for minio...'; sleep 2;
done
# provision <bucket> <user> <password> <policy>
provision() {
mc mb -p "local/$$1"
mc admin user add local "$$2" "$$3"
printf '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:*"],"Resource":["arn:aws:s3:::%s","arn:aws:s3:::%s/*"]}]}' "$$1" "$$1" > /tmp/policy.json
mc admin policy create local "$$4" /tmp/policy.json || true
mc admin policy attach local "$$4" --user "$$2" || true
echo "bucket $$1 + user $$2 ready"
}
# Единый бакет на все приложения (processing/measurements тоже сюда)
provision "$$MINIO_BUCKET" "$$MINIO_APP_USER" "$$MINIO_APP_PASSWORD" "$$MINIO_APP_POLICY"
environment:
MINIO_ROOT_USER: ${SAREX_MINIO_ROOT_USER:-minioadmin}
MINIO_ROOT_PASSWORD: ${SAREX_MINIO_ROOT_PASSWORD:-minioadmin}
# единый бакет/пользователь приложения
MINIO_BUCKET: ${SAREX_MINIO_BUCKET:-sarex-media-storage}
MINIO_APP_USER: ${SAREX_MINIO_APP_USER:-sarex-app}
MINIO_APP_PASSWORD: ${SAREX_MINIO_APP_PASSWORD:-sarex-app-secret}
MINIO_APP_POLICY: ${SAREX_MINIO_APP_POLICY:-sarex-app-rw}
restart: "no"
# ---------------------------------------------------------------------------
# Приложение sarex (backend + celery + frontend).
# Образы приватные (cr.yandex) — нужен `docker login cr.yandex`.
# Для локальной сборки backend раскомментируй build (репозиторий — соседний).
# ---------------------------------------------------------------------------
backend:
image: ${SAREX_BACKEND_IMAGE:-cr.yandex/crp3ccidau046kdj8g9q/sarex-backend-dev:latest}
# build:
# context: ../../generic/sarex-backend
# dockerfile: Dockerfile
container_name: sarex-backend
restart: unless-stopped
environment: &sarex-backend-env
ALLOWED_HOSTS: "*"
DJANGO_SETTINGS_MODULE: config.settings.production
JWT_PRIVATE_KEY: "JWT"
JWT_PUBLIC_KEY: "JPK"
DJANGO_POSTGRES_HOST: postgres
DJANGO_POSTGRES_DATABASE: ${SAREX_POSTGRES_DB:-sarex_db}
DJANGO_POSTGRES_USER: ${SAREX_DJANGO_DB_USER:-django}
DJANGO_POSTGRES_PASSWORD: ${SAREX_DJANGO_DB_PASSWORD:-django-secret}
DJANGO_REDIS_HOST: redis
DJANGO_RABBIT_HOSTNAME: rabbitmq
DJANGO_RABBIT_USER: ${SAREX_RABBITMQ_USER:-rabbit}
DJANGO_RABBIT_PASS: ${SAREX_RABBITMQ_PASSWORD:-rabbit}
DJANGO_RABBIT_VHOST: ${SAREX_RABBITMQ_VHOST:-api}
# S3 / объектное хранилище → MinIO (сервис minio)
S3_HOST: http://minio:9000
AWS_S3_ENDPOINT_URL: http://minio:9000
S3_LOGIN: ${SAREX_MINIO_APP_USER:-sarex-app}
S3_PASSWORD: ${SAREX_MINIO_APP_PASSWORD:-sarex-app-secret}
S3_BUCKET: ${SAREX_MINIO_BUCKET:-sarex-media-storage}
S3_REGION: ${SAREX_MINIO_REGION:-us-east-1}
# Сервис measurements (MeasurementSettings, env_prefix MEASUREMENTS_)
MEASUREMENTS_HOST: ${SAREX_MEASUREMENTS_HOST:-http://measurements:8000/}
tty: true
ports:
- "8000:8000" # HTTP API (uWSGI), migrate выполняется в entrypoint
depends_on:
postgres:
condition: service_healthy
postgres-init:
condition: service_completed_successfully
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
minio-init:
condition: service_completed_successfully
celery:
image: ${SAREX_BACKEND_IMAGE:-cr.yandex/crp3ccidau046kdj8g9q/sarex-backend-dev:latest}
container_name: sarex-celery
restart: unless-stopped
entrypoint: celery -A config worker -l info -E -Q default -n default_worker.%h --concurrency=1 -B
environment:
<<: *sarex-backend-env
depends_on:
postgres:
condition: service_healthy
postgres-init:
condition: service_completed_successfully
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
minio-init:
condition: service_completed_successfully
frontend:
image: ${SAREX_FRONTEND_IMAGE:-cr.yandex/crp3ccidau046kdj8g9q/sarex-frontend-dev:latest}
container_name: sarex-frontend
restart: unless-stopped
ports:
- "8080:80" # web UI
depends_on:
- backend
# ---------------------------------------------------------------------------
# Приложение processing (workflows-api + workflows-frontend).
# Образы приватные (cr.yandex). БД — отдельная workflow_db в общем postgres.
# Версии/env взяты из apps/processing/base/*.yaml.
# ---------------------------------------------------------------------------
processing-api:
image: ${SAREX_PROCESSING_API_IMAGE:-cr.yandex/crp3ccidau046kdj8g9q/workflows-api_prod:075fc0}
container_name: processing-api
restart: unless-stopped
entrypoint: ["/httpserver"]
command: ["migrate"] # в манифесте: /httpserver migrate (миграции + сервер на :8080)
environment:
HTTP_HOST: 0.0.0.0:8080
POSTGRES_ADDRESS: postgres
POSTGRES_PORT: "5432"
POSTGRES_DB: ${SAREX_PROCESSING_DB:-workflow_db}
POSTGRES_USER: ${SAREX_PROCESSING_DB_USER:-processing}
POSTGRES_PASSWORD: ${SAREX_PROCESSING_DB_PASSWORD:-processing-secret}
POSTGRES_POOL_SIZE: "3"
POSTGRES_SSL_USE: "0"
ENABLE_SQL_QUERY: "0"
DJANGO_HOST: http://backend:8000 # django-backend в этом же compose
PUBLIC_KEY: "JPK" # JWT public key (заглушка, как у backend)
ports:
- "8081:8080"
depends_on:
postgres:
condition: service_healthy
postgres-init:
condition: service_completed_successfully
processing-frontend:
image: ${SAREX_PROCESSING_FRONTEND_IMAGE:-cr.yandex/crp3ccidau046kdj8g9q/workflows-frontend:ugok2_85f6ce2c}
container_name: processing-frontend
restart: unless-stopped
ports:
- "8082:8080" # web UI (контейнер слушает 8080)
depends_on:
- processing-api
# ---------------------------------------------------------------------------
# measurements — FastAPI, считает измерения по растрам из S3/MinIO (GDAL vsis3).
# БД/воркера нет. Обязателен S3_JSON_SETTINGS. Источник: apps/measurements/base.
# ---------------------------------------------------------------------------
measurements:
image: ${SAREX_MEASUREMENTS_IMAGE:-cr.yandex/crp3ccidau046kdj8g9q/measurements:production_a5bb3e84}
container_name: measurements
restart: unless-stopped
entrypoint: ["/opt/entrypoint.sh"]
environment:
# host http:// → GDAL переключается на AWS_HTTPS=NO (см. CONFIGURATION.md)
S3_JSON_SETTINGS: '{"host":"http://minio:9000","login":"${SAREX_MINIO_APP_USER:-sarex-app}","password":"${SAREX_MINIO_APP_PASSWORD:-sarex-app-secret}","verify":false,"buckets":["${SAREX_MINIO_BUCKET:-sarex-media-storage}"]}'
LOG_LEVEL: INFO
TRACING_USE: "false"
AUTH: "0"
DJANGO_HOST: http://backend:8000
# порт наружу не публикуем — доступ только из backend по http://measurements:8000/
depends_on:
minio-init:
condition: service_completed_successfully
# Верхний reverse-proxy: 3 домена → платформа / rabbitmq (admin) / minio
nginx:
image: nginx:1.27-alpine
container_name: sarex-nginx
restart: unless-stopped
ports:
- "80:80" # http
- "443:443" # https (самоподписанный сертификат)
environment:
# подставляются envsubst'ом в шаблон при старте контейнера
PLATFORM_DOMAIN: ${PLATFORM_DOMAIN:-sarex.local}
ADMIN_DOMAIN: ${ADMIN_DOMAIN:-admin.sarex.local}
MINIO_DOMAIN: ${MINIO_DOMAIN:-minio.sarex.local}
volumes:
- ./nginx/templates:/etc/nginx/templates:ro,z # :z — SELinux label для RedOS
- ./nginx/certs:/etc/nginx/certs:ro,z # TLS-сертификаты
depends_on:
# - backend # TODO: закомментированы в шаблоне nginx, пока в работе
# - frontend
- minio
- rabbitmq
# - processing-api # processing пока не поднимаем (закомментирован в шаблоне nginx)
# - processing-frontend
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost/healthz"]
interval: 10s
timeout: 5s
retries: 6
start_period: 10s
volumes:
k3s-server-data:
k3s-worker-data:
gitea-data:
sarex-postgres-data:
sarex-redis-data:
sarex-rabbitmq-data:
sarex-minio-data: