dockercontainersdevops

Docker & Docker Compose

Collect logs from containerized services and send them to ScryWatch — using the log driver, a sidecar, or direct HTTP from your app.

Docker & Docker Compose

ScryWatch accepts logs over HTTP from any containerized service. There is no daemon to install — your app posts events directly to the ingest API.

This guide covers three patterns:

  1. Direct from app — the service calls /api/ingest itself
  2. Log-collector sidecar — a Fluent Bit container forwards stdout/stderr
  3. curl smoke test — quick verification from any container

What you’ll need


Pattern 1: Direct HTTP from your service

The simplest approach. Your app makes HTTP calls to ScryWatch the same way it would call any API.

docker-compose.yml

version: '3.9'

services:
  api:
    image: node:20-alpine
    working_dir: /app
    volumes:
      - .:/app
    command: node server.js
    environment:
      SCRYWATCH_API_KEY: ${SCRYWATCH_API_KEY}
      SCRYWATCH_ENDPOINT: https://api.scrywatch.com/api/ingest
      NODE_ENV: production
    ports:
      - '3000:3000'

.env

SCRYWATCH_API_KEY=sw_your_api_key_here

Node.js example (server.js)

import { LogMonitor } from '@scrywatch/sdk';

const monitor = new LogMonitor({
  endpoint: process.env.SCRYWATCH_ENDPOINT,
  apiKey: process.env.SCRYWATCH_API_KEY,
  service: 'api',
  environment: process.env.NODE_ENV,
});

// Log on startup
monitor.info('API server started', { port: 3000 });

// Flush before container stops
process.on('SIGTERM', async () => {
  await monitor.flush();
  process.exit(0);
});

Pattern 2: Fluent Bit sidecar (forward stdout/stderr)

Use this if you want all container stdout/stderr forwarded to ScryWatch without changing your app code.

docker-compose.yml

version: '3.9'

services:
  api:
    image: your-service:latest
    logging:
      driver: fluentd
      options:
        fluentd-address: localhost:24224
        tag: api.logs

  fluent-bit:
    image: fluent/fluent-bit:3
    ports:
      - '24224:24224'
    volumes:
      - ./fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf:ro
    environment:
      SCRYWATCH_API_KEY: ${SCRYWATCH_API_KEY}

fluent-bit.conf

[SERVICE]
    Flush         5
    Daemon        Off
    Log_Level     info

[INPUT]
    Name          forward
    Listen        0.0.0.0
    Port          24224

[FILTER]
    Name          record_modifier
    Match         *
    Record        service api
    Record        environment production

[OUTPUT]
    Name          http
    Match         *
    Host          api.scrywatch.com
    Port          443
    TLS           On
    URI           /api/ingest
    Header        Authorization Bearer ${SCRYWATCH_API_KEY}
    Header        Content-Type application/json
    Format        json
    json_date_key timestamp
    json_date_format epoch_int

Note: Fluent Bit’s HTTP output sends one event per request. For high-throughput services, consider batching with the http output batch_size option or switching to the direct-from-app pattern with the JS SDK’s built-in buffer.


Pattern 3: curl smoke test

Verify connectivity from inside your Docker network before wiring up a full SDK:

version: '3.9'

services:
  smoke-test:
    image: curlimages/curl:latest
    environment:
      SCRYWATCH_API_KEY: ${SCRYWATCH_API_KEY}
    command: >
      curl -sf -X POST https://api.scrywatch.com/api/ingest
      -H "Authorization: Bearer $$SCRYWATCH_API_KEY"
      -H "Content-Type: application/json"
      -d '{"events":[{"timestamp":0,"level":"info","type":"custom","message":"Docker smoke test"}]}'
      && echo "OK"

Replace "timestamp":0 with a real epoch millisecond value in production.


Environment variables reference

VariableDescription
SCRYWATCH_API_KEYProject API key
SCRYWATCH_ENDPOINTIngest URL (default: https://api.scrywatch.com/api/ingest)

Pass secrets using a .env file or your orchestrator’s secrets manager (Docker Swarm secrets, AWS Secrets Manager, etc.). Never hardcode API keys in docker-compose.yml.


Multi-service example

version: '3.9'

x-scrywatch: &scrywatch
  SCRYWATCH_API_KEY: ${SCRYWATCH_API_KEY}
  SCRYWATCH_ENDPOINT: https://api.scrywatch.com/api/ingest

services:
  web:
    image: your-web:latest
    environment:
      <<: *scrywatch
      SERVICE_NAME: web

  worker:
    image: your-worker:latest
    environment:
      <<: *scrywatch
      SERVICE_NAME: worker

  db-migrator:
    image: your-migrator:latest
    environment:
      <<: *scrywatch
      SERVICE_NAME: db-migrator

Each service passes SERVICE_NAME to the SDK’s service field so events are filterable by service in the Log Explorer.


Next steps

← All guides