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
- 1 What “No Control Panel” Really Means on a VPS
- 2 Prerequisites: Skills and Mindset for SSH‑Only Hosting
- 3 Step 1: Initial VPS Setup and Security Hardening
- 4 Step 2: Build a Lean Web Stack Without a Panel
- 5 Step 3: Deploying Websites Over SSH Only
- 6 Step 4: Domains, HTTPS and Logs Without a Panel
- 7 Step 5: Backups, Updates and Ongoing Maintenance
- 8 When a Control Panel Still Makes Sense
- 9 Practical Workflow Tips That Make SSH‑Only Hosting Comfortable
- 10 Conclusion: A Clean, Controllable Way to Run Your Websites
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,
aptordnf). - 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,pwdand manage files withcp,mv,rm. - Edit configuration files with
nanoorvim. - Use
sudosafely and understand the difference between root and a normal user. - Generate SSH keys (
ssh-keygen) and usessh,scp,sftp. - Start, stop and inspect services using
systemctlandjournalctl.
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/masterbranch. - 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:
- Create a bare Git repository on the VPS.
- Configure a
post-receivehook that checks out the latest code tocurrent/. - 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
mainor 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
rsyncscript 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.compointing 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.comif 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,
mysqldumpexports 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:
toporhtop– 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.
