• v0.1.5 1db4d59f6f

    v0.1.5
    Some checks failed
    Check / eval (push) Successful in 6s
    Release / release (push) Failing after 23s
    Stable

    josephembrey released this 2026-03-26 16:42:31 -04:00 | 13 commits to main since this release

    devvm module, shell direnv, wireguard fixes

    Downloads
  • v0.1.4 7c94570a2c

    v0.1.4
    All checks were successful
    Release / release (push) Successful in 2s
    Check / eval (push) Successful in 4s
    Stable

    josephembrey released this 2026-03-24 16:46:05 -04:00 | 25 commits to main since this release

    Added

    • auth, localDomain, localAuth options on all 27 web-exposed services.
      Every service with a Caddy reverse proxy now has:
      • auth (bool) — toggle Authelia forward-auth on the public domain (default
        true for most services, false for jellyfin, miniflux, forgejo, webhook)
      • localDomain (nullable string) — LAN FQDN for Caddy, automatically excluded
        from Cloudflare DNS records and tunnel ingress
      • localAuth (bool) — toggle Authelia on the local domain (default false)
    • Smart localDomain filtering in cloudflare/dns, cloudflare/tunnel, and
      pihole. These modules now collect all localDomain values from enabled services
      and exclude them from public DNS and tunnel ingress, regardless of naming
      convention. The .local. heuristic is kept as a fallback for non-module Caddy
      hosts.
    • Flake checks output with module evaluation test — verifies all 48 modules
      evaluate without errors. Run with nix flake check.
    • Forgejo CI workflow (.forgejo/workflows/check.yml) — runs nix flake check
      on every push.
    • Flake formatter outputalejandra available via nix fmt.
    • Plex media group optionjosephembrey.plex.group (default "media") and
      meta.groups = [cfg.group], matching the pattern used by all other media services.
    • Caddy Authelia assertion — when caddy's auth.address points to the default
      Authelia address (127.0.0.1:9091), an assertion verifies that
      josephembrey.authelia is enabled. Prevents silent 502 errors from a missing
      auth backend.
    • Jellyfin backward compatibility shimmkRemovedOptionModule for the old
      josephembrey.jellyfin.domains option with a migration message pointing to
      domain/localDomain.

    Changed

    • Breaking: josephembrey.jellyfin.domains replaced with domain/localDomain.
      The old domains (list of strings) option is removed. Use domain for the
      public FQDN and localDomain for LAN access. Existing configs using domains
      will get a clear error message with migration instructions.
    • Media group GID aligned to 1200 across all media services (audiobookshelf,
      bazarr, calibre, jellyfin, radarr, sabnzbd, sonarr, plex). Previously services
      used lib.mkDefault 2000 while the registry module set 1200 — the registry
      always won in practice, but the inconsistency was confusing. All services now
      agree on 1200.
    • docs/OPTIONS.md updated with the new domain option pattern.
    • CLAUDE.md key rules updated to reflect conditional auth.
    • README.md jellyfin example updated from domains to localDomain.

    Fixed

    • Caddy response buffering for media streamingflush_interval -1 added to
      jellyfin, audiobookshelf, and immich reverse proxy blocks. Caddy no longer
      buffers response bodies before forwarding, which caused video/audio stutter
      especially over higher-latency connections (e.g., WireGuard gateway).
    • Redundant cfg.enable removed from 11 impermanence guards (10 media
      services + podman). These guards were inside config = lib.mkIf cfg.enable (lib.mkMerge [...]) which already gates on enable. Plex correctly retains the
      check (different config structure).
    • Crosswatch caddy port — public domain block now uses the ${port} variable
      instead of hardcoded 8787, matching the localDomain block.
    • Cloudflare DNS .local. filter — the DNS module now excludes .local.
      domains from auto-discovered DNS records, matching the existing tunnel filter.
    Downloads
  • v0.1.3 3b649b37fe

    v0.1.3
    All checks were successful
    Release / release (push) Successful in 1s
    Stable

    josephembrey released this 2026-03-23 20:13:12 -04:00 | 34 commits to main since this release

    Changed

    • Breaking: removed josephembrey.caddy.accessLogFile. Consumers should
      remove any accessLogFile setting.

    Fixed

    • josephembrey.caddyglobalConfig and extraConfig are now set at normal
      priority instead of lib.mkDefault. The nixpkgs caddy module also defines
      globalConfig at normal priority (for email + log block), and types.lines
      only concatenates definitions at the same priority — lib.mkDefault was
      silently dropped, which broke acme_dns cloudflare and trusted_proxies.
    • josephembrey.caddy — no longer overrides logFormat, so Caddy uses its
      default console output on stderr (human-readable journalctl -u caddy).
    • josephembrey.cloudflare.fail2ban — when the homelab Caddy module is enabled
      and the caddy jail is active, a named log fail2ban logger is injected into
      services.caddy.globalConfig that writes JSON access logs to
      /var/log/caddy/access.log (with logrotate and impermanence). fail2ban reads
      from the file; journal stays human-readable.
    Downloads
  • v0.1.2 6fb9b583e9

    v0.1.2
    All checks were successful
    Release / release (push) Successful in 2s
    Stable

    josephembrey released this 2026-03-21 23:00:13 -04:00 | 45 commits to main since this release

    Fixed

    • josephembrey.searxng — set services.searx.settings.server.* per key (port, bind_address, secret_key, base_url) instead of one server = lib.mkDefault { ... } attrset, so values merge with nixpkgs and secret_key = "$SEARXNG_SECRET_KEY" is present in generated settings (avoids falling back to upstream ultrasecretkey when use_default_settings is on).
    Downloads
  • v0.1.1 82c90c24b5

    v0.1.1
    All checks were successful
    Release / release (push) Successful in 3s
    Stable

    josephembrey released this 2026-03-21 22:50:31 -04:00 | 46 commits to main since this release

    Added

    • josephembrey.crosswatch.tag (default "latest") for the container image; replaces a hardcoded :latest reference.
    • josephembrey.scrutiny.zfs.collectorTag (default "latest-collector-zfs") for the ZFS collector sidecar image.
    • docs/OPTIONS.md — container modules must expose a tag (or nested tag) per OCI image; defaults must match the tag previously hardcoded on image so unchanged configs keep the same pull behavior.

    Fixed

    • josephembrey.uptime-kuma — avoid services.uptime-kuma.settings.PORT conflicting with nixpkgs (mkDefault "3001" vs homelab "3030"): set PORT with lib.mkOverride 999 so the homelab default wins over upstream mkDefault but plain consumer assignments still override. Caddy reverse_proxy uses the merged settings.PORT so host overrides stay in sync with the app.
    Downloads
  • v0.1.0 019f6414cb

    v0.1.0
    All checks were successful
    Release / release (push) Successful in 9s
    Stable

    josephembrey released this 2026-03-21 19:31:27 -04:00 | 47 commits to main since this release

    First versioned release. Major restructuring of the module tree, consumer ergonomics improvements, and comprehensive documentation.

    Added

    • meta.type option on all service modules — classifies each as nixos (wraps a NixOS service module), container (OCI/podman), or custom (original logic). Available at config.josephembrey.<service>.meta.type.
    • port options on container modules with web UIs: calibre (8081), factorio (34197), gokapi (53842), linkding (9090), sabnzbd (8080), seerr (5055), silverbullet (3000), syncthing (8384). Defaults match previously hardcoded values — no action needed on upgrade.
    • tag option on scrutiny (default "latest-omnibus") for pinning container image versions.
    • uid/gid options on factorio (default 845/845) for stable container user IDs.
    • Stable media group GID: all media modules now set users.groups.${cfg.group}.gid = lib.mkDefault 2000, ensuring consistent file ownership across audiobookshelf, bazarr, calibre, jellyfin, radarr, sabnzbd, and sonarr.
    • Sops ordering guards (after/wants on sops-install-secrets.service) added to linkding, copyparty, openclaw, cloudflare/fail2ban, cloudflare/tunnel. These ensure secrets are available before the service starts.
    • Documentation directory docs/:
      • ORGANIZATION.md — directory layout, category rules, flat vs directory criteria
      • MODULE-STYLE.md — code structure, section ordering, module type patterns
      • OPTIONS.md — option conventions, standard options by module type, UID/GID table
      • GUARDS.mdmkIf vs optionalAttrs, sops and impermanence guard patterns
      • FLAKE.md — flake outputs/inputs, lib.discover, consumer integration, dev shell
    • CHANGELOG.md following Keep a Changelog format.
    • Tag-triggered release workflow (.forgejo/workflows/release.yml) — extracts version notes from this file and creates a Forgejo release on v* tag push.

    Changed

    • BREAKING: Module file paths reorganized. All modules flattened from multi-file directories (e.g., services/bazarr/{options,module,caddy,impermanence}.nix) into single files (e.g., services/media/bazarr.nix). Complex modules (cloudflare, wireguard, recyclarr) retain a directory but with self-contained sub-files instead of split options/module pairs. Transparent to consumers using nixosModules.default — only affects direct file imports.
    • BREAKING: Services organized into categories. Media services moved to modules/services/media/, networking services to modules/services/networking/. Uncategorized services remain flat under modules/services/. Again, transparent to nixosModules.default consumers.
    • BREAKING: josephembrey.searxng default port changed from 8888 to 8890. The old default collided with gluetun's HTTP proxy port. Set josephembrey.searxng.port = 8888 to restore old behavior (not recommended if gluetun is also enabled).
    • BREAKING: services.caddy.logFormat now defaults to JSON with file output at /var/log/caddy/access.log. Previously defaulted to plain text level-only format. This enables fail2ban log parsing. Consumers can override via services.caddy.logFormat (now mkDefault).
    • All NixOS wrapper module values on services.* options now use lib.mkDefault. Consumers can override any preset value at normal priority without needing mkForce. This applies to 22 wrapper modules.
    • Module discovery (modules/services/default.nix) updated from single-level directory scan to hybrid flat-file + category + directory scanning. modules/system/default.nix updated for flat-file scanning.
    • home-assistant uid/gid now use lib.mkForce — required because the upstream NixOS module sets these at normal priority, and our stable IDs must take precedence.
    • CLAUDE.md trimmed to a concise overview with references to docs/.

    Fixed

    • Port collision between searxng (8888) and gluetun HTTP proxy (8888). Searxng moved to 8890; gluetun retains 8888 as the port owner.
    • crosswatch meta.type corrected from custom to container (it runs as an OCI container).
    • webhook meta.type corrected from custom to nixos (it wraps the NixOS webhook service module).
    • discord meta.type corrected from container to custom (it implements a script-based webhook, not an OCI container).
    • backups.nix replaced with pkgs; with explicit pkgs.restic, pkgs.rclone references per Nix style guidelines.
    • glance environment file now uses the upstream services.glance.environmentFile option instead of mkForce on systemd.services.glance.serviceConfig.EnvironmentFile.
    • pihole virtualisation.podman.defaultNetwork.settings.dns_enabled changed from lib.mkForce false to plain false — sufficient to override podman module's mkDefault true without force.
    • bazarr removed redundant systemd.services.bazarr.serviceConfig overrides for DynamicUser, User, and Group that duplicated upstream behavior.
    • Hardcoded sops-install-secrets.service dependencies in backups and cloudflare/dns replaced with conditional (lib.mkIf (config ? sops) ...) guards, so modules work correctly without sops-nix loaded.
    Downloads