Files
aura-crm/production/docker-compose.yml
T

133 lines
5.1 KiB
YAML

services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: production
POSTGRES_USER: production
# No fallback default — a missing .env value must stop the stack, not
# silently start Postgres with a well-known password.
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in .env}
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U production"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
ports:
# Bound to TAILSCALE_IP (or loopback if unset), never 0.0.0.0 — useful
# if you replicate/back up this database to another host over a
# private network (e.g. Tailscale) instead of exposing Postgres
# publicly. Safe to ignore if you don't need that; it just falls back
# to 127.0.0.1.
- "${TAILSCALE_IP:-127.0.0.1}:5433:5432"
minio:
image: minio/minio
command: server /data --console-address ":9001"
environment:
# No fallback defaults — see POSTGRES_PASSWORD above for why.
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:?MINIO_ACCESS_KEY must be set in .env}
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:?MINIO_SECRET_KEY must be set in .env}
volumes:
- minio_data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
ports:
# Same Tailscale-only binding as postgres above — useful for MinIO
# bucket replication/backups to another host over a private network.
- "${TAILSCALE_IP:-127.0.0.1}:9002:9000"
backend:
# Built locally from source by default so anyone can `docker compose up
# --build` without needing access to a private image registry. If you
# run this in production at scale, you may prefer to build images in CI
# and push them to your own registry instead (see
# .gitea/workflows/build-release.yml for an example of that pattern) and
# swap this `build:` block for `image: your-registry/production-backend:latest`.
build:
context: ./backend
dockerfile: Dockerfile
env_file: .env
# Optional deploy-agent self-update integration (see
# deploy-agent/README.md) is NOT wired up by default — it needs a bind
# mount to a Unix socket that doesn't exist on a fresh install, which
# would otherwise fail `docker compose up` for everyone. If you want the
# "check/apply update" button in Settings → Обновления, install
# deploy-agent per its README first, then add:
# volumes:
# - ./deploy-agent/agent.sock:/run/deploy-agent/agent.sock:ro
# here yourself.
ports:
# loopback-only — put a reverse proxy (Caddy, nginx, etc.) in front
# for public access.
- "127.0.0.1:18091:3000"
networks:
default: {}
platform:
aliases:
- production
depends_on:
postgres:
condition: service_healthy
minio:
condition: service_healthy
restart: unless-stopped
# Self-hosted Telegram Bot API server (internal/notify) — backend talks to
# it over the docker network (TG_API_BASE_URL) instead of
# api.telegram.org directly. This is optional: requires
# TELEGRAM_API_ID/TELEGRAM_API_HASH from my.telegram.org (one-time manual
# registration, needs a phone number) or it exits immediately on start;
# restart: "no" so a missing registration doesn't crash-loop this into the
# logs forever. backend has no depends_on for this service —
# notify.Handler fails soft when it's down or unreachable, same as an
# invalid token would. If you don't need Telegram notifications, leave
# this service stopped.
telegram-bot-api:
image: aiogram/telegram-bot-api:latest
environment:
TELEGRAM_API_ID: ${TELEGRAM_API_ID:-}
TELEGRAM_API_HASH: ${TELEGRAM_API_HASH:-}
TELEGRAM_LOCAL: "1"
volumes:
- telegram_bot_api_data:/var/lib/telegram-bot-api
restart: unless-stopped
web:
# Built locally from source, same reasoning as backend above. Vite bakes
# VITE_CORE_URL/VITE_PRODUCTION_URL into the JS bundle at build time (the
# browser's own URLs for core/production, not the container-network
# addresses) — wired here from WEB_CORE_URL/WEB_PRODUCTION_URL in .env.
# If you build/push images in CI instead (see .gitea/workflows/
# build-release.yml), pass the same two build args there and swap this
# for `image: your-registry/production-web:latest`.
build:
context: ./web
dockerfile: Dockerfile
args:
VITE_CORE_URL: ${WEB_CORE_URL}
VITE_PRODUCTION_URL: ${WEB_PRODUCTION_URL}
ports:
- "127.0.0.1:18092:80"
restart: unless-stopped
volumes:
pg_data:
minio_data:
telegram_bot_api_data:
networks:
# Shared with the companion "core" auth service (and any other modules
# you run alongside this one) — lets this module reach core's
# /api/modules/:name/heartbeat by the "core" alias. Create it once:
# `docker network create platform_net`.
platform:
name: platform_net
external: true