This guide covers common issues you might encounter when self-hosting Cap and how to resolve them.
General Debugging
Check Service Status
Verify all services are running:
Expected output:
NAME STATUS
cap-web Up (healthy)
cap-media-server Up (healthy)
cap-mysql Up (healthy)
cap-minio Up (healthy)
cap-minio-setup Exited (0)
View Logs
# All services
docker compose logs -f
# Specific service
docker compose logs cap-web -f
# Last 100 lines
docker compose logs --tail=100 cap-web
# Since specific time
docker compose logs --since 10m cap-web
Restart Services
# Restart all
docker compose restart
# Restart specific service
docker compose restart cap-web
# Full restart (recreate containers)
docker compose down
docker compose up -d
Installation Issues
Port Already in Use
Error :
Error starting userland proxy: listen tcp 0.0.0.0:3000: bind: address already in use
Solution : Find and stop the process using the port
# Find process
sudo lsof -i :3000
# Or
sudo netstat -tulpn | grep :3000
# Kill process
sudo kill -9 < PI D >
# Or change Cap port
echo "CAP_PORT=8080" >> .env
docker compose down
docker compose up -d
Docker Not Running
Error :
Cannot connect to the Docker daemon
Solution :
# Start Docker
sudo systemctl start docker
# Enable on boot
sudo systemctl enable docker
# Check status
sudo systemctl status docker
Permission Denied
Error :
permission denied while trying to connect to the Docker daemon socket
Solution :
# Add user to docker group
sudo usermod -aG docker $USER
# Log out and back in
# Or run:
newgrp docker
# Test
docker ps
Image Pull Fails
Error :
Error response from daemon: manifest for ghcr.io/capsoftware/cap-web:latest not found
Solution :
# Check internet connection
ping -c 3 github.com
# Try pulling manually
docker pull ghcr.io/capsoftware/cap-web:latest
# If behind proxy, configure Docker proxy
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf
# Add:
# [Service]
# Environment="HTTP_PROXY=http://proxy.example.com:80"
# Environment="HTTPS_PROXY=https://proxy.example.com:443"
Application Issues
Can’t Access Cap Web
Symptom : Browser shows “Connection refused” at http://localhost:3000
Check if container is running
docker compose ps cap-web
If not running: docker compose up -d cap-web
Check health status
docker inspect cap-web | grep -A 10 Health
If unhealthy, check logs: docker compose logs cap-web
Test from inside container
docker compose exec cap-web wget -O- http://localhost:3000
If this works but external access doesn’t, it’s a networking issue.
Check firewall
sudo ufw status
sudo ufw allow 3000/tcp
Database Connection Errors
Error in logs :
Error: connect ECONNREFUSED mysql:3306
Wait for MySQL to finish initializing: docker compose logs mysql | grep "ready for connections"
If not ready, wait 30-60 seconds and check again.
Verify connection string: docker compose exec cap-web env | grep DATABASE_URL
Should be: mysql://cap:password@mysql:3306/cap
Fix in .env and restart: docker compose restart cap-web
Test connection from cap-web to mysql: docker compose exec cap-web ping mysql
docker compose exec cap-web nc -zv mysql 3306
If fails, recreate network: docker compose down
docker network prune
docker compose up -d
S3/MinIO Errors
Error : Videos won’t upload or display
Check MinIO is running
Access console: Login with MINIO_ROOT_USER and MINIO_ROOT_PASSWORD
Verify bucket exists
docker compose exec minio mc ls local/
Should show cap bucket. If not: docker compose exec minio mc mb local/cap
docker compose exec minio mc anonymous set download local/cap
Check S3 credentials
docker compose exec cap-web env | grep CAP_AWS
Verify:
CAP_AWS_ACCESS_KEY matches MINIO_ROOT_USER
CAP_AWS_SECRET_KEY matches MINIO_ROOT_PASSWORD
Test S3 upload
docker compose exec cap-web sh -c '
echo "test" > /tmp/test.txt
aws s3 cp /tmp/test.txt s3://cap/test.txt \
--endpoint-url $S3_INTERNAL_ENDPOINT
'
Authentication Issues
Symptom : Can’t log in or session expires immediately
docker compose exec cap-web env | grep NEXTAUTH_SECRET
If empty, generate and add to .env: Then: NEXTAUTH_SECRET = your-generated-secret
Must match actual access URL: # Local
NEXTAUTH_URL = http://localhost:3000
# Production
NEXTAUTH_URL = https://cap.yourdomain.com
Clear browser cookies for your Cap domain and try again. Or test in incognito/private mode.
Database sessions not working
Check if sessions table exists: docker compose exec mysql mysql -u cap -p cap -e "SHOW TABLES LIKE 'session';"
If empty, run migrations: docker compose exec cap-web pnpm db:push
Email Issues
No Login Email Received
Check if Resend is configured
docker compose exec cap-web env | grep RESEND
If empty, emails go to logs instead: docker compose logs cap-web | grep "Login link"
Verify Resend API key
Test with curl: curl -X POST 'https://api.resend.com/emails' \
-H "Authorization: Bearer $RESEND_API_KEY " \
-H 'Content-Type: application/json' \
-d '{
"from": "[email protected] ",
"to": "[email protected] ",
"subject": "Test",
"html": "<p>Test</p>"
}'
Check spam folder
Login emails might be marked as spam initially.
Verify domain
In Resend dashboard, check domain is verified.
Email Sends but Errors in Logs
docker compose logs cap-web | grep -i "error\|fail"
Common errors:
Invalid API key - Wrong RESEND_API_KEY
Domain not verified - Verify domain in Resend
Rate limit exceeded - Wait or upgrade Resend plan
Video Processing Issues
Videos Stuck in Processing
Check media server logs
docker compose logs media-server
Look for FFmpeg errors.
Verify media server is running
docker compose ps media-server
Test health: curl http://localhost:3456/health
Check MEDIA_SERVER_WEBHOOK_SECRET
Must match between cap-web and media-server: docker compose exec cap-web env | grep MEDIA_SERVER_WEBHOOK_SECRET
docker compose exec media-server env | grep MEDIA_SERVER_WEBHOOK_SECRET
Manually retry processing
Find video in database and trigger reprocessing: docker compose exec mysql mysql - u cap - p cap
UPDATE videos SET status = 'pending' WHERE id = 'video-id' ;
Video Playback Errors
Symptom : Video uploaded but won’t play
CORS errors in browser console
F12 → Console shows: Access to video from origin 'https://cap.yourdomain.com' has been blocked by CORS
Fix : Configure S3 CORSMinIO: docker compose exec minio mc anonymous set public local/cap
AWS S3: Add CORS configuration (see S3 Storage )
Verify file exists in S3: docker compose exec minio mc ls local/cap/videos/
If missing, reprocess video.
Video URL should be accessible from browser: curl -I http://localhost:9000/cap/videos/test.mp4
Update .env: S3_PUBLIC_ENDPOINT = http://localhost:9000
SSL/HTTPS Issues
Certificate Not Obtained
Let’s Encrypt errors in Caddy/Nginx logs
Verify DNS
dig cap.yourdomain.com
nslookup cap.yourdomain.com
Should point to your server IP.
Check port 80 is open
sudo ufw status | grep 80
telnet yourdomain.com 80
Let’s Encrypt requires port 80 for HTTP challenge.
Check rate limits
Let’s Encrypt limits:
50 certs per domain per week
5 failures per hour
Wait 1 hour or use staging: sudo certbot --nginx --staging
Mixed Content Warnings
Browser : “This page includes insecure resources”
Update all URLs to HTTPS
WEB_URL = https://cap.yourdomain.com
NEXTAUTH_URL = https://cap.yourdomain.com
S3_PUBLIC_ENDPOINT = https://s3.yourdomain.com
Check video URLs in database
If videos were uploaded before HTTPS, URLs might be HTTP. Update: UPDATE videos
SET thumbnail_url = REPLACE (thumbnail_url, 'http://' , 'https://' );
Slow Page Loads
Check resource usage
Look for high CPU or memory usage.
Check database performance
docker compose exec mysql mysql -u cap -p cap -e "SHOW PROCESSLIST;"
Look for slow queries.
Enable database query logging
SET GLOBAL slow_query_log = 'ON' ;
SET GLOBAL long_query_time = 1 ;
View slow queries: docker compose exec mysql cat /var/lib/mysql/slow-query.log
Check network latency
docker compose exec cap-web ping mysql
docker compose exec cap-web ping minio
High CPU Usage
Media server at 100% CPU
This is normal during video processing. FFmpeg is CPU-intensive.
To reduce:
Process videos at lower quality
Add more media server workers
Use external transcoding service
Out of Memory
Error : Killed or OOMKilled
Increase Docker memory limits
services :
cap-web :
deploy :
resources :
limits :
memory : 2G
Add swap
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# Make permanent
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Docker Issues
Disk Space Full
# Check Docker disk usage
docker system df
# Remove unused images
docker image prune -a
# Remove unused volumes
docker volume prune
# Full cleanup
docker system prune -a --volumes
docker system prune -a --volumes removes ALL unused data. Be careful with volumes.
Network Issues
Services can’t communicate
# Inspect network
docker network inspect cap_cap-network
# Recreate network
docker compose down
docker network prune
docker compose up -d
Container Won’t Start
# Check exit code
docker compose ps -a
# View full logs
docker compose logs --tail=500 < service-nam e >
# Try starting in foreground
docker compose up < service-nam e >
# Remove and recreate
docker compose rm -f < service-nam e >
docker compose up -d < service-nam e >
Complete Reset
This deletes ALL data including videos, users, and database.
When all else fails:
# Stop and remove everything
docker compose down -v
# Remove images
docker rmi ghcr.io/capsoftware/cap-web:latest
docker rmi ghcr.io/capsoftware/cap-media-server:latest
# Clean Docker
docker system prune -a
# Start fresh
docker compose up -d
Getting Help
Collect Debug Info
Before asking for help, collect:
# System info
uname -a
docker --version
docker compose version
# Service status
docker compose ps
# Recent logs
docker compose logs --tail=100 > cap-logs.txt
# Environment (remove secrets!)
docker compose exec cap-web env | grep -v "SECRET\|KEY\|PASSWORD"
Where to Get Help
Reporting Bugs
Include:
Environment : OS, Docker version, deployment method
Steps to reproduce : Exact steps to trigger the issue
Expected behavior : What should happen
Actual behavior : What actually happens
Logs : Relevant error messages and stack traces
Configuration : Sanitized environment variables
Next Steps
Architecture Understand how Cap works
Scaling Optimize for performance
Environment Variables Review configuration options
Docker Compose Deployment guide