services: message-safety: build: . image: han/message-safety:${MESSAGE_SAFETY_IMAGE_TAG} command: ["message-safety"] user: "10001:10001" read_only: true init: true restart: unless-stopped expose: ["8080"] env_file: - /etc/han-chat/message-safety-bootstrap.env - /etc/han-chat/message-safety-mode.env environment: MESSAGE_SAFETY_PROCESS_ROLE: api MESSAGE_SAFETY_DATABASE_URL_FILE: /run/secrets/database_url MESSAGE_SAFETY_REDIS_URL_FILE: /run/secrets/redis_url MESSAGE_SAFETY_SERVICE_TOKEN_FILE: /run/secrets/service_token secrets: [database_url, redis_url, service_token] tmpfs: ["/tmp:rw,noexec,nosuid,nodev,size=64m"] security_opt: ["no-new-privileges:true"] cap_drop: [ALL] pids_limit: 128 mem_limit: 512m cpus: 1.0 networks: [backend, observability] healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/health/live', timeout=2)"] interval: 10s timeout: 3s retries: 3 message-safety-worker: image: han/message-safety:${MESSAGE_SAFETY_IMAGE_TAG} command: ["message-safety-worker"] user: "10001:10001" read_only: true init: true restart: unless-stopped env_file: - /etc/han-chat/message-safety-bootstrap.env - /etc/han-chat/message-safety-mode.env environment: MESSAGE_SAFETY_PROCESS_ROLE: worker MESSAGE_SAFETY_DATABASE_URL_FILE: /run/secrets/database_url MESSAGE_SAFETY_REDIS_URL_FILE: /run/secrets/redis_url SELECTEL_S3_QUARANTINE_READ_ACCESS_KEY_FILE: /run/secrets/s3_access_key SELECTEL_S3_QUARANTINE_READ_SECRET_KEY_FILE: /run/secrets/s3_secret_key secrets: [database_url, redis_url, s3_access_key, s3_secret_key] tmpfs: ["/tmp:rw,noexec,nosuid,nodev,size=64m"] security_opt: ["no-new-privileges:true"] cap_drop: [ALL] pids_limit: 256 mem_limit: 1536m cpus: 2.0 networks: [backend, egress, observability] # Root VM2 Compose owns these secret mappings and networks.