//Servers

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
When One VPS Beats Kubernetes: Simplify Your Production Stack

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:

  1. Web server / reverse proxy (Nginx or Apache) to terminate TLS, serve static assets, and route traffic.
  2. Application runtime (Node.js, Python, PHP, Java, etc.) that runs your code.
  3. Database (MySQL/MariaDB, PostgreSQL, or a NoSQL store) for persistent data.
  4. Process manager (systemd, Supervisor, or PM2) to keep the app alive and restart on failure.
  5. 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.

4.2 Basic TLS with Let’s Encrypt

Replace example.com with your domain.

Both families (certbot package differs)

# Debian/Ubuntu
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

# AlmaLinux/Rocky/RHEL
sudo dnf install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

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.

AlmaLinux/Rocky/RHEL

sudo dnf install -y mariadb-server
sudo systemctl enable --now mariadb

6.2 Secure the Installation

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;
}

Enable the site (Ubuntu) and reload Nginx:

# Debian/Ubuntu
sudo ln -s /etc/nginx/sites-available/yourapp.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

# AlmaLinux/Rocky/RHEL
sudo nginx -t && sudo systemctl reload nginx

8. Monitoring, Backups, and Maintenance

  • Health checks. Use systemctl status nginx, pm2 status, and mysqladmin ping to verify each service.
  • Log rotation. The default logrotate packages already rotate Nginx and system logs daily.
  • Automated backups. Schedule a nightly dump of the MariaDB database:
    0 2 * * * /usr/bin/mysqldump -u appuser -pStrongPassword! yourapp | gzip > /var/backups/yourapp-$(date +\%F).sql.gz
    
    Adjust the path and credentials as needed.
  • Fail2ban. Install to block repeated SSH brute‑force attempts:
    # Debian/Ubuntu
    sudo apt install -y fail2ban
    
    # AlmaLinux/Rocky/RHEL
    sudo dnf install -y fail2ban
    sudo systemctl enable --now fail2ban
    

9. When to Consider Moving to Kubernetes

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.

databasefirewallnginxnode.jsubuntualmalinuxserverweb‑application

Try it on your own server

Follow along on a Cloud VPS with full root access, or read the step-by-step knowledge base guides.