docs: add README and per-file header comments
Test nginx configuration / Static Analysis (pull_request) Failing after 4s
Test nginx configuration / nginx Syntax Check (pull_request) Successful in 16s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m21s

- Rewrote README with full directory structure, add/remove site
  workflows, deploy instructions, and a test suite reference table
- Added a one-line header comment to each sites-available/*.conf
  explaining what category of sites belongs in that file
This commit is contained in:
2026-03-03 16:26:37 -08:00
committed by Naomi Carrigan
parent 12687ad1a2
commit e8318215a9
29 changed files with 154 additions and 3 deletions
+125 -3
View File
@@ -1,10 +1,132 @@
# Nginx Configs # Nginx Configs
This repository holds our NGINX configs and offers a basic script for pulling the latest versions from our servers. This repository holds the nginx configuration for NHCarrigan's production server, with scripts for deploying and pulling changes.
## Live Version ## Directory Structure
These can't really be viewed live... ```
nginx/nginx/ # Maps directly to /etc/nginx/ on the server
├── nginx.conf # Global settings (workers, gzip, TLS, logging)
├── conf.d/
│ ├── cloudflare_ips.conf # Real-IP trust for Cloudflare ranges (auto-updated by cron)
│ ├── logging.conf # Custom log formats (custom_format + json_analytics)
│ └── tuning.conf # Performance tweaks (server_names_hash_bucket_size)
├── sites-available/ # One .conf file per logical group of sites
│ └── *.conf
├── sites-enabled/ # Symlinks to active configs in sites-available/
│ └── * -> ../sites-available/*.conf
└── ... # Standard nginx package files (mime.types, proxy_params, etc.)
```
## Adding a New Site
1. **Identify the right file.** Each `sites-available/*.conf` has a comment at the top describing what belongs there. Pick the most appropriate file, or create a new one if the site does not fit anywhere.
2. **Add the server block**, following this template for a proxied app:
```nginx
server {
listen 443 ssl;
server_name yourapp.nhcarrigan.com;
ssl_certificate /etc/letsencrypt/live/yourapp.nhcarrigan.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourapp.nhcarrigan.com/privkey.pem;
location / {
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:<PORT>;
proxy_redirect off;
}
}
```
Or this template for a static site:
```nginx
server {
listen 443 ssl;
server_name yoursite.nhcarrigan.com;
ssl_certificate /etc/letsencrypt/live/yoursite.nhcarrigan.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yoursite.nhcarrigan.com/privkey.pem;
root /home/naomi/yoursite;
location / {
index index.html;
}
}
```
3. **Keep server blocks sorted alphabetically** by `server_name` within the file. The CI sort check will fail if they are out of order. Note that hyphenated names sort before the bare domain in C locale (e.g. `app-api` before `app`).
4. **If you created a new `.conf` file**, create the corresponding symlink in `sites-enabled/`:
```bash
cd nginx/nginx/sites-enabled
ln -s ../sites-available/newfile.conf newfile.conf
```
5. **Get the SSL certificate** on the server before deploying:
```bash
sudo certbot certonly --nginx -d yourapp.nhcarrigan.com
```
6. **Run the tests** locally to verify everything passes:
```bash
bash test.sh
```
7. **Deploy** (see below).
## Removing a Site
1. Delete the server block from the relevant `sites-available/*.conf` file.
2. If the entire `.conf` file is now empty, delete the file and its `sites-enabled/` symlink.
3. Run `bash test.sh` to confirm nothing is broken.
4. Deploy.
## Deploying Changes
Push the local `nginx/nginx/` directory to the server (the `--delete` flag removes any files on the server that no longer exist locally):
```bash
bash push.sh
```
Then reload nginx to apply the changes:
```bash
ssh prod "sudo systemctl reload nginx"
```
To pull the current server config back into this repository:
```bash
bash pull.sh
```
## Testing
The test suite runs static analysis checks against the config files without requiring a live nginx instance:
```bash
bash test.sh
```
The following checks are run:
| # | Check |
|---|-------|
| 1 | No deprecated TLS versions (TLSv1 / TLSv1.1) |
| 2 | No duplicate `server_name` values |
| 3 | Every `sites-available/*.conf` has a `sites-enabled` symlink |
| 4 | No broken symlinks in `sites-enabled` |
| 5 | No orphaned symlinks in `sites-enabled` |
| 6 | No port-80 listeners in custom server blocks |
| 7 | `ssl_certificate` and `ssl_certificate_key` counts match per file |
| 8 | All plain-HTTP `proxy_pass` targets are local |
| 9 | All SSL cert paths use `/etc/letsencrypt/live/` |
| 10 | Certs use `fullchain.pem` / keys use `privkey.pem` |
| 11 | No raw IP addresses as `server_name` |
| 12 | `conf.d` contains only expected files |
| 13 | Server blocks are sorted alphabetically by `server_name` within each file |
CI additionally runs an nginx syntax check (`nginx -t`) using stub SSL certificates, catching any configuration errors that static analysis cannot detect.
## Feedback and Bugs ## Feedback and Bugs
+1
View File
@@ -1,3 +1,4 @@
# AFP service proxy.
server { server {
listen 443 ssl; listen 443 ssl;
server_name afp.nhcarrigan.com; server_name afp.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Aria bot, Cordelia AI assistant, trans-related services, and legacy redirects.
server { server {
listen 443 ssl; listen 443 ssl;
server_name aria.nhcarrigan.com; server_name aria.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Discord bots and automated services (one entry per bot, sorted alphabetically).
server { server {
listen 443 ssl; listen 443 ssl;
server_name altaria.nhcarrigan.com; server_name altaria.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# CDN reverse proxy to Hetzner object storage, with legacy path redirects and CORS headers.
server { server {
listen 443 ssl; listen 443 ssl;
listen [::]:443 ssl; listen [::]:443 ssl;
@@ -1,3 +1,4 @@
# Celestine webhook handler and legacy hooks redirect.
server { server {
listen 443 ssl; listen 443 ssl;
server_name celestine.nhcarrigan.com; server_name celestine.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Static content and publishing sites: blog, books, donate, music, secrets, style, testimonials.
server { server {
listen 443 ssl; listen 443 ssl;
server_name blog.nhcarrigan.com; server_name blog.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Data service proxy.
server { server {
listen 443 ssl; listen 443 ssl;
server_name data.nhcarrigan.com; server_name data.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Documentation and informational sites: contact, docs, manual, sitemap, socials.
server { server {
listen 443 ssl; listen 443 ssl;
server_name contact.nhcarrigan.com; server_name contact.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Eclaire Angular SPA.
server { server {
listen 443 ssl; listen 443 ssl;
server_name eclaire.nhcarrigan.com; server_name eclaire.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Elowyn Angular SPA.
server { server {
listen 443 ssl; listen 443 ssl;
server_name elowyn.nhcarrigan.com; server_name elowyn.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Grist forms platform (forms-api backend + forms frontend with CSS injection) and legacy form URL redirects.
server { server {
listen 443 ssl; listen 443 ssl;
server_name forms-api.nhcarrigan.com; server_name forms-api.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Games and gaming projects: beccalia, games hub, goblin, loan, lore, silly, wompwomp, yurigpt.
server { server {
listen 443 ssl; listen 443 ssl;
server_name beccalia.nhcarrigan.com; server_name beccalia.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Self-hosted Gitea instance.
server { server {
listen 443 ssl; listen 443 ssl;
server_name git.nhcarrigan.com; server_name git.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Hikari desktop app (Angular SPA + API backend) and legacy redirect subdomains.
server { server {
listen 443 ssl; listen 443 ssl;
server_name announcements.nhcarrigan.com; server_name announcements.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Library service proxy.
server { server {
listen 443 ssl; listen 443 ssl;
server_name library.nhcarrigan.com; server_name library.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Lucinda full-stack app (Angular SPA + API backend).
server { server {
listen 443 ssl; listen 443 ssl;
server_name lucinda.nhcarrigan.com; server_name lucinda.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Lynira.link domain (bare + www).
server { server {
listen 443 ssl; listen 443 ssl;
server_name lynira.link; server_name lynira.link;
+1
View File
@@ -1,3 +1,4 @@
# Mommy bot suite: mommy-bot Discord bot, mommy-slack Slack bot, mommy web front-end.
server { server {
listen 443 ssl; listen 443 ssl;
server_name mommy-bot.nhcarrigan.com; server_name mommy-bot.nhcarrigan.com;
@@ -1,3 +1,4 @@
# Monitoring stack: analytics, incidents, logs, telemetry, uptime.
server { server {
listen 443 ssl; listen 443 ssl;
server_name analytics.nhcarrigan.com; server_name analytics.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Nails app: Angular front-end SPA and API backend.
server { server {
listen 443 ssl; listen 443 ssl;
server_name nails-api.nhcarrigan.com; server_name nails-api.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# SilverBullet notes instance and Planka project board.
server { server {
listen 443 ssl; listen 443 ssl;
server_name board.nhcarrigan.com; server_name board.nhcarrigan.com;
@@ -1,3 +1,5 @@
# Personal portfolio and vanity domains (naomi.lgbt, naomi.party, nhcarrigan.com, nhcarrigan.link, resume)
# plus a wildcard catch-all that redirects *.naomi.lgbt → *.nhcarrigan.com.
server { server {
listen 443 ssl; listen 443 ssl;
server_name naomi.lgbt; server_name naomi.lgbt;
+1
View File
@@ -1,3 +1,4 @@
# Rosalia alerting service and legacy alerts redirect.
server { server {
listen 443 ssl; listen 443 ssl;
server_name alerts.nhcarrigan.com; server_name alerts.nhcarrigan.com;
@@ -1,3 +1,4 @@
# Scheduling shortcuts that redirect to zcal.co (cyc, meet) and tasks redirect.
server { server {
listen 443 ssl; listen 443 ssl;
server_name cyc.nhcarrigan.com; server_name cyc.nhcarrigan.com;
@@ -1,3 +1,4 @@
# Security tooling: SonarQube code quality gate and DefectDojo vulnerability management.
server { server {
listen 443 ssl; listen 443 ssl;
server_name quality.nhcarrigan.com; server_name quality.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Discourse community support forum and legacy chat/forum redirects.
server { server {
listen 443 ssl; listen 443 ssl;
server_name chat.nhcarrigan.com; server_name chat.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# Vitalia app: Angular front-end SPA and API backend.
server { server {
listen 443 ssl; listen 443 ssl;
server_name vitalia-api.nhcarrigan.com; server_name vitalia-api.nhcarrigan.com;
+1
View File
@@ -1,3 +1,4 @@
# wtf.naomi.lgbt personal project.
server { server {
listen 443 ssl; listen 443 ssl;
server_name wtf.naomi.lgbt; server_name wtf.naomi.lgbt;