VPS / SSH Deployment
Deploy to any VPS or server via SSH. Full control with automated deployments to DigitalOcean, Linode, Hetzner, Vultr, or any SSH-accessible server.
Setup Time
~15 minutes
Complexity
Advanced
Best For
Full Control
Overview
VPS (Virtual Private Server) deployment gives you complete control over your infrastructure. QODRYX automates the deployment process via SSH, handling code transfer, build steps, process management, and health checks.
Full Control
VPS deployment is ideal when you need full control over the server environment, custom configurations, or cost-effective hosting for steady workloads.
Supported VPS Providers
DigitalOcean
Droplets with SSH access
Linode (Akamai)
Linodes with SSH access
Hetzner
Cloud & dedicated servers
Vultr
Cloud compute instances
OVHcloud
VPS & dedicated servers
Any SSH Server
Any Linux server with SSH
Prerequisites
- A VPS or server with SSH access
- SSH key pair for authentication
- Root or sudo access on the server
- Required software installed (Node.js, Docker, etc.)
Step 1: Server Setup
Prepare your server for QODRYX deployments:
# Update system
sudo apt update && sudo apt upgrade -y
# Install Node.js (example for Node 20)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# Install Docker (optional)
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
# Install PM2 for process management
sudo npm install -g pm2
# Create deploy user
sudo useradd -m -s /bin/bash deploy
sudo usermod -aG sudo deploy
# Set up SSH key for deploy user
sudo mkdir -p /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh
# Add your public key to authorized_keysStep 2: Configure SSH Access
Add your SSH key to QODRYX:
# Generate SSH key pair (if you don't have one)
ssh-keygen -t ed25519 -C "qodryx-deploy"
# Add private key to QODRYX secrets
qodryx secrets set SSH_PRIVATE_KEY "$(cat ~/.ssh/id_ed25519)"
# Add the public key to your server
ssh-copy-id deploy@your-server.com
# Or manually add to server
cat ~/.ssh/id_ed25519.pub
# Copy and add to /home/deploy/.ssh/authorized_keys on serverSecurity Best Practice
Use a dedicated SSH key for deployments. Never use your personal SSH key or root account for automated deployments.
Step 3: Configure Deployment
Configure VPS deployment in your QODRYX config:
deployment:
provider: ssh
ssh:
# Server connection
host: 123.45.67.89
port: 22
user: deploy
# SSH key (from secrets)
private_key: "{{secrets.SSH_PRIVATE_KEY}}"
# Deployment directory
directory: /var/www/my-app
# Build and deploy steps
before_deploy:
- echo "Starting deployment..."
- sudo systemctl stop my-app || true
deploy:
- rsync -avz --delete --exclude=node_modules ./ deploy@server:/var/www/my-app/
- cd /var/www/my-app && npm ci --production
- cd /var/www/my-app && npm run build
after_deploy:
- sudo systemctl start my-app
- sudo systemctl enable my-app
# Health check
healthcheck:
url: http://localhost:3000/health
retries: 5
interval: 5s
# Rollback on failure
rollback:
enabled: true
keep_releases: 5Deployment Strategies
Simple Sync
Direct file synchronization (suitable for simple apps):
deployment:
provider: ssh
ssh:
strategy: sync
# Files to exclude from sync
exclude:
- node_modules
- .git
- .env.local
- logs/Release-Based
Zero-downtime deployments with release management:
deployment:
provider: ssh
ssh:
strategy: releases
# Directory structure:
# /var/www/my-app/
# releases/
# 20240101120000/
# 20240102120000/
# current -> releases/20240102120000
# shared/
# node_modules/
# uploads/
releases:
directory: /var/www/my-app
keep: 5
# Shared directories (persisted across releases)
shared_directories:
- node_modules
- uploads
- logs
# Shared files
shared_files:
- .env
# Deployment hooks
hooks:
before_symlink:
- cd {{ release_path }} && npm ci --production
- cd {{ release_path }} && npm run build
after_symlink:
- sudo systemctl reload my-appDocker-Based
Deploy Docker containers to your VPS:
deployment:
provider: ssh
ssh:
strategy: docker
docker:
# Pull and run container
image: myregistry/myapp:latest
container_name: my-app
# Port mapping
ports:
- 3000:3000
# Environment file
env_file: /var/www/my-app/.env
# Volumes
volumes:
- /var/www/my-app/data:/app/data
# Docker Compose alternative
compose_file: docker-compose.prod.yml
# Commands
before_deploy:
- docker pull myregistry/myapp:latest
deploy:
- docker compose -f docker-compose.prod.yml up -d
after_deploy:
- docker system prune -fProcess Management
Configure process management with PM2 or systemd:
PM2 Configuration
module.exports = {
apps: [{
name: 'my-app',
script: 'npm',
args: 'start',
cwd: '/var/www/my-app',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'production',
PORT: 3000
},
// Auto-restart on crash
autorestart: true,
max_memory_restart: '1G',
// Log files
error_file: '/var/log/my-app/error.log',
out_file: '/var/log/my-app/out.log',
}]
};Systemd Service
[Unit]
Description=My App
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/var/www/my-app
ExecStart=/usr/bin/node dist/index.js
Restart=always
RestartSec=10
Environment=NODE_ENV=production
Environment=PORT=3000
[Install]
WantedBy=multi-user.targetSSL & Nginx
Configure Nginx as a reverse proxy with SSL:
server {
listen 80;
server_name myapp.com www.myapp.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name myapp.com www.myapp.com;
ssl_certificate /etc/letsencrypt/live/myapp.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myapp.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;
}
}Deployment Commands
# Deploy to server
qodryx deploy --provider ssh
# Deploy to specific server
qodryx deploy --provider ssh --host production-server
# Rollback to previous release
qodryx rollback --provider ssh
# SSH into server
qodryx ssh production-server
# View server logs
qodryx logs --provider ssh --follow
# Run remote command
qodryx ssh production-server -- "pm2 status"Key Features
Works with any SSH-accessible server
Release-based deployments
Instant rollback to previous versions
Automatic health verification
Troubleshooting
SSH Connection Failed
- Verify SSH key is correct and has proper permissions (600)
- Check server firewall allows SSH (port 22)
- Ensure SSH key is added to authorized_keys on server
Permission Denied
- Check deploy user has permissions to the deployment directory
- Verify sudo access for system commands
- Review systemd/PM2 permissions
Server Maintenance
VPS requires manual maintenance for OS updates, security patches, and backups. Consider managed services if you need hands-off operations.