Deployment Guide

Deploy DeepChain to production with Docker, Kubernetes, or cloud platforms

Deploy DeepChain to Production

This guide covers everything you need to deploy DeepChain to production environments, whether locally with Docker, on Kubernetes, or to major cloud platforms.

Quick Start (5 minutes)

Get DeepChain running locally:

# 1. Initialize project
./deepchain init
# Choose "Development" when prompted

# 2. Deploy containers
./deepchain deploy
# Takes 2-5 minutes to build and start

# 3. Verify everything works
./deepchain status

# 4. Open in browser
open http://localhost:3000

Done! You're running DeepChain locally. Frontend, API, database, and workers are all running.

Deployment Paths

Choose your deployment method:

Method Setup Time Cost Best For
Local (Docker Compose) 5 min Free Development, testing
Docker 15 min ~$5-10/month Small production
Kubernetes 30 min ~$10-50/month Scaling, high availability
AWS 20 min Variable Enterprise, AWS-focused
GCP 20 min Variable Enterprise, GCP-focused
Heroku 10 min ~$50/month Quick hosting

Requirements

For Local Development

# Check you have these installed
docker --version      # 20.10 or newer
docker-compose -v     # 2.0 or newer
dart --version        # 3.2 or newer

For Cloud Deployment

Choose based on your platform:

Google Cloud (GCP):

gcloud auth login
gcloud config set project YOUR_PROJECT_ID

AWS:

aws configure
# Enter your access key, secret key, and region

Kubernetes:

kubectl version
# Connected to your cluster

💿 Installation

  1. Clone the repository:
git clone <repository-url>
cd deepchain
  1. Make CLI executable:
chmod +x deepchain
  1. Initialize:
./deepchain init

The init command will:

  • Detect your environment (development/production)
  • Generate secure credentials
  • Create necessary directories
  • Set up configuration files

⚙️ Configuration

Environment Selection

During initialization, you'll choose:

  • Development: Local Docker deployment for testing
  • Production: GCloud Compute Engine for live deployment

Generated Files

  • .env - Environment variables and credentials
  • .deepchain.state - CLI state management
  • credentials-*.txt - Production credentials (keep secure!)

Key Configuration

Edit .env to customize:

# Database
POSTGRES_PASSWORD=<generated>
POSTGRES_DB=deepchain_db

# RabbitMQ  
RABBITMQ_PASSWORD=<generated>
RABBITMQ_VHOST=deepchain

# Redis
REDIS_PASSWORD=<generated>

# JWT
JWT_SECRET=<generated-64-char-secret>

# API
LOG_LEVEL=info
API_PORT=8080

🌐 Deployment

Development Deployment

# Initialize for development
./deepchain init
# Select option 1 (Development)

# Deploy locally
./deepchain deploy

# Access services
# Frontend: http://localhost:3000
# API:      http://localhost:8080
# RabbitMQ: http://localhost:15672

Production Deployment

# Initialize for production
./deepchain init
# Select option 2 (Production)
# Enter GCP details:
#   - Project ID: aicedc
#   - Zone: us-central1-a
#   - Instance name: deepchain-production
#   - Domain: aice.deepchain.dev

# Deploy to GCloud
./deepchain deploy

# Setup SSL (after DNS configured)
./deepchain ssl setup

Architecture

Development Stack:

┌─────────────┐
│  localhost  │
└──────┬──────┘
       │
   ┌───┴────┐
   │ Docker │
   └───┬────┘
       │
   ┌───┴──────────────────────────┐
   │                              │
┌──┴──┐  ┌────┐  ┌──────┐  ┌────┐
│ API │  │ DB │  │ Queue│  │ Web│
└─────┘  └────┘  └──────┘  └────┘

Production Stack:

┌──────────────┐
│  Cloudflare  │ (DNS + SSL)
└──────┬───────┘
       │
┌──────┴────────┐
│  GCloud VM    │ (e2-standard-4)
│               │
│  ┌─────────┐  │
│  │  Nginx  │  │ (Reverse Proxy)
│  └────┬────┘  │
│       │       │
│  ┌────┴─────┐ │
│  │  Docker  │ │
│  └────┬─────┘ │
│       │       │
│  ┌────┴─────────────────────┐
│  │                          │
│ ┌┴──┐ ┌──┐ ┌────┐ ┌──┐ ┌──┐│
│ │API│ │DB│ │RMQ │ │RD│ │WEB│
│ └───┘ └──┘ └────┘ └──┘ └──┘│
└──────────────────────────────┘

