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 MySQL (SSD-optimized) and MinIO (S3-compatible storage), including custom BAUER GROUP branding.
- Custom Branding - BAUER GROUP logos and styling
- 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 | ✅ Stable |
| 0.6.x | cap-v0.4.1+ | ✅ Stable |
| 0.7.x | cap-v0.4.3+ | ✅ Stable |
Note: Cap 0.4.x introduces cloud services (Workflow, Tinybird) that are automatically disabled for self-hosted deployments.
The following patches are automatically applied during Docker build:
| 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 |
005-remove-intercom.ast |
Remove Intercom chat widget |
006-replace-google-with-microsoft.ast |
Replace Google OAuth with Microsoft Entra ID |
007-remove-stripe.ast |
Disable Stripe payments, enable unlimited Pro license |
008-skip-onboarding-steps.ast |
Skip cloud-only onboarding steps |
009-disable-workflow.ast |
Disable cloud services (Workflow, Tinybird) |
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 image locally):
docker compose -f docker-compose.development.yml up -dProduction with Traefik (uses pre-built GHCR image):
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) │
└─────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Cap Web │ │ MinIO S3 │ │MinIO Console│
│ :3000 │ │ :9000 │ │ :9001 │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ │
┌─────────────┐ │
│ MySQL │◄──────────────┘
│ :3306 │ (Video Storage)
└─────────────┘
CS-ScreenRecorder/
├── .github/
│ ├── workflows/
│ │ └── docker-release.yml # CI/CD pipeline
│ └── dependabot.yml # Dependency updates
├── scripts/
│ ├── generate-secrets.sh # Secret generator
│ └── generate-assets.sh # Logo/favicon generator
├── src/
│ ├── Dockerfile # Custom Cap image
│ ├── patches/ # Source code patches (AST-based)
│ │ ├── 002-smtp-email.ast/ # SMTP email support
│ │ ├── 003-branding.sh # Custom branding
│ │ ├── 004-redirects.ast/ # URL redirects
│ │ ├── 005-remove-intercom.ast/ # Remove Intercom chat
│ │ ├── 006-replace-google-with-microsoft.ast/ # Azure AD OAuth
│ │ ├── 007-remove-stripe.ast/ # Disable payments (Pro license)
│ │ ├── 008-skip-onboarding-steps.ast/ # Skip cloud onboarding
│ │ └── 009-disable-workflow.ast/ # Disable cloud services
│ └── branding/ # Logo sources
│ ├── branding.env # Branding config
│ └── logo-source-*.{eps,svg,png}
├── tools/
│ ├── Dockerfile # Development tools
│ ├── run.sh # Linux/macOS launcher
│ └── run.ps1 # PowerShell launcher
├── docker-compose.development.yml
├── docker-compose.traefik.yml
├── docker-compose.coolify.yml
├── .env.example
├── 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) |
MINIO_ROOT_PASSWORD |
MinIO admin password (generated) |
CAP_AWS_SECRET_KEY |
S3 service account key (generated) |
| Setting | Value |
|---|---|
| Database name | cap |
| Database user | cap |
| S3 bucket | media |
| S3 user | cap |
| S3 region | global |
| 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 |
| Payments | STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET |
See .env.example for all options.
Custom branding is built into the Docker image. To update:
-
Place logo files in
src/branding/:logo-source-wide.{eps,svg,png}- Wide logologo-source-square.{eps,svg,png}- Square logo
-
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
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 ${STACK_NAME}-minio-data:/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 ${STACK_NAME}-minio-data:/data -v $(pwd):/backup alpine \
tar xzf /backup/minio-backup.tar.gz -C /# View logs
docker compose -f docker-compose.development.yml logs -f
# 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 ${STACK_NAME}-mysql-data ${STACK_NAME}-minio-datadocker compose -f docker-compose.traefik.yml pull
docker compose -f docker-compose.traefik.yml up -dMIT License - See LICENSE for details.