Docker-based self-hosting solution for Cap - Beautiful screen recordings, owned by you.
This repository provides production-ready Docker Compose configurations for self-hosting Cap with a dedicated Media Server, MySQL (SSD-optimized) and MinIO (S3-compatible storage), including custom BAUER GROUP branding.
- Custom Branding - BAUER GROUP logos and styling
- Media Server - Dedicated video/audio processing microservice (FFmpeg + Bun)
- Microsoft Entra ID - Azure AD OAuth (single/multi-tenant)
- SMTP Email - Use your own mail server (no cloud dependency)
- Unlimited Pro License - All Pro features enabled, no Stripe payments
- SSD-optimized MySQL - InnoDB tuning for NVMe/SSD storage
- MinIO with Init Container - Automatic bucket and user setup
- Three Deployment Options - Development, Traefik (Production), Coolify (PaaS)
- Automatic Secret Generation - Secure passwords with one script
- Health Checks - All services monitored
- Log Rotation - Configured out of the box
| Screen Recorder Version | Cap Version | Status |
|---|---|---|
| 0.5.x | cap-v0.3.83 | Archived |
| 0.6.x | cap-v0.4.1+ | Archived |
| 0.7.x - 0.8.x | cap-v0.4.3+ | Archived |
| 0.9.x | cap-v0.4.6 | Maintained |
| 0.10.x | cap-v0.4.71 | β Current |
Note: Cap 0.4.x introduces cloud services (Workflow, Tinybird) that are automatically disabled for self-hosted deployments. Cap 0.4.6 introduces the Media Server as a separate microservice for video/audio processing. Cap 0.4.7 replaced Intercom with a built-in Messenger widget (removed by patch 010).
The following patches are automatically applied during Docker build of the frontend image:
| Patch | Description |
|---|---|
002-smtp-email.ast |
SMTP email support (alternative to Resend) |
003-branding.sh |
Custom BAUER GROUP branding |
004-redirects.ast |
URL redirects for self-hosted deployment |
006-replace-google-with-microsoft.ast |
Replace Google OAuth with Microsoft Entra ID (login + signup) |
007-remove-stripe.ast |
Disable Stripe payments, enable unlimited Pro license |
008-skip-onboarding-steps.ast |
Skip cloud-only onboarding steps (Custom Domain, Invite Team) |
009-disable-workflow.ast |
Disable cloud services (Workflow, Tinybird) |
010-remove-messenger.ast |
Remove Cap Messenger chat widget |
Note: Patch 005 (Remove Intercom) was retired - Cap replaced Intercom with its own Messenger widget since v0.4.7. Patch 010 handles the new widget.
All patches are AST-based (using ts-morph) for robust version compatibility.
# Clone the repository
git clone https://github.com/bauer-group/CS-ScreenRecorder.git
cd CS-ScreenRecorder
# Generate secrets and create .env file
./scripts/generate-secrets.shEdit .env and set your domain:
# For development
WEB_URL=http://localhost:3000
# For production (set your own domain)
WEB_URL=https://your-domain.com
SERVICE_HOSTNAME=your-domain.com
S3_HOSTNAME=assets.your-domain.com
S3_CONSOLE_HOSTNAME=assets-console.your-domain.comDevelopment (builds custom branded images locally):
docker compose -f docker-compose.development.yml up -dProduction with Traefik (uses pre-built GHCR images):
docker compose -f docker-compose.traefik.yml up -dCoolify PaaS:
# Deploy via Coolify dashboard using docker-compose.coolify.yml| Service | URL |
|---|---|
| Web App | http://localhost:3000 |
| MinIO Console | http://localhost:9001 |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Traefik β
β (Reverse Proxy + SSL) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β Frontend β β MinIO S3 β βMinIO Consoleβ
β (Cap Web) β β :9000 β β :9001 β
β :3000 β βββββββββββββββ βββββββββββββββ
βββββββββββββββ β
β β β
βΌ βΌ β
ββββββββββ βββββββββββββββ β
β MySQL β βMedia Server β β
β :3306 β β :3456 βββββ
ββββββββββ β (FFmpeg) β (Video Storage)
βββββββββββββββ
Services:
| Service | Image | Description |
|---|---|---|
| Frontend | ghcr.io/bauer-group/cs-screenrecorder/frontend |
Cap web application (Next.js) |
| Media Server | ghcr.io/bauer-group/cs-screenrecorder/mediaserver |
Video/audio processing (Bun + FFmpeg) |
| MySQL | mysql:8.4 |
Database (SSD-optimized) |
| MinIO | quay.io/minio/minio |
S3-compatible object storage |
CS-ScreenRecorder/
βββ .github/
β βββ workflows/
β β βββ docker-release.yml # CI/CD pipeline (frontend + mediaserver)
β β βββ docker-maintenance.yml # Dockerfile maintenance
β βββ config/
β βββ release/
β βββ semantic-release.json
βββ scripts/
β βββ generate-secrets.sh # Secret generator
β βββ generate-assets.sh # Logo/favicon generator
β βββ setup-client-bucket.py # Client download bucket setup
β βββ sync-clients.py # Client installer sync
βββ src/
β βββ frontend/ # Cap Web Application
β β βββ Dockerfile # Multi-stage build with patches
β β βββ patches/ # Source code patches (AST-based)
β β β βββ apply-patches.sh # Patch runner
β β β βββ 002-smtp-email.ast/ # SMTP email support
β β β βββ 003-branding.sh # Custom branding
β β β βββ 004-redirects.ast/ # URL redirects
β β β βββ 006-replace-google-with-microsoft.ast/ # Azure AD OAuth
β β β βββ 007-remove-stripe.ast/ # Disable payments
β β β βββ 008-skip-onboarding-steps.ast/ # Skip cloud onboarding
β β β βββ 009-disable-workflow.ast/ # Disable cloud services
β β β βββ 010-remove-messenger.ast/ # Remove messenger widget
β β βββ branding/ # Logo sources & config
β β βββ branding.env # Branding configuration
β β βββ apply-branding.sh # Asset copy script
β β βββ assets/ # Generated favicons & icons
β βββ mediaserver/ # Cap Media Server
β β βββ Dockerfile # Bun + FFmpeg build
β βββ tools/ # Development tools container
β βββ Dockerfile
β βββ run.sh # Linux/macOS launcher
β βββ run.ps1 # PowerShell launcher
βββ docker-compose.development.yml # Local build + port exposure
βββ docker-compose.traefik.yml # Production with Traefik reverse proxy
βββ docker-compose.coolify.yml # Coolify PaaS deployment
βββ .env.example # Configuration template
βββ .gitattributes # Line ending normalization
βββ NOTICE.md # Third-party licenses
βββ README.md
| Variable | Description |
|---|---|
WEB_URL |
Public URL of Cap |
NEXTAUTH_SECRET |
Session encryption key (generated) |
DATABASE_PASSWORD |
MySQL password (generated) |
DATABASE_ENCRYPTION_KEY |
Database field encryption key (generated) |
MINIO_ROOT_PASSWORD |
MinIO admin password (generated) |
CAP_AWS_SECRET_KEY |
S3 service account key (generated) |
MEDIA_SERVER_WEBHOOK_SECRET |
Media server webhook auth secret (generated) |
| Setting | Value |
|---|---|
| Database name | cap |
| Database user | cap |
| S3 bucket | media |
| S3 user | cap |
| S3 region | global |
| Media server port | 3456 |
| Feature | Variables |
|---|---|
| SMTP Email | SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, SMTP_FROM |
| Resend Email | RESEND_API_KEY, RESEND_FROM_DOMAIN |
| Microsoft Entra ID | AZURE_AD_CLIENT_ID, AZURE_AD_CLIENT_SECRET, AZURE_AD_TENANT_ID |
| Google OAuth | GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET |
| Enterprise SSO | WORKOS_CLIENT_ID, WORKOS_API_KEY |
| AI Transcription | DEEPGRAM_API_KEY |
| AI Summaries | OPENAI_API_KEY or GROQ_API_KEY |
| Domain Restriction | CAP_ALLOWED_SIGNUP_DOMAINS |
| Client Downloads | CAP_CLIENT_DOWNLOAD_URL |
See .env.example for all options.
Custom branding is built into the frontend Docker image. To update:
-
Place logo files in
src/frontend/branding/:logo-source-wide.{eps,svg,png}- Wide logologo-source-square.{eps,svg,png}- Square logo
-
Edit branding colors/names in
src/frontend/branding/branding.env -
Generate assets using the tools container:
./tools/run.sh ./scripts/generate-assets.sh
-
Rebuild the Docker image:
docker compose -f docker-compose.development.yml build frontend-server
If email is not configured, login links appear in container logs:
docker logs ${STACK_NAME}_APPOption 1: SMTP (Recommended for self-hosted)
SMTP_HOST=mail.example.com
SMTP_PORT=587
SMTP_TLS=false
SMTP_USER=user@example.com
SMTP_PASSWORD=secret
SMTP_FROM=no-reply@example.com
SMTP_FROM_NAME=Screen RecorderOption 2: Resend (Cloud)
RESEND_API_KEY=re_xxxxx
RESEND_FROM_DOMAIN=mail.your-domain.comPriority: SMTP > Resend > Console Log
- Register app at Entra Portal
- Set redirect URI:
https://${SERVICE_HOSTNAME}/api/auth/callback/azure-ad - Configure environment:
AZURE_AD_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
AZURE_AD_CLIENT_SECRET=your-client-secret
AZURE_AD_TENANT_ID=your-tenant-id # Leave empty for multi-tenantSee .env.example for detailed setup instructions.
To use Cap Desktop with your self-hosted instance:
- Open Cap Desktop settings
- Set "Cap Server URL" to your deployment URL
- Login and start recording
See detailed instructions: English | Deutsch
# MySQL
docker exec ${STACK_NAME}_MYSQL mysqldump -u root -p${DATABASE_PASSWORD} cap > backup.sql
# MinIO
docker run --rm -v screenrecorder-storage:/data -v $(pwd):/backup alpine \
tar czf /backup/minio-backup.tar.gz /data# MySQL
docker exec -i ${STACK_NAME}_MYSQL mysql -u root -p${DATABASE_PASSWORD} cap < backup.sql
# MinIO
docker run --rm -v screenrecorder-storage:/data -v $(pwd):/backup alpine \
tar xzf /backup/minio-backup.tar.gz -C /# View logs
docker compose -f docker-compose.development.yml logs -f
# View specific service logs
docker compose -f docker-compose.development.yml logs -f frontend-server
docker compose -f docker-compose.development.yml logs -f media-server
# Check health
docker compose -f docker-compose.development.yml ps
# Reset (WARNING: deletes data!)
docker compose -f docker-compose.development.yml down
docker volume rm screenrecorder-database screenrecorder-storagedocker compose -f docker-compose.traefik.yml pull
docker compose -f docker-compose.traefik.yml up -dMIT License - See LICENSE for details.