Server Production Readiness
Step-by-step checklist for Ubuntu VPS production setup: security, Docker, Nginx, SSL, backups, monitoring.
You've rented a VPS and got SSH access. Just push the code and start Docker? No. A production server is an ecosystem of security, monitoring, backups, and optimization. This checklist walks you through every step.
Server Requirements
Make sure your VPS meets the minimum requirements.
LTS = 5 years of support and security updates. Most guides and docs are written for Ubuntu.
The NestJS + React + PostgreSQL + Redis stack requires at least 4 GB.
First Login and System Update
Connect to the server and install basic utilities.
ssh root@YOUR_SERVER_IPapt update && apt upgrade -yapt install -y curl wget git vim htop ufwFirewall Setup (UFW)
Configure the firewall BEFORE enabling it — otherwise you risk locking yourself out.
sudo ufw default deny incoming
sudo ufw default allow outgoingIf you enable UFW without this rule, you will lose access to the server.
sudo ufw allow 22/tcp comment 'SSH'sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'sudo ufw enablesudo ufw status numberedDo NOT expose PostgreSQL (5432), Redis (6379), or pgAdmin (8082) to the internet. Use an SSH tunnel instead.
Secure SSH Access
Create a user, set up SSH keys, and disable root login.
Running as root is bad practice. Create a dedicated user.
adduser username
usermod -aG sudo usernameSSH keys are more secure than passwords. Copy your public key from your local machine.
ssh-copy-id username@YOUR_SERVER_IPIn a NEW terminal, test: ssh username@YOUR_SERVER_IP. Do not close the current session!
# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication nosudo systemctl restart sshdDocker Installation
sudo apt remove docker docker-engine docker.io containerd runcsudo apt install -y ca-certificates curl gnupg lsb-releasesudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpgsudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginsudo usermod -aG docker $USER
newgrp dockerdocker --version
docker compose versionNginx Installation and Configuration
sudo apt install -y nginxsudo systemctl status nginxsudo mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled /etc/nginx/conf.dsudo nginx -t
sudo systemctl restart nginxSSL Certificates (Let's Encrypt)
Before obtaining SSL certificates, make sure DNS records are configured and the domain points to your server.
Let's Encrypt verifies DNS when issuing a certificate.
sudo apt install -y certbot python3-certbot-nginxsudo certbot --nginx -d yourdomain.com -d www.yourdomain.comsudo systemctl status certbot.timersudo certbot renew --dry-runMonitoring and Logging
sudo apt install -y htopsudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.logdocker logs -f container_namesudo journalctl -u nginx -f
sudo journalctl -u docker -fBackups
#!/bin/bash
BACKUP_DIR="/backups/postgres"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
docker exec postgres pg_dump -U your_user your_db | gzip > $BACKUP_DIR/backup_$DATE.sql.gz
# Delete backups older than 7 days
find $BACKUP_DIR -name "backup_*.sql.gz" -mtime +7 -deletesudo chmod +x /usr/local/bin/backup-db.shsudo crontab -e
# Add: 0 3 * * * /usr/local/bin/backup-db.shFinal Check
Make sure everything is working before launching your application.
sudo ufw statusdocker --versionDetailed guide on this topic:
Read full article →