When One VPS Beats Kubernetes: Simplify Your Production Stack
Skip Kubernetes and run a production‑grade app on a single AtoZNode VPS: secure OS, firewall, Nginx, Node.js, MariaDB, PM2, backups, and monitoring.
6 min read
Running a production‑grade application does not always require a full Kubernetes cluster. For many small‑to‑medium projects—especially those hosted on a single VPS from AtoZNode—a well‑tuned traditional stack can be simpler, cheaper, and easier to manage. This article explains why you might skip Kubernetes, outlines the core components you’ll need, and provides step‑by‑step commands for both Debian/Ubuntu (APT) and AlmaLinux/Rocky/RHEL (DNF) environments.
1. When a Single VPS Is Sufficient
Before investing time in container orchestration, check whether your workload meets these criteria:
Predictable traffic. Modest, relatively stable request volumes that a single VPS can handle.
Limited services. A few tightly coupled components (e.g., web server, application runtime, database).
Simple scaling needs. Vertical scaling (adding CPU/RAM) or basic horizontal scaling (adding a second VPS) is enough.
Budget constraints. Managing a cluster adds operational overhead and cost that may not be justified for a modest project.
If these points describe your situation, a single VPS can provide the reliability you need without the complexity of Kubernetes.
2. Core Components of a Production‑Ready Stack
A typical web‑application stack on one VPS includes:
Web server / reverse proxy (Nginx or Apache) to terminate TLS, serve static assets, and route traffic.
Application runtime (Node.js, Python, PHP, Java, etc.) that runs your code.
Database (MySQL/MariaDB, PostgreSQL, or a NoSQL store) for persistent data.
Process manager (systemd, Supervisor, or PM2) to keep the app alive and restart on failure.
Firewall & monitoring (UFW/Firewalld, fail2ban, and basic health checks).
3. Setting Up the Environment
3.1 Update the System
Debian/Ubuntu (APT)
sudo apt update && sudo apt upgrade -y
# Updates the package index and installs the latest security patches.
AlmaLinux/Rocky/RHEL (DNF)
sudo dnf update -y
# Performs the same update process for the RHEL‑compatible distribution.
3.2 Install a Firewall
Debian/Ubuntu (UFW)
sudo apt install -y ufw
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full' # Opens ports 80 and 443
sudo ufw enable
# UFW is a simple front‑end for iptables; the rules permit SSH and web traffic.
AlmaLinux/Rocky/RHEL (Firewalld)
sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
# Firewalld manages zones and services; the commands open the same ports as above.
4. Installing the Web Server
4.1 Nginx (recommended as reverse proxy)
Debian/Ubuntu
sudo apt install -y nginx
sudo systemctl enable --now nginx
# Installs Nginx and starts it immediately; the service will launch on boot.
AlmaLinux/Rocky/RHEL
sudo dnf install -y nginx
sudo systemctl enable --now nginx
# Same steps for the RHEL family.
Certbot obtains a free certificate from Let’s Encrypt, configures Nginx to use it, and sets up automatic renewal.
5. Deploying the Application Runtime
The example below shows how to set up a Node.js application. Adjust the language/runtime according to your stack.
5.1 Install Node.js (LTS)
Debian/Ubuntu
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
# The script adds the NodeSource repository and installs the latest LTS version.
AlmaLinux/Rocky/RHEL
curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash -
sudo dnf install -y nodejs
# Same process using the RPM repository.
5.2 Clone Your Code and Install Dependencies
git clone https://github.com/youruser/yourapp.git /var/www/yourapp
cd /var/www/yourapp
npm ci # Installs exact versions from package-lock.json
5.3 Use a Process Manager (PM2)
PM2 keeps the Node process alive, restarts it on crashes, and can generate a systemd unit.
sudo npm install -g pm2
pm2 start index.js --name yourapp
pm2 save # Persists the process list
pm2 startup systemd # Generates a systemd service
sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u $USER --hp $HOME
# Registers PM2 with systemd for the current user.
6. Setting Up the Database
6.1 MariaDB (MySQL compatible)
Debian/Ubuntu
sudo apt install -y mariadb-server
sudo systemctl enable --now mariadb
# Installs MariaDB, the community‑maintained MySQL fork.
sudo mysql_secure_installation
# Prompts to set a root password, remove anonymous users, disallow remote root login,
# and delete test databases. Follow the interactive prompts.
6.3 Create an Application Database and User
sudo mysql -u root -p
CREATE DATABASE yourapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'StrongPassword!';
GRANT ALL PRIVILEGES ON yourapp.* TO 'appuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Replace StrongPassword! with a strong, unique password. Your app’s configuration file should reference this user.
7. Configuring Nginx as a Reverse Proxy
Create a site configuration that forwards traffic to the Node.js process listening on localhost:3000.
# Debian/Ubuntu: /etc/nginx/sites-available/yourapp.conf
# AlmaLinux/Rocky/RHEL: /etc/nginx/conf.d/yourapp.conf
server {
listen 80;
server_name example.com www.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
# Optional: redirect HTTP to HTTPS if Certbot did not add the rule automatically
return 301 https://$host$request_uri;
}
If any of the following become true, revisiting container orchestration may be worthwhile:
Traffic spikes demand rapid horizontal scaling across many nodes.
Multiple microservices need independent lifecycle management.
Advanced traffic routing, canary releases, or zero‑downtime deployments are required.
Regulatory or operational policies mandate immutable infrastructure.
At that point, you can migrate individual components (e.g., containerize the app, use a managed database) while keeping the existing VPS as a node in a larger cluster.
Conclusion
A single, well‑configured VPS can host a production‑grade web‑application stack without the overhead of Kubernetes. By securing the server, installing a reverse proxy, managing processes with systemd or PM2, and isolating the database, you achieve reliability, performance, and ease of maintenance. Start with the steps outlined above, monitor resource usage, and adopt Kubernetes only when your architecture truly outgrows a single‑node environment.