~/tutorials $
Linux server tutorials
Step-by-step tutorials for a Linux server: VPNs, web servers, databases, containers, security and backups. Each one names the distributions it was tested on.
45 tutorials
AlmaLinux vs Rocky Linux: which should you choose for a server?
AlmaLinux and Rocky Linux both rebuild Red Hat Enterprise Linux for free. What actually differs, which runs your software, and how to pick one in a minute.
Automate snapshots before risky changes with the CLI
A small script that takes a VPSNine snapshot with the vps9 CLI, waits until it is ready and rotates old ones, then runs your risky change.
Cron vs systemd timers: how to schedule jobs on Linux
Schedule a recurring job both ways, with a crontab line and with a systemd timer, and pick the right one for logging, missed runs and random delays.
How to check open ports on Linux with ss and nmap
List the ports your server listens on with ss, find which program owns each one, then scan the server from outside with nmap to see what the internet can reach.
How to configure firewalld on AlmaLinux and Rocky Linux
Turn on firewalld, open services and ports for good, limit SSH to your own addresses with a zone, and use rich rules, without locking yourself out.
How to create a sudo user and disable root login on Ubuntu and Debian
Add a normal user with sudo rights on Ubuntu or Debian, give it your SSH key, then stop root logging in over SSH without locking yourself out.
How to create a sudo user on AlmaLinux and Rocky Linux
Add a user to the wheel group on AlmaLinux or Rocky Linux, give it your SSH key with the right SELinux labels, and turn off root logins over SSH.
How to find what's using disk space on Linux and free it safely
Find what filled your server's disk with df, du and ncdu, then safely clean package caches, logs, old kernels and deleted files still held open.
How to host a static website with nginx on Ubuntu or Debian
Serve a static site with nginx from your own server, with clean URLs, gzip, HTTP/2, the right caching headers and one-command deploys with rsync.
How to install and secure MariaDB on Ubuntu 24.04
Install MariaDB on Ubuntu 24.04, answer mariadb-secure-installation correctly, give each app its own user and keep port 3306 private.
How to install Node.js on Ubuntu 24.04
Three ways to install Node.js on Ubuntu 24.04, NodeSource, nvm and Ubuntu's own package, which one to pick, and how to update or switch versions later.
How to install PostgreSQL on Ubuntu 24.04 and keep it private
Install PostgreSQL 16 from Ubuntu or 18 from the PostgreSQL repository, create a role and a database, and connect safely over an SSH tunnel.
How to monitor a Linux server with Netdata
Install Netdata for per-second CPU, memory, disk and network charts, keep its dashboard private behind an SSH tunnel, and get its built-in alerts.
How to point a domain at your VPS (A and AAAA records)
Point your domain at your server with A and AAAA records, add www, pick a sensible TTL, and check with dig that the change has really taken effect.
How to read logs with journalctl
Find the log lines you need with journalctl, by service, time, priority and boot, keep logs across reboots, and cap how much disk the journal uses.
How to set the time zone, hostname and NTP on a Linux server
Set a server's time zone with timedatectl, give it a proper hostname, and keep its clock in sync with chrony or systemd-timesyncd, then check it really is.
Self-host Uptime Kuma with Docker and HTTPS
Run Uptime Kuma 2 in Docker Compose, claim it privately over an SSH tunnel, put Caddy in front for HTTPS, then add monitors, alerts and a status page.
Use curl and jq with the VPSNine API
Drive the VPSNine API from a shell with curl and jq: filter servers, take snapshots and wait for them, read errors, page invoices, edit the firewall.
Deploy a FastAPI app with Gunicorn, Uvicorn workers and systemd
Run a FastAPI app in a virtualenv under Gunicorn with Uvicorn workers, keep it up with a systemd service, and put nginx in front as a reverse proxy.
Deploy a Node.js app with PM2 and nginx on Ubuntu 24.04
Run a Node.js app under its own user with PM2, bring it back after reboots, put nginx in front as a reverse proxy, and ship updates without downtime.
Deploy on push with GitHub Actions and the VPSNine API
Build on every push to main in GitHub Actions, snapshot the VPSNine server through the API, then ship with rsync over SSH and switch releases atomically.
Get Slack and Discord alerts from VPSNine webhooks
VPSNine has no Slack or Discord integration, so run a tiny relay that verifies webhook signatures and posts alerts and events to your channels.
How to automate BorgBackup with borgmatic to a second server
Back up files and databases to a second server over SSH with borgmatic: an append-only key, one YAML config, retention, checks and a daily timer.
How to back up a Linux server with restic to S3 storage
Encrypted nightly backups to any S3-compatible bucket with restic: database dumps, a systemd timer, a retention policy and a tested restore.
How to get a Let's Encrypt wildcard certificate with the DNS challenge
Get a free *.example.com certificate from Let's Encrypt with certbot or acme.sh and your DNS provider's API, renew it automatically and reload your web server.
How to install and secure Redis on Ubuntu 24.04
Install Redis on Ubuntu 24.04, keep it on localhost, replace the open default user with ACL users, block dangerous commands and cap its memory.
How to install CrowdSec on Ubuntu and Debian
Install the CrowdSec engine and its nftables firewall bouncer, watch SSH and nginx logs, allowlist your own addresses, and see what it blocks.
How to send email from a VPS through an SMTP relay
Send your server's mail (alerts, cron output, app email) through an SMTP relay on port 587 with Postfix, so it's delivered without running a full mail server.
How to set up a WireGuard VPN server on AlmaLinux and Rocky Linux
Install WireGuard on AlmaLinux or Rocky Linux, write wg0.conf, route clients through the server with firewalld masquerading, and connect your devices.
How to set up a WireGuard VPN server on Ubuntu 24.04
Install WireGuard on Ubuntu 24.04, write the server config, route clients' traffic through it and connect a laptop and a phone.
How to troubleshoot high CPU and memory usage on a Linux server
Find the process behind high CPU or memory use with top, ps, vmstat and pidstat, read load average and steal time correctly, and spot the OOM killer.
How to upgrade Debian 12 (bookworm) to Debian 13 (trixie)
Upgrade a Debian 12 server to Debian 13 in place, the way the release notes describe, with a snapshot to fall back on and checks before and after.
How to upgrade Ubuntu 22.04 to 24.04 LTS safely
Upgrade an Ubuntu 22.04 server to 24.04 LTS in place with do-release-upgrade, with a snapshot first, a backup SSH port, and checks for what changes.
How to use Caddy as a reverse proxy for multiple sites and apps
One Caddyfile that serves several domains and apps on one server, each with its own automatic HTTPS certificate, path routing, headers, logs and basic auth.
How to write a systemd service for your app
Run your own program as a systemd service that starts at boot, restarts when it crashes, runs as its own user, reads an env file and is sandboxed.
Install PHP 8.3 with PHP-FPM and nginx on Ubuntu 24.04
Install PHP 8.3 and PHP-FPM from Ubuntu's archive, wire it to nginx, give each site its own FPM pool and user, and tune the settings that matter.
Manage VPSNine servers with Ansible
Build an Ansible inventory from the VPSNine API, grouped by tag, plan and image, and run a playbook that patches servers and locks SSH to keys.
Receive VPSNine webhooks in Node.js and Python
A dependency-free webhook receiver in Node.js or Python that checks every VPSNine signature, refuses replays, skips duplicates and runs under systemd.
Run a multi-container app with Docker Compose and a reverse proxy
One compose.yaml with an app, its PostgreSQL database and Caddy for HTTPS, on private networks with named volumes, health checks, secrets, updates and backups.
Script your infrastructure with the TypeScript SDK
Use @vpsnine/sdk from TypeScript to list servers, snapshot before a reboot, order a server safely and handle errors, with retries and idempotency keys built in.
Self-host Gitea with Docker, PostgreSQL and HTTPS
Run your own Git server with Gitea and PostgreSQL in Docker Compose, Git over SSH on port 2222, HTTPS from Caddy, no open sign-ups, and backups you can restore.
Self-host Plausible Analytics (Community Edition) with Docker
Install Plausible Community Edition with its official Docker Compose setup, serve it over HTTPS with Caddy, add your site, and back up and upgrade it.
Self-host Vaultwarden safely with Docker and HTTPS
Run Vaultwarden, the Bitwarden-compatible password server, in Docker behind Caddy with HTTPS, sign-ups closed, a hashed admin token and backups you can restore.
WP-CLI tutorial: manage and harden WordPress from the command line
Install WP-CLI, then update WordPress, manage plugins and users, move a site to a new domain, back up the database and lock the site down, all over SSH.
Create and destroy preview servers per pull request
Order a VPSNine server per pull request from GitHub Actions, deploy the branch, comment its address, and delete the server when the PR closes.