Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Docker Compose Setup

This guide explains how to deploy Yet Another Status Page using Docker Compose.

Quick Start

1. Clone the Repository

git clone https://github.com/Hostzero-GmbH/yet-another-status-page.git
cd yet-another-status-page

2. Create Environment File

cp .env.example .env

Edit .env with your configuration:

# Database
DATABASE_URI=postgres://hostzero:your-secure-password@db:5432/hostzero_status
POSTGRES_PASSWORD=your-secure-password

# Security
PAYLOAD_SECRET=your-32-character-secret-key-here

# URLs
SERVER_URL=https://status.yourdomain.com

Note: Email (SMTP) and SMS (Twilio) settings are configured via the admin panel under Configuration → Email Settings and Configuration → SMS Settings, not through environment variables.

3. Start the Services

docker compose up -d

4. Access the Application

  • Status Page: http://localhost:3000
  • Admin Panel: http://localhost:3000/admin

Docker Compose File

Create a docker-compose.yml in your project root:

version: '3.8'

services:
  app:
    image: ghcr.io/hostzero-gmbh/status-page:latest
    # Or build from source:
    # build:
    #   context: ./cms
    #   dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URI=${DATABASE_URI}
      - PAYLOAD_SECRET=${PAYLOAD_SECRET}
      - SERVER_URL=${SERVER_URL}
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    volumes:
      - uploads:/app/public/media

  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_USER=hostzero
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=hostzero_status
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U hostzero -d hostzero_status"]
      interval: 5s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  postgres_data:
  uploads:

Production Deployment

version: '3.8'

services:
  app:
    image: ghcr.io/hostzero-gmbh/status-page:latest
    environment:
      - DATABASE_URI=${DATABASE_URI}
      - PAYLOAD_SECRET=${PAYLOAD_SECRET}
      - SERVER_URL=https://status.yourdomain.com
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    volumes:
      - uploads:/app/public/media
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.status.rule=Host(`status.yourdomain.com`)"
      - "traefik.http.routers.status.entrypoints=websecure"
      - "traefik.http.routers.status.tls.certresolver=letsencrypt"
      - "traefik.http.services.status.loadbalancer.server.port=3000"
    networks:
      - traefik
      - internal

  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_USER=hostzero
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=hostzero_status
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U hostzero -d hostzero_status"]
      interval: 5s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    networks:
      - internal

volumes:
  postgres_data:
  uploads:

networks:
  traefik:
    external: true
  internal:

With nginx

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - app
    restart: unless-stopped

  app:
    image: ghcr.io/hostzero-gmbh/status-page:latest
    environment:
      - DATABASE_URI=${DATABASE_URI}
      - PAYLOAD_SECRET=${PAYLOAD_SECRET}
      - SERVER_URL=https://status.yourdomain.com
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    volumes:
      - uploads:/app/public/media

  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_USER=hostzero
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=hostzero_status
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U hostzero -d hostzero_status"]
      interval: 5s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  postgres_data:
  uploads:

Updating

To update to the latest version:

# Pull the latest image
docker compose pull

# Restart with the new image
docker compose up -d

Backup & Restore

Backup Database

docker compose exec db pg_dump -U hostzero hostzero_status > backup.sql

Restore Database

cat backup.sql | docker compose exec -T db psql -U hostzero hostzero_status

Backup Uploads

docker compose cp app:/app/public/media ./media-backup