Docs
Deployment

Virtual Private Server (VPS)

Learn how to deploy the marketing and dashboard apps on a VPS.

Prerequisites

  • Linux-based VPS (Debian or Ubuntu recommended).
  • DNS control for yourdomain.com.
  • SSH access to your VPS

Server preparation

Update the system

sudo apt update && sudo apt upgrade -y

Install dependencies

Install essential tools:

sudo apt install -y build-essential curl software-properties-common git

Install Node.js

Use the NodeSource setup script:

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

Install pnpm globally:

corepack enable
corepack prepare pnpm@latest --activate

Install PostgreSQL

sudo apt install -y postgresql postgresql-contrib
sudo -u postgres psql

In the PostgreSQL shell, set up a user:

CREATE USER postgres WITH PASSWORD 'secure_password';
ALTER USER postgres WITH SUPERUSER;
\q

Install PM2

sudo npm install -g pm2

DNS configuration

Add DNS records

Configure the following DNS records:

TypeNameValue
A@VPS_IP_ADDRESS
AdashboardVPS_IP_ADDRESS

Replace VPS_IP_ADDRESS with your server's IP address.

Application Deployment

Clone the repository

Log in to your VPS and clone your project:

git clone https://github.com/your-repo/achromatic.git /var/www/achromatic
cd /var/www/achromatic

Install dependencies and build

Use pnpm for faster and disk-efficient installs:

pnpm install
pnpm build

Start applications with PM2

Set up the Marketing and Dashboard services:

pm2 start npm --name "marketing" --prefix ./marketing -- run start
pm2 start npm --name "dashboard" --prefix ./dashboard -- run start
pm2 save

Ensure PM2 restarts your apps on reboot:

pm2 startup

SSL with Certbot

Install Certbot and generate SSL certificates:

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

Configure auto-renewal:

sudo systemctl enable certbot.timer

Nginx configuration

Marketing application

Create a configuration for Marketing:

sudo nano /etc/nginx/sites-available/marketing
server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$host$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:3001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Enable the configuration:

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

Dashboard application

Create a configuration for Dashboard:

sudo nano /etc/nginx/sites-available/dashboard
server {
    listen 80;
    server_name dashboard.yourdomain.com;
    return 301 https://$host$request_uri;
}
 
server {
    listen 443 ssl http2;
    server_name dashboard.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_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Enable the configuration:

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

CI/CD pipeline

GitHub Actions workflow

Create .github/workflows/deploy.yml in your repository:

name: Deploy Achromatic
 
on:
  push:
    branches:
      - main
 
jobs:
  deploy:
    runs-on: ubuntu-latest
 
    steps:
    - name: Checkout Code
      uses: actions/checkout@v3
 
    - name: Set up Node.js
      uses: actions/setup-node@v3
      with:
        node-version: 20
        cache: 'pnpm'
 
    - name: Install pnpm
      run: |
        corepack enable
        corepack prepare pnpm@latest --activate
 
    - name: Install Dependencies
      run: pnpm install
 
    - name: Build Applications
      run: pnpm build
 
    - name: Deploy to Server
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.SSH_HOST }}
        username: ${{ secrets.SSH_USERNAME }}
        key: ${{ secrets.SSH_PRIVATE_KEY }}
        script: |
          cd /var/www/achromatic
          git pull origin main
          pnpm install
          pnpm build
          pm2 restart all

Setting up secrets

Add the following secrets in your repository settings:

Secret NameValue
SSH_HOSTVPS_IP_ADDRESS
SSH_USERNAMEYour SSH username
SSH_PRIVATE_KEYYour private SSH key

Monitoring

Check application status:

pm2 list
pm2 logs

Further steps

Next you can harden your security by installing ufw as your firewall, fail2ban to prevent intrusions and a cron job to upload your db backups to s3.