-
v0.1.5
Stablereleased this
2026-03-26 16:42:31 -04:00 | 13 commits to main since this releasedevvm module, shell direnv, wireguard fixes
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
3 downloads
-
Source code (ZIP)
-
v0.1.4
Stablereleased this
2026-03-24 16:46:05 -04:00 | 25 commits to main since this releaseAdded
auth,localDomain,localAuthoptions 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
truefor most services,falsefor jellyfin, miniflux, forgejo, webhook)localDomain(nullable string) — LAN FQDN for Caddy, automatically excluded
from Cloudflare DNS records and tunnel ingresslocalAuth(bool) — toggle Authelia on the local domain (defaultfalse)
- Smart
localDomainfiltering in cloudflare/dns, cloudflare/tunnel, and
pihole. These modules now collect alllocalDomainvalues 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
checksoutput with module evaluation test — verifies all 48 modules
evaluate without errors. Run withnix flake check. - Forgejo CI workflow (
.forgejo/workflows/check.yml) — runsnix flake check
on every push. - Flake
formatteroutput —alejandraavailable vianix fmt. - Plex media group option —
josephembrey.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.addresspoints to the default
Authelia address (127.0.0.1:9091), an assertion verifies that
josephembrey.autheliais enabled. Prevents silent 502 errors from a missing
auth backend. - Jellyfin backward compatibility shim —
mkRemovedOptionModulefor the old
josephembrey.jellyfin.domainsoption with a migration message pointing to
domain/localDomain.
Changed
- Breaking:
josephembrey.jellyfin.domainsreplaced withdomain/localDomain.
The olddomains(list of strings) option is removed. Usedomainfor the
public FQDN andlocalDomainfor LAN access. Existing configs usingdomains
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
usedlib.mkDefault 2000while the registry module set 1200 — the registry
always won in practice, but the inconsistency was confusing. All services now
agree on 1200. docs/OPTIONS.mdupdated with the new domain option pattern.CLAUDE.mdkey rules updated to reflect conditional auth.README.mdjellyfin example updated fromdomainstolocalDomain.
Fixed
- Caddy response buffering for media streaming —
flush_interval -1added 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.enableremoved from 11 impermanence guards (10 media
services + podman). These guards were insideconfig = 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 hardcoded8787, 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
-
Source code (ZIP)
3 downloads
-
Source code (TAR.GZ)
3 downloads
-
released this
2026-03-23 20:13:12 -04:00 | 34 commits to main since this releaseChanged
- Breaking: removed
josephembrey.caddy.accessLogFile. Consumers should
remove anyaccessLogFilesetting.
Fixed
josephembrey.caddy—globalConfigandextraConfigare now set at normal
priority instead oflib.mkDefault. The nixpkgs caddy module also defines
globalConfigat normal priority (for email + log block), andtypes.lines
only concatenates definitions at the same priority —lib.mkDefaultwas
silently dropped, which brokeacme_dns cloudflareandtrusted_proxies.josephembrey.caddy— no longer overrideslogFormat, so Caddy uses its
default console output on stderr (human-readablejournalctl -u caddy).josephembrey.cloudflare.fail2ban— when the homelab Caddy module is enabled
and the caddy jail is active, a namedlog fail2banlogger is injected into
services.caddy.globalConfigthat writes JSON access logs to
/var/log/caddy/access.log(with logrotate and impermanence). fail2ban reads
from the file; journal stays human-readable.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
2 downloads
- Breaking: removed
-
released this
2026-03-21 23:00:13 -04:00 | 45 commits to main since this releaseFixed
josephembrey.searxng— setservices.searx.settings.server.*per key (port,bind_address,secret_key,base_url) instead of oneserver = lib.mkDefault { ... }attrset, so values merge with nixpkgs andsecret_key = "$SEARXNG_SECRET_KEY"is present in generated settings (avoids falling back to upstreamultrasecretkeywhenuse_default_settingsis on).
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
3 downloads
-
released this
2026-03-21 22:50:31 -04:00 | 46 commits to main since this releaseAdded
josephembrey.crosswatch.tag(default"latest") for the container image; replaces a hardcoded:latestreference.josephembrey.scrutiny.zfs.collectorTag(default"latest-collector-zfs") for the ZFS collector sidecar image.docs/OPTIONS.md— container modules must expose atag(or nested tag) per OCI image; defaults must match the tag previously hardcoded onimageso unchanged configs keep the same pull behavior.
Fixed
josephembrey.uptime-kuma— avoidservices.uptime-kuma.settings.PORTconflicting with nixpkgs (mkDefault "3001"vs homelab"3030"): setPORTwithlib.mkOverride 999so the homelab default wins over upstreammkDefaultbut plain consumer assignments still override. Caddyreverse_proxyuses the mergedsettings.PORTso host overrides stay in sync with the app.
Downloads
-
Source code (ZIP)
4 downloads
-
Source code (TAR.GZ)
3 downloads
-
released this
2026-03-21 19:31:27 -04:00 | 47 commits to main since this releaseFirst versioned release. Major restructuring of the module tree, consumer ergonomics improvements, and comprehensive documentation.
Added
meta.typeoption on all service modules — classifies each asnixos(wraps a NixOS service module),container(OCI/podman), orcustom(original logic). Available atconfig.josephembrey.<service>.meta.type.portoptions 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.tagoption on scrutiny (default"latest-omnibus") for pinning container image versions.uid/gidoptions 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/wantsonsops-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 criteriaMODULE-STYLE.md— code structure, section ordering, module type patternsOPTIONS.md— option conventions, standard options by module type, UID/GID tableGUARDS.md—mkIfvsoptionalAttrs, sops and impermanence guard patternsFLAKE.md— flake outputs/inputs,lib.discover, consumer integration, dev shell
CHANGELOG.mdfollowing Keep a Changelog format.- Tag-triggered release workflow (
.forgejo/workflows/release.yml) — extracts version notes from this file and creates a Forgejo release onv*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 usingnixosModules.default— only affects direct file imports. - BREAKING: Services organized into categories. Media services moved to
modules/services/media/, networking services tomodules/services/networking/. Uncategorized services remain flat undermodules/services/. Again, transparent tonixosModules.defaultconsumers. - BREAKING:
josephembrey.searxngdefault port changed from 8888 to 8890. The old default collided with gluetun's HTTP proxy port. Setjosephembrey.searxng.port = 8888to restore old behavior (not recommended if gluetun is also enabled). - BREAKING:
services.caddy.logFormatnow 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 viaservices.caddy.logFormat(nowmkDefault). - All NixOS wrapper module values on
services.*options now uselib.mkDefault. Consumers can override any preset value at normal priority without needingmkForce. 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.nixupdated for flat-file scanning. home-assistantuid/gid now uselib.mkForce— required because the upstream NixOS module sets these at normal priority, and our stable IDs must take precedence.CLAUDE.mdtrimmed to a concise overview with references todocs/.
Fixed
- Port collision between searxng (8888) and gluetun HTTP proxy (8888). Searxng moved to 8890; gluetun retains 8888 as the port owner.
crosswatchmeta.type corrected fromcustomtocontainer(it runs as an OCI container).webhookmeta.type corrected fromcustomtonixos(it wraps the NixOS webhook service module).discordmeta.type corrected fromcontainertocustom(it implements a script-based webhook, not an OCI container).backups.nixreplacedwith pkgs;with explicitpkgs.restic,pkgs.rclonereferences per Nix style guidelines.glanceenvironment file now uses the upstreamservices.glance.environmentFileoption instead ofmkForceonsystemd.services.glance.serviceConfig.EnvironmentFile.piholevirtualisation.podman.defaultNetwork.settings.dns_enabledchanged fromlib.mkForce falseto plainfalse— sufficient to override podman module'smkDefault truewithout force.bazarrremoved redundantsystemd.services.bazarr.serviceConfigoverrides forDynamicUser,User, andGroupthat duplicated upstream behavior.- Hardcoded
sops-install-secrets.servicedependencies in backups and cloudflare/dns replaced with conditional(lib.mkIf (config ? sops) ...)guards, so modules work correctly without sops-nix loaded.
Downloads
-
Source code (ZIP)
2 downloads
-
Source code (TAR.GZ)
2 downloads