PrintMaster DOCS
GitHub ↗

Docker Deployment

Deploy PrintMaster Server using Docker containers with multi-architecture support.

Quick Start

docker run -d \
  --name printmaster-server \
  -p 9090:9090 \
  -v printmaster-data:/var/lib/printmaster/server \
  -e ADMIN_PASSWORD=your-secure-password \
  ghcr.io/printmaster-org/printmaster-server:latest

Access at http://localhost:9090 with username admin.


Supported Architectures

All images are built for multiple architectures automatically:

ArchitecturePlatformUse Case
linux/amd64x86_64 serversIntel/AMD servers, cloud VMs
linux/arm64ARM 64-bitApple Silicon, AWS Graviton, Raspberry Pi 4+
linux/arm/v7ARM 32-bitRaspberry Pi 3/4 (32-bit OS)

Docker automatically pulls the correct architecture for your platform.

Image Details

Base Image: gcr.io/distroless/static:nonroot

  • Size: ~30MB (70% smaller than Alpine-based)
  • Security: No shell, no package manager, minimal attack surface
  • User: Runs as non-root (UID 65532)

Image tags:

  • latest - Latest stable release (recommended)
  • v0.23.6 - Specific version

Docker Compose

Create a docker-compose.yml file:

version: '3.8'
services:
  printmaster-server:
    image: ghcr.io/printmaster-org/printmaster-server:latest
    container_name: printmaster-server
    ports:
      - "9090:9090"
      - "9443:9443"  # HTTPS (optional)
    volumes:
      - printmaster-data:/var/lib/printmaster/server
      - printmaster-logs:/var/log/printmaster/server
    environment:
      - ADMIN_PASSWORD=your-secure-password
      - BIND_ADDRESS=0.0.0.0
      - LOG_LEVEL=info
      - PM_DISABLE_SELFUPDATE=true
    restart: unless-stopped

volumes:
  printmaster-data:
  printmaster-logs:

Start with:

docker compose up -d

Environment Variables

Essential

VariableDefaultDescription
ADMIN_PASSWORDprintmasterSet before first run!
BIND_ADDRESS127.0.0.1Set to 0.0.0.0 for external access
LOG_LEVELinfodebug, info, warn, error

Network & Ports

VariableDefaultDescription
SERVER_HTTP_PORT9090HTTP port
SERVER_HTTPS_PORT9443HTTPS port
BEHIND_PROXYfalseSet true if behind reverse proxy
PROXY_USE_HTTPSfalseProxy terminates SSL

TLS/HTTPS

VariableDefaultDescription
TLS_MODEself-signednone, self-signed, acme, manual
TLS_CERT_PATH—Certificate path (manual mode)
TLS_KEY_PATH—Key path (manual mode)

Let’s Encrypt

VariableDescription
LETSENCRYPT_DOMAINDomain for certificate
LETSENCRYPT_EMAILNotification email
LETSENCRYPT_ACCEPT_TOSAccept ToS (true)

Agent Management

VariableDefaultDescription
AUTO_APPROVE_AGENTSfalseAuto-approve new agents
AGENT_TIMEOUT_MINUTES5Timeout before marking offline

Container Detection

VariableEffect
PM_DISABLE_SELFUPDATEDisable self-update (recommended for Docker)
CONTAINER=dockerAuto-detected, disables self-update

See Environment Variables Reference for the complete list.


Behind a Reverse Proxy

Nginx Proxy Manager / Traefik / Caddy

environment:
  - BEHIND_PROXY=true
  - BIND_ADDRESS=0.0.0.0
  - PROXY_USE_HTTPS=true  # If proxy handles SSL

Reverse proxy requirements:

  • Forward to port 9090
  • Enable WebSocket support (required for real-time features)
  • Handle SSL termination

Nginx Configuration Example

server {
    listen 443 ssl;
    server_name printmaster.example.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    location / {
        proxy_pass http://printmaster-server:9090;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Volumes & Data

Container PathPurpose
/var/lib/printmaster/serverDatabase and config
/var/log/printmaster/serverLog files

The TimescaleDB PostgreSQL 18 Compose image mounts its database volume at /var/lib/postgresql. Do not change this to /var/lib/postgresql/data; that older mount layout can prevent the PG18 image from finding its data directory.

For PostgreSQL major-version migrations and TimescaleDB restore hooks, see PostgreSQL and TimescaleDB Upgrades.

Backup

# Stop container first for consistent backup
docker stop printmaster-server

# Backup database
docker cp printmaster-server:/var/lib/printmaster/server/server.db ./backup-$(date +%Y%m%d).db

# Restart
docker start printmaster-server

Health Check

The distroless image doesn’t include curl/wget. Use external monitoring:

# From host
curl -s http://localhost:9090/api/v1/health

# Docker health check (compose v3.8+)
healthcheck:
  test: ["CMD-SHELL", "wget -q -O /dev/null http://localhost:9090/api/v1/health || exit 1"]
  interval: 30s
  timeout: 10s
  retries: 3

Updating

# Pull latest image
docker pull ghcr.io/printmaster-org/printmaster-server:latest

# Recreate container
docker compose down
docker compose up -d

# Check version
docker logs printmaster-server | head -5

PostgreSQL and TimescaleDB upgrades

The repository Compose examples use timescale/timescaledb:latest-pg18 for new deployments. Changing a PostgreSQL major version while reusing an existing database volume is not a valid upgrade and can make the database refuse to start. Never delete the old volume as a workaround.

For the required backup, new-volume migration, and verification steps, see PostgreSQL and TimescaleDB Upgrades.


Agent in Docker

For specialized deployments (not typical):

docker run -d \
  --name printmaster-agent \
  --network host \
  -v printmaster-agent-data:/var/lib/printmaster/agent \
  -e SERVER_ENABLED=true \
  -e SERVER_URL=http://your-server:9090 \
  ghcr.io/printmaster-org/printmaster-agent:latest

Note: --network host is required for SNMP discovery to work properly.


See Also