services: app: build: context: . dockerfile: Dockerfile args: BUILD_DATE: ${BUILD_DATE:-} VCS_REF: ${VCS_REF:-} image: flamy-trade:${APP_IMAGE_TAG:-local} restart: unless-stopped init: true read_only: true environment: NODE_ENV: production HOST: 0.0.0.0 PORT: 3000 ORIGIN: ${ORIGIN:-https://trade.flamy.studio} BODY_SIZE_LIMIT: ${BODY_SIZE_LIMIT:-1M} SHUTDOWN_TIMEOUT: ${SHUTDOWN_TIMEOUT:-15} PUBLIC_SITE_URL: ${PUBLIC_SITE_URL:-https://trade.flamy.studio} PUBLIC_SITE_NAME: ${PUBLIC_SITE_NAME:-Flamy Trade} PUBLIC_SITE_DESCRIPTION: ${PUBLIC_SITE_DESCRIPTION:-Публичная витрина ML-прогнозов для крипторынка.} expose: - '3000' networks: - backend cpus: 0.50 mem_limit: 384m mem_reservation: 128m memswap_limit: 384m pids_limit: 128 security_opt: - no-new-privileges:true cap_drop: - ALL tmpfs: - /tmp:size=32m,noexec,nosuid,nodev healthcheck: test: [ 'CMD-SHELL', 'node -e "fetch(''http://127.0.0.1:3000/healthz'').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"' ] interval: 30s timeout: 5s retries: 3 start_period: 20s logging: driver: json-file options: max-size: 10m max-file: '3' nginx: image: nginx:1.30.4-alpine@sha256:97d490c12ba55b4946b01546d1c3ed324e8d41ab1c9fcb2a616aa470620e5b46 restart: unless-stopped init: true read_only: true depends_on: app: condition: service_healthy ports: - name: http target: 8080 published: '${APP_PUBLISHED_PORT:-18082}' host_ip: '${APP_HOST_IP:-10.20.0.20}' protocol: tcp app_protocol: http volumes: - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro networks: - backend cpus: 0.10 mem_limit: 64m mem_reservation: 16m memswap_limit: 64m pids_limit: 64 security_opt: - no-new-privileges:true cap_drop: - ALL tmpfs: - /var/cache/nginx:size=32m,nosuid,nodev - /var/run:size=8m,nosuid,nodev - /tmp:size=16m,noexec,nosuid,nodev healthcheck: test: ['CMD-SHELL', 'wget -qO- http://127.0.0.1:8080/healthz >/dev/null || exit 1'] interval: 30s timeout: 5s retries: 3 start_period: 20s logging: driver: json-file options: max-size: 10m max-file: '3' networks: backend: internal: true