Self-Hosting Cachet with Docker Compose

What Is Cachet?

Cachet is a self-hosted status page system for communicating service availability to your users. It provides a public dashboard showing component status, scheduled maintenance windows, and incident history with subscriber notifications. Think StatusPage.io or Atlassian Statuspage, but running on your own infrastructure with no monthly fees. Used by teams who need to communicate downtime professionally without paying $29-$99/month for a SaaS status page.

Official site: cachethq.io | GitHub

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 1 GB of free disk space
  • 512 MB of RAM minimum
  • A domain name (recommended — status pages need a public URL)

Docker Compose Configuration

services:
  cachet:
    image: cachethq/docker:2.3.18
    container_name: cachet
    restart: unless-stopped
    ports:
      - "8000:8000"
    environment:
      - APP_KEY=base64:changeme_generate_with_artisan
      - APP_ENV=production
      - APP_DEBUG=false
      - APP_URL=http://localhost:8000
      - DB_DRIVER=pgsql
      - DB_HOST=cachet-db
      - DB_PORT=5432
      - DB_DATABASE=cachet
      - DB_USERNAME=cachet
      - DB_PASSWORD=changeme_db
      - DB_PREFIX=chq_
      - CACHE_DRIVER=redis
      - SESSION_DRIVER=redis
      - QUEUE_DRIVER=redis
      - REDIS_HOST=cachet-redis
      - REDIS_PORT=6379
      - MAIL_DRIVER=smtp
      - MAIL_HOST=smtp.example.com
      - MAIL_PORT=587
      - MAIL_USERNAME=null
      - MAIL_PASSWORD=null
      - [email protected]
      - MAIL_NAME="Status Page"
      - MAIL_ENCRYPTION=tls
    depends_on:
      - cachet-db
      - cachet-redis
    networks:
      - cachet-net

  cachet-db:
    image: postgres:16-alpine
    container_name: cachet-db
    restart: unless-stopped
    environment:
      - POSTGRES_USER=cachet
      - POSTGRES_PASSWORD=changeme_db
      - POSTGRES_DB=cachet
    volumes:
      - cachet-pgdata:/var/lib/postgresql/data
    networks:
      - cachet-net

  cachet-redis:
    image: redis:7-alpine
    container_name: cachet-redis
    restart: unless-stopped
    volumes:
      - cachet-redis:/data
    networks:
      - cachet-net

volumes:
  cachet-pgdata:
  cachet-redis:

networks:
  cachet-net:

Generate the APP_KEY before starting:

docker compose run --rm cachet php artisan key:generate --show

Copy the output and set it as APP_KEY in the Compose file.

Start the stack:

docker compose up -d

Run the database migrations:

docker compose exec cachet php artisan cachet:install

Initial Setup

Open http://your-server-ip:8000/setup in your browser. The setup wizard walks you through:

  1. Environment setup — verify database and cache connections
  2. Status page setup — name, domain, timezone, language
  3. Admin account — create your administrator login
  4. Done — status page is live

Managing Your Status Page

Components

Components represent individual services you want to track (Website, API, Database, Email, etc.):

  1. Go to Dashboard → Components → Add Component
  2. Set a name, description, status, and optional link
  3. Group components into Component Groups for organization

Status levels: Operational, Performance Issues, Partial Outage, Major Outage.

Incidents

When something breaks:

  1. Dashboard → Incidents → Report Incident
  2. Set the incident name, message, status, and affected components
  3. Choose visibility (public or internal)
  4. Post updates as the situation evolves

Incident statuses: Investigating, Identified, Watching, Fixed.

Scheduled Maintenance

Communicate planned downtime:

  1. Dashboard → Incidents → Schedule Maintenance
  2. Set the maintenance window, affected components, and message
  3. Subscribers are notified before and after the window

Subscriber Notifications

Users can subscribe to status updates via email. Enable this in Settings → App Setup. When incidents are created or updated, subscribers receive email notifications.

Configuration

