Web Services
Web Services & Databases
Modern, high-performance web architecture with automated certificate management and robust database backends.
Nginx Reverse Proxy
Our web architecture uses Nginx (specifically the nginxQuic fork) as a centralized reverse proxy and SSL terminator.
Core Features
- Protocols: Native support for HTTP/3 (QUIC) and kTLS (Kernel TLS acceleration) for maximum performance.
- SSL/TLS: Automated certificate management via ACME (Let’s Encrypt) using DNS-01 challenges (Cloudflare).
- Security:
- Sinkhole: A default “deny-by-default” virtual host drops all requests using unknown hostnames or raw IPs (HTTP 444).
- Tailscale Real-IP: Automatically restores original client IPs from Tailscale proxy headers.
- 0-RTT: Supports TLS 1.3 Early Data to reduce connection latency.
Deployment Architecture
We typically employ a “VPN-Backend” architecture:
- Edge VPS (
vps-pacman): Terminates public SSL and forwards traffic over Tailscale. - Homelab Nodes (
lab-matrix,id3-eniac): Receive traffic over encrypted Tailscale tunnels (Port 80). - Internal SSL: Optional “Double TLS” can be enabled for strict environments, though Tailscale’s native WireGuard encryption is the default transport.
Troubleshooting ACME Permissions
If you encounter permission errors where Nginx cannot read certificates:
- The
nginxuser is automatically added to theacmegroup in our modules. - Ensure the certificate exists in
/var/lib/acme/<domain>/.
PostgreSQL Database
PostgreSQL is the primary database backend for most web services in this repository.
Declarative Lifecycle (How it works)
Unlike traditional systems that require manual CREATE DATABASE and CREATE USER commands, our setup is fully declarative via the ensures system in modules/services/dev/postgresql.nix.
- Definition: You define your required DB and user in the module (e.g.,
vaultwarden.nixorheadscale.nix) usingmodules.services.database.postgresql.ensures. - NixOS Options: This populates the standard NixOS options:
services.postgresql.ensureDatabasesservices.postgresql.ensureUsers
- Automated Construction: At boot, the PostgreSQL Post-Start script runs automatically. It checks for the existence of the user and database. If they don’t exist, it creates them instantly with the correct ownership.
- Password Management: Our module extends this by automatically running
ALTER USER ... WITH PASSWORDusing secrets from Agenix (ifpasswordFileis provided), ensuring your DB is both initialized and secured without any manual steps.
Maintenance & Versions
We aim for the latest stable versions (currently PostgreSQL 18).
- State Preservation: PostgreSQL data is stored in
/var/lib/postgresql/<version>. - Upgrading: When upgrading the
package(e.g., from 17 to 18), NixOS will NOT automatically migrate your data. You must manually run the migration scripts provided by the module.
Manually Upgrading PostgreSQL
The postgresql.nix module provides custom helper scripts in the system path:
# Example: Upgrading from 17 to 18
sudo upgrade-pg-cluster-17-18
Note: Always backup your data before running an upgrade script.
Authentication Policy
We use a “Security-First, Ease-of-Use Second” policy:
- Local Trust: Services defined in the
ensureslist are automatically grantedtrustaccess over local TCP/Unix sockets. - Tailscale Trust: All traffic originating from the Tailscale/Headscale network (
100.64.0.0/10) is trusted by default, allowing seamless cross-host database access. - SCRAM-SHA-256: All other TCP connections require strong password authentication using SCRAM.
Service Specifics
Forgejo Mailer
Forgejo is configured to use a professional SMTP setup. By default, it uses Mailjet but can be easily pointed to your self-hosted Stalwart server.
- Sender Address: Defaults to
[email protected]. - Customizing SMTP:
modules.services.git.forgejo.mailer = { from = "[email protected]"; host = "mail.alienzj.org"; # Point to your Stalwart server port = 587; }; - Secrets: SMTP credential is managed via
age.secrets.forgejo-smtp-pass.