OpenCodeHub - Production Deployment Guide
✅ Production Readiness Status
ALL CRITICAL SECURITY FIXES IMPLEMENTED
OpenCodeHub is now production-ready with enterprise-grade security features.
🔒 Implemented Security Features
1. Rate Limiting ✅
Location: src/middleware/rate-limit.ts
Protection:
- Login attempts: 5 per 15 minutes
- API requests: 100 per minute
- Git operations: 200 per minute
Applied To:
/api/auth/login/api/auth/register/api/repos/[repoId]/branch-protection
2. CSRF Protection ✅
Location: src/middleware/csrf.ts
Method: Double-submit cookie pattern
Coverage: All state-changing operations (POST/PUT/DELETE)
3. Input Validation ✅
Location: src/lib/validation.ts
Schemas:
RegisterUserSchema- Username, email, password validationBranchProtectionSchema- Pattern and permission validationCreateRepositorySchema,CreateIssueSchema,CreatePullRequestSchemaStorageConfigSchema,GeneralConfigSchema,WebhookConfigSchema
Prevention: SQL injection, XSS, invalid data attacks
4. Git Hook Authentication ✅
Locations:
src/lib/git.ts- Hook installation with secretssrc/pages/api/internal/hooks/pre-receive.tssrc/pages/api/internal/hooks/post-receive.ts
Security: Shared secret in X-Hook-Secret header prevents unauthorized hook execution
5. Environment Validation ✅
Location: src/lib/env-validation.ts
Validates:
- Required secrets (JWT_SECRET, SESSION_SECRET, INTERNAL_HOOK_SECRET)
- Secret strength (32+ characters)
- URL formats (SITE_URL must be valid)
- Production-specific checks (HTTPS, no default secrets)
Platform-Specific Deployment Guides
For step-by-step guides on specific platforms, see:
- Coolify — Self-hosted PaaS (easiest, recommended)
- CyberPanel — OpenLiteSpeed hosting panel
- cPanel — Shared/VPS hosting
- NAS (Synology/TrueNAS/QNAP) — Network Attached Storage
📋 Production Deployment Checklist
Prerequisites
- PostgreSQL 14+ database configured
- Domain name with DNS configured
- SSL certificate (Let's Encrypt recommended)
- S3/R2 bucket for storage (or cloud storage alternative)
Required Environment Variables
Critical Security (MUST SET):
# Generate with: openssl rand -hex 32
JWT_SECRET=<64-char-hex>
SESSION_SECRET=<64-char-hex>
INTERNAL_HOOK_SECRET=<64-char-hex>
# Production URL (MUST be HTTPS)
SITE_URL=https://git.yourcompany.com
NODE_ENV=production
Database:
DATABASE_DRIVER=postgres
DATABASE_URL=postgresql://user:password@host:5432/opencodehub
Storage (S3-compatible; works with AWS S3, MinIO, Cloudflare R2, Garage, SeaweedFS, Ceph RGW, etc.):
STORAGE_TYPE=s3
STORAGE_BUCKET=opencodehub-production
STORAGE_REGION=us-east-1
STORAGE_ACCESS_KEY_ID=<your-access-key>
STORAGE_SECRET_ACCESS_KEY=<your-secret-key>
# STORAGE_ENDPOINT=https://<account>.r2.cloudflarestorage.com # set for non-AWS vendors
Only
localands3storage backends are supported. Google Drive,
OneDrive, Dropbox, FTP, GCS, Azure, and rclone-as-adapter have been
removed; use thes3driver with a vendor-specificSTORAGE_ENDPOINT
for object storage. Seedocs/guides/storage-adapters.mdfor the
full list of compatible object stores.
Optional but Recommended:
# Email
SMTP_HOST=smtp.example.com
SMTP_PORT=587
[email protected]
SMTP_PASSWORD=<smtp-password>
[email protected]
# Redis (for session management)
REDIS_URL=redis://:your-password@localhost:6379
Deployment Steps
# 1. Clone and configure
git clone https://github.com/swadhinbiswas/OpencodeHub.git
cd OpenCodeHub
# 2. Install dependencies
bun install # or npm install
# 3. Create production .env
cp .env.example .env
nano .env # Configure all production values (secrets: openssl rand -hex 32)
# 4. Validate environment
bun run src/lib/env-validation.ts
# Should output: ✅ Environment validation passed
# 5. Run database migrations (applies committed drizzle/ migrations)
bun run migrate
# or for dev: npm run db:push
# 6. Create admin user
bun run scripts/seed-admin.ts
# Enter username, email, password when prompted
# 7. Build for production
npm run build
# 8. Start the production server (built in step 7)
npm start # → node ./dist/server/entry.mjs
Docker is the recommended path for production. Use the repository's
docker-compose.yml(quickstart) ordocker-compose.production.yml
(Caddy TLS + isolated networks) — do not hand-roll a compose file.
Docker Deployment (Recommended)
Use the repository's own compose files — they are kept in sync with the
codebase and are production-safe (no default secrets, migrations applied
at boot, worker + SSH services included):
# Quickstart (app + SSH + worker + PostgreSQL + Redis)
cp .env.example .env # then set ALL secrets
docker compose up -d
# Production profile (adds Caddy TLS termination + isolated networks)
docker compose -f docker-compose.production.yml --profile production up -d
# NAS / dedicated-disk deployments
OCH_DATA_DIR=/mnt/nas/opencodehub docker compose -f docker-compose.nas.yml up -d
Minimal reference compose (for illustration only):
services:
app:
build: .
restart: always
ports:
- "4321:4321"
env_file: .env
environment:
NODE_ENV: production
depends_on:
- postgres
- redis
postgres:
image: postgres:16-alpine
restart: always
environment:
POSTGRES_DB: opencodehub
POSTGRES_USER: opencodehub
POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
redis:
image: redis:7-alpine
restart: always
command: redis-server --requirepass ${REDIS_PASSWORD}
volumes:
postgres_data:
Exposed ports: 4321 (web/API/Git HTTP) and 2222 (SSH Git).
PostgreSQL (5432) and Redis (6379) stay on an internal network.
# Deploy with Docker
docker-compose -f docker-compose.prod.yml up -d
# View logs
docker-compose -f docker-compose.prod.yml logs -f app
# Create admin user in container
docker-compose exec app bun run scripts/seed-admin.ts
Reverse Proxy (Nginx)
# /etc/nginx/sites-available/opencodehub
server {
listen 443 ssl http2;
server_name git.yourcompany.com;
ssl_certificate /etc/letsencrypt/live/git.yourcompany.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.yourcompany.com/privkey.pem;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Proxy configuration
location / {
proxy_pass http://localhost:4321;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support (for live updates)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Git operations (larger timeouts)
location ~ ^/[^/]+/[^/]+\.git/ {
proxy_pass http://localhost:4321;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
client_max_body_size 100M;
}
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name git.yourcompany.com;
return 301 https://$server_name$request_uri;
}
# Enable site
sudo ln -s /etc/nginx/sites-available/opencodehub /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
🔍 Verification Steps
1. Environment Validation
bun run src/lib/env-validation.ts
Expected Output:
🔍 Validating environment configuration...
✅ Environment validation passed
2. Build Verification
npm run build
Expected: No errors, successful build output
3. Security Features Test
Rate Limiting:
# Try 6 login attempts rapidly - should get rate limited
for i in {1..6}; do
curl -X POST https://git.yourcompany.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{"login":"test","password":"wrong"}' \
-w "\nStatus: %{http_code}\n"
done
Expected: First 5 return 401, 6th returns 429 (Too Many Requests)
Hook Authentication:
# Try without secret - should fail
curl -X POST https://git.yourcompany.com/api/internal/hooks/post-receive \
-H "Content-Type: application/json" \
-d '{"oldrev":"abc","newrev":"def","refname":"refs/heads/main"}'
Expected: 401 Unauthorized
4. Health Check
curl https://git.yourcompany.com/api/health
Expected:
{
"status": "ok",
"checks": {
"database": "ok",
"storage": "ok"
},
"uptime": 12345,
"version": "1.0.0"
}
🐛 Troubleshooting
Rate Limit Issues
Problem: Users getting rate limited legitimately
Solution:
# Increase limits in .env
RATE_LIMIT_AUTH=10 # Increase from 5
RATE_LIMIT_API=200 # Increase from 100
Git Hooks Not Working
Problem: Push succeeds but hooks don't trigger
Checklist:
- Verify
SITE_URLis set correctly - Verify
INTERNAL_HOOK_SECRETmatches in .env - Check hook files exist:
data/repos/owner/repo.git/hooks/post-receive - Verify hooks are executable:
chmod +x hooks/* - Check application logs for hook errors
Database Connection Errors
Problem: Can't connect to database
Solutions:
# Test connection
psql $DATABASE_URL
# Check PostgreSQL is running
sudo systemctl status postgresql
# Verify credentials in .env
echo $DATABASE_URL
Storage Upload Failures
Problem: Can't upload files
Solutions:
- Test S3 credentials:
aws s3 ls s3://$STORAGE_BUCKET --profile opencodehub
Verify bucket permissions (needs: s3:PutObject, s3:GetObject, s3:DeleteObject)
Check CORS configuration if using direct uploads
📊 Monitoring & Maintenance
Database Backups
# Daily backup script
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
pg_dump $DATABASE_URL | gzip > /backups/opencodehub_$DATE.sql.gz
# Retain last 30 days
find /backups -name "opencodehub_*.sql.gz" -mtime +30 -delete
Add to crontab:
0 2 * * * /usr/local/bin/backup-opencodehub.sh
Log Rotation
# /etc/logrotate.d/opencodehub
/var/log/opencodehub/*.log {
daily
rotate 30
compress
delaycompress
notifempty
create 0644 www-data www-data
sharedscripts
postrotate
systemctl reload opencodehub
endscript
}
Metrics to Monitor
- Request rate (should stay within rate limits)
- Failed login attempts (detect brute force)
- Database connection pool usage
- Storage usage
- Memory and CPU usage
- Error rate (4xx, 5xx responses)
🚀 Post-Deployment
Create Organizations
- Login as admin
- Navigate to Settings → Organizations
- Create organization
- Invite team members
Configure Branch Protection
- Go to Repository → Settings → Branches
- Add protection rule for
main:- Require PR: ✅
- Required approvals: 2
- Dismiss stale reviews: ✅
Setup CI/CD Runners
# Start self-hosted runner
docker run -d \
--name opencodehub-runner \
-e SERVER_URL=https://git.yourcompany.com \
-e RUNNER_TOKEN=<from-admin-panel> \
opencodehub/runner:latest
Enable Email Notifications
Configure SMTP in .env, then test:
curl -X POST https://git.yourcompany.com/api/admin/test-email \
-H "Cookie: och_session=<your-session>" \
-H "Content-Type: application/json" \
-d '{"to":"[email protected]"}'
📚 Additional Resources
- API Documentation: https://git.yourcompany.com/api/docs
- Admin Panel: https://git.yourcompany.com/admin
- User Guide: See README.md
- Security Best Practices: See production_analysis.md
✅ Production Readiness Confirmed
All critical security features are implemented and tested:
- ✅ Rate limiting (brute force protection)
- ✅ CSRF protection (cross-site attacks)
- ✅ Input validation (injection prevention)
- ✅ Hook authentication (git security)
- ✅ Environment validation (configuration safety)
OpenCodeHub is ready for production deployment! 🎉