Technology

Running a VPS Without a Control Panel Over SSH Only

If you are comfortable with a terminal and you want full control over your infrastructure, running a VPS without a control panel is often the cleanest and most efficient option. No extra daemons, no auto-generated configs you do not understand, no mystery resource usage. Just Linux, SSH and the exact services you choose. In this article, I will walk through how we at dchost.com approach SSH-only VPS setups for real projects: from first login and hardening, to configuring Nginx and PHP, to deploying websites using Git, rsync or simple file sync. The goal is not to turn you into a Linux guru overnight, but to give you a practical, reproducible checklist you can apply every time you get a new VPS. Whether you are hosting a single client site, a small Laravel or Node.js app, or a lean WordPress installation, you will see how to keep everything manageable, secure and well-documented without ever touching a hosting control panel.

İçindekiler

What “No Control Panel” Really Means on a VPS

Let us first clarify what we mean by running a VPS without a control panel. You still have an operating system, system services and a web stack. The difference is that you install and manage everything directly over SSH instead of through cPanel, DirectAdmin or Plesk.

In practice, this usually means:

  • You connect via SSH to manage the server instead of using a browser-based panel.
  • You install packages with your distro’s package manager (for example, apt or dnf).
  • You configure services (Nginx, Apache, PHP-FPM, databases) using text files under /etc.
  • You create and manage system users, SSH keys and permissions yourself.
  • You handle deployments with tools like Git, rsync, SFTP or CI/CD pipelines.

This approach makes the most sense when you:

  • Run a small number of sites or applications and prefer a minimal footprint.
  • Care about understanding exactly what runs on your VPS.
  • Want maximum flexibility for custom stacks (Node.js, Go, containers, etc.).
  • Are comfortable with Linux basics and willing to document your setup.

If you are unsure which Linux distribution to start with, I strongly recommend reading our guide on choosing a Linux distro for your VPS. It will help you pick a platform that matches both your habits and your long-term maintenance needs.

Prerequisites: Skills and Mindset for SSH‑Only Hosting

Before going panel-free, it helps to be honest about the skills you already have and those you need to build. You do not need to be a kernel developer, but you should be comfortable with a few fundamentals.

Core Linux and SSH skills

At minimum, you should know how to:

  • Navigate directories with cd, ls, pwd and manage files with cp, mv, rm.
  • Edit configuration files with nano or vim.
  • Use sudo safely and understand the difference between root and a normal user.
  • Generate SSH keys (ssh-keygen) and use ssh, scp, sftp.
  • Start, stop and inspect services using systemctl and journalctl.

Networking and DNS basics

You will also need a basic understanding of:

  • Public IP addresses, ports (22 for SSH, 80 for HTTP, 443 for HTTPS), and firewalls.
  • DNS A/AAAA records and how to point your domain to your VPS IP.
  • What an SSL/TLS certificate is and why you need one for HTTPS.

If DNS concepts are still fuzzy, bookmark our detailed guide to DNS records explained from A to Z and refer back whenever you are wiring domains to your VPS.

Version control and deployments

You do not strictly need Git to deploy over SSH, but it makes your life much easier. Ideally you:

  • Track your website or application code in a Git repository.
  • Tag releases or at least keep a clean main / master branch.
  • Are open to using simple deployment scripts or CI/CD later on.

Step 1: Initial VPS Setup and Security Hardening

Once your dchost.com VPS is provisioned and you have the root credentials, your first tasks are always the same: log in, create a non‑root user, lock down SSH and set up a basic firewall. A few minutes of discipline here will save you from a lot of noise and risk later.

1. Log in as root and update the system

ssh root@your-server-ip

# On Debian/Ubuntu
apt update && apt upgrade -y

# On AlmaLinux/Rocky Linux
yum update -y  # or dnf update -y

2. Create a non‑root sudo user

