Home Assistant
Overview
Section titled “Overview”Home Assistant runs as a Podman OCI container (virtualisation.oci-containers) using the official image (ghcr.io/home-assistant/home-assistant:stable). It runs with host networking (--network=host) for direct LAN and local loopback connectivity with other homelab services (such as Mosquitto, Matter Server, Whisper, and Piper).
The state directory /var/lib/hass is mounted to /config inside the container. This preserves all runtime state, entity registries, Lovelace dashboards, automations, and long-lived tokens, while eliminating the operational maintenance of declaring Python packages or component derivations in NixOS.
In this homelab, Home Assistant is enhanced with HACS (Home Assistant Community Store) for custom integrations and LLMs (OpenAI, Gemini, Anthropic, Ollama) for advanced voice conversation capabilities. Entities are exposed to voice platforms through the dedicated Matter Hub bridge rather than an in-instance integration.
| Port | Protocol | Purpose |
|---|---|---|
| 8123 | TCP | Web UI and API (Local) |
External Access
Section titled “External Access”| Access Method | URL |
|---|---|
| Local network | http://<homelab.ip>:8123 |
| Cloudflare Tunnel | https://home-assistant-home.javiersc.com |
Mobile App Access
Section titled “Mobile App Access”The Home Assistant iOS/Android app does not natively support the Cloudflare Access login screen. For seamless mobile app access, use Tailscale: connect your phone to the Tailscale network and configure the Home Assistant app to use the Tailscale IP as both internal and external URL (e.g., http://100.82.100.68:8123).
Secrets
Section titled “Secrets”Home Assistant uses 1Password for sensitive API keys (OpenAI, Anthropic, etc.). These are injected or managed through the UI and secret store. Long-lived access tokens used by internal homelab services (matter-hub, litellm, picoclaw) are stored persistently in .storage/auth.
| Secret | 1Password Item | Field |
|---|---|---|
| OpenAI API Key | op://Homelab/OpenAI/credential | API key for GPT-4 conversation |
| Anthropic API Key | op://Homelab/Anthropic/credential | API key for Claude conversation |
Backup
Section titled “Backup”Data is backed up daily to Backblaze B2 via Restic. Because the host state directory remains /var/lib/hass, the Restic snapshot group ([Host + Paths]) remains consistent with the homelab backup schedule.
- Restic Path:
/var/lib/hass(excluding/backups,tts, and logs) - Internal Snapshots: Managed via Home Assistant UI (Daily, Retention: 1-7 days). These are kept locally for fast “undo” operations but are not stored in the cloud.
Retention policy: 7 daily, 4 weekly, 6 monthly snapshots.
Configuration
Section titled “Configuration”Containerized Configuration Model
Section titled “Containerized Configuration Model”Home Assistant runs as an OCI container with all core integrations pre-bundled:
- Container Runtime: Managed by systemd via
podman-home-assistant.service. - Config Persistence: Bound to
/var/lib/hass:/config. - No NixOS Component Declarations: Because the official image pre-bundles all dependencies, official integrations (such as
mqtt,tuya,google_generative_ai_conversation,openai_conversation,esphome) are installed and configured directly via the UI without requiringextraComponentsor rebuilds in NixOS.
To allow UI-driven automations, scripts, and scenes, the persistent configuration.yaml includes:
default_config: {}automation: !include automations.yamlscript: !include scripts.yamlscene: !include scenes.yamlhttp: server_host: - 0.0.0.0 - '::' server_port: 8123 trusted_proxies: - 127.0.0.1 - ::1 - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16 use_x_forwarded_for: trueThe system automatically creates these files with root permissions via systemd.tmpfiles.rules if they don’t exist.
Custom Components (HACS)
Section titled “Custom Components (HACS)”Custom components reside in /var/lib/hass/custom_components/.
- HACS: Installed in
/var/lib/hass/custom_components/hacs. Updates to HACS and custom components are performed directly through the HACS interface without requiring Nix rebuilds. - Custom Integrations: Integrations like
midea_ac_lanandxiaomi_miotare placed directly incustom_components/.
AI Integrations
Section titled “AI Integrations”Multiple LLM components are supported out of the box in the container, including:
- OpenAI Conversation
- Google Generative AI (Gemini)
- Anthropic
- Ollama (Local LLM at
http://127.0.0.1:11434) - OpenRouter
Localization
Section titled “Localization”The Home Assistant UI is configured for Spanish (es) localization. This affects date/time formats, number formatting, and the default language for the frontend.
MQTT Integration
Section titled “MQTT Integration”When configuring the MQTT integration in the UI:
- Broker: Use
127.0.0.1(port1883). - Username/Password: Use the credentials managed in 1Password (
Homelab/Mosquitto).
Hardware Integrations
Section titled “Hardware Integrations”- Nanoleaf: Discovery finds Nanoleaf devices automatically on the local network via host networking and mDNS.
- ESPHome: Native support for managing and controlling ESPHome-flashed devices.
- Ball_v2 (ESP32-S3 + GC9A01A round display): Custom voice assistant device with I2S microphone/speaker, RGB LED (WS2812) for state feedback, and touch button. Microphone gain set to 12dB. LED colors indicate assistant state: green during listening, blue during thinking, and amber during replying. Config lives in
assets/esphome/Ball_v2.yaml.
- Ball_v2 (ESP32-S3 + GC9A01A round display): Custom voice assistant device with I2S microphone/speaker, RGB LED (WS2812) for state feedback, and touch button. Microphone gain set to 12dB. LED colors indicate assistant state: green during listening, blue during thinking, and amber during replying. Config lives in
Voice Platform Bridging (Matter Hub)
Section titled “Voice Platform Bridging (Matter Hub)”HA entities — including Zigbee devices bridged through Zigbee2MQTT — are exposed to Alexa, Apple Home, and Google Home by the Matter Hub. The Matter Hub connects to Home Assistant over local loopback (http://127.0.0.1:8123/).
Troubleshooting
Section titled “Troubleshooting”Checking Container Logs
Section titled “Checking Container Logs”To view runtime logs for Home Assistant:
journalctl -u podman-home-assistant -fOr directly from Podman:
podman logs -f home-assistantRestarting the Service
Section titled “Restarting the Service”To restart the Home Assistant container:
sudo systemctl restart podman-home-assistantReverse Proxy Issues (400 Bad Request)
Section titled “Reverse Proxy Issues (400 Bad Request)”Symptom: Accessing Home Assistant through Nginx or Cloudflare returns 400: Bad Request.
Cause: Reverse proxy IP is not listed under trusted_proxies in configuration.yaml.
Solution: Verify /var/lib/hass/configuration.yaml includes use_x_forwarded_for: true and trusted_proxies includes 127.0.0.1, ::1, and LAN subnets (192.168.0.0/16). Restart the container.