Skip to main content
Self-hosting Openfront gives you complete control over your infrastructure, data, and deployment environment. This guide covers Docker deployment, manual setup, and scaling considerations.

Deployment Options

Openfront can be self-hosted using:
  • Docker - Containerized deployment (recommended)
  • Manual Installation - Direct Node.js deployment
  • Kubernetes - Orchestrated deployment for scale

Prerequisites

System Requirements

  • Operating System: Linux (Ubuntu 20.04+, Debian 11+, CentOS 8+) or macOS
  • Node.js: 20.0.0 or higher
  • PostgreSQL: 12 or higher
  • Memory: 2GB RAM minimum (4GB+ recommended)
  • Storage: 5GB minimum (more for product images)
  • Network: HTTPS-capable domain (required for payment processing)

Required Software

  • Git
  • Node.js and npm
  • PostgreSQL database
  • Process manager (PM2 or systemd)
  • Nginx or Apache (for reverse proxy)
  • SSL certificate (Let’s Encrypt recommended)

Docker Deployment

Create Dockerfile

While Openfront doesn’t include a Dockerfile by default, create one:
FROM node:20-alpine AS base

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

COPY package.json package-lock.json* ./
RUN npm ci

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

ENV NODE_ENV=production

# Build Keystone and Next.js
RUN npm run build

# Production image, copy all 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
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma

USER nextjs

EXPOSE 3000

ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

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

Docker Compose Setup

Create docker-compose.yml:
version: '3.8'

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

  openfront:
    build: .
    environment:
      DATABASE_URL: postgresql://openfront:${POSTGRES_PASSWORD}@postgres:5432/openfront
      SESSION_SECRET: ${SESSION_SECRET}
      NODE_ENV: production
    ports:
      - "3000:3000"
    depends_on:
      - postgres
    restart: unless-stopped
    volumes:
      - ./uploads:/app/public/uploads

volumes:
  postgres_data:

Environment Configuration

Create .env file:
# Database
POSTGRES_PASSWORD=your-secure-postgres-password
DATABASE_URL=postgresql://openfront:your-secure-postgres-password@postgres:5432/openfront

# Session
SESSION_SECRET=your-very-long-session-secret-minimum-32-characters

# Optional - Payment Providers
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
PAYPAL_CLIENT_ID=your-paypal-client-id
PAYPAL_CLIENT_SECRET=your-paypal-client-secret

# Optional - Shipping
SHIPPO_API_KEY=shippo_live_...

# Optional - File Storage
S3_BUCKET_NAME=your-bucket
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key

# Optional - Email
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=[email protected]
SMTP_PASS=your-app-password
FROM_EMAIL=[email protected]
Generate secure passwords and secrets:
# PostgreSQL password
openssl rand -base64 32

# Session secret
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Deploy with Docker Compose

1

Clone Repository

git clone https://github.com/openshiporg/openfront.git
cd openfront
2

Configure Environment

Create and configure .env file with required variables
3

Build and Start Services

docker-compose up -d
4

Check Logs

docker-compose logs -f openfront
5

Access Application

Navigate to http://localhost:3000

Manual Installation

Step-by-Step Setup

1

Install Node.js 20

# Using nvm (recommended)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install 20
nvm use 20
2

Install PostgreSQL

# Ubuntu/Debian
sudo apt update
sudo apt install postgresql postgresql-contrib

# Start PostgreSQL
sudo systemctl start postgresql
sudo systemctl enable postgresql
3

Create Database

sudo -u postgres psql

# In PostgreSQL prompt:
CREATE DATABASE openfront;
CREATE USER openfront WITH PASSWORD 'your-secure-password';
GRANT ALL PRIVILEGES ON DATABASE openfront TO openfront;
\q
4

Clone and Install Openfront

git clone https://github.com/openshiporg/openfront.git
cd openfront
npm install
5

Configure Environment

cp .env.example .env
nano .env
Update with your database credentials and session secret
6

Build Application

npm run build
7

Start Application

npm start

Process Management with PM2

For production, use PM2 to manage the Node.js process:
# Install PM2 globally
npm install -g pm2

# Start Openfront with PM2
pm2 start npm --name "openfront" -- start

# Configure PM2 to start on boot
pm2 startup
pm2 save

# Monitor application
pm2 status
pm2 logs openfront
Create ecosystem.config.js for advanced PM2 configuration:
module.exports = {
  apps: [{
    name: 'openfront',
    script: 'npm',
    args: 'start',
    instances: 2,
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    max_memory_restart: '1G',
    error_file: './logs/err.log',
    out_file: './logs/out.log',
    log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
    merge_logs: true
  }]
}
Start with:
pm2 start ecosystem.config.js

Reverse Proxy Configuration

Nginx Configuration

Create /etc/nginx/sites-available/openfront:
upstream openfront {
    server localhost:3000;
    keepalive 64;
}

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

