Chameleon

Dokploy Deployment

Deploy Chameleon using Dokploy self-hosted platform

Dokploy Deployment

Learn how to deploy Chameleon AI SaaS using Dokploy, a self-hosted deployment platform that provides Docker-based containerization and easy management.

Overview

Dokploy is a self-hosted deployment platform that simplifies the process of deploying applications using Docker containers. It provides a web-based interface for managing deployments, environment variables, and monitoring. This deployment method is ideal for users who want full control over their infrastructure and prefer self-hosting.

Prerequisites

Required Infrastructure

  • VPS/Server: Ubuntu 20.04+ or similar Linux distribution
  • Docker: Version 20.10+ installed
  • Docker Compose: Version 2.0+ installed
  • Domain Name: For custom domain setup
  • SSL Certificate: Let's Encrypt or custom certificate

Required Accounts

  • GitHub Account: For repository access
  • Database Provider: PostgreSQL or MySQL
  • Stripe Account: For payment processing

Installation Process

Step 1: Install Dokploy

# Install Dokploy on your server
curl -sSL https://dokploy.com/install.sh | sh

# Start Dokploy service
sudo systemctl start dokploy
sudo systemctl enable dokploy

# Check service status
sudo systemctl status dokploy

Step 2: Access Dokploy Dashboard

  1. Open Dokploy Dashboard

    • Navigate to http://your-server-ip:3000
    • Create admin account
    • Complete initial setup
  2. Configure Server Settings

    • Set server name and description
    • Configure email notifications
    • Set up backup settings

Step 3: Connect GitHub Repository

  1. Add GitHub Integration

    • Go to Settings → Integrations
    • Connect your GitHub account
    • Grant repository access
  2. Import Project

    • Click "New Project"
    • Select "Import from GitHub"
    • Choose your Chameleon repository

Deployment Configuration

Step 4: Create Dockerfile

Create Dockerfile in your project root:

# Dockerfile
FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Install dependencies
COPY package.json pnpm-lock.yaml* ./
RUN corepack enable pnpm && pnpm i --frozen-lockfile

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Build the application
RUN corepack enable pnpm && pnpm build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public

# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next

# Automatically leverage output traces to reduce image size
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000
ENV HOSTNAME "0.0.0.0"

CMD ["node", "server.js"]

Step 5: Create Docker Compose File

Create docker-compose.yml:

# docker-compose.yml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=${DATABASE_URL}
      - NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
      - AUTH_SECRET=${AUTH_SECRET}
      - NEXTAUTH_URL=${NEXTAUTH_URL}
      - NEXT_PUBLIC_WEB_URL=${NEXT_PUBLIC_WEB_URL}
      - ADMIN_EMAILS=${ADMIN_EMAILS}
      - AUTH_GOOGLE_ID=${AUTH_GOOGLE_ID}
      - AUTH_GOOGLE_SECRET=${AUTH_GOOGLE_SECRET}
      - AUTH_GITHUB_ID=${AUTH_GITHUB_ID}
      - AUTH_GITHUB_SECRET=${AUTH_GITHUB_SECRET}
      - STRIPE_PUBLISHABLE_KEY=${STRIPE_PUBLISHABLE_KEY}
      - STRIPE_PRIVATE_KEY=${STRIPE_PRIVATE_KEY}
    restart: unless-stopped
    depends_on:
      - postgres

  postgres:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - app
    restart: unless-stopped

volumes:
  postgres_data:

Step 6: Configure Nginx

Create nginx.conf:

# nginx.conf
events {
    worker_connections 1024;
}

http {
    upstream app {
        server app:3000;
    }

    server {
        listen 80;
        server_name your-domain.com www.your-domain.com;
        return 301 https://$server_name$request_uri;
    }

    server {
        listen 443 ssl http2;
        server_name your-domain.com www.your-domain.com;

        ssl_certificate /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/key.pem;

        location / {
            proxy_pass http://app;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            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;
            proxy_cache_bypass $http_upgrade;
        }
    }
}

Environment Configuration

Step 7: Set Environment Variables

Create .env file:

# .env
# Database
DATABASE_URL="postgresql://user:password@postgres:5432/chameleon"
POSTGRES_DB="chameleon"
POSTGRES_USER="user"
POSTGRES_PASSWORD="password"

# Authentication
NEXTAUTH_SECRET="your-random-secret-key"
AUTH_SECRET="your-random-secret-key"
NEXTAUTH_URL="https://your-domain.com"
NEXT_PUBLIC_WEB_URL="https://your-domain.com"
ADMIN_EMAILS="admin@example.com"

