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 directoriesls— see what's in the current directorymkdir— create a new foldernanoorvim— edit files right there in the terminalsudo— 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, orgeditare all common. If you're not familiar with any of them yet,nanois the gentlest starting point. - A package manager. Most distros come with one built in — Ubuntu and Debian use
apt, while CentOS typically usesyumordnf. - 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 apache2orsudo systemctl status nginxwill 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.htmlactually 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.