Skip to main content

Docker Deployment

Panguard provides Docker images and Compose configurations for containerized deployments. This guide covers single-container setup, full-stack Compose deployments, and production hardening.

Prerequisites

RequirementVersion
Docker>= 24.0
Docker Compose>= 2.20

Quick Start with Docker

1

Pull the Image

docker pull panguard/panguard-ai:latest
2

Run the Container

docker run -d \
  --name panguard \
  -p 3000:3000 \
  -v panguard-data:/data \
  panguard/panguard-ai:latest
3

Verify

docker logs panguard

Docker Compose: Basic Setup (API + Ollama)

This configuration runs the Panguard API server with a local Ollama instance for Layer 2 AI analysis at zero cost.
# docker-compose.yml
services:
  panguard:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: panguard
    restart: unless-stopped
    ports:
      - '3000:3000'
    volumes:
      - panguard-data:/data
      - ./config:/app/config:ro
    environment:
      - PANGUARD_DATA_DIR=/data
      - PANGUARD_PORT=3000
      - OLLAMA_ENDPOINT=http://ollama:11434
    depends_on:
      ollama:
        condition: service_healthy

  ollama:
    image: ollama/ollama:latest
    container_name: panguard-ollama
    restart: unless-stopped
    ports:
      - '11434:11434'
    volumes:
      - ollama-models:/root/.ollama
    healthcheck:
      test: ['CMD', 'curl', '-f', 'http://localhost:11434/api/tags']
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 30s

volumes:
  panguard-data:
  ollama-models:
# Build and start
docker compose up -d

# Pull an Ollama model (first time only)
docker exec panguard-ollama ollama pull llama3

# View logs
docker compose logs -f panguard

Docker Compose: Full Stack (Auth + Manager + Guard + Ollama)

This configuration runs the complete Panguard platform with authentication, fleet management, and local AI.
# docker-compose.full.yml
services:
  panguard-auth:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: panguard-auth
    restart: unless-stopped
    ports:
      - '3000:3000'
    volumes:
      - auth-data:/data
      - ./config:/app/config:ro
    environment:
      - PANGUARD_DATA_DIR=/data
      - PANGUARD_PORT=3000
      - JWT_SECRET=your-secret-key-here
      - GOOGLE_CLIENT_ID=your-google-client-id
      - GOOGLE_CLIENT_SECRET=your-google-client-secret
      - MANAGER_URL=http://panguard-manager:8443
      - MANAGER_AUTH_TOKEN=your-manager-token
      - OLLAMA_ENDPOINT=http://ollama:11434
    depends_on:
      panguard-manager:
        condition: service_started
      ollama:
        condition: service_healthy
    networks:
      - panguard-net

  panguard-manager:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: panguard-manager
    command: ["node", "dist/cli/index.js", "manager", "--port", "8443"]
    restart: unless-stopped
    ports:
      - '8443:8443'
    environment:
      - MANAGER_PORT=8443
      - MANAGER_AUTH_TOKEN=your-manager-token
      - MANAGER_MAX_AGENTS=500
      - CORS_ALLOWED_ORIGINS=http://localhost:3000
    networks:
      - panguard-net

  ollama:
    image: ollama/ollama:latest
    container_name: panguard-ollama
    restart: unless-stopped
    ports:
      - '11434:11434'
    volumes:
      - ollama-models:/root/.ollama
    networks:
      - panguard-net
    healthcheck:
      test: ['CMD', 'curl', '-f', 'http://localhost:11434/api/tags']
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 30s

volumes:
  auth-data:
  ollama-models:

networks:
  panguard-net:
    driver: bridge
docker compose -f docker-compose.full.yml up -d

Port Reference

PortServiceProtocolNotes
3000API Server (Auth + Web)HTTPMain entry point
8443Manager ServerHTTPAgent registration, heartbeats, SSE
11434OllamaHTTPLocal AI inference
2222Trap: SSH HoneypotTCPDefault SSH trap port
8080Trap: HTTP HoneypotTCPDefault HTTP trap port
2121Trap: FTP HoneypotTCPDefault FTP trap port
4450Trap: SMB HoneypotTCPDefault SMB trap port
3307Trap: MySQL HoneypotTCPDefault MySQL trap port
3390Trap: RDP HoneypotTCPDefault RDP trap port
2323Trap: Telnet HoneypotTCPDefault Telnet trap port

Environment Variables

Guard Agent

VariableDefaultDescription
PANGUARD_DATA_DIR./dataData directory for baselines, logs, rules
PANGUARD_MODElearningGuard mode: learning or protection
OLLAMA_ENDPOINThttp://localhost:11434Ollama API endpoint
ANTHROPIC_API_KEY(none)Claude API key for cloud AI
OPENAI_API_KEY(none)OpenAI API key for cloud AI
ABUSEIPDB_KEY(none)AbuseIPDB API key for threat intel

Auth Server

VariableDefaultDescription
PANGUARD_PORT3000API server port
JWT_SECRET(none)JWT signing secret (required in production)
GOOGLE_CLIENT_ID(none)Google OAuth client ID
GOOGLE_CLIENT_SECRET(none)Google OAuth client secret

Manager

VariableDefaultDescription
MANAGER_PORT8443Manager HTTP server port
MANAGER_AUTH_TOKEN(none)Bearer token for API authentication
MANAGER_MAX_AGENTS500Maximum registered agents
Never pass secrets via the environment key in production Compose files. Use env_file with restricted permissions instead:
env_file:
  - /etc/panguard/guard.env  # chmod 600

Production Hardening

Docker Image Security

The production Docker image includes:
  • Multi-stage build — Build dependencies are not in the final image
  • Non-root user — Runs as panguard (UID 1001)
  • tini — Proper PID 1 signal handling and zombie reaping
  • Minimal packages — Only tini and curl in the final image

Required Capabilities

For Guard response actions to function inside Docker, grant these capabilities:
cap_add:
  - NET_ADMIN    # Block IPs via iptables
  - KILL         # Terminate malicious processes
  - SYS_PTRACE   # Memory scanning

Checklist

  • Set NODE_ENV=production (enables HSTS, disables wildcard CORS)
  • Generate strong secrets (openssl rand -hex 32)
  • Use TLS termination (nginx/Caddy reverse proxy in front)
  • Restrict network access to Manager port
  • Mount secrets as env files, not inline environment variables
  • Use named volumes for persistent data
  • Configure log rotation for container logs

Log Locations (Inside Container)

ComponentPathFormat
Guard events/data/events.jsonlJSONL
Guard actions/data/action-manifest.jsonlJSONL
Guard baseline/data/baseline.jsonJSON
Application logsstdout/stderrStructured JSON

Log Rotation

The ReportAgent handles log rotation automatically:
SettingDefault
Max file size50 MB
Max rotated files10
Retention90 days

Backup Strategy

Back up these critical files regularly:
  • Baseline data (/data/baseline.json) — Loss requires re-running learning mode
  • Auth database (auth.db) — Back up daily with sqlite3 auth.db ".backup backup.db"
  • Threat Cloud database — Back up the SQLite database on schedule
  • Configuration — Store config and env files in version control or a secrets manager