Skip to main content

How to Set Up a Linux Web Server and Host an HTML Page Easily

Setting up a web server on Linux means spending a fair amount of time in the terminal — Linux leans heavily on the command line rather than clicking through menus, so you'll be typing out instructions more often than not. 

If you're new to this, it can feel a little intimidating at first, but the good news is you don't need to become a Linux wizard overnight. A handful of core commands will get you surprisingly far.

A few you'll lean on constantly:

  • cd — move between directories
  • ls — see what's in the current directory
  • mkdir — create a new folder
  • nano or vim — edit files right there in the terminal
  • sudo — run something with administrator privileges

Get comfortable with these and you'll be able to navigate around, tweak configuration files, and install software without much trouble. You don't need to memorize everything — you just need to be confident enough to follow along with clear instructions, which is exactly what this guide aims to give you.

What You'll Need Before Starting

A Linux Distribution and a Way to Access It

First things first — you need a Linux system to actually work on. Ubuntu, Debian, CentOS, and Fedora are all common choices, and Ubuntu in particular tends to be the friendliest for beginners. Whether that's a cloud server or a machine sitting on your desk doesn't matter much; what matters is that you have reliable access to it.

Specifically, you'll want:

  • A Linux distribution installed. If you don't already have one, you can install it locally or spin up a virtual server through a hosting provider.
  • SSH access. If you're working with a remote server, you'll need an SSH client — PuTTY on Windows, or just your regular terminal on macOS/Linux — to connect securely.
  • Root or administrative privileges. A lot of the commands ahead (particularly installing software) require elevated permissions. Without root access, you won't be able to fully configure the server.

Once those three things are sorted, you're ready to actually start building.

The Software Tools You'll Need

A few more pieces round out your setup:

  • A text editor. You'll be editing configuration files constantly, so pick something you're comfortable with — nano, vim, or gedit are all common. If you're not familiar with any of them yet, nano is the gentlest starting point.
  • A package manager. Most distros come with one built in — Ubuntu and Debian use apt, while CentOS typically uses yum or dnf.
  • A working internet connection. You'll need to pull software packages from online repositories, so make sure your networking is actually functional before diving in.

Think of these three as the basic toolkit — nothing fancy, but you genuinely can't get far without them.

With the prerequisites out of the way, you're ready to start installing and configuring the actual software that'll power your server.

Installing the Web Server Software

Choosing Between Apache and Nginx

The two heavyweights here are Apache and Nginx — both are mature, reliable, and well-supported across pretty much every Linux distro. Which one you pick really comes down to personal preference or what your specific project needs.

Installing Apache:

On Ubuntu/Debian:

sudo apt update
sudo apt install apache2 -y

On CentOS/RHEL:

sudo yum install httpd -y

Once it's installed, enable it to start on boot and get it running now:

sudo systemctl enable apache2     # Ubuntu/Debian
sudo systemctl enable httpd       # CentOS/RHEL

sudo systemctl start apache2      # Ubuntu/Debian
sudo systemctl start httpd        # CentOS/RHEL

Installing Nginx is just as painless:

On Ubuntu/Debian:

sudo apt update
sudo apt install nginx -y

On CentOS/RHEL:

sudo yum install nginx -y

Then enable and start it:

sudo systemctl enable nginx
sudo systemctl start nginx

Either path leaves you with a working web server — pick whichever one fits your needs and move on.

Making Sure It Actually Worked

Once installed, the easiest way to confirm everything's working is to just check whether the default landing page loads.

Open a browser and enter your server's address — for a local setup, that's usually http://localhost or your machine's internal IP. If Apache's running, you'll see the default Apache landing page. If it's Nginx, you'll get the classic "Welcome to nginx!" message. Either one showing up means the server is alive and responding.

If nothing loads, check whether the service is actually running:

sudo systemctl status apache2     # Ubuntu/Debian
sudo systemctl status httpd       # CentOS/RHEL
sudo systemctl status nginx

Whatever error message pops up will usually point you toward the fix — sometimes it's as simple as restarting the service (sudo systemctl restart apache2 or nginx), other times it's a typo hiding somewhere in a config file.

Opening Up the Firewall

Here's a step that trips people up constantly: even with the web server running perfectly, nothing outside your own machine can reach it until the firewall allows it. By default, most firewalls block incoming traffic, so you need to explicitly open port 80 (and port 443 later, if you add HTTPS).

On Ubuntu/Debian, using UFW:

sudo ufw allow 'Apache'       # If you're using Apache
sudo ufw allow 'Nginx HTTP'   # If you're using Nginx

Then confirm it took effect:

sudo ufw status

On CentOS/RHEL, using firewalld:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload

You can double-check what's currently open with:

sudo firewall-cmd --list-all

After making these changes, go back and try loading your server's IP in the browser again. If it still doesn't connect, it's worth checking whether there's a second layer of firewall in play — cloud providers in particular often have their own security-group rules sitting on top of the OS firewall, and it's easy to forget about that extra layer.

Getting Your First HTML Page Online

With the server running and the firewall out of the way, it's time to actually put something on it.

