version: "3.9" x-workspace: &workspace ${XCONTROL_WORKSPACE:-..} services: db: image: postgres:17-alpine container_name: xcontrol-db restart: unless-stopped environment: POSTGRES_DB: ${XCONTROL_DB_NAME:-xcontrol} POSTGRES_USER: ${XCONTROL_DB_USER:-xcontrol} POSTGRES_PASSWORD: ${XCONTROL_DB_PASSWORD:-xcontrol} healthcheck: test: ["CMD-SHELL", "pg_isready -U ${XCONTROL_DB_USER:-xcontrol}"] interval: 5s timeout: 60s retries: 10 start_period: 5s volumes: - data:/var/lib/postgresql/data:rw networks: - db init: image: postgres:17-alpine container_name: xcontrol-init profiles: ["init"] depends_on: db: condition: service_healthy environment: DB_USER: ${XCONTROL_DB_USER:-xcontrol} PGPASSWORD: ${XCONTROL_DB_PASSWORD:-xcontrol} command: > sh -c "\ psql -v ON_ERROR_STOP=1 -h db -U \"$DB_USER\" -d postgres -c \"SELECT 'CREATE DATABASE account OWNER ' || quote_ident(current_user) || ';' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'account') \gexec\" &&\ psql -v ON_ERROR_STOP=1 -h db -U \"$DB_USER\" -d postgres -c \"SELECT 'CREATE DATABASE rag OWNER ' || quote_ident(current_user) || ';' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'rag') \gexec\" &&\ psql -v ON_ERROR_STOP=1 -h db -U \"$DB_USER\" -d account -f /workspace/account/sql/schema.sql &&\ psql -v ON_ERROR_STOP=1 -h db -U \"$DB_USER\" -d rag -f /workspace/rag-server/sql/schema.sql\ " volumes: - *workspace:/workspace:ro networks: - db account: build: context: *workspace dockerfile: account/Dockerfile container_name: account restart: unless-stopped environment: PORT: 8080 CONFIG_PATH: /etc/xcontrol/account-compose.yaml volumes: - *workspace:/workspace:ro - ./config/account.yaml:/etc/xcontrol/account-compose.yaml:ro depends_on: db: condition: service_healthy ports: - "8080:8080" networks: - app - db rag-server: build: context: *workspace dockerfile: rag-server/Dockerfile container_name: rag-server restart: unless-stopped environment: PORT: 8090 CONFIG_PATH: /etc/rag-server/server-compose.yaml volumes: - *workspace:/workspace:ro - ./config/server.yaml:/etc/rag-server/server-compose.yaml:ro depends_on: db: condition: service_healthy ports: - "8090:8090" networks: - app - db dashboard: build: context: *workspace dockerfile: dashboard/Dockerfile container_name: dashboard restart: unless-stopped environment: PORT: 3000 ports: - "3000:3000" depends_on: account: condition: service_started rag-server: condition: service_started networks: - app proxy-external-tls: image: nginx:mainline-alpine container_name: proxy-external-tls restart: unless-stopped volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./certbot/conf:/etc/letsencrypt - ./certbot/www:/var/www/certbot ports: - "80:80" - "443:443" networks: - app depends_on: account: condition: service_started rag-server: condition: service_started dashboard: condition: service_started redis: image: redis:7-alpine container_name: redis restart: unless-stopped command: ["redis-server", "--save", "", "--appendonly", "no"] networks: - app bootstrap-nginx: profiles: ["bootstrap"] image: nginx:mainline-alpine container_name: bootstrap-nginx volumes: - ./certbot/www:/var/www/certbot - ./certbot/conf:/etc/letsencrypt - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./nginx/conf.d/bootstrap-nginx.conf:/etc/nginx/conf.d/default.conf ports: - "80:80" networks: - app healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost"] interval: 3s timeout: 2s retries: 10 start_period: 3s certbot: profiles: ["bootstrap"] image: certbot/certbot container_name: certbot command: > certonly --webroot --webroot-path=/var/www/certbot --email ${XCONTROL_CERTBOT_EMAIL:-manbuzhe2009@qq.com} --agree-tos --no-eff-email --keep-until-expiring --non-interactive -d ${XCONTROL_CERTBOT_DOMAINS:-svc.plus} volumes: - ./certbot/conf:/etc/letsencrypt - ./certbot/www:/var/www/certbot networks: - app networks: app: db: volumes: data: