services: gangway: build: context: . args: REVISION: ${GIT_REVISION:-} VERSION: ${GANGWAY_VERSION:-} image: gangway:local user: "1000:1000" group_add: - "${DOCKER_GID:?Set DOCKER_GID to the host Docker socket group ID}" command: - --docker-socket=/run/docker-host/docker.sock environment: # Set above the worst case below with room for the garbage a saturated # decode produces, so saturation shows up as GC pressure rather than an # OOM kill. It cannot substitute for that bound: the collector cannot # reclaim a response a request is still decoding. GOMEMLIMIT: 448MiB volumes: - type: bind source: ${DOCKER_SOCKET_DIR:-/var/run} target: /run/docker-host read_only: true bind: create_host_path: false - type: volume source: proxy-socket target: /run/gangway read_only: true cap_drop: [ALL] security_opt: - no-new-privileges:true network_mode: none restart: unless-stopped stop_grace_period: 70s pids_limit: 128 cpus: 2.0 # Worst case in flight is --max-concurrent (8) responses at # --max-response-bytes (1 MiB), and each costs up to sixteen times the JSON # it came from once decoded: 128 MiB of live heap, which GOMEMLIMIT above # leaves the collector room over. Raising either flag raises that # proportionally, and needs both limits raised with it; the proxy logs # worst_case_memory_bytes at start-up and warns when GOMEMLIMIT no longer # covers twice it. mem_limit: 512m mem_reservation: 32m # Headroom over 4 x --max-concurrent connections plus one upstream socket # per request, not a throttle. ulimits: nofile: soft: 1024 hard: 1024 logging: driver: json-file options: max-size: "10m" max-file: "3" volumes: proxy-socket: