Ravindra BagaleCourses & study guides मराठी Track your progress

Chapter 6: Web Servers — Nginx and Apache

Common Mistakes I See Students Make

Friends, I see these web server mistakes in every batch – two servers on port 80, forgetting to reload, the wrong web root. Read them once; later it will really save you time.

  • Installing both Nginx and Apache and starting both → Address already in use on port 80.
  • Editing the config but not reloading the service, then wondering why nothing changed.
  • Putting files in /var/www/html while Nginx on Amazon Linux serves /usr/share/nginx/html.
  • Using apache2 commands on Amazon Linux/CentOS (it is httpd there).
  • Disabling SELinux permanently instead of fixing labels or booleans.
  • Adding comments at the end of an Apache directive line (Apache does not allow inline comments).
  • Forgetting the semicolon ; at the end of an Nginx directive — nginx -t will tell you the exact line.

Each mistake, what you see, and the fix

Q. Both nginx and Apache started
You see bind() to 0.0.0.0:80 failed (98: Address already in use). Fix: sudo ss -tlnp | grep :80 to find the owner, then stop and disable one of them.

Q. Edited but not reloaded
Nothing changes in the browser. Fix: test and reload, then check with curl -I.

Q. Wrong web root on Amazon Linux nginx
You see the default page. The default nginx root there is /usr/share/nginx/html. Check with sudo nginx -T | grep root.

Q. apache2 commands on Amazon Linux
You see Unit apache2.service not found. On Amazon Linux and CentOS it is httpd.

Similar mistakes on other servers

The same kinds of slips happen on application servers.

Tomcat

Tomcat and another app both want 8080. You see Address already in use in catalina.out. Fix: change the connector port in server.xml or the other app.

Node.js / PM2

The app was started twice (PM2 and systemd). You see EADDRINUSE :::3000. Fix: use one process manager.

Python / Gunicorn

Gunicorn binds 0.0.0.0:8000 and the port is open in the security group, which bypasses nginx. Fix: bind 127.0.0.1:8000.

.NET / Kestrel

Kestrel listens only on localhost:5000 by default, so nginx proxying to the server IP fails. Fix: proxy to 127.0.0.1:5000.

PHP-FPM

The socket path in nginx does not match the FPM pool. You see 502 and "connect() to unix:/run/php-fpm/www.sock failed". Fix: match the paths.

Real examples

Global: Shodan-style internet scans regularly find app ports like 3000, 5000 and 8080 exposed directly. Students often open these "just to test" and forget them. Everyday: two shopkeepers trying to open the same shutter. Only one can own port 80.

Quick self-check before you close the terminal

  1. sudo ss -tlnp: only one owner on port 80.
  2. sudo nginx -t or apachectl configtest: successful.
  3. curl -I http://localhost: 200.
  4. curl -I http://<public-ip> from your laptop: 200.
  5. getenforce on CentOS: still Enforcing.

Indian company example (sample): a junior engineer at a Wipro client project disabled SELinux to fix a 403 and forgot to turn it back on. The audit found it months later. The correct fix (restorecon) takes one command.

Key terms

  • Web server: Serves files and proxies apps: nginx, Apache.
  • Application server: Runs code: PHP-FPM, Gunicorn, PM2, Tomcat, Kestrel.
  • Reverse proxy: Receives requests and forwards them to an app.
  • Status 403: Forbidden: permissions, SELinux or no index file.
  • Status 502: Bad gateway: the app behind the proxy is down.
  • SELinux: Mandatory access control on RHEL-family systems.

Mini case study

Suppose we are a junior cloud engineer at a Bengaluru e-commerce startup (sample data). The team runs a PHP admin, a Node.js storefront API and a Python report job on two EC2 instances. Using this chapter, you write a one-page runbook: which service listens where, how to test and reload each one, which logs to read, and which ports are public (only 80 and 443, plus 22 from the office IP). New team members can then fix most problems on their own.

Recap

  • One owner per port.
  • Test, reload, verify.
  • Know the service name for your OS and your app server.