Finding the Root Directory

Your web server serves files out of a specific folder — the "document root" — and that's where anything you want visible to the world needs to live. For Apache, this is typically /var/www/html. Nginx usually defaults to the same location, unless someone's changed it.

If you want to confirm the exact path, check the config file directly. For Apache:

sudo nano /etc/apache2/sites-available/000-default.conf

Look for the DocumentRoot line. For Nginx, the equivalent check is:

sudo nano /etc/nginx/sites-available/default

Whatever directory is listed there is the one you'll actually use — don't assume it's /var/www/html if the config says otherwise. Once you've confirmed it, navigate there:

cd /var/www/html

Creating a Test Page

Now for the fun part — actually creating something to serve.

sudo nano index.html

Drop in a bit of basic HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My First HTML Page</title>
</head>
<body>
    <h1>Welcome to My Web Server!</h1>
    <p>This is a sample HTML page hosted on my Linux server.</p>
</body>
</html>

Save it — in nano, that's Ctrl+O, then Enter, then Ctrl+X to exit.

Why index.html specifically? Because most web servers automatically look for a file with that exact name when no specific page is requested. It's just a long-standing convention that keeps things simple — no extra configuration needed.

Confirming It's Live

Open a browser on any device on the same network as your server and type in its IP address — something like http://192.168.1.100, or http://localhost if you're testing locally. If everything's configured correctly, you should see your "Welcome to My Web Server!" message pop right up. If you've already got a domain pointed at the server, that'll work too.

If it doesn't load, work through these checks:

  • Is the server actually running? sudo systemctl status apache2 or sudo systemctl status nginx will tell you.
  • Is the firewall letting HTTP traffic through? Revisit the firewall steps above.
  • Is the file sitting in the right place? Double-check that index.html actually landed in the correct root directory.

Once that page loads, congratulations — anyone with the IP or domain can now see what you've built.

Leveling Up: Advanced Configuration

Once the basics are working, there's a natural next set of steps: pointing a real domain at your server, securing it with HTTPS, and — if you're hosting more than one site — setting up virtual hosts.

Pointing a Domain at Your Server

Using a domain instead of a raw IP address makes everything feel a lot more legitimate, and it's not hard to set up.

First, buy a domain from a registrar — Namecheap, GoDaddy, Google Domains, whatever you prefer. Then head into its DNS settings and create an A record pointing at your server's public IP:

A Record:
Host: @
Value: 203.0.113.10
TTL: Set to the lowest available (e.g., 5 minutes)

DNS changes aren't instant — give it anywhere from a few minutes to a full day to propagate.

Next, tell your web server about the domain. For Apache, open (or create) the site's config file:

sudo nano /etc/apache2/sites-available/yourdomain.conf

And add:

<VirtualHost *:80>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com
    DocumentRoot /var/www/html
    <Directory /var/www/html>
        AllowOverride All
    </Directory>
</VirtualHost>

Then enable the site and restart Apache:

sudo a2ensite yourdomain.conf
sudo systemctl restart apache2

For Nginx, open:

sudo nano /etc/nginx/sites-available/yourdomain

And add:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Then link it into sites-enabled and restart:

sudo ln -s /etc/nginx/sites-available/yourdomain /etc/nginx/sites-enabled
sudo systemctl restart nginx

Once DNS has propagated, typing your domain into a browser should show the exact same content you were seeing at the IP address before.

Adding HTTPS

Serving your site over plain HTTP is fine for testing, but for anything real, HTTPS matters — for user trust, for security, and for SEO. Thankfully, Let's Encrypt makes getting a free certificate almost trivial via a tool called Certbot.

Install Certbot:

sudo apt update
sudo apt install certbot python3-certbot-apache -y   # Apache
sudo apt update
sudo apt install certbot python3-certbot-nginx -y    # Nginx

Then request the certificate — Certbot handles almost the entire configuration process for you:

sudo certbot --apache
sudo certbot --nginx

It'll ask for your domain name and can automatically set up a redirect from HTTP to HTTPS. Once it's done, visit https://yourdomain.com — if you see the padlock icon in your browser, you're set.

One thing worth knowing: Let's Encrypt certificates expire every 90 days, but Certbot can handle renewal automatically. You can test that the renewal process works with:

sudo certbot renew --dry-run

Hosting Multiple Sites with Virtual Hosts

If you're running more than one site off the same server, virtual hosts let each one live in its own directory with its own configuration, completely separate from the others.

On Apache:

Create a directory for each site:

sudo mkdir -p /var/www/site1.com /var/www/site2.com

Set the right ownership:

sudo chown -R www-data:www-data /var/www/site1.com /var/www/site2.com

Then create a config file per site. For site1.com:

sudo nano /etc/apache2/sites-available/site1.com.conf
<VirtualHost *:80>
    ServerName site1.com
    DocumentRoot /var/www/site1.com
</VirtualHost>

Repeat the same for site2.com, then enable both and restart:

sudo a2ensite site1.com.conf
sudo a2ensite site2.com.conf
sudo systemctl restart apache2