📊 Monitoring

Status Checks

# Overall status
./deepchain status

# Health checks
./deepchain health

# Comprehensive diagnostics
./deepchain diagnose

Viewing Logs

# All services
./deepchain logs

# Specific service
./deepchain logs api
./deepchain logs worker
./deepchain logs frontend

# Follow mode (live updates)
./deepchain logs api -f

Key Metrics

The CLI automatically checks:

  • ✅ Service health (HTTP endpoints)
  • ✅ Container status
  • ✅ Port availability
  • ✅ Disk usage
  • ✅ Recent errors

🔧 Maintenance

Updates

# Update to latest version
./deepchain update

# This will:
# 1. Create automatic backup
# 2. Build new images
# 3. Deploy updates
# 4. Verify health

Database Operations

# Create backup
./deepchain db backup

# Restore from backup
./deepchain db restore backups/deepchain_20231123_120000.sql

# Database shell
./deepchain db shell

# Run migrations
./deepchain db migrate

SSL Certificate Management

# Setup Let's Encrypt SSL
./deepchain ssl setup

# Renew certificate
./deepchain ssl renew

# Check certificate status
./deepchain ssl status

Service Management

# Restart all services
./deepchain restart

# Restart specific service
./deepchain restart api
./deepchain restart worker
./deepchain restart nginx

🔍 Troubleshooting

Quick Fixes

# Fix RabbitMQ connection issues
./deepchain fix rabbitmq

# Reload nginx configuration
./deepchain fix nginx

# Fix file permissions
./deepchain fix permissions

Common Issues

1. RabbitMQ Connection Failed

Symptoms:

Exception: Failed to execute workflow: "Could not connect to deepchain-rabbitmq-1.5672"

Fix:

./deepchain fix rabbitmq

Root Cause: Queue service using wrong hostname. Fixed by reading RABBITMQ_URL environment variable.

2. API Routes Return 404 or HTML

Symptoms:

  • /workspaces returns HTML instead of JSON
  • API endpoints not accessible

Fix:

./deepchain fix nginx

Root Cause: Nginx regex pattern required trailing slash. Fixed by changing ^/(auth|api|...)/ to ^/(auth|api|...)(/|$).

3. Invalid Credentials After Password Reset

Symptoms:

  • Login fails with "Invalid credentials"
  • Password hash doesn't match

Fix: Ensure JWT_SECRET environment variable matches between:

  • Password hashing
  • API verification

Root Cause: AuthService used hardcoded _jwtSecret instead of Platform.environment['JWT_SECRET'].

4. GoRouter Redirect Loop

Symptoms:

  • Infinite redirects between /login and /onboarding
  • App never loads

Fix: Wait for async data before creating router:

Future<void> _initializeApp() async {
  // Load onboarding status FIRST
  final onboardingStatus = await ref.read(onboardingStatusProvider.future);
  _requiresOnboarding = onboardingStatus.requiresOnboarding;
  
  // Create router AFTER data loaded
  setState(() {
    _router = _createRouter();
    _initialized = true;
  });
}

Root Cause: FutureProvider returned different values on successive redirect evaluations.

5. Aggressive Browser Caching

Symptoms:

  • Code changes not visible
  • Old version loads after deployment

Fix: Build version tracking in index.html:

var buildVersion = '20231123-1745';
var lastVersion = localStorage.getItem('build-version');

if (lastVersion !== buildVersion) {
  localStorage.clear();
  sessionStorage.clear();
  // Clear caches and reload
}

Plus nginx no-cache headers:

location ~* \.(js|css)$ {
    expires -1;
    add_header Cache-Control "no-store, no-cache";
}

Diagnostic Commands

# Comprehensive diagnostics
./deepchain diagnose

# Check specific service
./deepchain logs api | grep -i error

# Test API endpoint
curl https://aice.deepchain.dev/health

# Check database
./deepchain db shell
\dt  # List tables
SELECT * FROM "User";

📚 Lessons Learned

1. Environment Variables

Always use environment variables for:

  • ✅ JWT secrets
  • ✅ Database credentials
  • ✅ Service hostnames
  • ✅ RabbitMQ URLs

Never hardcode:

  • const String _jwtSecret = 'hardcoded'
  • final host = 'deepchain-rabbitmq-1'

