Docker Deployment

DocPlatform ships as a multi-architecture Docker image (amd64/arm64) built on Alpine Linux.

Quick start

docker run -d \
  --name docplatform \
  -p 3000:3000 \
  -v docplatform-data:/data \
  ghcr.io/valoryx-org/docplatform:latest

Open http://localhost:3000 and register your admin account.

Docker Compose

For easier management, use Docker Compose:

# docker-compose.yml
services:
  docplatform:
    image: ghcr.io/valoryx-org/docplatform:latest
    container_name: docplatform
    ports:
      - "3000:3000"
    volumes:
      - docplatform-data:/data
      - ./deploy_key:/etc/docplatform/deploy_key:ro
    environment:
      - DATA_DIR=/data
      - PORT=3000
      - GIT_SSH_KEY_PATH=/etc/docplatform/deploy_key
      - BACKUP_RETENTION_DAYS=30  # default is 7
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "docplatform", "doctor"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

volumes:
  docplatform-data:
docker compose up -d

Image details

Property Value
Registry ghcr.io/valoryx-org/docplatform
Base image Alpine Linux 3.20
Architectures linux/amd64, linux/arm64
Size ~120 MB compressed
User Non-root (docplatform, UID 1000)
Exposed port 3000
Data directory /data

Tags

Tag Description
latest Most recent stable release
v0.10.0 Specific version

Volumes

Mount a persistent volume at /data to preserve data across container restarts:

-v docplatform-data:/data

The /data directory contains:

/data/
├── data.db              # SQLite database
├── analytics.db         # Analytics database
├── jwt-private.pem      # Auto-generated RS256 signing key
├── search-index/        # Full-text search index
├── backups/             # Daily backup files
└── workspaces/
    └── {workspace-id}/  # Markdown files (the git working tree)
        ├── .git/        # Git repository (if connected)
        └── .docplatform/   # workspace.yaml, publish.yaml, nav.yaml, redirects.yaml

Do not skip the volume mount. Without it, all data is lost when the container is removed.

Environment variables

Pass configuration via -e flags, --env-file, or Docker Compose environment:

docker run -d \
  --name docplatform \
  -p 3000:3000 \
  -v docplatform-data:/data \
  -e DATA_DIR=/data \
  -e SMTP_HOST=smtp.example.com \
  -e SMTP_PORT=587 \
  -e SMTP_FROM=docs@example.com \
  -e SMTP_USERNAME=docs@example.com \
  -e SMTP_PASSWORD=app-password \
  -e OIDC_GOOGLE_CLIENT_ID=your-client-id \
  -e OIDC_GOOGLE_CLIENT_SECRET=your-client-secret \
  ghcr.io/valoryx-org/docplatform:latest

Or use an env file:

docker run -d \
  --name docplatform \
  -p 3000:3000 \
  -v docplatform-data:/data \
  --env-file .env.production \
  ghcr.io/valoryx-org/docplatform:latest

See Environment Variables for the complete reference.

SSH key for git sync

Mount your deploy key as a read-only volume:

-v /path/to/deploy_key:/etc/docplatform/deploy_key:ro
-e GIT_SSH_KEY_PATH=/etc/docplatform/deploy_key

Ensure the key file has correct permissions on the host:

chmod 600 /path/to/deploy_key

Health checks

DocPlatform exposes health endpoints:

Endpoint Purpose
GET /api/health Basic liveness check (server is running)
GET /api/ready Readiness check (database and search are initialized, reconciliation complete)

Use these for load balancer probes or orchestrator liveness/readiness probes. Note that the Dockerfile’s built-in healthcheck uses docplatform doctor rather than wget.

With a reverse proxy

Caddy + Docker Compose

services:
  docplatform:
    image: ghcr.io/valoryx-org/docplatform:latest
    volumes:
      - docplatform-data:/data
    environment:
      - DATA_DIR=/data
    restart: unless-stopped

  caddy:
    image: caddy:2-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    restart: unless-stopped

volumes:
  docplatform-data:
  caddy-data:
  caddy-config:
# Caddyfile
docs.yourcompany.com {
    reverse_proxy docplatform:3000
}

Caddy handles TLS automatically via Let’s Encrypt.

Upgrades

# Pull the latest image
docker pull ghcr.io/valoryx-org/docplatform:latest

# Recreate the container
docker compose up -d

Or with plain Docker:

docker pull ghcr.io/valoryx-org/docplatform:latest
docker stop docplatform
docker rm docplatform
docker run -d \
  --name docplatform \
  -p 3000:3000 \
  -v docplatform-data:/data \
  ghcr.io/valoryx-org/docplatform:latest

Data in the volume persists across container recreations.

Logs

# Follow container logs
docker logs -f docplatform

# Last 100 lines
docker logs --tail 100 docplatform

Logs are JSON-structured with request IDs for observability.

Backup and restore

Manual backup

# Copy the database from the container
docker cp docplatform:/data/data.db ./backup-$(date +%Y%m%d).db

Automated backups

Daily backups run automatically inside the container (enabled by default). They’re stored in /data/backups/ and included in the volume.

Restore

docker stop docplatform
docker cp ./backup-20250115.db docplatform:/data/data.db
docker start docplatform