Skip to main content

Assignment 1: Stand up Nginx in front of an app database

Goal: Put the whole module together: create a properly isolated per-app database and user on a lab DB VM, then serve and reverse-proxy a small app through Nginx — the everyday "web tier + data tier" shape you'll meet constantly.

Where: One Nginx host of your choice on the lab plus a lab database VM — PostgreSQL-Server (10.100.100.13), MariaDB-Server (10.100.100.14), or MySQL-Server (10.100.100.15). Pick one DB VM.

Tasks

  1. Create the per-app database + user on your chosen DB VM. Connect as admin (sudo mysql or sudo -u postgres psql), then:
    • CREATE DATABASE a database named for your app (e.g. notesdb).
    • CREATE USER a dedicated app user with its OWN password (record it as <REDACTED> in your write-up — never paste the real one).
    • GRANT privileges on only that database to that user. Do not use root/admin as the app account.
  2. Connect over the network from a second host as the app user (mysql -h 10.100.100.15 -u notesuser -p notesdb or psql -h 10.100.100.13 -U notesuser -d notesdb) to prove the user and grant work. Create one table and insert one row.
  3. Install Nginx on your web host and serve a static index.html from a server block you write in /etc/nginx/sites-available/, enabled via a symlink into sites-enabled/.
  4. Run a tiny app that talks to your database (any small Node/Python/PHP script, or a stand-in service on a local port like 3000 that returns a page). It must read from the database using the per-app credentials.
  5. Reverse-proxy that app through Nginx: add a location / with proxy_pass to http://127.0.0.1:3000, preserving the Host header. Validate with nginx -t, then systemctl reload nginx.
  6. Confirm the chain works end to end with curl against Nginx (port 80), and note where TLS would terminate in the lab.

Deliverable

A short markdown write-up containing: the SQL you ran (passwords shown as <REDACTED>), your Nginx server block(s), the output of nginx -t, and a curl showing both the static page and the proxied app responding. State which DB VM/IP you used and which app user owns which database.

Acceptance criteria — you're done when:

  • A dedicated database exists on a named lab DB VM (record which IP).
  • A dedicated app user exists with its OWN password and is granted privileges on ONLY that database (not root/admin, not server-wide).
  • You connected over the network as that app user and created a table + inserted a row.
  • Nginx serves your static index.html via a server block enabled through sites-enabled/.
  • sudo nginx -t reports the configuration is OK.
  • Nginx reverse-proxies to your app on 127.0.0.1:3000 and preserves the Host header (proxy_set_header Host $host).
  • curl http://<nginx-host>/ returns the proxied app's response.
  • Your write-up states where TLS terminates in the lab (HAProxy edge) and why the app's server block uses listen 80;.

Hints

  • Test from a different host than the DB VM — connecting from the DB's own localhost can hide grant/host-matching problems.
  • MySQL identifies users as 'user'@'host'; use a host pattern like 'notesuser'@'10.100.100.%' so the lab subnet can connect.
  • For Postgres remote logins you may need listen_addresses in postgresql.conf and a pg_hba.conf line for the subnet, then reload.
  • A 502 Bad Gateway from Nginx almost always means your app isn't running on the expected port — check the app, then the proxy_pass URL.
  • Run nginx -t before every reload; read /var/log/nginx/error.log when stuck.
  • Do NOT add TLS certs to your Nginx — in the lab the HAProxy edge terminates TLS and forwards plain HTTP with the Host header.
  • Blocked for >~30 min after re-reading the lessons? Bring what you've tried to your mentor.