CoreMVP
Deployment

VPS Deployment

Self-hosted deployment on a VPS.

Overview

Deploy to a Virtual Private Server (VPS) for full control and predictable costs.

ProviderStarting PriceNotes
Hetzner$4/moBest value, EU/US locations
DigitalOcean$6/moSimple, good docs
Linode$5/moReliable, good support
Vultr$5/moMany locations

Server Requirements

  • 2 GB RAM minimum (4 GB recommended)
  • 2 vCPU
  • 40 GB SSD
  • Ubuntu 22.04 LTS

Server Setup

Initial Setup

# Update system
sudo apt update && sudo apt upgrade -y

# Install Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER

# Log out and back in for docker group to take effect

Clone Repository

git clone https://github.com/your-org/your-repo.git
cd your-repo

Configure Environment

Create .env file with production values:

nano .env

Add all required environment variables. See Environment Variables.

Build and Start

docker compose up -d --build

The app runs on port 3000.

Setup Nginx

sudo apt install nginx
sudo nano /etc/nginx/sites-available/myapp

Paste the Nginx configuration below.

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Enable SSL

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com

Nginx Configuration

/etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

Firewall

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

Updating the App

Pull latest code and rebuild:

cd your-repo
git pull
docker compose up -d --build

Non-Docker Deployment

If you prefer not to use Docker:

Install Node.js

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

Install Bun (Optional)

curl -fsSL https://bun.sh/install | bash

Install Dependencies and Build

cd your-repo
npm install
npm run build

Use PM2 for Process Management

npm install -g pm2
pm2 start npm --name "nextjs" -- start
pm2 save
pm2 startup

Monitoring

Check Status

docker compose ps
docker compose logs -f

Health Check

curl http://localhost:3000/api/health

System Resources

htop
df -h

Auto-Updates with Watchtower

Add to your docker-compose.yml:

services:
  watchtower:
    image: containrrr/watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    command: --interval 300

This checks for new images every 5 minutes.

Backups

Database backups are handled by Supabase. Ensure you have backups enabled in your Supabase project.

For application code, use Git. For user uploads (if any), set up S3 or similar storage with backup policies.

Troubleshooting

Container won't start

docker compose logs

SSL Certificate Issues

sudo certbot renew --dry-run

High Memory Usage

Check container memory:

docker stats

Consider adding swap:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Was this page helpful?

On this page