Correct approach:

static final String _jwtSecret = Platform.environment['JWT_SECRET'] ?? 'fallback';

2. Async Initialization

Wrong:

GoRouter(
  redirect: (context, state) {
    // Reading FutureProvider here causes race conditions
    final onboarding = ref.watch(onboardingStatusProvider);
  }
)

Correct:

Future<void> _initializeApp() async {
  // Wait for all async data
  final onboarding = await ref.read(onboardingStatusProvider.future);
  
  // Store in state
  _requiresOnboarding = onboarding.requiresOnboarding;
  
  // Create router with stable data
  setState(() => _router = _createRouter());
}

3. Nginx Routing

Generic pattern matching is better than specific routes:

Before:

location /api/auth/login { ... }
location /api/auth/ { ... }
location /workspaces { ... }
# ... 20+ specific routes

After:

location ~ ^/(auth|api|workspaces|...)(/|$) {
    proxy_pass http://api_backend;
}

Benefits:

  • Automatically supports new routes
  • Maintains exact URL-to-route mapping
  • Simpler to maintain

4. Cache Busting Strategy

Multi-layer approach:

  1. Build version tracking (JavaScript)
  2. Service worker unregistration
  3. Nginx headers for JS/CSS
  4. Query parameter versioning

Why all layers?

  • Cloudflare caches
  • Browser HTTP cache
  • Service worker cache
  • localStorage persistence

5. Docker Hostname Resolution

Use Docker service names in docker-compose:

environment:
  DATABASE_URL: postgresql://user:pass@postgres:5432/db
  RABBITMQ_URL: amqp://user:pass@rabbitmq:5672/vhost

Not container names:

# ❌ Wrong
DATABASE_URL: postgresql://user:pass@deepchain-db:5432/db

6. SSL Certificate Management

Let's Encrypt auto-renewal:

# Certbot handles renewal automatically
sudo certbot renew --quiet

# Copy to nginx
sudo cp /etc/letsencrypt/live/domain/fullchain.pem /opt/deepchain/nginx/ssl/

Set up cron job:

# Auto-renew and restart nginx
0 3 * * * certbot renew --quiet && cd /opt/deepchain && ./deepchain restart nginx

7. Password Hashing

Consistent JWT_SECRET is critical:

Hash creation (registration/reset):

String _hashPassword(String password) {
  final jwt = Platform.environment['JWT_SECRET']!;
  return sha256.convert(utf8.encode(password + jwt)).toString();
}

Hash verification (login):

bool _verifyPassword(String input, String stored) {
  return _hashPassword(input) == stored;
}

Both must use the SAME JWT_SECRET!

8. Platform-Specific Docker Builds

For GCloud (AMD64):

docker buildx build --platform linux/amd64 \
  -t gcr.io/project/image:latest \
  --push .

For local Mac (ARM64):

docker build -t local/image:dev .

🎯 Best Practices

  1. Always backup before updates

    ./deepchain db backup
  2. Use the CLI for all operations

    • Ensures consistency
    • Handles environment detection
    • Provides proper error handling
  3. Monitor logs regularly

    ./deepchain logs | grep -i error
  4. Test in development first

    ./deepchain init  # Choose development
    ./deepchain deploy
    # Test thoroughly before production
  5. Keep credentials secure

    • Never commit .env to git
    • Store credentials-*.txt safely
    • Rotate secrets periodically
  6. Document environment-specific settings

    • DNS configuration
    • Firewall rules
    • SSL certificates

📞 Support

For issues or questions:

  1. Run diagnostics: ./deepchain diagnose
  2. Check logs: ./deepchain logs <service>
  3. Review this guide's troubleshooting section
  4. Check recent errors: ./deepchain logs | grep -i error

🔄 Quick Reference

Task Command
Initialize ./deepchain init
Deploy ./deepchain deploy
Status ./deepchain status
Logs ./deepchain logs [service]
Backup DB ./deepchain db backup
Restore DB ./deepchain db restore <file>
Update ./deepchain update
Restart ./deepchain restart [service]
Health Check ./deepchain health
Diagnostics ./deepchain diagnose
Fix RabbitMQ ./deepchain fix rabbitmq
Fix Nginx ./deepchain fix nginx
SSL Setup ./deepchain ssl setup
View Config ./deepchain config
Help ./deepchain help

Version: 1.0.0
Last Updated: November 23, 2025
License: MIT