Web Server Setup with Apache/Nginx on Ubuntu
A web server delivers content to users over the internet. This tutorial covers setting up both Apache and Nginx web servers on Ubuntu, two of the most popular web server options.
Prerequisites
- Ubuntu Server 20.04 LTS or newer
- Root or sudo privileges
- Static IP address configured
- Domain name pointing to your server (optional but recommended)
- Basic knowledge of Linux command line
1 Install Apache Web Server
Update your package list and install Apache:
sudo apt update
sudo apt install apache2 -y
Check if Apache is running:
sudo systemctl status apache2
You should see output indicating that the service is active and running.
2 Configure Firewall
Allow HTTP and HTTPS traffic through the firewall:
sudo ufw allow 'Apache'
sudo ufw allow 'Apache Full' # If you plan to use SSL
sudo ufw allow 'Apache Secure' # HTTPS only
sudo ufw enable
Verify the firewall status:
sudo ufw status
3 Test Your Web Server
Open your web browser and navigate to your server's IP address:
http://your_server_ip
You should see the Apache Ubuntu default page, indicating that Apache is working correctly.
ip addr show
or hostname -I
4 Configure Virtual Hosts
Create a directory for your domain (replace example.com with your actual domain):
sudo mkdir -p /var/www/example.com/html
Assign ownership of the directory:
sudo chown -R $USER:$USER /var/www/example.com/html
sudo chmod -R 755 /var/www/example.com
Create a sample index.html page:
sudo nano /var/www/example.com/html/index.html
Add the following HTML content:
<html>
<head>
<title>Welcome to Example.com!</title>
</head>
<body>
<h1>Success! The example.com virtual host is working!</h1>
</body>
</html>
5 Create Virtual Host Configuration File
Create a new virtual host configuration file:
sudo nano /etc/apache2/sites-available/example.com.conf
Add the following configuration (replace example.com with your domain):
<VirtualHost *:80>
ServerAdmin admin@example.com
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
6 Enable the Virtual Host
Enable the new virtual host:
sudo a2ensite example.com.conf
Disable the default Apache virtual host:
sudo a2dissite 000-default.conf
Test for configuration errors:
sudo apache2ctl configtest
If you see "Syntax OK", restart Apache:
sudo systemctl restart apache2
7 Enable SSL with Let's Encrypt
Install Certbot and the Apache plugin:
sudo apt install certbot python3-certbot-apache -y
Obtain an SSL certificate (replace example.com with your domain):
sudo certbot --apache -d example.com -d www.example.com
Follow the prompts to complete the SSL certificate installation. Certbot will automatically configure Apache to use HTTPS.
Set up automatic certificate renewal:
sudo crontab -e
Add the following line at the end of the file:
0 12 * * * /usr/bin/certbot renew --quiet
8 Additional Apache Configuration
Enable useful Apache modules:
sudo a2enmod rewrite
sudo a2enmod headers
sudo a2enmod ssl
sudo systemctl restart apache2
To optimize Apache performance, edit the mpm_prefork configuration:
sudo nano /etc/apache2/mods-available/mpm_prefork.conf
Adjust the values based on your server's resources:
<IfModule mpm_prefork_module>
StartServers 2
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 50
MaxConnectionsPerChild 1000
</IfModule>
1 Install Nginx Web Server
Update your package list and install Nginx:
sudo apt update
sudo apt install nginx -y
Check if Nginx is running:
sudo systemctl status nginx
You should see output indicating that the service is active and running.
2 Configure Firewall
Allow HTTP and HTTPS traffic through the firewall:
sudo ufw allow 'Nginx HTTP'
sudo ufw allow 'Nginx HTTPS'
sudo ufw allow 'Nginx Full' # Both HTTP and HTTPS
sudo ufw enable
Verify the firewall status:
sudo ufw status
3 Test Your Web Server
Open your web browser and navigate to your server's IP address:
http://your_server_ip
You should see the Nginx welcome page, indicating that Nginx is working correctly.
4 Configure Server Blocks (Virtual Hosts)
Create a directory for your domain (replace example.com with your actual domain):
sudo mkdir -p /var/www/example.com/html
Assign ownership of the directory:
sudo chown -R $USER:$USER /var/www/example.com/html
sudo chmod -R 755 /var/www/example.com
Create a sample index.html page:
sudo nano /var/www/example.com/html/index.html
Add the following HTML content:
<html>
<head>
<title>Welcome to Example.com!</title>
</head>
<body>
<h1>Success! The example.com server block is working!</h1>
</body>
</html>
5 Create Server Block Configuration File
Create a new server block configuration file:
sudo nano /etc/nginx/sites-available/example.com
Add the following configuration (replace example.com with your domain):
server {
listen 80;
listen [::]:80;
root /var/www/example.com/html;
index index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ =404;
}
}
6 Enable the Server Block
Enable the new server block by creating a symbolic link:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Test for configuration errors:
sudo nginx -t
If you see "test is successful", restart Nginx:
sudo systemctl restart nginx
7 Enable SSL with Let's Encrypt
Install Certbot and the Nginx plugin:
sudo apt install certbot python3-certbot-nginx -y
Obtain an SSL certificate (replace example.com with your domain):
sudo certbot --nginx -d example.com -d www.example.com
Follow the prompts to complete the SSL certificate installation. Certbot will automatically configure Nginx to use HTTPS.
Set up automatic certificate renewal:
sudo crontab -e
Add the following line at the end of the file:
0 12 * * * /usr/bin/certbot renew --quiet
8 Additional Nginx Configuration
To optimize Nginx performance, edit the main configuration file:
sudo nano /etc/nginx/nginx.conf
Adjust the worker processes and connections based on your server's resources:
worker_processes auto;
worker_rlimit_nofile 100000;
events {
worker_connections 4096;
multi_accept on;
use epoll;
}
http {
# Basic settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# Security headers
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
}
Test the configuration and restart Nginx:
sudo nginx -t
sudo systemctl restart nginx