SettingEnvironment VariableDescription
App URLAPP_URLPublic URL for the status page
DatabaseDB_DRIVERpgsql, mysql, or sqlite
CacheCACHE_DRIVERredis, file, or database
QueueQUEUE_DRIVERredis, sync, or database
MailMAIL_DRIVERsmtp, sendmail, or log
BeaconCACHET_BEACONAnonymous usage stats (set false to disable)

API Access

Cachet provides a full REST API for automation:

# Get component status
curl -s http://localhost:8000/api/v1/components | jq

# Report an incident via API
curl -X POST http://localhost:8000/api/v1/incidents \
  -H "X-Cachet-Token: your-api-token" \
  -d "name=Service Disruption" \
  -d "message=Investigating elevated error rates" \
  -d "status=1" \
  -d "component_id=1" \
  -d "component_status=3"

API tokens are generated in Dashboard → Team → API Tokens.

Reverse Proxy

Set APP_URL to your public domain:

APP_URL=https://status.example.com

For proxy configuration, see Reverse Proxy Setup.

Backup

Back up the PostgreSQL database:

docker compose exec cachet-db pg_dump -U cachet cachet > cachet-backup-$(date +%Y%m%d).sql

For a full backup strategy, see Backup Strategy.

Troubleshooting

”500 Server Error” After Setup

Symptom: Status page shows a 500 error after completing the setup wizard.

Fix: Verify APP_KEY is set correctly. Run migrations again:

docker compose exec cachet php artisan migrate --force

Emails Not Sending

Symptom: Subscriber notifications and incident emails don’t arrive.

Fix: Check SMTP settings. Test with:

docker compose exec cachet php artisan tinker --execute="Mail::raw('test', function(\$m) { \$m->to('[email protected]')->subject('Test'); });"

Redis Connection Refused

Symptom: “Connection refused” errors in the logs.

Fix: Ensure the Redis container is running and the REDIS_HOST matches the container name in the Compose file.

Resource Requirements

  • RAM: ~150 MB (PHP-FPM + PostgreSQL + Redis)
  • CPU: Low — status pages have minimal traffic
  • Disk: ~200 MB for application, database grows slowly

Verdict

Cachet is the most established self-hosted status page with a solid feature set — components, incidents, maintenance windows, and subscriber notifications cover the essentials. The main concern is maintenance velocity — the v3 rewrite has been in progress for a while. For a simpler, more actively maintained alternative, Gatus offers monitoring + status page in one tool with better alerting. Uptime Kuma is better if you need monitoring with a status page as a secondary feature. Cachet wins when you need a dedicated, professional-looking incident communication platform.

Frequently Asked Questions

Is Cachet still actively maintained?

The v3 rewrite has been in progress for several years with slow progress. The v2.x branch receives occasional patches but no major features. For new deployments, evaluate whether the current feature set meets your needs and consider Gatus or Upptime as alternatives if long-term maintenance concerns you.

Does Cachet include monitoring or just status display?

Cachet is a status page and incident communication platform only — it doesn’t monitor your services. You need a separate tool (Uptime Kuma, Gatus, or Prometheus) to detect outages, then update Cachet via its API or manually through the dashboard. Gatus combines monitoring and a status page in one tool if you want both.

Can I automate incident creation in Cachet?

Yes. Cachet has a REST API that lets you create incidents, update component status, and manage metrics programmatically. Hook it into your monitoring stack: when Uptime Kuma detects an outage, trigger a webhook that creates a Cachet incident via the API. This eliminates manual incident reporting.

Does Cachet support email notifications to subscribers?

Yes. Users can subscribe to your status page and receive email notifications when incidents are created or updated. Configure SMTP settings in the .env file. Subscribers can choose to receive notifications for all components or only specific ones they care about.

Can I customize the Cachet status page appearance?

Yes. Cachet supports custom CSS, logos, and branding through the admin dashboard. The default theme is clean and professional. For deeper customization, you can modify the Blade templates in the source code, though this makes upgrades harder. The banner, colors, and header text are all configurable without code changes.

What database does Cachet use?

Cachet supports PostgreSQL, MySQL, and SQLite. PostgreSQL is recommended for production deployments. SQLite works for small installations with light traffic. The Docker Compose configuration in this guide uses PostgreSQL with Redis for caching and queue processing.

Comments