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
Clone Repository
git clone https://github.com/openshiporg/openfront.git
cd openfront
Configure Environment
Create and configure .env file with required variables
Check Logs
docker-compose logs -f openfront
Access Application
Navigate to http://localhost:3000
Manual Installation
Step-by-Step Setup
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
Install PostgreSQL
# Ubuntu/Debian
sudo apt update
sudo apt install postgresql postgresql-contrib
# Start PostgreSQL
sudo systemctl start postgresql
sudo systemctl enable postgresql
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
Clone and Install Openfront
git clone https://github.com/openshiporg/openfront.git
cd openfront
npm install
Configure Environment
cp .env.example .env
nano .env
Update with your database credentials and session secret
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:
Use External PostgreSQL
Managed database service (AWS RDS, Google Cloud SQL)
Configure S3 Storage
Required for multi-instance deployments
Set Up Load Balancer
Nginx, HAProxy, or cloud load balancer
Deploy Multiple Instances
Run multiple Openfront instances behind load balancer
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
# 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