# NPM Hands-On Runsheet Use this when you are ready to actively configure Nginx Proxy Manager for Fiddy. ## Inputs To Decide First - `DOMAIN`: Fiddy public domain (example: `fiddy.example.com`) - `UPSTREAM_HOST`: internal app host/IP (example: `192.168.1.50`) - `UPSTREAM_PORT`: app port (default `3000`) - `NPM_CONTAINER`: your NPM container name (for SSH fallback) - `NPM_LOG_PATH`: log path if different from `/var/log/nginx` ## Run 1: Proxy Host Baseline (NPM UI) 1. Proxy Hosts -> Add Proxy Host. 2. Domain Names: `DOMAIN`. 3. Scheme: `http`. 4. Forward Hostname/IP: `UPSTREAM_HOST`. 5. Forward Port: `UPSTREAM_PORT`. 6. Enable: - Block Common Exploits - Websockets Support 7. SSL tab: - Request/choose cert - Force SSL - HTTP/2 Stop and verify: - opening `https://DOMAIN` reaches app homepage. ## Run 2: Proxy Host Advanced (NPM UI) Paste: - `docker/nginx/npm/proxy-host-advanced.conf.example` Stop and verify: - save succeeds with no Nginx validation errors. ## Run 3: Root Location `/` (NPM UI) 1. In that Proxy Host, add Custom Location path `/`. 2. Paste: - `docker/nginx/npm/location-root-advanced.conf.example` Stop and verify: - `curl -I https://DOMAIN` includes `X-Request-Id`. ## Run 4: API Location Controls (NPM UI) Add custom locations and advanced snippets: - `/api/auth/login` -> `docker/nginx/npm/location-auth-advanced.conf.example` - `/api/auth/register` -> `docker/nginx/npm/location-auth-advanced.conf.example` - `/api/entries` -> `docker/nginx/npm/location-write-advanced.conf.example` - `/api/buckets` -> `docker/nginx/npm/location-write-advanced.conf.example` - `/api/groups` -> `docker/nginx/npm/location-write-advanced.conf.example` - `/api/tags` -> `docker/nginx/npm/location-write-advanced.conf.example` - `/api/schedules` (canonical) -> `docker/nginx/npm/location-write-advanced.conf.example` - `/api/recurring-entries` (compatibility, deprecated) -> `docker/nginx/npm/location-write-advanced.conf.example` Stop and verify: - auth/login bad-password bursts eventually return `429`. ## Run 5: Global Nginx `http` Snippet (SSH fallback if needed) If NPM UI does not expose global `http` context: 1. `docker exec -it NPM_CONTAINER sh` 2. Ensure custom path exists: ```bash mkdir -p /data/nginx/custom ``` 3. Write: ```bash cat >/data/nginx/custom/http_top.conf <<'EOF' # paste docker/nginx/npm/http_top.conf.example EOF ``` 4. Reload: ```bash nginx -t && nginx -s reload ``` Stop and verify: - no reload errors - rate limit zones are recognized ## Run 6: Final Functional Validation Run: ```bash scripts/smoke-public-launch.sh https://DOMAIN ``` Expected: - `/api/health/live` and `/api/health/ready` are `200` - `X-Request-Id` header present - JSON response contains `request_id` ## Run 7: Log Path Alignment (if needed) If NPM logs are not in `/var/log/nginx`: - update: - `docker/observability/promtail-config.yml` - `docker/security/fail2ban/jail.d/fiddy-nginx.conf` - `docker/security/crowdsec/acquis.yaml` ## Completion Criteria - All Run 1-6 checks pass. - NPM config persists across restart. - Smoke check passes after NPM restart.