# Exercise 2: Run a Node.js App Properly Under systemd

You've been given a VM (Ubuntu 24.04, or a container with systemd such as `jrei/systemd-ubuntu`) and a Node.js app in `/opt/petpal/api` that currently runs as `root` inside a `screen` session started by hand. It listens on port 8080, writes uploads to `/var/lib/petpal/uploads` and needs `DATABASE_URL`.

## Tasks

1. Create a system user `petpal` without a login shell or home directory and give it ownership of only what it needs.
2. Write `/etc/systemd/system/petpal-api.service`: environment file (mode 0640, root:petpal), restart policy, graceful stop (the app handles SIGTERM in < 20 s), `LimitNOFILE`, memory limit 1 GiB, and hardening (`NoNewPrivileges`, `ProtectSystem=strict`, `ReadWritePaths`, `PrivateTmp`, `ProtectHome`, `CapabilityBoundingSet=` empty, `RestrictAddressFamilies`).
3. Get `systemd-analyze security petpal-api` below **4.0** ("OK") and record the before/after scores.
4. Prove the restart policy: `kill -9` the main PID and show that systemd restarts it; then show `StartLimitBurst` stopping a crash loop (make the app exit immediately 6 times).
5. Add a `petpal-cleanup.service` (oneshot) + `petpal-cleanup.timer` that deletes uploads older than 30 days daily at 04:00 with a random delay up to 10 min and `Persistent=true`.
6. Use `journalctl` to show only error-priority logs from the last hour, and configure journald to keep at most 2 GiB.
7. Explain what happens, step by step, on `systemctl stop petpal-api` if the app ignores SIGTERM.

## Requirements Checklist

- [ ] `useradd --system --no-create-home --shell /usr/sbin/nologin petpal`; ownership limited to `/var/lib/petpal`.
- [ ] Unit has `User=`, `EnvironmentFile=`, `Restart=on-failure`, `RestartSec`, `TimeoutStopSec=30`, `LimitNOFILE`, `MemoryMax=1G`, and the hardening options; `daemon-reload` + `enable --now` used.
- [ ] Security exposure score before/after recorded, final < 4.0.
- [ ] Restart after SIGKILL demonstrated; crash loop ends in `failed` state with "start request repeated too quickly".
- [ ] Timer unit with `OnCalendar=*-*-* 04:00:00`, `RandomizedDelaySec=600`, `Persistent=true`; `systemctl list-timers` shows it.
- [ ] `journalctl -u petpal-api -p err --since "1 hour ago"`; `SystemMaxUse=2G` in `journald.conf`.
- [ ] Stop sequence explained: SIGTERM → wait `TimeoutStopSec` → SIGKILL to the remaining cgroup processes.
