Basic Server Setup: Ubuntu

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

Basic Server Setup — Ubuntu

A clean, copy-paste-friendly guide to bootstrap a fresh Ubuntu server. No bloat, no theory — just the commands.

Tested on: Ubuntu 22.04 LTS and Ubuntu 24.04 LTS


1. First Things First — Update the System

Always start with a full update before installing anything.

sudo apt update && sudo apt upgrade -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

PHP is needed if you're running WordPress, Laravel, or any PHP app.

sudo apt install php php-fpm php-cli php-common php-mbstring php-xml php-curl php-zip php-bcmath -y

Check the installed version:

php -v

Enable PHP-FPM to start on boot:

sudo systemctl enable php8.3-fpm   # change version if needed
sudo systemctl start php8.3-fpm

Tip: Check your exact PHP version with php -v and use that version number in the systemctl command (e.g., php8.1-fpm).


5. Install MySQL

MySQL is the most popular relational database.

sudo apt install mysql-server -y
sudo systemctl enable mysql
sudo systemctl start mysql

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 MySQL to verify:

sudo mysql -u root -p

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

UFW (Uncomplicated Firewall) is the easiest firewall tool on Linux.

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 MySQL 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 comes pre-installed on most modern Ubuntu/Debian systems. Here's how to set it up properly.

Check if Python3 is already installed

python3 --version

Install Python3 and Pip3

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 one of the simplest options. According to the official Monitorix Debian/Ubuntu docs, on modern Ubuntu releases you 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 Ubuntu's APT 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 web interface:

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 who can reach the dashboard.
  • https_url = y is useful when you place Nginx as an HTTPS reverse proxy in front of Monitorix.

Edit the config:

sudo nano /etc/monitorix/monitorix.conf

Note: On Debian-based packages, extra overrides may also exist in /etc/monitorix/conf.d/. If your changes do not apply, check those files too.

Inside the <httpd_builtin> section, set it 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 the example IPs with your own public IP or office/home IP range. This is the safer setup because it does not expose Monitorix to the entire internet.

If you really want it reachable from anywhere, you can use:

hosts_deny =
hosts_allow = all

But that is not recommended unless 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 dashboard will be internet-facing, add authentication. The official Monitorix manpage supports Basic Auth through the <auth> section.

Create a password file with Apache's htpasswd tool:

sudo apt install apache2-utils -y
sudo htpasswd -c /var/lib/monitorix/htpasswd admin

Then update the <auth> section in /etc/monitorix/monitorix.conf:

<auth>
    enabled = y
    msg = Monitorix: Restricted access
    htpasswd = /var/lib/monitorix/htpasswd
    hosts_deny = all
    hosts_allow =
</auth>

That forces authentication for all hosts.

One-liner:

sudo apt install apache2-utils -y && sudo htpasswd -c /var/lib/monitorix/htpasswd admin

Step 6 — Restart Monitorix

After changing the config, restart the service:

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 put Nginx in front of it later, set https_url = y and proxy traffic over HTTPS instead of exposing port 8080 directly.

One-liner:

curl -I http://127.0.0.1:8080/monitorix/

Quick Reference Cheatsheet

Task Command
Update system sudo apt update && sudo apt upgrade -y
Start Nginx sudo systemctl start nginx
Issue SSL cert sudo certbot --nginx -d domain.com
MySQL secure setup sudo mysql_secure_installation
Install Node LTS nvm install --lts
Check firewall sudo ufw status verbose
Allow SSH sudo ufw allow OpenSSH
Python version python3 --version

That's it. Your server is now running Nginx with SSL, PHP, MySQL, Node.js, Python, and a properly configured firewall. Clean, minimal, production-ready.