feat: add production deployment for rf4spotter.ru

This commit is contained in:
ik
2026-09-06 13:52:30 +07:00
parent b45ba38a00
commit a4bd395856
10 changed files with 350 additions and 3 deletions
+134
View File
@@ -0,0 +1,134 @@
name: rf4-spotter
services:
proxy:
image: caddy:2.10.2-alpine
restart: unless-stopped
environment:
SITE_DOMAIN: ${SITE_DOMAIN:?Set SITE_DOMAIN}
FILES_DOMAIN: ${FILES_DOMAIN:?Set FILES_DOMAIN}
ACME_EMAIL: ${ACME_EMAIL:?Set ACME_EMAIL}
ADMIN_BASIC_USER: ${ADMIN_BASIC_USER:?Set ADMIN_BASIC_USER}
ADMIN_BASIC_PASSWORD_HASH: ${ADMIN_BASIC_PASSWORD_HASH:?Set ADMIN_BASIC_PASSWORD_HASH}
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./deploy/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
web:
condition: service_healthy
networks: [edge, backend]
security_opt: [no-new-privileges:true]
deploy:
resources:
limits: {cpus: "0.50", memory: 256M}
db:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB:-rf4_spotter}
POSTGRES_USER: ${POSTGRES_USER:-rf4}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-rf4} -d ${POSTGRES_DB:-rf4_spotter}"]
interval: 10s
timeout: 5s
retries: 10
networks: [backend]
security_opt: [no-new-privileges:true]
deploy:
resources:
limits: {cpus: "1.00", memory: 1G}
minio:
image: minio/minio:RELEASE.2025-07-23T15-54-02Z
command: server /data
restart: unless-stopped
environment:
MINIO_ROOT_USER: ${S3_ACCESS_KEY:?Set S3_ACCESS_KEY}
MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY:?Set S3_SECRET_KEY}
volumes:
- minio_data:/data
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:9000/minio/health/live"]
interval: 10s
timeout: 5s
retries: 10
networks: [backend]
security_opt: [no-new-privileges:true]
deploy:
resources:
limits: {cpus: "0.75", memory: 1G}
api:
build:
context: .
dockerfile: apps/api/Dockerfile
restart: unless-stopped
environment:
DEPLOYMENT_ENVIRONMENT: production
DATABASE_URL: ${DATABASE_URL:?Set DATABASE_URL}
ADMIN_TOKEN: ${ADMIN_TOKEN:?Set ADMIN_TOKEN}
CORS_ORIGINS: '["https://${SITE_DOMAIN:?Set SITE_DOMAIN}"]'
S3_ENDPOINT_URL: http://minio:9000
S3_PUBLIC_ENDPOINT_URL: https://${FILES_DOMAIN:?Set FILES_DOMAIN}
S3_ACCESS_KEY: ${S3_ACCESS_KEY:?Set S3_ACCESS_KEY}
S3_SECRET_KEY: ${S3_SECRET_KEY:?Set S3_SECRET_KEY}
S3_BUCKET: ${S3_BUCKET:-catch-screenshots}
OFFICIAL_RECORDS_URL: ${OFFICIAL_RECORDS_URL:-https://rf4game.de/records/region/RU/}
OFFICIAL_RECORDS_REGION: ${OFFICIAL_RECORDS_REGION:-RU}
OFFICIAL_RECORDS_CATEGORY: ${OFFICIAL_RECORDS_CATEGORY:-records}
OFFICIAL_IMPORT_REQUIRED: ${OFFICIAL_IMPORT_REQUIRED:-false}
IMPORT_INTERVAL_SECONDS: ${IMPORT_INTERVAL_SECONDS:-3600}
RATE_LIMIT_SECRET: ${RATE_LIMIT_SECRET:?Set RATE_LIMIT_SECRET}
LOG_LEVEL: ${LOG_LEVEL:-INFO}
depends_on:
db: {condition: service_healthy}
minio: {condition: service_healthy}
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/ready')"]
interval: 10s
timeout: 5s
retries: 12
networks: [backend, edge]
security_opt: [no-new-privileges:true]
deploy:
resources:
limits: {cpus: "1.00", memory: 1G}
web:
build: ./apps/web
restart: unless-stopped
environment:
PUBLIC_API_URL: https://${SITE_DOMAIN:?Set SITE_DOMAIN}
API_INTERNAL_URL: http://api:8000
depends_on:
api: {condition: service_healthy}
healthcheck:
test: ["CMD", "node", "-e", "fetch('http://localhost:4321').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
interval: 10s
timeout: 5s
retries: 10
networks: [backend]
security_opt: [no-new-privileges:true]
deploy:
resources:
limits: {cpus: "0.75", memory: 512M}
networks:
edge:
backend:
internal: true
volumes:
postgres_data:
minio_data:
caddy_data:
caddy_config: