Core & Portal
Remote Access
Section titled “Remote Access”All active services are accessible remotely via Cloudflare Zero Trust (Tunnel) — no open ports, no exposed IP. The tunnel is deployed directly as a native systemd service (cloudflared) in NixOS.
| Service | Local IP / Port | Local Alias | Public Route |
|---|---|---|---|
| Portal | <homelab.ip>:80 | nixos.local:80 | homepage-home.javiersc.com |
| Home Assistant | <homelab.ip>:8123 | nixos.local:8123 | home-assistant-home.javiersc.com |
| Jellyfin | <homelab.ip>:8096 | nixos.local:8096 | jellyfin-home.javiersc.com |
| Transmission | <homelab.ip>:9091 | nixos.local:9091 | transmission-home.javiersc.com |
| Sonarr | <homelab.ip>:8989 | nixos.local:8989 | sonarr-home.javiersc.com |
| Radarr | <homelab.ip>:7878 | nixos.local:7878 | radarr-home.javiersc.com |
| Prowlarr | <homelab.ip>:9696 | nixos.local:9696 | prowlarr-home.javiersc.com |
| Jackett | <homelab.ip>:9117 | nixos.local:9117 | jackett-home.javiersc.com |
| Backrest | <homelab.ip>:9898 | nixos.local:9898 | backrest-home.javiersc.com |
| Documentation | Cloudflare Pages | N/A | docs-home.javiersc.com |
| LiteLLM | <homelab.ip>:14000 | nixos.local:14000 | litellm-home.javiersc.com |
| Ollama | <homelab.ip>:11434 | nixos.local:11434 | ollama-home.javiersc.com |
| PicoClaw | <homelab.ip>:18800 | nixos.local:18800 | picoclaw-home.javiersc.com |
| Cockpit | <homelab.ip>:9090 | nixos.local:9090 | cockpit-home.javiersc.com |
| OTBR | <homelab.ip>:8091 | nixos.local:8091 | otbr-home.javiersc.com |
The Homelab SSH MCP endpoint intentionally does not appear in this table. It binds to 127.0.0.1:19000 and must not be registered in homelab.proxies.
Key Integration Logic
Section titled “Key Integration Logic”- Jackett: Acts as a proxy between our indexers (Torznab/RSS) and the Arr stack (Sonarr/Radarr). It is essential for searching content in private/public trackers that are not natively supported by Prowlarr or the Arr apps themselves.
- Local/Remote Access Toggle: To solve the issue of accessing services natively on LAN vs. via Cloudflare URLs externally, we developed a custom toggle injected via Nginx. It dynamically rewrites all dashboard links to point to either the internal IP (
<homelab.ip>) or the public domain.
Note: Multicast DNS (mDNS) is enabled via Avahi, making the
.localdomains available on the LAN without extra DNS configuration.
Homepage Dashboard
Section titled “Homepage Dashboard”The entry point for the homelab is built using Homepage, natively declared in modules/nixos/services/portal.nix.
UI & Structure:
- Layout: Organized into four main categories: Automation (Home Assistant), Media & Entertainment (Jellyfin, Transmission), Management (Sonarr, Radarr, Prowlarr), and Infrastructure (Documentation, Cloudflare).
- Aesthetics: Dark theme, blurred cards (
cardBlur: "sm"), and an Unsplash background image. - Widgets: Includes system monitoring (CPU/Memory) and date/time.
Secrets and Integrations
Section titled “Secrets and Integrations”The dashboard integrates with Home Assistant to show live data. This requires a Long-Lived Access Token, which is managed securely:
- Storage: Stored in the
Homelabvault in 1Password. - Injection: Fetched at runtime via
ExecStartPreusing thehomelab.fetchSecretFilehelper. - Sandboxing: Due to Homepage’s strict security, the
systemdunit sandbox is slightly relaxed to allow the 1Password CLI to run.
Nginx Proxy and Local/Remote Access Toggle
Section titled “Nginx Proxy and Local/Remote Access Toggle”The Homelab handles dynamic routing depending on where you access it from. We use Nginx (modules/nixos/services/proxy/default.nix) to serve the dashboard and proxy local services through port 80. This allows a single local entry point for the Cloudflare Tunnel.
To solve the issue of accessing services natively on LAN vs. via Cloudflare URLs externally, we developed a Local/Remote Access Toggle:
- A custom JavaScript file (
modules/nixos/services/proxy/toggle.js) is injected into the Homepage UI via Nginx (location = /api/config/custom.js). - It renders a toggle button next to the system clock on the dashboard.
- Remote Mode (Default): Links point to public Cloudflare domain routes (e.g.,
https://jellyfin-home.javiersc.com). - Local Mode: Toggling the button saves the state in
localStorageand dynamically rewrites all service links on the DOM to point to their direct local IP and port (e.g.,http://<homelab.ip>:8096).
Local Icons and Favicon
Section titled “Local Icons and Favicon”Service icons and the browser favicon are served locally — no external CDN dependencies.
Icon serving:
- Icons live in
assets/icons/(SVG or WebP) and are served by Nginx via a location alias at/icons/. - Referenced in Homepage config as
/icons/<name>-logo.svg(the-logosuffix prevents Homepage from resolving them via its built-in CDN). - Services without a local icon fall back to the Homepage CDN automatically.
Favicon:
- The browser favicon is the NixOS snowflake logo (
assets/icons/nixos-logo.svg). - Nginx intercepts all favicon-related paths (
/homepage.ico,/favicon-32x32.png,/favicon-16x16.png,/android-chrome-*.png) before proxying to Homepage. - PNG variants are generated at build time from the SVG using
librsvgvia apkgs.runCommandderivation inmodules/nixos/services/proxy/default.nix. - A custom
/site.webmanifestis also served so PWA installs use the NixOS icon.
Media Services Management
Section titled “Media Services Management”Transmission Scheduling
Section titled “Transmission Scheduling”To optimize network performance and ISP ratios, Transmission follows an automated schedule:
- Day Mode (08:00 - 00:00): Download capped at 50MB/s, Upload disabled (0 kb/s). This ensures maximum bandwidth for home use.
- Night Mode (00:00 - 08:00): Download 50MB/s, Upload 50MB/s. Maximum seeding performance during off-peak hours.
- Manual Overdrive: The “Turtle” button in the UI is reserved for emergency manual pausing.
Services Pending NixOS Migration
Section titled “Services Pending NixOS Migration”The following services were part of the previous architecture and are currently pending integration into the new NixOS native deployment:
- Appwrite (Backend)
- Immich (Photos)
- Penpot (Design)
- Postiz (Social)