On Nginx, the process is nearly identical — create the directories and set ownership the same way, then create a server block per site. For site1.com:

sudo nano /etc/nginx/sites-available/site1.com
server {
    listen 80;
    server_name site1.com;
    root /var/www/site1.com;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Do the same for site2.com, then symlink both into sites-enabled and restart:

sudo ln -s /etc/nginx/sites-available/site1.com /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/site2.com /etc/nginx/sites-enabled
sudo systemctl restart nginx

Once everything's in place, visiting each domain will load its own separate site — even though they're both physically sitting on the same machine.

Keeping Things Running Smoothly: A Few Best Practices

Getting a server up is one thing — keeping it reliable, secure, and performant over time is a whole separate skill. Three areas deserve ongoing attention.

Staying on Top of Updates

This is one of the simplest and most effective things you can do for security. New vulnerabilities get discovered constantly, and outdated software is exactly what attackers go looking for.

Update your system packages regularly:

sudo apt update && sudo apt upgrade -y   # Ubuntu/Debian
sudo yum update -y                       # CentOS/RHEL

Keep your web server software itself current too — updates to Apache or Nginx often bring both security patches and performance improvements.

If you want to take some of the manual effort out of this, Ubuntu lets you enable automatic updates for critical packages:

sudo apt install unattended-upgrades

Staying current on updates is a bit like locking your doors before you go to bed — it doesn't guarantee nothing bad happens, but it closes off the easiest paths in.

Keeping an Eye on Performance

If your server starts struggling under load, visitors generally won't stick around to find out why — they'll just leave. Regular monitoring catches problems while they're still small.

For quick, real-time checks, tools like htop are genuinely useful:

sudo apt install htop -y
htop

For tracking trends over longer periods — traffic spikes, gradual resource creep, that kind of thing — something like Prometheus or Zabbix is worth setting up. And it's worth configuring alerts too, so you find out about problems (high load, low disk space) before your users do. Tools like UptimeRobot or Nagios can handle that notification piece for you.

It's also worth periodically skimming your server logs for recurring errors, and tuning settings like Nginx's worker_processes to actually match your hardware and traffic levels rather than leaving defaults in place.

Think of this like glancing at your car's dashboard now and then — catching a small warning light early is a lot cheaper than dealing with a breakdown later.

Locking Things Down

A web server is exposed to the internet basically around the clock, which means it's constantly a potential target — brute-force login attempts, malware, unauthorized access attempts, all of it. Security here isn't optional.

Turn off what you're not using. Every extra module or service running is one more potential entry point. For Apache:

sudo a2dismod <module_name>
sudo systemctl restart apache2

Get serious about authentication. Strong, unique passwords are the baseline — but better still, disable password-based SSH login entirely and switch to SSH keys. To stop root logins over SSH specifically:

sudo nano /etc/ssh/sshd_config

Find PermitRootLogin and set it to no.

Install fail2ban. It watches your logs for repeated failed login attempts and automatically bans the offending IPs:

sudo apt install fail2ban -y

Configure which services it protects by editing:

sudo nano /etc/fail2ban/jail.local

Restart the service afterward, and you've got automated protection against brute-force attempts running in the background.

Lock down the firewall to only what's needed. On Ubuntu, that typically looks like:

sudo ufw allow 'Apache Full'   # For Apache  
sudo ufw allow 'Nginx Full'   # For Nginx  
sudo ufw enable

Security is less about any single fix and more about layering — each measure closes off another path an attacker might try, and together they make your server a much harder target.

Popular posts from this blog

How to Check if Someone is Connected to Your Machine in Linux

Picture this: you glance at your system monitor and notice your CPU is humming along even though you're not running anything demanding. Or maybe your internet feels sluggish for no obvious reason. A small, uneasy thought creeps in — is someone else on my machine right now? For Linux users, this isn't something you have to wonder about. Linux ships with a powerful set of built-in tools that let you see exactly who's connected, who's logged in, and what your network is doing at any given moment. You don't need to be a security expert to use them — you just need to know where to look. This guide walks you through the practical, no-nonsense steps to check for unauthorized connections on your Linux system, with real commands you can run right now. Why Monitoring Network Connections Matters Every device on a network — including your own Linux machine — communicates using an IP address. When another device or user connects to your system, that connection shows up as a trac...

Linux Network Troubleshooting

If you've spent any time as a sysadmin — or honestly, just as someone who's had to fix their own home network at 11pm — you know that connectivity issues are one of the most common headaches out there. The good news is that a handful of core tools and a methodical approach can take you from "why isn't this working" to a root cause pretty quickly.  This guide walks through the essentials: configuring interfaces, managing routes, and diagnosing problems when things go sideways. Configuring Network Interfaces Your network interfaces are the actual bridge between your machine and the outside world, so getting them configured correctly is step one for any kind of reliable connectivity. Doing It Manually ifconfig is the old-school, tried-and-true tool for this on Unix-like systems. To see everything currently configured, run: ifconfig -a If you need to manually set up a specific interface — assigning an IP, a netmask, and bringing it online — it looks like this: ifconf...