Protokit

Deployment

Deploy Datyze with Docker and Coolify on VPS infrastructure

Deployment

Datyze is optimized for self-hosting with Docker and Coolify on VPS infrastructure. The application uses Next.js standalone mode for minimal Docker image size.

Docker Configuration

Dockerfile Overview

The multi-stage Dockerfile optimizes for production:

# Stage 1: Dependencies
FROM node:20-alpine AS deps
# Install pnpm and dependencies
 
# Stage 2: Builder
FROM node:20-alpine AS builder
# Build the Next.js application
 
# Stage 3: Runner
FROM node:20-alpine AS runner
# Minimal production image with standalone output

Building the Image

docker build -t datyze .

Running Locally

docker run -p 3000:3000 \
  -e DATABASE_URL="postgresql://..." \
  -e AUTH_SECRET="..." \
  datyze

Coolify Deployment

Prerequisites

  • A VPS with Coolify installed
  • PostgreSQL database (can be provisioned in Coolify)
  • Domain name configured

Step 1: Connect Repository

  1. Open Coolify dashboard
  2. Create a new application
  3. Connect your Git repository
  4. Select Dockerfile as the build pack

Step 2: Configure Environment

Add all required environment variables:

# Core
DATABASE_URL="postgresql://user:pass@host:5432/datyze"
AUTH_SECRET="your-32-char-secret"
AUTH_URL="https://yourdomain.com"
NEXT_PUBLIC_APP_URL="https://yourdomain.com"
NEXT_PUBLIC_APP_NAME="Datyze"
 
# OAuth (optional)
GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""
GITHUB_CLIENT_ID=""
GITHUB_CLIENT_SECRET=""
 
# Email (optional)
RESEND_API_KEY=""
EMAIL_FROM="noreply@yourdomain.com"
 
# Payments (optional)
STRIPE_SECRET_KEY=""
STRIPE_WEBHOOK_SECRET=""
# ... or Lemon Squeezy keys

Step 3: Deploy

Click Deploy and Coolify will:

  1. Clone your repository
  2. Build the Docker image
  3. Run database migrations
  4. Start the application

Environment Variables

Required Variables

VariableDescription
DATABASE_URLPostgreSQL connection string
AUTH_SECRETMin 32-character secret for NextAuth
AUTH_URLYour production domain
NEXT_PUBLIC_APP_URLSame as AUTH_URL

Generate AUTH_SECRET

openssl rand -base64 32

OAuth Providers

VariableProvider
GOOGLE_CLIENT_IDGoogle OAuth
GOOGLE_CLIENT_SECRETGoogle OAuth
GITHUB_CLIENT_IDGitHub OAuth
GITHUB_CLIENT_SECRETGitHub OAuth

Email Configuration

VariableProvider
RESEND_API_KEYResend
BREVO_API_KEYBrevo
EMAIL_FROMSender email

Payment Configuration

Stripe:

VariableDescription
STRIPE_SECRET_KEYStripe secret key
STRIPE_WEBHOOK_SECRETWebhook signing secret
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYPublishable key

Lemon Squeezy:

VariableDescription
LEMONSQUEEZY_API_KEYAPI key
LEMONSQUEEZY_STORE_IDStore ID
LEMONSQUEEZY_WEBHOOK_SECRETWebhook secret

Database Setup

Using Coolify's PostgreSQL

  1. In Coolify, create a new PostgreSQL database
  2. Copy the connection string
  3. Add it as DATABASE_URL to your app

External Database

Use any PostgreSQL provider:

  • Neon - Serverless PostgreSQL
  • Supabase - PostgreSQL with extras
  • Railway - Simple hosting
  • Your own PostgreSQL - Self-hosted

Database Migrations

Development

Push schema changes directly:

pnpm db:push

Production

Generate and run migrations:

# Generate migration files
pnpm db:generate
 
# Run migrations
pnpm db:migrate

Migrations run automatically during Docker build.


Health Checks

The application includes a health check endpoint:

// GET /api/health
export async function GET() {
  return Response.json({ status: "ok" });
}

Configure in Coolify:

Health Check:
  Path: /api/health
  Port: 3000
  Interval: 30s

SSL/HTTPS

Coolify automatically provisions SSL certificates via Let's Encrypt. Ensure your domain's DNS is properly configured:

A Record: yourdomain.com → Your VPS IP
CNAME: www.yourdomain.com → yourdomain.com

Monitoring

Sentry Integration

Add Sentry for error tracking:

NEXT_PUBLIC_SENTRY_DSN="https://...@sentry.io/..."
SENTRY_AUTH_TOKEN="..."
SENTRY_ORG="your-org"
SENTRY_PROJECT="datyze"

Rate Limiting (Optional)

Rate limiting uses Upstash Redis but is completely optional. Without configuration:

  • All API requests are allowed (graceful degradation)
  • The application works normally
  • No errors or warnings

If you need rate limiting later, add:

UPSTASH_REDIS_REST_URL="https://..."
UPSTASH_REDIS_REST_TOKEN="..."

Tip: Start without rate limiting. Add it later when you have users and need protection against API abuse.


Performance Tips

  1. Enable standalone mode - Already configured in next.config.ts
  2. Use edge caching - Cloudflare or similar CDN
  3. Optimize images - Use Next.js Image component
  4. Database indexes - Already configured for common queries

Troubleshooting

Database Connection Failed

Check DATABASE_URL format:

postgresql://user:password@host:port/database

Build Errors

  • Verify all environment variables are set
  • Try with SKIP_ENV_VALIDATION=1
  • Clear Docker cache: docker build --no-cache

Auth Errors

  • Ensure AUTH_URL matches your domain exactly
  • Check OAuth callback URLs in provider settings

Docker Compose

For local production testing:

# docker-compose.yml
version: "3.8"
services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://postgres:postgres@db:5432/datyze
      - AUTH_SECRET=your-secret-here
    depends_on:
      - db
 
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=datyze
    volumes:
      - postgres_data:/var/lib/postgresql/data
 
volumes:
  postgres_data:

Run with:

docker-compose up -d

Next Steps