How to Self-Host GlitchTip with Docker Compose

What Is GlitchTip?

Want error tracking without Sentry’s pricing or complexity? GlitchTip is an open-source error tracking platform that accepts Sentry SDKs — meaning your existing Sentry integration code works without modification. Point your DSN at your GlitchTip instance and you get crash reports, performance monitoring, and uptime checks on your own infrastructure.

GlitchTip also includes built-in uptime monitoring, so you can track both application errors and service availability from a single dashboard. It runs on Django with PostgreSQL and uses under 512 MB of RAM.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 2 GB of RAM (512 MB minimum for all-in-one mode)
  • 10 GB of free disk space (scales with event volume)
  • A domain name (optional, for remote access)

Docker Compose Configuration

Create a docker-compose.yml file:

services:
  postgres:
    image: postgres:18
    restart: unless-stopped
    environment:
      POSTGRES_USER: glitchtip
      POSTGRES_PASSWORD: changeme_db_password    # Change this
      POSTGRES_DB: glitchtip
    volumes:
      - pg-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U glitchtip"]
      interval: 10s
      timeout: 5s
      retries: 5

  valkey:
    image: valkey/valkey:9
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "valkey-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  migrate:
    image: glitchtip/glitchtip:v6.0.10
    depends_on:
      postgres:
        condition: service_healthy
      valkey:
        condition: service_healthy
    command: ./manage.py migrate && ./manage.py createcachetable && ./manage.py maintain_partitions
    environment: &glitchtip-env
      SECRET_KEY: "changeme_generate_with_openssl_rand_hex_32"  # openssl rand -hex 32
      DATABASE_URL: "postgres://glitchtip:changeme_db_password@postgres:5432/glitchtip"
      GLITCHTIP_DOMAIN: "https://glitchtip.example.com"  # Your domain
      VALKEY_URL: "redis://valkey:6379/0"
      DEFAULT_FROM_EMAIL: "[email protected]"
      EMAIL_URL: "smtp://user:[email protected]:587"  # SMTP config
      GLITCHTIP_MAX_EVENT_LIFE_DAYS: "90"  # Data retention in days
      ENABLE_USER_REGISTRATION: "true"     # Disable after creating your account

  web:
    image: glitchtip/glitchtip:v6.0.10
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
      valkey:
        condition: service_healthy
      migrate:
        condition: service_completed_successfully
    ports:
      - "8000:8000"
    environment: *glitchtip-env
    volumes:
      - uploads:/code/uploads
    healthcheck:
      test: ["CMD-SHELL", "python3 /code/healthcheck.py || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s

  worker:
    image: glitchtip/glitchtip:v6.0.10
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
      valkey:
        condition: service_healthy
      migrate:
        condition: service_completed_successfully
    command: ./bin/run-celery.sh
    environment: *glitchtip-env
    volumes:
      - uploads:/code/uploads

volumes:
  pg-data:
  uploads:

Generate a secret key before starting:

openssl rand -hex 32

Replace changeme_generate_with_openssl_rand_hex_32 with the output. Update changeme_db_password in both the PostgreSQL environment and the DATABASE_URL.

Start the stack:

docker compose up -d

The migrate service runs database migrations and exits — this is expected behavior. Check that web and worker are healthy:

docker compose ps

Initial Setup

  1. Open http://your-server-ip:8000 in your browser
  2. Click Sign Up to create your admin account
  3. Create an organization (this groups your projects)
  4. Create your first project — select the platform (Python, JavaScript, React, etc.)
  5. GlitchTip generates a DSN (Data Source Name) for your project

Copy the DSN. It looks like https://[email protected]/1. Use this in your application’s Sentry SDK configuration.

After creating your account, set ENABLE_USER_REGISTRATION: "false" in the compose file and restart to prevent unauthorized signups.

Configuration

Connecting Your Application

GlitchTip is compatible with Sentry SDKs. Install the Sentry SDK for your language and point it at your GlitchTip instance:

Python:

import sentry_sdk
sentry_sdk.init(dsn="https://[email protected]/1")

JavaScript:

import * as Sentry from "@sentry/browser";
Sentry.init({ dsn: "https://[email protected]/1" });

Node.js:

const Sentry = require("@sentry/node");
Sentry.init({ dsn: "https://[email protected]/1" });

Key Configuration Options

VariableDefaultDescription
GLITCHTIP_MAX_EVENT_LIFE_DAYS90Days to retain error events before cleanup
ENABLE_USER_REGISTRATIONtrueAllow new user signups
ENABLE_ORGANIZATION_CREATIONfalseAllow users to create organizations
GLITCHTIP_ENABLE_UPTIMEtrueEnable uptime monitoring feature
GRANIAN_WORKERS1Number of web worker processes
DATABASE_POOL_MAX_SIZE20PostgreSQL connection pool size
VTASKS_CONCURRENCY20Background task concurrency
LOG_LEVELWARNINGApplication log verbosity

Uptime Monitoring

GlitchTip includes built-in uptime monitoring. Navigate to Uptime in the sidebar to add monitors. Each monitor checks a URL at configurable intervals and alerts on downtime. This eliminates the need for a separate uptime tool like Uptime Kuma.

Advanced Configuration

Social/OAuth Login

GlitchTip supports social authentication through Django’s allauth. Supported providers: GitHub, GitLab, Google, Microsoft, DigitalOcean, Gitea, NextCloud, Okta, and OpenID Connect.

To configure, enable the Django admin panel:

environment:
  ENABLE_ADMIN: "true"

Then navigate to https://glitchtip.example.com/admin/socialaccount/socialapp/ to add OAuth providers.

S3-Compatible Storage

For large deployments, offload uploaded source maps and attachments to S3:

environment:
  DEFAULT_FILE_STORAGE: "storages.backends.s3boto3.S3Boto3Storage"
  AWS_ACCESS_KEY_ID: "your-key"
  AWS_SECRET_ACCESS_KEY: "your-secret"
  AWS_STORAGE_BUCKET_NAME: "glitchtip-uploads"
  AWS_S3_ENDPOINT_URL: "https://s3.example.com"  # For MinIO or other S3-compatible storage

Prometheus Metrics

Enable the observability API for Prometheus scraping:

environment:
  ENABLE_OBSERVABILITY_API: "true"

Metrics are exposed at /api/0/observability/metrics/.

Reverse Proxy

Place GlitchTip behind a reverse proxy for SSL termination. With Nginx Proxy Manager, point to port 8000. Add CSRF_TRUSTED_ORIGINS to your environment:

environment:
  CSRF_TRUSTED_ORIGINS: "https://glitchtip.example.com"

Set client_max_body_size 40M in your Nginx configuration to handle source map uploads.

For general reverse proxy setup, see our Reverse Proxy guide.

Backup

Back up the PostgreSQL database and the uploads volume:

# Database backup
docker compose exec postgres pg_dump -U glitchtip glitchtip > glitchtip_backup.sql

# Uploads backup
docker run --rm -v glitchtip_uploads:/data -v $(pwd):/backup alpine \
  tar czf /backup/glitchtip-uploads.tar.gz -C /data .

Schedule daily backups with cron. For a comprehensive backup strategy, see our Backup guide.

Troubleshooting

Events Not Appearing

Symptom: Your application sends events but nothing shows up in GlitchTip.

Fix: Check that the DSN domain resolves to your GlitchTip instance. Verify the project ID in the DSN matches your project. Check the worker service logs:

docker compose logs worker

If the worker isn’t running, events queue in PostgreSQL but aren’t processed.

Migrate Service Keeps Restarting

Symptom: The migrate container restarts repeatedly.

Fix: This service should run once and exit. Add a restart policy exception or use restart: "no" for the migrate service. Check PostgreSQL is healthy first:

docker compose logs postgres

High Disk Usage

Symptom: Disk space growing rapidly.

Fix: Lower GLITCHTIP_MAX_EVENT_LIFE_DAYS to reduce retention. GlitchTip auto-cleans events older than this value. For high-volume applications, consider sampling events on the SDK side:

sentry_sdk.init(dsn="...", traces_sample_rate=0.1)  # Sample 10% of transactions

CSRF Errors Behind Reverse Proxy

Symptom: 403 Forbidden errors when submitting forms.

Fix: Set CSRF_TRUSTED_ORIGINS to your public domain including the scheme:

CSRF_TRUSTED_ORIGINS: "https://glitchtip.example.com"

Resource Requirements

ResourceMinimumRecommended
RAM256 MB (all-in-one)512 MB+
CPU1 core2+ cores
Disk5 GB10-30 GB (scales with event volume)
Disk estimate~30 GB per 1M events/monthDepends on source map uploads

GlitchTip is one of the lightest error tracking platforms available. The all-in-one mode (SERVER_ROLE: all_in_one) runs web server, worker, and migrations in a single process using under 256 MB of RAM.

Verdict

GlitchTip is the right tool if you want Sentry-compatible error tracking without Sentry’s complexity or cost. The Sentry SDK compatibility is the killer feature — you don’t rewrite your instrumentation code, just change the DSN. The built-in uptime monitoring is a bonus that eliminates one more external service.

For teams generating fewer than 5,000 events/month, Sentry’s free tier is hard to beat on convenience. But once you exceed that limit, Sentry’s pricing scales quickly ($26/month for 50K events, $80/month for 100K). GlitchTip handles unlimited events for the cost of hosting.

FAQ

Is GlitchTip fully compatible with Sentry SDKs?

GlitchTip supports the Sentry SDK wire protocol. Error tracking, breadcrumbs, and basic performance monitoring work. Some Sentry-specific features (replays, profiling, advanced dashboards) are not available.

Can GlitchTip replace Sentry for production use?

Yes, for error tracking and uptime monitoring. GlitchTip handles crash reports, stack traces, source maps, and alerting. It lacks Sentry’s session replays and advanced performance tracing.

How does GlitchTip handle data retention?

Set GLITCHTIP_MAX_EVENT_LIFE_DAYS to automatically delete events older than the specified number of days. PostgreSQL partitioning handles the cleanup efficiently.

What’s the difference between the production and minimal setup?

The production setup runs separate web and worker processes with Valkey for task queuing. The minimal setup uses SERVER_ROLE: all_in_one to embed the worker in the web process and skips Valkey entirely. Use the production setup for anything beyond personal projects.

Comments