Basic Server Setup: Debian
Basic Server Setup — Debian
A clean, copy-paste-friendly guide to bootstrap a fresh Debian server. No bloat, no theory — just the commands.
Tested on: Debian 11 (Bullseye) and Debian 12 (Bookworm)
1. First Things First — Update the System
Always start with a full update before installing anything.
sudo apt update && sudo apt upgrade -y
Install some common utilities that Debian minimal installs often skip:
sudo apt install curl wget gnupg2 ca-certificates lsb-release apt-transport-https -y
2. Install Nginx
Nginx is the web server. It handles HTTP requests and serves your site.
sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
Verify it's running:
sudo systemctl status nginx
Visit your server IP in a browser — you should see the Nginx welcome page.
3. Install Certbot (Free SSL via Let's Encrypt)
Certbot automatically issues and renews SSL certificates.
sudo apt install certbot python3-certbot-nginx -y
Issue a certificate for your domain (replace yourdomain.com):
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot will auto-configure Nginx for HTTPS and set up auto-renewal. Test the renewal timer:
sudo certbot renew --dry-run
4. Install PHP
Debian's default repos may carry an older PHP version. For PHP 8.x, use the Sury repository (the standard source on Debian).
Step 1 — Add the Sury PHP Repository
sudo curl -sSL https://packages.sury.org/php/README.txt | sudo bash -x
Or the manual way:
sudo wget -qO /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list
sudo apt update
Step 2 — Install PHP
sudo apt install php8.3 php8.3-fpm php8.3-cli php8.3-common php8.3-mbstring php8.3-xml php8.3-curl php8.3-zip php8.3-bcmath -y
Check the installed version:
php -v
Enable PHP-FPM:
sudo systemctl enable php8.3-fpm
sudo systemctl start php8.3-fpm
Tip: Replace
8.3with whichever version you installed. You can also install multiple PHP versions side by side and switch between them.
5. Install MariaDB
Debian ships with MariaDB as the default MySQL-compatible database — it's fully compatible with MySQL syntax and tools.
sudo apt install mariadb-server mariadb-client -y
sudo systemctl enable mariadb
sudo systemctl start mariadb
Run the security hardening script (highly recommended):
sudo mysql_secure_installation
It will guide you through:
- Setting a root password
- Removing anonymous users
- Disabling remote root login
- Removing the test database
Log into MariaDB to verify:
sudo mariadb -u root -p
Note: If you specifically need MySQL (not MariaDB), you can add the official MySQL APT repo from mysql.com. For most use cases MariaDB is a drop-in replacement.
6. Install Node.js with NVM
NVM (Node Version Manager) is the best way to install Node.js — it lets you switch versions easily and avoids permission issues.
Step 1 — Install NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash
Reload your shell:
source ~/.bashrc
Step 2 — Install Node.js
Install the latest LTS (Long Term Support) version:
nvm install --lts
Or install a specific version:
nvm install 22
Step 3 — Verify
node -v
npm -v
Useful NVM Commands
| Command | Description |
|---|---|
nvm install 22 |
Install Node 22 |
nvm use 22 |
Switch to Node 22 |
nvm ls |
List installed versions |
nvm alias default 22 |
Set default version |
7. Setup Firewall with UFW
Debian minimal installs often don't include ufw — install it first.
sudo apt install ufw -y
Allow essential ports
sudo ufw allow OpenSSH # SSH — ALWAYS do this first or you'll lock yourself out
sudo ufw allow 'Nginx Full' # HTTP (80) + HTTPS (443)
Warning: Always allow SSH before enabling the firewall. Skipping this will lock you out of your server.
Enable the firewall
sudo ufw enable
Check the status
sudo ufw status verbose
Common UFW Commands
sudo ufw allow 3306 # Allow MariaDB port (only if needed externally)
sudo ufw allow 3000 # Allow a Node.js app port
sudo ufw deny 3306 # Block a port
sudo ufw delete allow 3000 # Remove a rule
sudo ufw disable # Turn off the firewall
8. Install Python3 and Pip3
Python3 is included in Debian by default since Debian 10. Here's how to complete the setup.
sudo apt install python3 python3-pip python3-venv -y
Verify:
python3 --version
pip3 --version
Using Virtual Environments (Best Practice)
Always use a virtual environment for Python projects — keeps dependencies isolated.
python3 -m venv myenv # Create a virtual environment
source myenv/bin/activate # Activate it
pip install package-name # Install packages inside the env
deactivate # Exit the environment
9. Install Monitorix
If you want a lightweight web dashboard for server stats, Monitorix is a clean fit for Debian servers. According to the official Monitorix Debian/Ubuntu docs, Debian Buster and newer releases should install it directly with apt.
Official docs checked: Monitorix Downloads, Debian/Ubuntu install guide, and
monitorix.confmanpage.
Step 1 — Install Monitorix
Install the package from Debian's repositories:
sudo apt update && sudo apt install monitorix -y
The service normally starts automatically after installation.
One-liner:
sudo apt update && sudo apt install monitorix -y
Step 2 — Verify the Service
Check that the daemon is active:
sudo systemctl status monitorix
By default, Monitorix serves its dashboard on port 8080 and the default URL is:
http://localhost:8080/monitorix/
One-liner:
sudo systemctl status monitorix
Step 3 — Allow Port 8080 in UFW
If UFW is enabled, allow the Monitorix dashboard through the firewall:
sudo ufw allow 8080/tcp
One-liner:
sudo ufw allow 8080/tcp
Step 4 — Make Monitorix Publicly Accessible
Per the official monitorix.conf docs:
- If
hostis left empty, the built-in HTTP server binds to all interfaces. hosts_allowandhosts_denycontrol which IPs can access the dashboard.https_url = yis useful when you put Nginx in front of Monitorix as an HTTPS reverse proxy.
Edit the config:
sudo nano /etc/monitorix/monitorix.conf
Note: Debian-family packages can also load overrides from
/etc/monitorix/conf.d/. If your changes seem ignored, inspect that directory as well.
Inside the <httpd_builtin> section, use something like this:
<httpd_builtin>
enabled = y
host =
port = 8080
hosts_deny = all
hosts_allow = 203.0.113.10,198.51.100.0/24
https_url = n
</httpd_builtin>
Replace those example IPs with your own trusted IP address or subnet. That makes it reachable from outside while still keeping it restricted.
If you expose it to everyone:
hosts_deny =
hosts_allow = all
do it only if you also protect it with authentication or a reverse proxy.
One-liner:
sudo nano /etc/monitorix/monitorix.conf
Step 5 — Enable Basic Auth for Public Access
If the panel will be public, enable authentication. The official Monitorix docs support Basic Auth through the <auth> section.
Install htpasswd support and create a user:
sudo apt install apache2-utils -y
sudo htpasswd -c /var/lib/monitorix/htpasswd admin
Then update the <auth> section:
<auth>
enabled = y
msg = Monitorix: Restricted access
htpasswd = /var/lib/monitorix/htpasswd
hosts_deny = all
hosts_allow =
</auth>
That forces every remote client to authenticate.
One-liner:
sudo apt install apache2-utils -y && sudo htpasswd -c /var/lib/monitorix/htpasswd admin
Step 6 — Restart Monitorix
Apply the config changes:
sudo systemctl restart monitorix
sudo systemctl enable monitorix
One-liner:
sudo systemctl restart monitorix && sudo systemctl enable monitorix
Step 7 — Test Access
Local access:
http://127.0.0.1:8080/monitorix/
Public access:
http://your-server-ip:8080/monitorix/
If you later move it behind Nginx with HTTPS, set https_url = y so Monitorix generates secure links correctly.
One-liner:
curl -I http://127.0.0.1:8080/monitorix/
Debian 12+ Note: Debian Bookworm enforces PEP 668 — you can't install pip packages system-wide without
--break-system-packages. Virtual environments are the correct solution and the recommended approach.
Quick Reference Cheatsheet
| Task | Command |
|---|---|
| Update system | sudo apt update && sudo apt upgrade -y |
| Add PHP 8.x repo | sudo curl -sSL https://packages.sury.org/php/README.txt \| sudo bash -x |
| Start Nginx | sudo systemctl start nginx |
| Issue SSL cert | sudo certbot --nginx -d domain.com |
| MariaDB secure setup | sudo mysql_secure_installation |
| Install Node LTS | nvm install --lts |
| Install UFW | sudo apt install ufw -y |
| Allow SSH | sudo ufw allow OpenSSH |
| Check firewall | sudo ufw status verbose |
| Python version | python3 --version |
That's it. Your Debian server is now running Nginx with SSL, PHP 8.x, MariaDB, Node.js, Python, and a properly configured firewall. Clean, minimal, production-ready.