feat: add packaging, deployment, error pages, and project docs

Phase 7 — Polish:
- Error page template with styled 404/403/500 pages
- Error rendering helper on Renderer

Phase 8 — Packaging & Deployment:
- Containerfile: multi-stage build, non-root user, health check,
  OCI labels with build date and git revision
- Makefile: build, test, cross-compile, deb, rpm, container,
  tarballs, checksums targets
- nfpm.yaml: .deb and .rpm package config
- systemd service: hardened with NoNewPrivileges, ProtectSystem,
  ProtectHome, PrivateTmp, RestrictSUIDSGID
- Default environment file with commented examples
- postinstall/preremove scripts (shellcheck validated)
- compose.yaml: example Podman/Docker Compose
- Caddyfile.example: subdomain, subpath, and remote proxy configs
- CHANGELOG.md for release notes
- CLAUDE.md with architecture, conventions, and quick reference

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2026-03-29 16:34:32 +02:00
commit 1fc42bf1b2
16 changed files with 435 additions and 2 deletions

16
dist/favoritter.env vendored Normal file
View file

@ -0,0 +1,16 @@
# Favoritter configuration
# See README.md for all available environment variables.
FAVORITTER_DB_PATH=/var/lib/favoritter/favoritter.db
FAVORITTER_UPLOAD_DIR=/var/lib/favoritter/uploads
FAVORITTER_LISTEN=127.0.0.1:8080
# Uncomment and set on first run to create the admin user:
# FAVORITTER_ADMIN_USERNAME=admin
# FAVORITTER_ADMIN_PASSWORD=changeme
# Set this to your public URL for correct feeds, cookies, and OpenGraph:
# FAVORITTER_EXTERNAL_URL=https://faves.example.com
# If your reverse proxy is on another machine (WireGuard/Tailscale):
# FAVORITTER_TRUSTED_PROXIES=100.64.0.0/10

25
dist/favoritter.service vendored Normal file
View file

@ -0,0 +1,25 @@
[Unit]
Description=Favoritter - Self-hosted favorites web app
After=network.target
[Service]
Type=simple
User=favoritter
Group=favoritter
EnvironmentFile=/etc/favoritter/favoritter.env
ExecStart=/usr/bin/favoritter
Restart=on-failure
RestartSec=5
# Hardening
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/favoritter
PrivateTmp=yes
ProtectKernelTunables=yes
ProtectControlGroups=yes
RestrictSUIDSGID=yes
[Install]
WantedBy=multi-user.target

21
dist/postinstall.sh vendored Executable file
View file

@ -0,0 +1,21 @@
#!/bin/sh
# Post-install script for Favoritter .deb/.rpm package.
# Creates the system user and sets directory permissions.
set -e
# Create system user if it doesn't exist.
if ! getent passwd favoritter >/dev/null 2>&1; then
useradd -r -s /usr/sbin/nologin -d /var/lib/favoritter favoritter
fi
# Ensure data directories exist with correct ownership.
install -d -o favoritter -g favoritter -m 0750 /var/lib/favoritter
install -d -o favoritter -g favoritter -m 0750 /var/lib/favoritter/uploads
# Reload systemd to pick up the service file.
if command -v systemctl >/dev/null 2>&1; then
systemctl daemon-reload
fi
echo "Favoritter installed. Configure /etc/favoritter/favoritter.env then run:"
echo " sudo systemctl enable --now favoritter"

9
dist/preremove.sh vendored Executable file
View file

@ -0,0 +1,9 @@
#!/bin/sh
# Pre-remove script for Favoritter .deb/.rpm package.
# Stops the service before package removal.
set -e
if command -v systemctl >/dev/null 2>&1; then
systemctl stop favoritter 2>/dev/null || true
systemctl disable favoritter 2>/dev/null || true
fi