Docker Deployment
Use this page when you want to run FastForward as a standalone container on a single host. For Kubernetes clusters, see Kubernetes deployment.
Quick start
Section titled “Quick start”docker run -d \ --name ffwd \ -v /var/log:/var/log:ro \ -v ./config.yaml:/etc/ffwd/config.yaml:ro \ -v ffwd-data:/var/lib/ffwd \ -p 9090:9090 \ --cpus 1.0 \ --memory 256m \ ghcr.io/strawgate/fastforward:latest \ run --config /etc/ffwd/config.yamlFlag breakdown
Section titled “Flag breakdown”| Flag | Purpose |
|---|---|
-v /var/log:/var/log:ro | Gives FastForward read-only access to host log files |
-v ./config.yaml:/etc/ffwd/config.yaml:ro | Injects your pipeline configuration (read-only) |
-v ffwd-data:/var/lib/ffwd | Persists checkpoint data between container restarts |
-p 9090:9090 | Exposes the diagnostics/admin API on the host |
--cpus 1.0 | Limits the container to one CPU core |
--memory 256m | Hard memory cap; the OOM killer fires if exceeded |
Checkpoint persistence
Section titled “Checkpoint persistence”# Named volume (recommended — Docker manages the lifecycle)-v ffwd-data:/var/lib/ffwd
# Host-path bind mount (useful when you need direct access to checkpoint files)-v /opt/ffwd/data:/var/lib/ffwdYour configuration must reference the same directory:
storage: data_dir: /var/lib/ffwdResource constraints
Section titled “Resource constraints”For most single-host deployments, one CPU core and 256 MB of memory are a reasonable starting point. Increase these if your host generates a high volume of logs or if you run complex SQL transforms.
# Conservative — suitable for light-to-moderate log volumesdocker run -d --cpus 0.5 --memory 128m ...
# Production — high-throughput hosts (>10 k lines/s)docker run -d --cpus 2.0 --memory 512m ...Monitor ffwd_stage_seconds_total (metric prefix will change in a future release) and container memory usage via docker stats
to decide whether you need to adjust. See Monitoring & Diagnostics
for details on available metrics.
Environment variable passthrough
Section titled “Environment variable passthrough”Use -e flags to inject secrets or endpoint addresses without baking them into
the configuration file. FastForward interpolates ${VAR} references in YAML values
at startup.
docker run -d \ --name ffwd \ -e OTEL_ENDPOINT=https://collector.internal:4318 \ -e OTEL_TOKEN=my-secret-token \ -v /var/log:/var/log:ro \ -v ./config.yaml:/etc/ffwd/config.yaml:ro \ -v ffwd-data:/var/lib/ffwd \ -p 9090:9090 \ --cpus 1.0 \ --memory 256m \ ghcr.io/strawgate/fastforward:latest \ run --config /etc/ffwd/config.yamlThen reference them in config.yaml:
output: type: otlp endpoint: "${OTEL_ENDPOINT}" compression: zstd auth: bearer_token: "${OTEL_TOKEN}"Network inputs with port mapping
Section titled “Network inputs with port mapping”When FastForward receives logs over TCP or UDP (instead of tailing files), you need to publish the listener ports.
docker run -d \ --name ffwd \ -v ./config.yaml:/etc/ffwd/config.yaml:ro \ -v ffwd-data:/var/lib/ffwd \ -p 9090:9090 \ -p 5140:5140/tcp \ -p 5140:5140/udp \ --cpus 1.0 \ --memory 256m \ ghcr.io/strawgate/fastforward:latest \ run --config /etc/ffwd/config.yamlMatching input configuration:
pipelines: syslog-tcp: inputs: - type: tcp listen: 0.0.0.0:5140 format: raw
syslog-udp: inputs: - type: udp listen: 0.0.0.0:5140 format: rawDocker Compose
Section titled “Docker Compose”A Compose file is the easiest way to run FastForward alongside an OpenTelemetry Collector on the same host. The example below tails host logs, forwards them over OTLP to the collector sidecar, and exposes the diagnostics API.
services: ffwd: image: ghcr.io/strawgate/fastforward:latest command: ["run", "--config", "/etc/ffwd/config.yaml"] volumes: - /var/log:/var/log:ro - ./config.yaml:/etc/ffwd/config.yaml:ro - ffwd-data:/var/lib/ffwd ports: - "9090:9090" environment: - OTEL_ENDPOINT=http://otel-collector:4318 deploy: resources: limits: cpus: "1.0" memory: 256M depends_on: - otel-collector restart: unless-stopped
otel-collector: image: otel/opentelemetry-collector-contrib:latest command: ["--config", "/etc/otelcol/config.yaml"] volumes: - ./otel-collector-config.yaml:/etc/otelcol/config.yaml:ro ports: - "4317:4317" # gRPC receiver - "4318:4318" # HTTP receiver restart: unless-stopped
volumes: ffwd-data:Start the stack:
docker compose up -ddocker compose logs -f ffwdValidate container health
Section titled “Validate container health”# Process and startup logsdocker ps --filter name=ffwddocker logs --tail=100 ffwd
# Diagnosticscurl -s http://localhost:9090/live | jq .curl -s http://localhost:9090/admin/v1/status | jq .You should see increasing inputs[*].lines_total and outputs[*].lines_total when logs are present.
To verify the OTLP output is connected:
# Check that the output reports no errorscurl -s http://localhost:9090/admin/v1/status | jq '.pipelines[].output'Rollback
Section titled “Rollback”If a config/image update causes failures:
# Stop and remove current containerdocker rm -f ffwd
# Run last known-good image or configdocker run -d \ --name ffwd \ -v /var/log:/var/log:ro \ -v ./config.last-known-good.yaml:/etc/ffwd/config.yaml:ro \ -v ffwd-data:/var/lib/ffwd \ -p 9090:9090 \ ghcr.io/strawgate/fastforward:<known-good-tag> \ run --config /etc/ffwd/config.yamlThen validate with the same diagnostics commands above.
Dockerfile
Section titled “Dockerfile”The release workflow builds multi-arch images for linux/amd64 and linux/arm64 using a distroless base image.
See Dockerfile and .github/workflows/release.yml for details.
What’s next
Section titled “What’s next”- Monitoring & Diagnostics — health probes, metrics, and the built-in dashboard.
- Input Types — configure file, TCP, and UDP inputs.
- Output Types — OTLP and other output options.
- SQL Transforms — filter and reshape logs before they leave the host.
- Kubernetes Deployment — scale out to a cluster with a DaemonSet.
- Troubleshooting — common issues and diagnostic steps.