diff --git a/services/pelican.nix b/services/pelican.nix index 835d7e9..531fc46 100644 --- a/services/pelican.nix +++ b/services/pelican.nix @@ -28,36 +28,18 @@ # 3. Node → Configuration tab → copy the generated YAML to # /etc/pelican/config.yml on this host, then # `systemctl restart docker-pelican-wings`. -{ config, pkgs, lib, ... }: -let - # Replaces the image's default Caddyfile, which would try to fetch its own - # Let's Encrypt cert. nginx already terminates TLS for us, so serve plain - # HTTP on :80 and trust the forwarded headers. private_ranges rather than a - # literal IP: requests arrive from the docker bridge gateway, not 127.0.0.1, - # and the published port is localhost-only anyway. - caddyfile = pkgs.writeText "pelican-Caddyfile" '' - { - admin off - servers { - trusted_proxies static private_ranges - } - } - - :80 { - root * /var/www/html/public - encode gzip - - php_fastcgi 127.0.0.1:9000 - file_server - } - ''; -in +{ config, lib, ... }: { config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") { systemd.tmpfiles.rules = [ - "d /var/lib/pelican-panel 0755 root root -" - "d /var/lib/pelican-panel/logs 0755 root root -" + # Panel runs as www-data (uid/gid 82, alpine) and writes its .env, + # SQLite DB and storage into /pelican-data — root-owned host dirs make + # the entrypoint die on "touch: /pelican-data/.env: Permission denied". + # Numeric because no host user owns 82; nothing else on this box does. + "d /var/lib/pelican-panel 0750 82 82 -" + "d /var/lib/pelican-panel/logs 0750 82 82 -" + # wings runs as root (distroless image, no USER directive). "d /etc/pelican 0755 root root -" "d /var/lib/pelican 0755 root root -" "d /var/log/pelican 0755 root root -" @@ -69,18 +51,25 @@ in volumes = [ "/var/lib/pelican-panel:/pelican-data" "/var/lib/pelican-panel/logs:/var/www/html/storage/logs" - "${caddyfile}:/etc/caddy/Caddyfile:ro" ]; # Localhost-only; nginx fronts it (see nginx.nix). ports = [ "127.0.0.1:8092:80" ]; environment = { XDG_DATA_HOME = "/pelican-data"; APP_URL = "https://panel.nordhammer.it"; - ADMIN_EMAIL = "fredrik@nordhammer.it"; + # Required: with an https APP_URL the entrypoint refuses to start + # unless either LE_EMAIL is set or it knows TLS is terminated + # upstream. This also switches the bundled Caddy to plain :80 with + # auto_https off, so no custom Caddyfile is needed. + BEHIND_PROXY = "true"; APP_ENV = "production"; APP_DEBUG = "false"; - # Laravel otherwise renders http:// asset URLs behind the proxy. - TRUSTED_PROXIES = "*"; + # Without this Laravel sees the container's own IP and renders http:// + # asset URLs. Caddy reuses the same value for trusted_proxies, so it + # must be real CIDRs, not "*". nginx reaches us via the published + # localhost port, so the request arrives from the docker bridge + # gateway in 172.16/12 — not 127.0.0.1. + TRUSTED_PROXIES = "172.16.0.0/12,10.0.0.0/8,127.0.0.1/32"; TZ = "Europe/Stockholm"; }; extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];