name: mangacircus x-app: &app image: ${APP_IMAGE:-mangacircus:local} build: context: . args: VCS_REF: ${VCS_REF:-development} init: true restart: unless-stopped stop_grace_period: 90s read_only: true tmpfs: [/tmp] security_opt: [no-new-privileges:true] cap_drop: [ALL] secrets: [scraper_token] logging: driver: local options: max-size: "10m" max-file: "3" services: reader: <<: *app image: ${READER_IMAGE:-${APP_IMAGE:-mangacircus:local}} command: [node, runtime/launch.js, reader] ports: ["${READER_BIND:-127.0.0.1}:${READER_PORT:-8080}:8080"] volumes: - type: bind source: ${LIBRARY_PATH:-./library} target: /library read_only: true bind: {create_host_path: false} - type: bind source: ${DATA_PATH:-./data} target: /data bind: {create_host_path: false} environment: PORT: "8080" DATA: /data LIBRARY: /library TZ: ${TZ:-Europe/Berlin} SIGNUP: closed SCAN_INTERVAL: "10" COOKIE_SECURE: ${COOKIE_SECURE:-0} READING_WINDOWS_JSON: ${READING_WINDOWS_JSON:-} READING_TIMEZONE: ${READING_TIMEZONE:-Europe/Berlin} READING_QUIZ_UNLOCK_MINUTES: ${READING_QUIZ_UNLOCK_MINUTES:-60} READING_QUIZ_CATALOG_PATH: ${READING_QUIZ_CATALOG_PATH:-} SCRAPER_URL: http://scraper:8091 SENTINEL_URL: http://sentinel:8092 SCRAPER_TOKEN_FILE: /run/secrets/scraper_token networks: [backend, egress] healthcheck: test: [CMD, node, tools/healthcheck.js, reader] interval: 30s timeout: 5s start_period: 60s retries: 3 scraper: <<: *app command: [node, runtime/launch.js, scraper] volumes: - type: bind source: ${LIBRARY_PATH:-./library} target: /library bind: {create_host_path: false} - type: bind source: ${SCRAPER_DATA_PATH:-./data/scraper} target: /data/scraper bind: {create_host_path: false} - type: bind source: ${PEER_DATA_PATH:-./data/peering} target: /data/peering read_only: true environment: DATA: /data LIBRARY: /library SCRAPER_DATA: /data/scraper METADATA_CACHE: /data/scraper/metadata/anilist TZ: ${TZ:-Europe/Berlin} SCRAPER_HOST: 0.0.0.0 SCRAPER_PORT: "8091" SCRAPER_TOKEN_FILE: /run/secrets/scraper_token PEER_DATA: /data/peering networks: [backend, egress] healthcheck: test: [CMD, node, tools/healthcheck.js, scraper] interval: 30s timeout: 5s start_period: 60s retries: 3 sentinel: <<: *app command: [node, runtime/launch.js, sentinel] volumes: - type: bind source: ${SENTINEL_DATA_PATH:-./data/sentinel} target: /data/sentinel bind: {create_host_path: false} environment: DATA: /data SENTINEL_DATA: /data/sentinel SENTINEL_HOST: 0.0.0.0 SENTINEL_PORT: "8092" READER_URL: http://reader:8080 SCRAPER_URL: http://scraper:8091 SCRAPER_TOKEN_FILE: /run/secrets/scraper_token TZ: ${TZ:-Europe/Berlin} networks: [backend] healthcheck: test: [CMD, node, tools/healthcheck.js, sentinel] interval: 30s timeout: 5s start_period: 60s retries: 3 peer-gateway: <<: *app profiles: [peering] command: [node, peering/gateway.js] ports: ["${PEER_BIND:-127.0.0.1}:${PEER_PORT:-8093}:8093"] volumes: - type: bind source: ${LIBRARY_PATH:-./library} target: /library read_only: true bind: {create_host_path: false} - type: bind source: ${PEER_DATA_PATH:-./data/peering} target: /data/peering read_only: true - type: bind source: ${PEER_USAGE_PATH:-./data/peering-usage} target: /data/peering-usage environment: LIBRARY: /library PEER_DATA: /data/peering PEER_USAGE_FILE: /data/peering-usage/usage.json PEER_HOST: 0.0.0.0 PEER_PORT: "8093" # Docker Desktop does not publish host ports from an internal-only network. networks: [backend, egress] healthcheck: test: [CMD, node, tools/healthcheck-peer.js] interval: 30s timeout: 5s start_period: 30s retries: 3 networks: backend: internal: true egress: {} secrets: scraper_token: file: ${SCRAPER_TOKEN_PATH:-./.secrets/scraper_token}