Basic Server Setup: Debian

March 18, 2026 mrbeandev 7 min read
A no-fluff guide to get your Debian server production-ready — Nginx, PHP, MariaDB, Node.js, Python, and a solid firewall.

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.3 with 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.conf manpage.

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 host is left empty, the built-in HTTP server binds to all interfaces.
  • hosts_allow and hosts_deny control which IPs can access the dashboard.
  • https_url = y is 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.