Skip to main content

Overview

ActumX consists of two deployable components:
  1. API - Backend service (Elysia + Bun)
  2. Dashboard - Frontend application (Next.js)
Both can be deployed using Docker or directly on a server.

API Deployment

Docker Deployment

The API includes a production-ready Dockerfile.

Build Docker Image

From the api/ directory:

Run Container

Dockerfile Breakdown

The API Dockerfile (api/Dockerfile):
Key Features:
  • Uses official Bun Docker image (oven/bun:1)
  • Production dependencies only (--production flag)
  • Layer caching optimization (dependencies installed before source copy)
  • Includes migration files in drizzle/ directory
  • Exposes port 3001 by default

Production Build Process

1. Install Dependencies

The --frozen-lockfile flag ensures consistent dependencies from bun.lock.

2. Run Migrations

Before starting the API, apply database migrations:
Or manually using Drizzle Kit:

3. Type Check

Verify TypeScript types before deployment:

4. Start Production Server

This runs bun run src/index.ts without watch mode.

Direct Server Deployment

To deploy directly on a server:
  1. Install Bun:
  2. Clone and setup:
  3. Configure environment:
  4. Run migrations:
  5. Start with process manager (PM2):

Dashboard Deployment

Next.js Build

From the dashboard/ directory:
This creates an optimized production build in .next/.

Deployment Options

Vercel offers the best Next.js deployment experience:
  1. Install Vercel CLI:
  2. Deploy:
  3. Set environment variables in Vercel dashboard:
    • NEXT_PUBLIC_API_BASE_URL=https://api.yourdomain.com

Option 2: Docker

Create a Dockerfile in dashboard/:
Update next.config.js to enable standalone output:
Build and run:

Option 3: Direct Server Deployment

  1. Build the application:
  2. Start with PM2:

Option 4: Static Export

If you don’t need server-side features, export as static HTML: Update next.config.js:
Build:
This creates static files in out/ that can be served by any static host (Netlify, Cloudflare Pages, AWS S3, etc.).

Environment Configuration

Production Environment Variables

API Environment Variables

Required for production:
Security Notes:
  • Generate a secure BETTER_AUTH_SECRET (minimum 32 characters):
  • Use environment-specific URLs (not localhost)
  • Use mainnet Solana RPC for production

Dashboard Environment Variables

Important: The NEXT_PUBLIC_ prefix makes this variable accessible in the browser.

Environment Variable Management

Docker Compose

Create docker-compose.yml for easier deployment:
Deploy:

Database Migrations in Production

Manual Migration

Run migrations before deploying new API versions:

Automated Migration

Option 1: Run migrations in Docker entrypoint:
Option 2: Run as a separate job in CI/CD before deployment.
Always backup your database before running migrations in production.

Health Checks

API Health Check

Add a health endpoint to your API (if not already present):
Use in Docker:

Monitoring & Logging

Logs

View Docker container logs:

Performance Monitoring

Consider integrating:
  • Sentry - Error tracking
  • DataDog - APM and logging
  • New Relic - Performance monitoring
  • Prometheus + Grafana - Metrics and dashboards

SSL/TLS Configuration

Use a reverse proxy like Nginx or Caddy for SSL:

Caddy Example

Caddy automatically provisions SSL certificates from Let’s Encrypt.

Scaling

Horizontal Scaling

  • Deploy multiple API instances behind a load balancer
  • Use a managed PostgreSQL service (AWS RDS, Digital Ocean, etc.)
  • Deploy Dashboard to CDN (Vercel, Cloudflare, etc.)

Database Scaling

  • Use connection pooling (PgBouncer)
  • Enable read replicas for read-heavy workloads
  • Consider managed database services for automatic backups and scaling

Security Checklist

  • Use HTTPS for all services
  • Set secure BETTER_AUTH_SECRET (32+ characters)
  • Use production database credentials
  • Enable CORS only for trusted origins
  • Keep dependencies updated
  • Use environment variables (never commit secrets)
  • Enable database backups
  • Set up monitoring and alerts
  • Use mainnet RPC URLs in production
  • Restrict database access to API only

Troubleshooting

Build Failures

Migration Errors

If migrations fail in production:
  1. Check database connectivity
  2. Verify DATABASE_URL format
  3. Ensure database user has migration permissions
  4. Check migration logs for specific errors

Connection Issues

If services can’t communicate:
  1. Verify network configuration (Docker networks, firewalls)
  2. Check environment variable URLs
  3. Ensure services are running: docker ps