Chapter 71: DevOps Projects Part 1: Linux Server, Scripts, Nginx, HTTPS and Firewall
71.6 Project 6: Nginx web server with virtual hosts
Friends, one Nginx can host many sites. Today we install Nginx, add two server blocks, open port 80, and prove each hostname returns its own page.
मित्रांनो, एक Nginx अनेक sites host करू शकतो. आज Nginx install करू, दोन server blocks, port 80, आणि प्रत्येक hostname ची page दाखवू.
दोस्तों, एक Nginx कई sites host कर सकता है. आज Nginx install करेंगे, दो server blocks, port 80, और हर hostname की page दिखाएँगे.
What you will build in this project
- Nginx installed and running.
- Two virtual hosts with root folders.
- Enabled sites and reloaded.
- curl tests for each Host header.
1. Start from a real company story
At Freshworks in Chennai, marketing wanted docs.example.com and status.example.com on one small VM to save ₹4,000 a month.
One default site was breaking both brands. Leads looked wrong.
Sana added two server blocks, two root folders, and curl tests with Host headers.
Today we do the same with practice hostnames.
Ravindra Bagale's Tip
Many students edit nginx.conf for every site. Prefer sites-available and sites-enabled. Keep that habit.
खूप students प्रत्येक site साठी nginx.conf edit करतात. sites-available आणि sites-enabled वापरा. सवय ठेवा.
बहुत students हर site के लिए nginx.conf edit करते हैं. sites-available और sites-enabled इस्तेमाल करें. आदत रखिए.
2. Start and prepare
Step 1: Install Nginx
Why: Package must be present. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: apt install nginx. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 1: Install
Type this:
sudo apt-get install -y nginx 2>&1 | tail -2
You will see:
Setting up nginx ...
0 upgraded, 1 newly installed
What it means: Installed.
Example 2: Version
Type this:
nginx -v 2>&1
You will see:
nginx version: nginx/1.24.0
What it means: Version note.
Example 3: Binary
Type this:
command -v nginx
You will see:
/usr/sbin/nginx
What it means: Found.
Step 2: Check status
Why: Service must be active. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: systemctl status. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 4: Status
Type this:
sudo systemctl enable --now nginx && systemctl is-active nginx
You will see:
active
What it means: Running.
Example 5: Port
Type this:
ss -ltn | grep ':80 ' || echo 'listen check later'
You will see:
LISTEN 0 511 0.0.0.0:80
What it means: Port 80 open.
Example 6: Default curl
Type this:
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/
You will see:
200
What it means: Default page lives.
Step 3: Create web roots
Why: Each site needs a folder. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: mkdir -p. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 7: Roots
Type this:
sudo mkdir -p /var/www/docs /var/www/status && sudo chown -R $USER:$USER /var/www/docs /var/www/status && ls -d /var/www/docs /var/www/status
You will see:
/var/www/docs
/var/www/status
What it means: Ready.
Example 8: Modes
Type this:
stat -c '%a %n' /var/www/docs /var/www/status
You will see:
755 /var/www/docs
755 /var/www/status
What it means: OK.
Example 9: Empty
Type this:
ls /var/www/docs | wc -l
You will see:
0
What it means: Fresh.
3. Build the main pieces
Step 4: Write index pages
Why: Unique body text helps. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: printf index.html. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 10: docs index
Type this:
printf '%s\n' '<!doctype html><title>docs</title><h1>docs site</h1>' > /var/www/docs/index.html && cat /var/www/docs/index.html
You will see:
<!doctype html><title>docs</title><h1>docs site</h1>
What it means: Unique body.
Example 11: status index
Type this:
printf '%s\n' '<!doctype html><title>status</title><h1>status site</h1>' > /var/www/status/index.html && cat /var/www/status/index.html
You will see:
<!doctype html><title>status</title><h1>status site</h1>
What it means: Unique body.
Example 12: wc
Type this:
wc -c /var/www/docs/index.html /var/www/status/index.html
You will see:
58 /var/www/docs/index.html
62 /var/www/status/index.html
What it means: Small pages.
Step 5: Write docs vhost
Why: server_name selects the site. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: server block file. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 13: docs conf
Type this:
printf '%s\n' 'server {' ' listen 80;' ' server_name docs.example.com;' ' root /var/www/docs;' ' index index.html;' '}' | sudo tee /etc/nginx/sites-available/docs >/dev/null && cat /etc/nginx/sites-available/docs
You will see:
server {
listen 80;
server_name docs.example.com;
root /var/www/docs;
index index.html;
}
What it means: Block ready.
Example 14: syntax peek
Type this:
grep server_name /etc/nginx/sites-available/docs
You will see:
server_name docs.example.com;
What it means: Name set.
Example 15: Mode
Type this:
stat -c '%a' /etc/nginx/sites-available/docs
You will see:
644
What it means: OK.
Step 6: Write status vhost
Why: Second brand, second block. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: server block file. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 16: status conf
Type this:
printf '%s\n' 'server {' ' listen 80;' ' server_name status.example.com;' ' root /var/www/status;' ' index index.html;' '}' | sudo tee /etc/nginx/sites-available/status >/dev/null && cat /etc/nginx/sites-available/status
You will see:
server {
listen 80;
server_name status.example.com;
root /var/www/status;
index index.html;
}
What it means: Second block.
Example 17: Both files
Type this:
ls /etc/nginx/sites-available/
You will see:
default
docs
status
What it means: Three files.
Example 18: grep names
Type this:
grep server_name /etc/nginx/sites-available/docs /etc/nginx/sites-available/status
You will see:
/etc/nginx/sites-available/docs: server_name docs.example.com;
/etc/nginx/sites-available/status: server_name status.example.com;
What it means: Distinct.
4. Automate and verify
Step 7: Enable sites
Why: Symlinks enable. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: ln -s. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 19: Enable
Type this:
sudo ln -sf /etc/nginx/sites-available/docs /etc/nginx/sites-enabled/docs && sudo ln -sf /etc/nginx/sites-available/status /etc/nginx/sites-enabled/status && ls /etc/nginx/sites-enabled/
You will see:
default
docs
status
What it means: Symlinks.
Example 20: ls -l docs
Type this:
ls -l /etc/nginx/sites-enabled/docs
You will see:
lrwxrwxrwx 1 root root 34 Oct 28 12:00 /etc/nginx/sites-enabled/docs -> /etc/nginx/sites-available/docs
What it means: Points to available.
Example 21: count enabled
Type this:
ls /etc/nginx/sites-enabled/ | wc -l
You will see:
3
What it means: Including default for now.
Step 8: Test config and reload
Why: nginx -t then reload. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: nginx -t && reload. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 22: Test
Type this:
sudo nginx -t
You will see:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
What it means: Good.
Example 23: Reload
Type this:
sudo systemctl reload nginx && echo reloaded
You will see:
reloaded
What it means: Applied.
Example 24: Active
Type this:
systemctl is-active nginx
You will see:
active
What it means: Still up.
Step 9: curl Host tests
Why: Host header proves routing. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: curl -H. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 25: curl docs
Type this:
curl -s -H 'Host: docs.example.com' http://127.0.0.1/
You will see:
<!doctype html><title>docs</title><h1>docs site</h1>
What it means: docs body.
Example 26: curl status
Type this:
curl -s -H 'Host: status.example.com' http://127.0.0.1/
You will see:
<!doctype html><title>status</title><h1>status site</h1>
What it means: status body.
Example 27: codes
Type this:
curl -s -o /dev/null -w '%{http_code}' -H 'Host: docs.example.com' http://127.0.0.1/; echo; curl -s -o /dev/null -w '%{http_code}' -H 'Host: status.example.com' http://127.0.0.1/
You will see:
200
200
What it means: Both OK.
5. Harden and accept
Step 10: Disable default
Why: Default can confuse. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: unlink default. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 28: Disable default
Type this:
sudo unlink /etc/nginx/sites-enabled/default 2>/dev/null; sudo nginx -t && sudo systemctl reload nginx && ls /etc/nginx/sites-enabled/
You will see:
docs
status
What it means: Default gone.
Example 29: enabled only two
Type this:
ls /etc/nginx/sites-enabled/ | wc -l
You will see:
2
What it means: Clean.
Example 30: reload again
Type this:
sudo systemctl reload nginx && echo ok
You will see:
ok
What it means: Stable.
Step 11: Open firewall 80
Why: OS firewall must allow. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: ufw or firewalld. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 31: ufw allow
Type this:
sudo ufw allow 80/tcp 2>/dev/null || echo 'open SG instead'
You will see:
Rule added
What it means: Lab firewall.
Example 32: ss again
Type this:
ss -ltn | grep ':80 '
You will see:
LISTEN 0 511 0.0.0.0:80
What it means: Listening.
Example 33: curl external note
Type this:
echo 'from laptop: curl -H Host:docs.example.com http://SERVER_IP/'
You will see:
from laptop: curl -H Host:docs.example.com http://SERVER_IP/
What it means: Real test.
Step 12: Acceptance checklist
Why: Sana signs off when these pass. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: All green. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 34: nginx -t
Type this:
sudo nginx -t >/dev/null && echo conf_ok
You will see:
conf_ok
What it means: Valid.
Example 35: two bodies differ
Type this:
curl -s -H 'Host: docs.example.com' http://127.0.0.1/ | grep -o docs; curl -s -H 'Host: status.example.com' http://127.0.0.1/ | grep -o status
You will see:
docs
status
What it means: Routed.
Example 36: Sign-off
Type this:
echo 'Sana: PASS'
You will see:
Sana: PASS
What it means: Done.
Check yourself
Q1. Config test command?
nginx -t
Q2. Where do site files live?
sites-available
Q3. How do we enable a site?
Symlink into sites-enabled
Q4. Port for HTTP?
80
Q5. Who set this up at Freshworks?
Sana
Q6. Tool to test Host header?
curl -H Host
Friends, you hosted two sites on one Nginx with virtual hosts. Did you understand? Let us try it once more. Add a third practice host and prove it with curl.
मित्रांनो, तुम्ही एका Nginx वर दोन sites host केल्या. तिसरा host add करून curl ने सिद्ध करा.
दोस्तों, आपने एक Nginx पर दो sites host कीं. तीसरा host जोड़कर curl से सिद्ध करें.
Lab: try at home
- Install Nginx.
- Create two roots and index files.
- Write two server blocks.
- Enable and reload.
- curl with Host headers.
Recap
- One Nginx, many server_name values.
- sites-available holds configs.
- sites-enabled has symlinks.
- nginx -t before reload.
- curl -H Host tests.