Ana içeriğe geç

Worker (Gateway) — Docker

This guide walks through running the Apinizer Worker (the API Gateway runtime) as a Docker container. The Worker terminates HTTP / HTTPS / gRPC / WebSocket requests, runs the deployed proxy policy pipelines, and emits traffic logs.

Info

The Worker image is built on Ubuntu noble (glibc) — not Alpine — because the brotli4j native compression library has no musl build. Do not rebuild against Alpine.

Requirements​

  • A Linux x86-64 host with Docker Engine 24+
  • The same MongoDB instance used by the Manager
  • An Environment entry registered in the Manager UI (Server Management → Environments)
  • A reachable Apinizer Cache (Hazelcast cluster) if you use quotas, OIDC sessions, circuit breakers
  • Free TCP ports on the host:
    • 8091/tcp — HTTP gateway listener
    • 8443/tcp — HTTPS gateway listener (when enabled in the Environment)

1. Pull the image​

VERSION=2026.04.5
docker pull apinizercloud/worker:${VERSION}

2. Configure​

Required:

VariableDescription
SPRING_DATA_MONGODB_URIMongoDB connection string
SPRING_DATA_MONGODB_DATABASEMongoDB database name
APINIZER_ENVIRONMENT_NAMEEnvironment name. Must exactly match an Environment in the Manager UI.
WORKER_TIMEZONETimezone offset for log timestamps (e.g. +03:00)

Recommended:

VariableDefaultDescription
JAVA_OPTSempty"-server -XX:MaxRAMPercentage=75.0 -Dhttp.maxConnections=4096 -Dlog4j.formatMsgNoLookups=true" for production

Optional (Undertow / gateway tuning):

VariableDefaultDescription
tuneWorkerThreads1024XNIO worker pool
tuneWorkerMaxThreads4096Hard cap on the worker pool
tuneIoThreads4XNIO I/O selectors (set to vCPU count)
tuneBufferSize16384Read/write buffer size (bytes)
tuneDirectBufferstrueOff-heap buffers (less GC pressure)
tuneBacklog10000Kernel TCP listen backlog
APINIZER_WORKER_NODE_IPautoOverride the reported node IP (multi-NIC hosts)

3. Run the container​

docker run -d \
--name apinizer-worker \
-p 8091:8091 \
-p 8443:8443 \
--memory=8g \
--cpus=4 \
-e SPRING_DATA_MONGODB_URI='mongodb://user:pass@mongo:25080/?authSource=admin' \
-e SPRING_DATA_MONGODB_DATABASE='apinizer' \
-e APINIZER_ENVIRONMENT_NAME='prod-dc1' \
-e WORKER_TIMEZONE='+03:00' \
-e JAVA_OPTS='-server -XX:MaxRAMPercentage=75.0 -Dhttp.maxConnections=4096 -Dlog4j.formatMsgNoLookups=true' \
-v apinizer-worker-logs:/app/logs \
--restart unless-stopped \
--ulimit nofile=1048576:1048576 \
apinizercloud/worker:${VERSION}
Tip

The Worker is throughput-sensitive: it benefits from --ulimit nofile=1048576:1048576 for high concurrent connection counts.

4. docker-compose​

services:
worker:
image: apinizercloud/worker:2026.04.5
container_name: apinizer-worker
restart: unless-stopped
mem_limit: 8g
cpus: 4
ports:
- "8091:8091"
- "8443:8443"
environment:
SPRING_DATA_MONGODB_DATABASE: apinizer
APINIZER_ENVIRONMENT_NAME: prod-dc1
WORKER_TIMEZONE: "+03:00"
JAVA_OPTS: "-server -XX:MaxRAMPercentage=75.0 -Dhttp.maxConnections=4096 -Dlog4j.formatMsgNoLookups=true"
tuneWorkerThreads: "1024"
tuneIoThreads: "4"
env_file:
- ./secrets/worker.env
ulimits:
nofile:
soft: 1048576
hard: 1048576
volumes:
- worker-logs:/app/logs
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8091/server-status | grep -q OK || exit 1"]
interval: 30s
timeout: 5s
retries: 5
start_period: 60s

volumes:
worker-logs:

5. Verify​

curl -fsS http://127.0.0.1:8091/server-status

Send a test request through a deployed proxy:

curl -fsS http://127.0.0.1:8091/echo -H 'X-Trace: 1'

Expected boot logs:

ApiGateway standalone=true (env: prod-dc1)
HTTP listener bound: 0.0.0.0:8091
HTTPS listener bound: 0.0.0.0:8443 (only if Environment enables HTTPS)
Loaded N proxies for environment prod-dc1

6. Operations​

ActionCommand
Statusdocker ps --filter name=apinizer-worker
Logsdocker logs -f apinizer-worker
Restartdocker restart apinizer-worker
Stop (drain)docker stop -t 60 apinizer-worker
Warning

Use a generous stop timeout (docker stop -t 60) so in-flight HTTP / gRPC / WebSocket requests can drain. Without -t, Docker kills with SIGTERM after 10 s.

7. Networking​

Inbound

PortPurpose
8091HTTP gateway
8443HTTPS gateway

Outbound

  • MongoDB (proxy config + traffic log writes)
  • Cache cluster on 5701/tcp (Hazelcast wire) and 8090/tcp (REST), when quotas/OIDC/CB are used
  • Each backend service every deployed proxy is wired to

8. Multi-Worker (horizontal scale)​

Run the same image with the same APINIZER_ENVIRONMENT_NAME on each replica. Quota counters, OIDC sessions and circuit-breaker state are shared through the Apinizer Cache (Hazelcast). Without a shared Cache, each Worker has its own counters.

9. Resources​

Workloadmem_limitcpus
Smoke / staging (<200 rps)2 GB2
Production (1–3 krps per Worker)4–6 GB4
High throughput (5+ krps)8 GB4–8

Always load-test on the target hardware before changing JVM flags.

Troubleshooting​

APINIZER_ENVIRONMENT_NAME mismatch → container starts but proxies don't load​

If the name does not match an Environment in the Manager UI exactly (case sensitive), no proxy snapshot is fetched and every request returns 404. Fix: correct the env var or create the Environment.

UnsatisfiedLinkError: brotli​

You are running a custom build of the Worker on Alpine. Switch back to the official apinizercloud/worker image (Ubuntu noble base).

EMFILE: too many open files​

Add --ulimit nofile=1048576:1048576 to docker run. Also check that /etc/security/limits.conf / the host's LimitNOFILE allows it.