server {
    listen 443 ssl http2;
    server_name your-domain.com www.your-domain.com;
    
    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    
    # Client upload size
    client_max_body_size 50M;
    
    # Proxy configuration
    location / {
        proxy_pass http://openfront;
        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;
        proxy_read_timeout 90;
    }
    
    # Static files caching
    location /_next/static {
        proxy_pass http://openfront;
        proxy_cache_valid 200 365d;
        add_header Cache-Control "public, immutable";
    }
}
Enable and restart Nginx:
sudo ln -s /etc/nginx/sites-available/openfront /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

SSL Certificate with Let’s Encrypt

# Install Certbot
sudo apt install certbot python3-certbot-nginx

# Obtain certificate
sudo certbot --nginx -d your-domain.com -d www.your-domain.com

# Auto-renewal (should be automatic)
sudo certbot renew --dry-run

Database Management

Backup Strategy

Automated daily backups:
#!/bin/bash
# /usr/local/bin/backup-openfront.sh

BACKUP_DIR="/backups/openfront"
DATE=$(date +%Y%m%d_%H%M%S)
DATABASE="openfront"
USER="openfront"

mkdir -p $BACKUP_DIR

# Create backup
pg_dump -U $USER $DATABASE | gzip > $BACKUP_DIR/openfront_$DATE.sql.gz

# Keep only last 7 days
find $BACKUP_DIR -name "openfront_*.sql.gz" -mtime +7 -delete

echo "Backup completed: openfront_$DATE.sql.gz"
Schedule with cron:
# Run daily at 2 AM
0 2 * * * /usr/local/bin/backup-openfront.sh

Database Restoration

# Restore from backup
gunzip -c /backups/openfront/openfront_20260228_020000.sql.gz | psql -U openfront openfront

Database Optimization

-- Run weekly for maintenance
VACUUM ANALYZE;

-- Reindex if needed
REINDEX DATABASE openfront;

Scaling Considerations

Vertical Scaling

Increase server resources:
  • CPU: Handle more concurrent requests
  • Memory: Support larger datasets and caching
  • Storage: More product images and data

Horizontal Scaling

For high-traffic deployments:
1

Use External PostgreSQL

Managed database service (AWS RDS, Google Cloud SQL)
2

Configure S3 Storage

Required for multi-instance deployments
3

Set Up Load Balancer

Nginx, HAProxy, or cloud load balancer
4

Deploy Multiple Instances

Run multiple Openfront instances behind load balancer
5

Configure Session Store

Use Redis for shared session storage
File uploads require S3-compatible storage for horizontal scaling. Local filesystem storage only works with single-instance deployments.

Load Balancer Configuration

Nginx load balancer:
upstream openfront_cluster {
    least_conn;
    server 10.0.1.10:3000 max_fails=3 fail_timeout=30s;
    server 10.0.1.11:3000 max_fails=3 fail_timeout=30s;
    server 10.0.1.12:3000 max_fails=3 fail_timeout=30s;
    keepalive 64;
}

server {
    listen 443 ssl http2;
    server_name your-domain.com;
    
    location / {
        proxy_pass http://openfront_cluster;
        # ... other proxy settings
    }
}

Monitoring and Logging

Application Monitoring

PM2 monitoring:
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
Health check script:
#!/bin/bash
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/api/health)
if [ $RESPONSE -ne 200 ]; then
    echo "Health check failed with status $RESPONSE"
    # Alert or restart
fi

Database Monitoring

-- Monitor active connections
SELECT count(*) FROM pg_stat_activity;

-- Check slow queries
SELECT query, mean_exec_time 
FROM pg_stat_statements 
ORDER BY mean_exec_time DESC 
LIMIT 10;

Security Hardening

Firewall Configuration

# UFW (Ubuntu)
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable

# Only allow localhost PostgreSQL access
sudo ufw deny 5432

Regular Updates

# System updates
sudo apt update && sudo apt upgrade -y

# Node.js dependencies
npm audit
npm audit fix

# Database updates
sudo apt update && sudo apt install --only-upgrade postgresql

Security Best Practices

  • Change default PostgreSQL port
  • Use strong passwords for all accounts
  • Enable database connection encryption
  • Regular security audits
  • Keep all software updated
  • Monitor logs for suspicious activity
  • Use fail2ban for brute force protection

Troubleshooting

Application Won’t Start

# Check logs
pm2 logs openfront

# Check database connection
psql -U openfront -h localhost openfront

# Verify environment variables
cat .env

Performance Issues

# Check system resources
top
free -h
df -h

# Check database performance
psql -U openfront openfront -c "SELECT * FROM pg_stat_activity;"

# Check Node.js memory usage
pm2 info openfront

Database Connection Issues

  • Verify DATABASE_URL is correct
  • Check PostgreSQL is running
  • Verify firewall allows connections
  • Check connection pool settings

Next Steps

Build docs developers (and LLMs) love