feat: glitchtip docker stack + local dev integration
WS-7 PR-1 — bring up self-hosted GlitchTip alongside the existing dev stack. One compose file is portable to the production monitoring host (RFC-WS-7 §3.1). - docker-compose.glitchtip.yml: web/worker/postgres/redis pinned, web bound to 127.0.0.1:8200, internal network for postgres + valkey. - docker/glitchtip/.env.example: documented dev defaults + production checklist; .env itself ignored. - Makefile: services / services-stop merge both compose files; new services-glitchtip-status tail target. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -60,3 +60,7 @@ docs/.vitepress/cache
|
|||||||
|
|
||||||
# Claude Code runtime state
|
# Claude Code runtime state
|
||||||
.claude/*.lock
|
.claude/*.lock
|
||||||
|
|
||||||
|
# GlitchTip
|
||||||
|
docker/glitchtip/.env
|
||||||
|
backups/
|
||||||
|
|||||||
27
Makefile
27
Makefile
@@ -1,4 +1,4 @@
|
|||||||
.PHONY: help services services-stop api app docs migrate fresh db-shell test test-db-create schema-dump
|
.PHONY: help services services-stop services-glitchtip-status api app docs migrate fresh db-shell test test-db-create schema-dump
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
GREEN := \033[0;32m
|
GREEN := \033[0;32m
|
||||||
@@ -6,6 +6,10 @@ YELLOW := \033[0;33m
|
|||||||
CYAN := \033[0;36m
|
CYAN := \033[0;36m
|
||||||
NC := \033[0m
|
NC := \033[0m
|
||||||
|
|
||||||
|
# Compose files merged for local dev. Both files share one project so
|
||||||
|
# Mailpit (bm_mailpit) is reachable from the GlitchTip containers.
|
||||||
|
COMPOSE_FILES := -f docker-compose.yml -f docker-compose.glitchtip.yml
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "$(GREEN)╔══════════════════════════════════════════════════════════════╗$(NC)"
|
@echo "$(GREEN)╔══════════════════════════════════════════════════════════════╗$(NC)"
|
||||||
@@ -13,8 +17,9 @@ help:
|
|||||||
@echo "$(GREEN)╚══════════════════════════════════════════════════════════════╝$(NC)"
|
@echo "$(GREEN)╚══════════════════════════════════════════════════════════════╝$(NC)"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " $(YELLOW)Services (Docker):$(NC)"
|
@echo " $(YELLOW)Services (Docker):$(NC)"
|
||||||
@echo " make services Start MySQL, Redis, Mailpit"
|
@echo " make services Start MySQL, Redis, Mailpit, GlitchTip"
|
||||||
@echo " make services-stop Stop all Docker services"
|
@echo " make services-stop Stop all Docker services"
|
||||||
|
@echo " make services-glitchtip-status Tail GlitchTip web container logs"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " $(YELLOW)Development Servers:$(NC)"
|
@echo " $(YELLOW)Development Servers:$(NC)"
|
||||||
@echo " make api Laravel API → http://localhost:8000"
|
@echo " make api Laravel API → http://localhost:8000"
|
||||||
@@ -34,21 +39,27 @@ help:
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
@echo "$(GREEN)Starting Docker services...$(NC)"
|
@echo "$(GREEN)Starting Docker services...$(NC)"
|
||||||
@docker compose up -d
|
@docker compose $(COMPOSE_FILES) up -d
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "$(GREEN)Services:$(NC)"
|
@echo "$(GREEN)Services:$(NC)"
|
||||||
@echo " $(CYAN)MySQL:$(NC) localhost:3306 (crewli / secret)"
|
@echo " $(CYAN)MySQL:$(NC) localhost:3306 (crewli / secret)"
|
||||||
@echo " $(CYAN)Redis:$(NC) localhost:6379"
|
@echo " $(CYAN)Redis:$(NC) localhost:6379"
|
||||||
@echo " $(CYAN)Mailpit:$(NC) http://localhost:8025"
|
@echo " $(CYAN)Mailpit:$(NC) http://localhost:8025"
|
||||||
|
@echo " $(CYAN)GlitchTip:$(NC) http://localhost:8200"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "$(YELLOW)Waiting for MySQL...$(NC)"
|
@echo "$(YELLOW)Waiting for MySQL...$(NC)"
|
||||||
@until docker exec bm_mysql mysqladmin ping -h localhost -u root -proot --silent 2>/dev/null; do sleep 1; done
|
@until docker exec bm_mysql mysqladmin ping -h localhost -u root -proot --silent 2>/dev/null; do sleep 1; done
|
||||||
@echo "$(GREEN)✓ Ready!$(NC)"
|
@echo "$(GREEN)✓ Ready!$(NC)"
|
||||||
|
@echo "$(YELLOW)Note:$(NC) GlitchTip web takes ~60s on first boot (migrations)."
|
||||||
|
@echo " Tail logs with: $(CYAN)make services-glitchtip-status$(NC)"
|
||||||
|
|
||||||
services-stop:
|
services-stop:
|
||||||
@docker compose down
|
@docker compose $(COMPOSE_FILES) down
|
||||||
@echo "$(GREEN)✓ Services stopped$(NC)"
|
@echo "$(GREEN)✓ Services stopped$(NC)"
|
||||||
|
|
||||||
|
services-glitchtip-status:
|
||||||
|
@docker compose $(COMPOSE_FILES) logs -f glitchtip-web
|
||||||
|
|
||||||
api:
|
api:
|
||||||
@echo "$(GREEN)Starting Laravel API → http://localhost:8000$(NC)"
|
@echo "$(GREEN)Starting Laravel API → http://localhost:8000$(NC)"
|
||||||
@cd api && php artisan serve
|
@cd api && php artisan serve
|
||||||
|
|||||||
85
docker-compose.glitchtip.yml
Normal file
85
docker-compose.glitchtip.yml
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# GlitchTip — self-hosted error tracking (Sentry-protocol compatible).
|
||||||
|
#
|
||||||
|
# This file is portable: it runs standalone on the production monitoring
|
||||||
|
# host AND merges into the local Crewli dev stack via:
|
||||||
|
#
|
||||||
|
# docker compose -f docker-compose.yml -f docker-compose.glitchtip.yml up -d
|
||||||
|
#
|
||||||
|
# `make services` encapsulates the merge for local development.
|
||||||
|
#
|
||||||
|
# All configuration comes from docker/glitchtip/.env via env_file. Copy
|
||||||
|
# docker/glitchtip/.env.example to docker/glitchtip/.env on first run.
|
||||||
|
#
|
||||||
|
# Per RFC-WS-7-OBSERVABILITY §3.1. See dev-docs/GLITCHTIP.md for the
|
||||||
|
# operations runbook (boot, project provisioning, DSN handling, backup,
|
||||||
|
# restore).
|
||||||
|
|
||||||
|
services:
|
||||||
|
glitchtip-postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: glitchtip-postgres
|
||||||
|
env_file:
|
||||||
|
- ./docker/glitchtip/.env
|
||||||
|
volumes:
|
||||||
|
- glitchtip_postgres_data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U postgres -d glitchtip"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
glitchtip-redis:
|
||||||
|
image: valkey/valkey:7-alpine
|
||||||
|
container_name: glitchtip-redis
|
||||||
|
volumes:
|
||||||
|
- glitchtip_redis_data:/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "valkey-cli", "ping"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
glitchtip-web:
|
||||||
|
image: glitchtip/glitchtip:6.1.6
|
||||||
|
container_name: glitchtip-web
|
||||||
|
depends_on:
|
||||||
|
glitchtip-postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
glitchtip-redis:
|
||||||
|
condition: service_healthy
|
||||||
|
env_file:
|
||||||
|
- ./docker/glitchtip/.env
|
||||||
|
command: ["sh", "-c", "./bin/run-migrate.sh && ./bin/run-web.sh"]
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8200:8000"
|
||||||
|
volumes:
|
||||||
|
- glitchtip_uploads:/code/uploads
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "python", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://localhost:8000/api/0/', timeout=4).status==200 else 1)"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 6
|
||||||
|
start_period: 60s
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
glitchtip-worker:
|
||||||
|
image: glitchtip/glitchtip:6.1.6
|
||||||
|
container_name: glitchtip-worker
|
||||||
|
command: ./bin/run-celery-with-beat.sh
|
||||||
|
depends_on:
|
||||||
|
glitchtip-postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
glitchtip-redis:
|
||||||
|
condition: service_healthy
|
||||||
|
env_file:
|
||||||
|
- ./docker/glitchtip/.env
|
||||||
|
volumes:
|
||||||
|
- glitchtip_uploads:/code/uploads
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
glitchtip_postgres_data:
|
||||||
|
glitchtip_redis_data:
|
||||||
|
glitchtip_uploads:
|
||||||
62
docker/glitchtip/.env.example
Normal file
62
docker/glitchtip/.env.example
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# GlitchTip — environment configuration
|
||||||
|
#
|
||||||
|
# Local development: cp .env.example .env (the dev defaults below are
|
||||||
|
# functional out of the box — no edits required for `make services`).
|
||||||
|
#
|
||||||
|
# ⚠️ PRODUCTION CHECKLIST (deploying to monitoring.hausdesign.nl):
|
||||||
|
# - Regenerate SECRET_KEY with:
|
||||||
|
# python -c "import secrets; print(secrets.token_urlsafe(50))"
|
||||||
|
# - Set POSTGRES_PASSWORD to a strong random value from the 1Password
|
||||||
|
# vault. The password embedded in DATABASE_URL MUST match.
|
||||||
|
# - Set EMAIL_URL to the real SMTP relay (smtp+tls://USER:PASS@HOST:PORT).
|
||||||
|
# - Set GLITCHTIP_DOMAIN=https://monitoring.hausdesign.nl (HTTPS, no
|
||||||
|
# trailing slash).
|
||||||
|
# - Set DEFAULT_FROM_EMAIL to a real sender on the hausdesign.nl domain.
|
||||||
|
# - Never commit the production .env. Keep it on the host only.
|
||||||
|
|
||||||
|
# === GlitchTip core ===
|
||||||
|
# Generate a real value for production: see header for the python one-liner.
|
||||||
|
SECRET_KEY=dev-only-not-for-production-use
|
||||||
|
|
||||||
|
# Postgres connection. Password MUST match POSTGRES_PASSWORD below.
|
||||||
|
DATABASE_URL=postgres://postgres:devsecret@glitchtip-postgres:5432/glitchtip
|
||||||
|
|
||||||
|
# Valkey/Redis connection (Celery broker + result backend).
|
||||||
|
REDIS_URL=redis://glitchtip-redis:6379/0
|
||||||
|
|
||||||
|
# Internal listen port for the GlitchTip web container.
|
||||||
|
PORT=8000
|
||||||
|
|
||||||
|
# Public-facing URL of the GlitchTip web UI.
|
||||||
|
# Dev: http://localhost:8200
|
||||||
|
# Prod: https://monitoring.hausdesign.nl
|
||||||
|
GLITCHTIP_DOMAIN=http://localhost:8200
|
||||||
|
|
||||||
|
# Default sender address for outbound mail (alerts, password resets, …).
|
||||||
|
# Dev: glitchtip@localhost.dev
|
||||||
|
# Prod: glitchtip@hausdesign.nl
|
||||||
|
DEFAULT_FROM_EMAIL=glitchtip@localhost.dev
|
||||||
|
|
||||||
|
# Outbound SMTP relay.
|
||||||
|
# Dev: smtp://bm_mailpit:1025 (alerts visible at http://localhost:8025)
|
||||||
|
# Prod: smtp+tls://USER:PASSWORD@HOST:PORT
|
||||||
|
EMAIL_URL=smtp://bm_mailpit:1025
|
||||||
|
|
||||||
|
# === Registration (locked down — same in dev and prod) ===
|
||||||
|
# Bert is the only user; first admin is created via:
|
||||||
|
# docker exec -it glitchtip-web ./manage.py createsuperuser
|
||||||
|
ENABLE_USER_REGISTRATION=False
|
||||||
|
ENABLE_OPEN_USER_REGISTRATION=False
|
||||||
|
|
||||||
|
# === Worker tuning ===
|
||||||
|
# Celery autoscale: min,max workers. 1,3 is the production default.
|
||||||
|
CELERY_WORKER_AUTOSCALE=1,3
|
||||||
|
|
||||||
|
# Recycle each worker after N tasks to bound memory growth.
|
||||||
|
CELERY_WORKER_MAX_TASKS_PER_CHILD=10000
|
||||||
|
|
||||||
|
# === Postgres (consumed only by the glitchtip-postgres service) ===
|
||||||
|
POSTGRES_USER=postgres
|
||||||
|
# MUST match the password embedded in DATABASE_URL above.
|
||||||
|
POSTGRES_PASSWORD=devsecret
|
||||||
|
POSTGRES_DB=glitchtip
|
||||||
Reference in New Issue
Block a user