← Self-Hosting · Home & Life · Replaces: Google Home, Alexa, SmartThings, vendor apps
What You'll Build
Home Assistant brings every smart device — lights, plugs, thermostats, cameras, TVs, sensors, from hundreds of brands — into one app with one set of automations, running locally. When the internet goes down (or a company shuts down its cloud), your home keeps working.
Port: 8123 · Time: 45 minutes · Difficulty: Medium
Container vs Home Assistant OS: this guide runs Home Assistant in Docker alongside your other apps. That version does not support Home Assistant's one-click apps (formerly "add-ons"). If you want those, install Home Assistant OS on its own Raspberry Pi, or as a VM with KVM.
What You Need
- Your home server from Foundations 1 (Docker installed,
~/stacksfolder). - Nginx Proxy Manager with your
*.home.example.comcertificate (recommended). - Optional: a Zigbee or Z-Wave USB stick if you use those kinds of devices.
Step 1: Start Home Assistant
mkdir -p ~/stacks/homeassistant && cd ~/stacks/homeassistant
nano compose.yaml
services:
homeassistant:
image: ghcr.io/home-assistant/home-assistant:stable
container_name: homeassistant
restart: unless-stopped
stop_grace_period: 60s
privileged: true # access to USB sticks and Bluetooth
network_mode: host # needed to discover devices on your network
environment:
TZ: "America/New_York"
volumes:
- ./config:/config # ALL of Home Assistant's settings live here
- /etc/localtime:/etc/localtime:ro
- /run/dbus:/run/dbus:ro # Bluetooth
# Zigbee/Z-Wave stick? Uncomment and use your stick's path (ls /dev/serial/by-id/):
# devices:
# - /dev/serial/by-id/usb-your-stick-id:/dev/ttyUSB0
docker compose up -d
sudo ufw allow 8123/tcp # host networking means UFW rules apply to this app
Step 2: Onboarding
- Open
http://192.168.1.50:8123(the first start takes a minute or two). - Create your owner account, then set your home location (used for sunrise/sunset and weather), time zone, and units.
- Home Assistant shows devices it discovered on your network — smart TVs, printers, Chromecasts, Hue bridges, Sonos, and more. Click each one to add it.
Step 3: Add Devices and Integrations
Settings → Devices & services → Add integration, then search for your brand. A few common paths:
| Devices | How they connect |
|---|---|
| Philips Hue, IKEA, Sonos, Chromecast | Usually auto-discovered — just click Configure. |
| Wi-Fi plugs / bulbs (TP-Link Kasa/Tapo, Shelly) | Local integrations; enter the device IP. |
| Zigbee sensors and bulbs | A USB Zigbee stick + the built-in ZHA integration. |
| Matter / Thread devices | The Matter integration + the companion app to pair. |
Step 4: The Companion App
Install Home Assistant on your phone and connect to https://ha.home.example.com. The app gives you notifications, controls, and turns your phone into a sensor (location, battery, "is at home") for automations.
Step 5: Your First Automation
Settings → Automations & scenes → Create automation → Create new automation:
- When: Sun → Sunset (offset
-00:15:00) - And if: Zone → "someone is home"
- Then do: Light → Turn on → Living room lamp
Save and name it. Every automation can also be viewed as YAML (⋮ → Edit in YAML) — a great way to learn.
Step 6: Put It Behind the Proxy
Home Assistant rejects proxied requests until you tell it to trust the proxy. Add this to ~/stacks/homeassistant/config/configuration.yaml:
# Trust Nginx Proxy Manager (it reaches HA from Docker's internal network range)
http:
use_x_forwarded_for: true
trusted_proxies:
- 172.16.0.0/12
- 127.0.0.1
docker compose restart
Then add the proxy host ha.home.example.com → http, 192.168.1.50, port 8123, Websockets on (required), wildcard certificate.
Backups: ~/stacks/homeassistant/config is covered by your restic script. Home Assistant can also make its own backups under Settings → System → Backups.
Troubleshooting
- "400: Bad Request" through the proxy — the
http:block in Step 6 is missing or has an indentation mistake. Checkdocker compose logs. - Devices aren't discovered —
network_mode: hostis required, and discovery doesn't cross VLANs/guest networks. - Zigbee stick not found — use the
/dev/serial/by-id/…path, not/dev/ttyUSB0, which can change after a reboot.