VPS management for web developers

VPS management for web developers: you need some CLI, not a PhD

We may earn an affiliate commission through purchases made from our guides and tutorials.

You can run a stable, secure Virtual Private Server (VPS) with a small toolkit of command-line skills. You will sign in with Secure Shell (SSH), explore the filesystem, edit configuration files, deploy or restart services, and keep the box patched. The point is not to memorize hundreds of commands; it is to recognize patterns and apply a few reliable workflows repeatedly. Once you internalize those, everything else becomes a variant.

Connect with SSH the right way

Use SSH keys rather than passwords. On your laptop, create a key, then copy the public part to the server account you will use. Disable password logins only after the key works, then keep a second session open before you change anything, so you cannot lock yourself out. Key-based auth is standard practice and is both simpler and safer once set up.

# On your laptop
ssh-keygen -t ed25519 -C "your-email"    # accept defaults for a first key
ssh-copy-id [email protected]        # or: cat ~/.ssh/id_ed25519.pub | ssh [email protected] 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'

# First login
ssh [email protected]

# Harden SSH on the server *after* key login works
sudo grep -RP '^(?<!#)\s*PasswordAuthentication' /etc/ssh/sshd_config /etc/ssh/sshd_config.d
sudoeditor=/usr/bin/nano sudo $sudoeditor /etc/ssh/sshd_config
# set: PasswordAuthentication no
# optionally: PermitRootLogin prohibit-password
sudo systemctl restart ssh

Disabling password authentication (after keys are in place) reduces credential-stuffing risk. Be aware that on some cloud images a drop-in file in /etc/ssh/sshd_config.d/ can re-enable passwords; check and override it explicitly.

Lock down basics with a firewall and bans

A host firewall limits inbound traffic to the services you intend to expose. On Ubuntu, UFW (Uncomplicated Firewall) makes rule management straightforward. Enable SSH first, then enable the firewall; later, allow ports for HTTP/HTTPS or anything else you run.

# Allow SSH before enabling the firewall
sudo ufw allow OpenSSH
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable
sudo ufw status verbose

To slow brute-force logins, install Fail2ban. It tails logs and temporarily bans IPs that fail authentication repeatedly, which lowers noise and reduces risk. Start with the SSH jail, then tune ban times as you observe traffic.

sudo apt update && sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudoeditor=/usr/bin/nano sudo $sudoeditor /etc/fail2ban/jail.local
# in [sshd]: enabled = true
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

Navigate the filesystem with confidence

You will spend most of your time listing, searching, and peeking into files. Learn these patterns: print where you are, list smartly, and search precisely. Then pivot: pipe to a pager to read and to grep to filter. These primitives are stable across all Linux distributions.

pwd                               # show working directory
ls -al                            # long list, including dotfiles
cd /etc/nginx/sites-available     # move directly to a path

# Search for files by name, type, or size (examples)
find /var/www -type f -name '*.php'
find /var/log -type f -size +10M
find /etc -type f -iname '*nginx*' 2>/dev/null

find scales to real systems and supports filters like type, name (case-insensitive with -iname), and size. Use -exec to act on matches safely. Redirect errors (2>/dev/null) when traversing directories you cannot read.

Read and edit files without fear

Use a pager to inspect files and an editor you actually like to make changes. less opens instantly and supports search; nano keeps keystrokes discoverable; vim is powerful once you learn save/quit. Start with less for browsing, then nano for edits.

# Browse
sudo less /var/log/nginx/error.log          # space = down, g/G = top/bottom, /text = search
head -n 50 /etc/nginx/nginx.conf            # first lines
tail -n 50 /var/log/syslog                  # last lines
tail -f /var/log/nginx/access.log           # follow in real time

# Edit (nano): write and exit cleanly
sudo nano /etc/nginx/sites-available/example.conf
# Ctrl+O (write out), Enter (confirm), Ctrl+X (exit)

# Edit (vim): save and quit
sudo vim /etc/nginx/nginx.conf
# :wq to save and quit, :q! to quit without saving

If you only change one line, prefer a small, reversible edit and keep a backup in place. For example, duplicate the config file before modifications, then compare with diff if something breaks. That habit makes rollbacks instantaneous.

sudo cp /etc/nginx/nginx.conf{,.bak-$(date +%F)}
sudo diff -u /etc/nginx/nginx.conf{.bak-$(date +%F),}

Move files between your laptop and the VPS

For ad-hoc transfers, scp (secure copy) mirrors the mental model of cp: source, then destination. For repeatable or large transfers, use rsync over SSH to send only changed bytes and resume when connections blip. Both inherit SSH authentication and encryption.

# Copy from laptop to server
scp ./build.tar.gz [email protected]:/var/www/

# Copy from server to laptop
scp [email protected]:/var/log/nginx/error.log ./logs/

# Sync a directory, preserving metadata, showing progress, deleting stale files on the far side
rsync -avz --delete ./site/ [email protected]:/var/www/site/

rsync can serve as a quick backup. Add --exclude patterns for ephemeral paths and run it from cron to snapshot changed content on a schedule.

Manage services, check status, and restart safely

Most modern distributions use systemd. You will start, stop, enable at boot, and check logs for units such as nginx, php-fpm, or your app. The pattern is consistent: systemctl <verb> <unit>, plus a quick status or journal tail to verify outcomes.