adduser deploy
usermod -aG sudo deploy   # on Debian/Ubuntu
# or
usermod -aG wheel deploy  # on RHEL-family

From now on, you will log in as deploy (or whatever name you choose) and only use sudo when necessary.

3. Set up SSH keys and disable password logins

On your local machine:

ssh-keygen -t ed25519 -C '[email protected]'
ssh-copy-id deploy@your-server-ip

Then harden SSH on the server by editing /etc/ssh/sshd_config:

PermitRootLogin no
PasswordAuthentication no

Reload SSH:

sudo systemctl reload sshd

For a deeper dive into hardening SSH itself (hardware keys, SSH CA, key rotation) you can follow our playbook in VPS SSH hardening without the drama.

4. Configure a simple firewall

On Debian/Ubuntu, ufw is a great starting point:

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 enable

On RHEL-family distros, you can use firewalld or go more advanced later with nftables.

5. Add basic intrusion protection

Tools like Fail2ban watch logs for repeated failed logins and temporarily block abusive IPs. On Debian/Ubuntu:

sudo apt install fail2ban -y

Use the default jail for SSH to start, and tune later as you add services.

If you want a broader, step-by-step checklist covering firewalls, patching, intrusion detection and more, our article how to secure a VPS server without leaving the door open is written exactly for this phase.

Step 2: Build a Lean Web Stack Without a Panel

With a secure base, you can now install the components that actually serve your websites. I will assume a common stack:

  • Nginx as the web server and reverse proxy
  • PHP-FPM for PHP applications like WordPress and Laravel
  • MariaDB or MySQL for databases (PostgreSQL is also an option)

Install Nginx, PHP-FPM and MariaDB

On Debian/Ubuntu:

sudo apt install nginx php-fpm php-mysql mariadb-server -y

On AlmaLinux/Rocky Linux, package names will differ slightly (for example php-fpm, php-mysqlnd, mariadb-server via dnf).

Enable and start the services:

sudo systemctl enable nginx php-fpm mariadb
sudo systemctl start nginx php-fpm mariadb

Secure the database minimally

Run the secure installation script:

sudo mysql_secure_installation

Set a strong root password, remove anonymous users and test databases, and disable remote root login unless you have a specific reason to keep it.

Create a web root and user-friendly structure

A clear directory structure makes SSH-only management far easier. A common pattern:

/var/www/
  example.com/
    current/      # active release
    releases/     # older releases (optional, for zero-downtime)
    shared/       # uploads, env files, logs

Create the base directories and set permissions:

sudo mkdir -p /var/www/example.com/current
sudo chown -R deploy:www-data /var/www/example.com
sudo chmod -R 750 /var/www/example.com

Replace www-data with your web server user if different (on some distros it is nginx).

Configure an Nginx server block (virtual host)

Create a new config file, for example /etc/nginx/sites-available/example.com.conf:

server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/example.com/current/public;
    index index.php index.html;

    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php-fpm.sock;
    }

    location ~* /.(git|env|htaccess)$ {
        deny all;
    }
}

Enable the site and reload Nginx:

sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

At this point, Nginx will serve whatever you place inside /var/www/example.com/current, even if it is just a static index.html.

Step 3: Deploying Websites Over SSH Only

With the web stack ready, the main question becomes: how do you get your code onto the server, and how do you update it safely? There is no control panel file manager, so your deployment flow matters a lot.

Option A: Simple SFTP or SCP for small, infrequent sites

For a basic static site or a rarely updated brochure site, SFTP is often enough. You can use tools like FileZilla, WinSCP or the sftp command-line client:

