VPS Deployment
Deploy GridWork HQ to a DigitalOcean, Hetzner, or other VPS for always-on operation.
VPS Deployment
Deploy both the dashboard and pipeline server on a VPS for maximum control and always-on availability. This guide uses Ubuntu, but the steps apply to any Linux distribution.
Recommended Specs
| Provider | Plan | Specs | Price |
|---|---|---|---|
| DigitalOcean | Basic Droplet | 2 vCPU, 4 GB RAM, 80 GB SSD | ~$24/mo |
| Hetzner | CX22 | 2 vCPU, 4 GB RAM, 40 GB SSD | ~$4.49/mo |
For running Claude Code and the pipeline server concurrently, 4 vCPU and 8 GB RAM is recommended.
1. Initial Server Setup
# Connect to your VPS
ssh root@YOUR_SERVER_IP
# Create a non-root user
adduser agency
usermod -aG sudo agency
# Set up SSH key authentication (from your local machine)
ssh-copy-id agency@YOUR_SERVER_IP
# Disable password auth on the server
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart sshdConfigure Firewall
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enableInstall Node.js 22
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
source ~/.bashrc
nvm install 22
nvm use 22
nvm alias default 22Install PM2
npm install -g pm22. DNS and SSL
Point DNS to Your VPS
| Type | Name | Value |
|---|---|---|
| A | @ | YOUR_SERVER_IP |
| A | hq | YOUR_SERVER_IP |
| A | api | YOUR_SERVER_IP (optional, for pipeline API) |
Install Nginx and Certbot
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx
# Get SSL certificates
sudo certbot --nginx -d hq.yourdomain.com -d api.yourdomain.comNginx Config — Dashboard
Create /etc/nginx/sites-available/gridwork-hq:
server {
listen 80;
server_name hq.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name hq.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/hq.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hq.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1: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;
}
}Nginx Config — Pipeline Server
Create /etc/nginx/sites-available/agency-pipeline:
server {
listen 80;
server_name api.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name api.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8750;
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 86400;
}
}Enable both sites:
sudo ln -s /etc/nginx/sites-available/gridwork-hq /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/agency-pipeline /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx3. Clone and Configure
sudo mkdir -p /var/www
sudo chown agency:agency /var/www
cd /var/www
git clone https://github.com/YOUR_ORG/gridwork-hq.git
git clone https://github.com/YOUR_ORG/pipeline-server.git
cd /var/www/gridwork-hq && npm install
cd /var/www/pipeline-server && npm installRun the Setup Wizard
cd /var/www/gridwork-hq
node setup-wizard.mjsWhen Phase 4 asks for VPS-specific settings:
| Prompt | VPS Answer |
|---|---|
| Deployment target | vps |
| Knowledge vault path | /home/agency/agency-workspace/knowledge |
| Scripts directory | /home/agency/agency-workspace/.scripts |
| Tailscale | no (Nginx handles external access) |
Set Up the Knowledge Vault
mkdir -p /home/agency/agency-workspace
cd /home/agency/agency-workspace
cp -r /var/www/gridwork-hq/knowledge-template knowledge
cd knowledge && git init && git add . && git commit -m "Initial knowledge vault"
mkdir -p /home/agency/agency-workspace/.scriptsUpdate URLs
# In /var/www/gridwork-hq/.env.local
HQ_URL=https://hq.yourdomain.com
NEXTAUTH_URL=https://hq.yourdomain.com4. Build and Start
Build the Dashboard
cd /var/www/gridwork-hq
npm run buildStart with PM2
pm2 start npm --name "gridwork-hq" -- start
pm2 save
# Auto-start on reboot
pm2 startup systemd -u agency --hp /home/agency
# Run the command PM2 outputs
pm2 savePipeline Server as a Service
Create /etc/systemd/system/agency-pipeline.service:
[Unit]
Description=Agency Pipeline Server
After=network.target
[Service]
Type=simple
User=agency
WorkingDirectory=/var/www/pipeline-server
ExecStart=/home/agency/.nvm/versions/node/v22.*/bin/bun run pipeline-server/src/server.ts
Restart=on-failure
RestartSec=10
EnvironmentFile=/var/www/pipeline-server/.env
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable agency-pipeline
sudo systemctl start agency-pipeline5. Monitoring
Install Glances
The dashboard System page can display CPU, RAM, and disk metrics from Glances:
sudo apt install -y glances
glances -w --port 8760 &Set Up Logrotate
Create /etc/logrotate.d/agency-pipeline:
/var/log/agency-pipeline/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
}External Monitoring
Set up UptimeRobot (free tier) to monitor:
https://hq.yourdomain.com— dashboard availabilityhttps://api.yourdomain.com/health— pipeline server health
6. Updating
# Update dashboard
cd /var/www/gridwork-hq
git pull origin main
npm install
npm run build
pm2 restart gridwork-hq
# Update pipeline server
cd /var/www/pipeline-server
git pull origin main
npm install
sudo systemctl restart agency-pipelineYour config/brand.json, .env.local, and pipeline-server/.env are gitignored and will not be overwritten by pulls.
Troubleshooting
See the Troubleshooting page for common VPS issues including 502 Bad Gateway, token mismatches, memory issues, and SSL certificate renewal failures.