# Service life cycle
sudo systemctl status nginx
sudo systemctl restart nginx
sudo systemctl enable --now nginx

# Read recent service logs
sudo journalctl -u nginx --since "30 min ago"

When you deploy, prefer “reload” if the service supports it, because reload applies new configuration without dropping current connections. When in doubt, check status and journalctl first to avoid restarting a healthy service unnecessarily.

Keep the server patched

Security updates close known holes. On Ubuntu, enable unattended upgrades for security fixes and then review logs or email notifications. For interactive maintenance windows, you can still run updates manually and reboot when the kernel or critical libraries change.

# Manual update
sudo apt update && sudo apt upgrade

# Enable automatic security updates (if not already)
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

The implication is simple: most compromises exploit old software, not novel zero-days. Automating baseline updates and checking once a week keeps your risk low without extra work.

Permissions and ownership without surprises

File permissions govern who can read, write, or execute. You will change ownership when a deployment writes files as one user but the service reads them as another, and you will set execution only on scripts that need it. Keep changes as narrow as possible and audit with ls -l. Red Hat’s primer explains why this matters for server security.

# Make web content owned by the web server user and group
sudo chown -R www-data:www-data /var/www/site

# Grant owner read/write, group read, others none, recursively
sudo chmod -R 640 /var/www/site

# Mark a script as executable
chmod +x ./deploy.sh

When something “works on my machine” but fails on the VPS, suspect ownership or mode first. A quick ls -al in the problem directory often answers it in seconds.

Apply the patterns to a tiny real world task

Goal: Serve a static site with Nginx, with a firewall and key-only SSH, and confirm logs are flowing.

  1. Prep and security. Add your key, disable SSH passwords, enable UFW with SSH allowed. Verify you can reconnect with keys and that ufw status lists OpenSSH.
  2. Install service. sudo apt install nginx && sudo systemctl enable --now nginx. Check systemctl status nginx and browse to the server IP.
  3. Open the web ports. sudo ufw allow 80,443/tcp. Recheck sudo ufw status verbose.
  4. Deploy content. scp -r ./dist/ [email protected]:/var/www/site/ and create a simple server block in /etc/nginx/sites-available/site.conf; symlink to sites-enabled, then sudo nginx -t && sudo systemctl reload nginx.
  5. Observe. sudo tail -f /var/log/nginx/access.log and hit the site to see live requests. less the error log if the config check fails.

A few commands, reused in sequence, carry most of the work.

Troubleshoot quickly and safely

First, reproduce and read. The fastest triage loop is: check the service status, read recent logs, verify the file you edited, and roll back if needed. Second, isolate scope: if the web is down, does curl -I http://127.0.0.1 work locally? Third, change one thing at a time and keep a shell open for recovery. The tools above exist to keep feedback immediate and reversible.

Quick reference you will actually use

  • Connect: ssh, keys first, then disable passwords when confirmed.
  • Explore: pwd, ls -al, find /path -type f -name '*.conf'.
  • Read: less file, tail -f log, journalctl -u service.
  • Edit: nano file (Ctrl-O, Enter, Ctrl-X) or vim (:wq).
  • Transfer: scp local remote:dest, rsync -avz dir/ remote:dest/.
  • Services: systemctl status|restart|enable nginx.
  • Firewall: ufw allow OpenSSH && ufw enable, then app ports.
  • Updates: apt update && apt upgrade, enable unattended upgrades.

You now have the minimum viable CLI to manage a VPS: connect securely, read and edit with confidence, move files, control services, and keep the host patched and filtered. Practice these workflows on a staging droplet or VM, and you will be ready to operate production calmly.

References & manuals

Linux ships with manual pages (“man pages”), which are built-in reference documents for almost every command. You access them with the man command followed by the tool’s name. Each page explains syntax, options, and examples. Man pages are terse by design, but they are authoritative and available on every server. Online mirrors also exist, which makes them easy to read in a browser.

  • man ssh: documents the Secure Shell client, including authentication options and connection flags.
  • man sshd_config: details all directives available in the SSH server configuration file.
  • man ls: covers listing options, from showing dotfiles to sorting by time or size.
  • man find: explains filters such as -type, -name, -mtime, and actions with -exec.
  • man less: describes navigation, searching, and options for paging through files.
  • man nano and man vim: provide editor commands and configuration flags.
  • man scp and man rsync: outline secure file transfer syntax and advanced synchronization options.
  • man systemctl: describes how to start, stop, reload, and inspect services under systemd.
  • man ufw: shows usage of the Uncomplicated Firewall command-line interface.
  • man apt: documents the package manager used on Debian/Ubuntu to install and update software.
  • man chmod and man chown: explain file permissions and ownership changes.

Whenever you forget a flag or need to confirm exact behavior, run man <command> in the VPS itself. Online versions like man7.org or Ubuntu’s manpages.ubuntu.com mirror the same content and are easier to browse or bookmark.

Was this helpful?

Thanks for your feedback!
Alex is the resident editor and oversees all of the guides published. His past work and experience include Colorlib, Stack Diary, Hostvix, and working with a number of editorial publications. He has been wrangling code and publishing his findings about it since the early 2000s.

Leave a comment

Your email address will not be published. Required fields are marked *