sftp deploy@your-server-ip
sftp> cd /var/www/example.com/current
sftp> put -r /local/path/to/site/*

Pros: very simple, no extra setup. Cons: easy to drift from Git, easy to forget which files changed, hard to roll back quickly.

Option B: rsync over SSH for repeatable file sync

rsync is ideal when you want fast, incremental uploads and the ability to mirror your local directory to the server:

rsync -avz --delete 
  /local/project/ 
  deploy@your-server-ip:/var/www/example.com/current/

Key flags:

  • -a: archive mode (preserves permissions, timestamps, etc.).
  • -v: verbose output.
  • -z: compress during transfer.
  • --delete: remove files on the server that you deleted locally.

You can wrap this in a small shell script (for example, deploy.sh) and commit it to your repo so everyone uses the same process.

Option C: Git-based deployments (push to your VPS)

For anything more than a toy project, I strongly prefer Git-based deployments. The simplest pattern is:

  1. Create a bare Git repository on the VPS.
  2. Configure a post-receive hook that checks out the latest code to current/.
  3. Push from your local machine to the VPS remote.

On the server:

sudo -u deploy mkdir -p /var/www/example.com/repo.git
cd /var/www/example.com/repo.git
sudo -u deploy git init --bare

Create hooks/post-receive (owned by deploy):

#!/bin/bash
set -e
TARGET="/var/www/example.com/current"
GIT_DIR="/var/www/example.com/repo.git"
TMP_DIR="/var/www/example.com/tmp-deploy-$$"

mkdir -p "$TMP_DIR"
GIT_WORK_TREE="$TMP_DIR" git --git-dir="$GIT_DIR" checkout -f main

# Run build steps here if needed (npm build, composer install, etc.)
# For example, for a PHP app:
# cd "$TMP_DIR" && composer install --no-dev --optimize-autoloader

rm -rf "$TARGET"
mv "$TMP_DIR" "$TARGET"
sudo chmod +x /var/www/example.com/repo.git/hooks/post-receive

On your local machine, add a remote and push:

git remote add production deploy@your-server-ip:/var/www/example.com/repo.git
git push production main

Each push will trigger the hook and update your site. For more sophisticated zero-downtime rollouts with symlinked releases, you can build on the patterns we share in our zero-downtime CI/CD to a VPS guide.

Option D: CI/CD from GitHub, GitLab or your own runner

Once you are comfortable deploying manually, adding a CI/CD pipeline is the natural next step. The general flow looks like this:

  • On push to main or on a tagged release, your CI pipeline runs tests and builds assets.
  • If everything passes, CI connects to your VPS via SSH.
  • It either runs your rsync script or pushes to the bare repo, possibly with environment-specific steps.

This keeps deployments repeatable and makes it easy for teammates to ship changes without shell access to the server.

Step 4: Domains, HTTPS and Logs Without a Panel

A control panel normally hides domain pointing, SSL and log access behind nice buttons. On an SSH-only VPS, you do the same things manually, but they are not complicated once you see the pattern.

Point your domain to the VPS

At your domain registrar or DNS provider, create:

  • An A record for example.com pointing to your VPS IPv4.
  • An optional AAAA record pointing to your IPv6 if your VPS has one.
  • A CNAME or additional A record for www.example.com if you want it.

After DNS propagation (often a few minutes if TTLs are low), visiting http://example.com should hit your Nginx server block.

Obtain a free Let’s Encrypt certificate via SSH

On Debian/Ubuntu, the certbot package makes this easy:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d example.com -d www.example.com

Certbot will:

  • Validate domain ownership using HTTP-01 challenge.
  • Obtain a certificate.
  • Update your Nginx config to use HTTPS and redirect HTTP to HTTPS.
  • Install a cron job or systemd timer for auto-renewal.

If you later need wildcards or more advanced DNS-01 flows at scale, we cover this in detail in our article about Let’s Encrypt wildcard automation and DNS challenges (linked from other posts).

Understand where logs live and how to read them

Without a panel, logs are your main observability tool. For a typical Nginx + PHP-FPM stack:

  • /var/log/nginx/example.com.access.log – all HTTP requests.
  • /var/log/nginx/example.com.error.log – Nginx and upstream errors.
  • journalctl -u php-fpm – PHP-FPM service logs.
  • journalctl -u nginx – Nginx service logs.

Simple commands you will use a lot:

sudo tail -f /var/log/nginx/example.com.error.log
sudo journalctl -u nginx -f

As your stack grows, you may want centralised log collection and alerts; we explore those patterns in various monitoring and log management guides on our blog.

Step 5: Backups, Updates and Ongoing Maintenance

Control panels often come with built-in backup wizards, update buttons and monitoring widgets. On an SSH-only VPS, you must consciously design these routines yourself. The good news: you can make them simpler and more reliable than many default panel setups.

Back up both data and configuration

A solid backup strategy always includes:

  • Database backups (for example, mysqldump exports for MariaDB/MySQL).
  • Application files (code, uploads, configs). Usually your /var/www/ tree.
  • Offsite copies (to another VPS, S3-compatible storage, or a backup service).

Example quick-and-dirty backup script (run via cron):

#!/bin/bash
set -e
BACKUP_DIR="/var/backups/example.com/$(date +%F)"
mkdir -p "$BACKUP_DIR"

# Database
mysqldump -u root -p'STRONGPASS' exampledb > "$BACKUP_DIR/db.sql"

# Files
rsync -a /var/www/example.com/ "$BACKUP_DIR/www/"

For a more robust, automated approach (including storing backups on remote storage), study our article on the 3‑2‑1 backup strategy and automating backups on a VPS. The same principles apply perfectly to SSH-only servers.

Keep the OS and packages updated

Set a recurring reminder (or cron job) to update your system:

# Debian/Ubuntu
sudo apt update && sudo apt upgrade -y

# AlmaLinux/Rocky
sudo dnf update -y

Security updates should not be postponed for months. For critical servers, you can enable unattended security upgrades, but always keep an eye on change logs and be ready to roll back in case of rare regressions.

Monitor resource usage and basic health

Even simple tools can give you a good feel for the health of your SSH-only VPS:

  • top or htop – CPU and memory usage.
  • df -h – disk space.
  • free -h – memory and swap usage.
  • systemctl status – check that core services are active.

As traffic grows, consider adding proper monitoring and alerting (Prometheus, Grafana, external uptime checks) so you do not have to babysit the terminal all day.

When a Control Panel Still Makes Sense

Running everything over SSH is powerful, but it is not the right tool for every team or project. In our experience at dchost.com, a graphical control panel can still be a better fit when:

  • You host dozens or hundreds of small sites for non-technical clients.
  • You need to delegate email, DNS, FTP and database access to many different users.
  • Your internal team is more comfortable with web interfaces than the terminal.
  • You value the convenience of wizards for tasks like email setup and one-click installers.

The nice part is that your choice is not permanent. You can start with an SSH-only VPS for your core applications, and later add a panel on another VPS for multi-tenant hosting, or the other way around. Our infrastructure at dchost.com is built to support both models: lean SSH-only VPS setups for developers who want full control, and panel-based hosting for agencies and businesses that need delegation and convenience.

Practical Workflow Tips That Make SSH‑Only Hosting Comfortable

Before we wrap up, here are a few patterns we see consistently working well for teams that live on SSH-only VPS servers.

Standardise your layout and scripts

Pick a directory layout and stick to it across all projects (for example, the current/releases/shared pattern). Use the same user name for deployments (for example, deploy) on all servers. Create small, well-documented scripts for common tasks:

  • deploy.sh – runs rsync or Git-based deployment.
  • backup.sh – dumps the database and syncs files.
  • logs.sh – tails the most relevant logs for that app.

Commit these scripts into each project’s repository so they live alongside your code.

Use systemd units for background jobs

Instead of running ad-hoc background commands inside a screen or tmux session, define systemd services and timers. For example, to run a Laravel queue worker or a Node.js process, create a unit file under /etc/systemd/system/, enable it, and let systemd handle restarts and logs. It is cleaner, more debuggable, and easier to document.

Take SSH security seriously from day one

SSH is your single front door in an SSH-only world. Beyond disabling passwords and root logins, consider:

  • Using FIDO2 hardware keys for SSH authentication.
  • Setting up an internal SSH certificate authority if you have many servers.
  • Rotating keys regularly and revoking access promptly when people leave.

We walk through these patterns with real examples in our detailed guide on VPS SSH hardening without the drama, which is worth a careful read if SSH-only is your primary access method.

Conclusion: A Clean, Controllable Way to Run Your Websites

Running a VPS without a control panel and deploying websites over SSH only is not about being “more hardcore” than everyone else. It is about clarity. You know exactly which packages are installed, which processes listen on which ports, how your code gets onto the server and where your logs and backups live. For many developers and small teams, this simplicity is a relief compared to the opaque layers that panels sometimes add.

The trade-off is that you must take responsibility for security, backups, monitoring and deployments. The good news is that these responsibilities are manageable once you break them into checklists: harden SSH, keep the OS updated, use Git or rsync for deployments, test your backups and practice restores. If you want a structured view of backup planning specifically, our article on the 3‑2‑1 backup strategy on VPS is a great next step.

At dchost.com, our VPS, dedicated server and colocation services are built to support exactly this style of hosting: clean, predictable Linux machines with full root access, proper network and power redundancy, and the freedom to choose whether you ever install a control panel at all. Start with a modest VPS, apply the patterns in this article on top of our infrastructure, and you will have a fast, understandable and future-proof environment for your websites and applications.

Frequently Asked Questions

Yes, running a VPS without a control panel can be very safe, often safer than panel-based setups, as long as you follow good practices. You must harden SSH (disable password logins and root access, use keys), keep the operating system and packages updated, enable a firewall, and add basic intrusion protection such as Fail2ban. The main difference is that you configure these elements yourself instead of relying on panel defaults. Our team strongly recommends starting with a clear security checklist so that every new SSH-only VPS is configured consistently.

You have several options for deploying updates over SSH. For simple static or rarely changed sites, SFTP or SCP is enough: you manually upload new files to the web root. For more repeatable deployments, use rsync over SSH to synchronise your local project directory with the server, ideally via a small deploy script. For serious projects, consider Git-based deployments: push to a bare repo on the VPS and let a post-receive hook update the live directory. You can then integrate this with CI/CD so tests run before any code hits production.

You can obtain free Let’s Encrypt certificates entirely over SSH using tools like certbot or acme.sh. After pointing your domain’s DNS A/AAAA records to your VPS, install certbot from your package manager and run a command such as `certbot --nginx -d example.com -d www.example.com`. Certbot will validate domain ownership, obtain the certificate, and can auto-configure Nginx or Apache for HTTPS, including HTTP-to-HTTPS redirection and automated renewal. This approach works perfectly on SSH-only VPS setups and avoids any need for a control panel.

A control panel is often better when you host many small, unrelated sites for non-technical clients, need to delegate email, FTP and database access to different people, or want non-technical staff to manage domains and mailboxes. Panels like cPanel or DirectAdmin make it easy to create isolated accounts, run one-click applications and handle email. By contrast, SSH-only setups shine when you have a small number of applications, prefer a minimal stack, and have the Linux skills to manage services directly. Many teams use both models: panel hosting for multi-tenant sites and SSH-only VPSs for core apps.

On an SSH-only VPS, you design your own backup routines. At a minimum, you should regularly dump your databases (for example using mysqldump for MariaDB/MySQL), back up your application directories (code, uploads, configuration) and store at least one copy offsite on another server or S3-compatible storage. You can script this process with rsync, tar and cron so backups run automatically. Following the 3‑2‑1 rule (three copies, two different media, one offsite) is a practical way to minimise risk. Periodically testing a full restore to another VPS is just as important as creating the backups themselves.