# OAuth Providers (Optional)
AUTH_GOOGLE_ID="your-google-client-id"
AUTH_GOOGLE_SECRET="your-google-client-secret"
AUTH_GITHUB_ID="your-github-client-id"
AUTH_GITHUB_SECRET="your-github-client-secret"

# Payment (Optional)
STRIPE_PUBLISHABLE_KEY="pk_live_..."
STRIPE_PRIVATE_KEY="sk_live_..."

Step 8: Configure SSL Certificate

# Install Certbot
sudo apt update
sudo apt install certbot

# Generate SSL certificate
sudo certbot certonly --standalone -d your-domain.com -d www.your-domain.com

# Copy certificates to project directory
sudo cp /etc/letsencrypt/live/your-domain.com/fullchain.pem ./ssl/cert.pem
sudo cp /etc/letsencrypt/live/your-domain.com/privkey.pem ./ssl/key.pem
sudo chown $USER:$USER ./ssl/*

Deployment Process

Step 9: Deploy with Dokploy

  1. Create New Deployment

    • Go to Dokploy dashboard
    • Click "New Deployment"
    • Select your repository
    • Choose "Docker Compose" deployment type
  2. Configure Deployment

    • Set deployment name: "chameleon-ai-saas"
    • Select branch: "main"
    • Set build context: "."
    • Configure environment variables
  3. Deploy Application

    • Click "Deploy"
    • Monitor build logs
    • Wait for deployment to complete

Step 10: Database Setup

# Connect to running container
docker exec -it chameleon-ai-saas-app-1 sh

# Run database migrations
pnpm db:push

# Seed initial data
pnpm db:seed

Monitoring and Maintenance

Step 11: Set Up Monitoring

# Add to docker-compose.yml
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    restart: unless-stopped

  grafana:
    image: grafana/grafana
    ports:
      - "3001:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana
    restart: unless-stopped

Step 12: Backup Configuration

# Create backup script
#!/bin/bash
# backup.sh

# Backup database
docker exec chameleon-ai-saas-postgres-1 pg_dump -U user chameleon > backup_$(date +%Y%m%d_%H%M%S).sql

# Backup application data
docker cp chameleon-ai-saas-app-1:/app/uploads ./backup_uploads_$(date +%Y%m%d_%H%M%S)

# Clean old backups (keep last 7 days)
find ./backup_* -mtime +7 -delete

File Locations

  • Dockerfile - Container configuration
  • docker-compose.yml - Multi-container setup
  • nginx.conf - Reverse proxy configuration
  • .env - Environment variables
  • backup.sh - Backup script

Common Tasks

Deploy New Version

# Pull latest changes
git pull origin main

# Rebuild and restart containers
docker-compose down
docker-compose build --no-cache
docker-compose up -d

# Run database migrations
docker exec chameleon-ai-saas-app-1 pnpm db:push

View Logs

# View application logs
docker-compose logs -f app

# View database logs
docker-compose logs -f postgres

# View nginx logs
docker-compose logs -f nginx

Update SSL Certificate

# Renew certificate
sudo certbot renew

# Copy new certificates
sudo cp /etc/letsencrypt/live/your-domain.com/fullchain.pem ./ssl/cert.pem
sudo cp /etc/letsencrypt/live/your-domain.com/privkey.pem ./ssl/key.pem

# Restart nginx
docker-compose restart nginx

Scale Application

# Update docker-compose.yml
services:
  app:
    # ... existing configuration
    deploy:
      replicas: 3

Troubleshooting

Container won't start

Problem: Application container fails to start

Solution:

  1. Check container logs: docker-compose logs app
  2. Verify environment variables are set
  3. Check database connection
  4. Ensure all required files are present

Database connection issues

Problem: Cannot connect to database

Solution:

  1. Verify DATABASE_URL is correct
  2. Check if postgres container is running
  3. Ensure database credentials are valid
  4. Check network connectivity between containers

SSL certificate issues

Problem: HTTPS not working

Solution:

  1. Verify certificate files exist
  2. Check nginx configuration
  3. Ensure domain points to server IP
  4. Test certificate validity

Performance issues

Problem: Slow response times

Solution:

  1. Monitor resource usage: docker stats
  2. Optimize nginx configuration
  3. Scale application containers
  4. Enable caching

Next Steps