Home Assistant Docker: The Complete Install and Setup Guide

Docker gives you the flexibility to run Home Assistant alongside other services on the same machine. But it also means more decisions upfront. Here's how to get it right when starting fresh or moving an existing setup into containers.

Check Your Setup Starter Kit Guide

When Does Docker Make Sense?

Docker is great when Home Assistant is not the only thing on your server. If it is, you're probably better off with Home Assistant OS. Here's a quick decision guide.

Use Docker When

  • You already run other Docker containers (Plex, Pi-hole, Nextcloud)
  • Your server runs a NAS OS like Unraid, TrueNAS, or Synology DSM
  • You want full control over the host operating system
  • You need to run specific Linux software alongside HA
  • You enjoy tinkering and don't mind managing updates manually

Use HA OS Instead When

  • Home Assistant is the only thing on this machine
  • You want one-click add-on installs
  • You prefer automatic, managed updates
  • You're new to Home Assistant (start simple, move to Docker later)
  • You don't want to learn Docker Compose

The honest truth: About 70% of Home Assistant users are better off with HA OS. Docker adds complexity that only pays off if you actually need to share that machine with other services. If you're reading this page because someone told you Docker is "the pro way," think about what problem you're actually solving first.

The Four Installation Types

Home Assistant comes in four flavors. Two use Docker directly (Container and Supervised), and two don't require you to touch Docker at all (OS and Core).

๐Ÿ 

Home Assistant OS

RECOMMENDED

The full package. Runs its own minimal Linux OS with Docker under the hood (you never touch it). Includes the Supervisor for add-ons, automatic backups, and managed updates.

Best for: Dedicated hardware (Pi, NUC, mini PC). Most users.

๐Ÿณ

Home Assistant Container

THIS GUIDE

Just the Home Assistant core app in a single Docker container. You manage everything: Docker Compose config, companion services, updates, backups. No Supervisor, no add-on store.

Best for: NAS users, existing Docker setups, people who want full control.

๐Ÿ”ง

Home Assistant Supervised

Runs the Supervisor on top of your own Linux install (Debian 13 required). You get add-ons and managed updates while keeping control of the host OS. Fragile if you deviate from the requirements.

Best for: Advanced users who need add-ons AND host OS access.

๐Ÿ

Home Assistant Core

Installed directly in a Python virtual environment. No Docker involved. You manage Python dependencies, system packages, and everything else. Rarely the right choice anymore.

Best for: Developers contributing to HA core. That's about it.

Docker Compose Setup: Step by Step

This gets Home Assistant Container running in about 10 minutes. You'll need Docker and Docker Compose already installed on your machine.

1

Create the project directory

mkdir -p ~/homeassistant cd ~/homeassistant
2

Create your docker-compose.yml

services: homeassistant: container_name: homeassistant image: ghcr.io/home-assistant/home-assistant:stable volumes: - ./config:/config - /etc/localtime:/etc/localtime:ro - /run/dbus:/run/dbus:ro restart: unless-stopped network_mode: host

Why network_mode: host? Home Assistant uses mDNS to discover devices on your network. Bridge networking blocks this. Host mode lets HA see everything on your LAN, which is what you want for auto-discovery of lights, speakers, and other smart devices.

3

Start the container

docker compose up -d

Give it a minute to download and start up. Then open http://your-server-ip:8123 in your browser. You'll see the onboarding wizard to create your first user account.

4

Verify it's running

docker compose logs -f homeassistant

Watch the logs scroll by. Once you see "Setup of domain homeassistant took X seconds," you're good. Press Ctrl+C to exit the log view.

Networking: Host vs Bridge Mode

This trips up more people than anything else in Docker-based HA setups.

Host Mode (Recommended)

  • mDNS/Bonjour discovery works
  • SSDP/UPnP auto-discovery works
  • No port mapping needed
  • Multicast traffic passes through
  • Easiest for smart home use

Bridge Mode (Limited)

  • Auto-discovery does not work
  • Need to map port 8123 manually
  • Some integrations break silently
  • Better network isolation
  • Works for HA + reverse proxy setups

Bottom line: Use host mode unless you have a specific reason not to. The most common reason for bridge mode is running a reverse proxy (like Nginx or Traefik) to put HA behind HTTPS on port 443. In that case, use bridge mode with port 8123 mapped, and configure your proxy to forward traffic to it. Check our remote access guide for the full setup.

Passing USB Devices to Docker

Zigbee coordinators, Z-Wave sticks, and Bluetooth adapters all connect via USB. Docker containers can't see them unless you explicitly pass them through.

Find your device path

# List USB serial devices ls -la /dev/serial/by-id/ # Example output: # usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus-if00-port0 -> ../../ttyUSB0

Always use the /dev/serial/by-id/ path, not /dev/ttyUSB0. The by-id path stays the same even if you plug in additional USB devices. The numbered path can shift around.

Add it to your compose file

services: homeassistant: container_name: homeassistant image: ghcr.io/home-assistant/home-assistant:stable volumes: - ./config:/config - /etc/localtime:/etc/localtime:ro - /run/dbus:/run/dbus:ro devices: - /dev/serial/by-id/usb-ITead_Sonoff_Zigbee_3.0-if00-port0:/dev/ttyUSB0 restart: unless-stopped network_mode: host

After changing the compose file, recreate the container: docker compose up -d. The device will be available inside the container at the path you mapped it to. For more on Zigbee, see our Zigbee guide.

Essential Companion Containers

Without the add-on store, you run these services as separate Docker containers. Here's a production-ready compose file with the most common ones.

services: homeassistant: container_name: homeassistant image: ghcr.io/home-assistant/home-assistant:stable volumes: - ./ha-config:/config - /etc/localtime:/etc/localtime:ro - /run/dbus:/run/dbus:ro devices: - /dev/serial/by-id/your-zigbee-dongle:/dev/ttyUSB0 depends_on: - mosquitto restart: unless-stopped network_mode: host mosquitto: container_name: mosquitto image: eclipse-mosquitto:2 volumes: - ./mosquitto/config:/mosquitto/config - ./mosquitto/data:/mosquitto/data - ./mosquitto/log:/mosquitto/log ports: - "1883:1883" restart: unless-stopped zigbee2mqtt: container_name: zigbee2mqtt image: koenkk/zigbee2mqtt volumes: - ./zigbee2mqtt-data:/app/data - /run/udev:/run/udev:ro devices: - /dev/serial/by-id/your-zigbee-dongle:/dev/ttyACM0 ports: - "8080:8080" depends_on: - mosquitto restart: unless-stopped esphome: container_name: esphome image: ghcr.io/esphome/esphome volumes: - ./esphome-config:/config network_mode: host restart: unless-stopped

Note: If you use Zigbee2MQTT, pass the Zigbee dongle to the Z2M container instead of Home Assistant. Only one process can access a serial device at a time. For more on these services, check our guides on MQTT, Zigbee, and ESPHome.

Mosquitto

MQTT broker. Required for Zigbee2MQTT, Tasmota devices, and many automations. Lightweight, runs on any hardware.

Zigbee2MQTT

Bridges your Zigbee devices to MQTT. Supports 4,000+ devices with a web UI for management. Alternative to ZHA.

ESPHome

Program ESP32/ESP8266 boards for custom sensors and devices. Great for DIY projects.

Node-RED

Visual flow-based automation tool. Image: nodered/node-red. Port 1880. Good for complex multi-step automations.

Frigate

AI-powered NVR for security cameras. Needs a Coral TPU for real-time detection. Port 5000. See our camera guide.

InfluxDB + Grafana

Long-term data storage and beautiful charts. Great for energy monitoring and historical trends.

Backups: Don't Skip This

Without the Supervisor, you don't get automatic backups. Set this up now, before you have 50 automations and a dozen integrations you'd hate to rebuild from scratch.

What to back up

  • ./config/ (or ./ha-config/) contains everything: automations, integrations, scripts, scenes, and the database
  • ./zigbee2mqtt-data/ has your Zigbee device pairing data. Losing this means re-pairing every device
  • ./mosquitto/ can be rebuilt easily, but backing it up saves time
  • docker-compose.yml is the most important file. Keep it in version control

Simple backup script

#!/bin/bash # backup-ha.sh BACKUP_DIR="/backups/homeassistant" DATE=$(date +%Y-%m-%d_%H%M) mkdir -p "$BACKUP_DIR" # Stop HA to ensure consistent backup docker compose stop homeassistant # Create compressed archive tar -czf "$BACKUP_DIR/ha-backup-$DATE.tar.gz" \ ./config ./zigbee2mqtt-data ./mosquitto \ docker-compose.yml # Restart docker compose up -d # Keep last 7 backups ls -t "$BACKUP_DIR"/ha-backup-*.tar.gz | tail -n +8 | xargs rm -f echo "Backup complete: ha-backup-$DATE.tar.gz"

Add this to cron with crontab -e and add 0 3 * * * /path/to/backup-ha.sh to run it daily at 3 AM. For offsite backups, add an rclone sync line to push to Google Drive or a remote server.

The SSD rule: If you're running Home Assistant on an SD card, stop. SD cards were not designed for the constant read/write that HA does to its SQLite database. They will fail, usually within 3 to 12 months. Use an SSD. Even a cheap one will outlast any SD card by years. Your backups are useless if the card dies between backups.

Updating Home Assistant in Docker

Updates are straightforward. Just pull the new image and recreate. Your config survives because it lives in a mounted volume.

Manual update (recommended)

# 1. Check the release notes first # https://www.home-assistant.io/blog/categories/release-notes/ # 2. Create a backup ./backup-ha.sh # 3. Pull the new image docker compose pull # 4. Recreate the container with the new image docker compose up -d # 5. Check the logs for errors docker compose logs -f homeassistant

Automatic updates with Watchtower (optional)

services: watchtower: container_name: watchtower image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WATCHTOWER_CLEANUP=true - WATCHTOWER_SCHEDULE=0 0 4 * * * restart: unless-stopped

Fair warning: Watchtower updates all your containers automatically. Home Assistant releases occasionally include breaking changes that require manual config updates. Many experienced users prefer manual updates so they can read the release notes first and test in advance. If you do use Watchtower, at least monitor the HA changelog.

Rolling back after a bad update

# Pin to a specific version in docker-compose.yml: image: ghcr.io/home-assistant/home-assistant:2026.2.0 # Then recreate: docker compose up -d

You can pin any version. Check available tags on the GitHub releases page. Restoring from your backup after downgrading is the safest approach since the database schema sometimes changes between versions.

Performance Tips for Docker Setups

A few things that make a real difference in day-to-day performance.

Use an SSD, not an SD card

Home Assistant writes to its database constantly. SSDs handle this without breaking a sweat. SD cards degrade fast under write-heavy workloads. A $20 SSD will save you from data loss headaches.

Limit the recorder database

By default, HA keeps 10 days of history. That database can grow to several gigabytes. In configuration.yaml, set recorder: purge_keep_days: 5 and exclude entities you don't need history for. If you want long-term data, offload it to InfluxDB.

Give HA enough memory

Home Assistant itself needs about 512MB to 1GB of RAM. Add more for each companion container: Zigbee2MQTT uses 100-200MB, Frigate can use 2-4GB depending on camera count. Monitor with docker stats.

Pin image versions in production

Instead of :stable or :latest, pin a specific version like :2026.2.0. This prevents surprise updates when you recreate a container and makes rollbacks trivial.

Recommended Hardware

Your hardware needs depend on how many containers you plan to run. Here are three tiers that cover most situations.

๐Ÿฅ‰

Starter

Raspberry Pi 4 (4GB)
+ SSD via USB 3.0 adapter

HA + Mosquitto + Z2M. Handles 50-100 devices. About $60-80 total.

๐Ÿฅ‡

Sweet Spot

Intel N100 mini PC (8-16GB)
+ NVMe SSD

Full stack including Frigate. Low power (10-15W). Future-proof. About $120-180.

๐Ÿ‹๏ธ

NAS / Server

Synology / Unraid / TrueNAS
or any x86 server

Already have one? Run HA alongside your existing services. Perfect Docker use case.

Moving Between Installation Types

Already running HA OS and want to switch to Docker? Or going the other direction? Here's what to expect.

HA OS to Docker Container

  1. Create a full backup from Settings, System, Backups in your current HA
  2. Download the backup .tar file to your computer
  3. Set up the Docker Container install (use the compose file above)
  4. Copy your backup into the new config directory
  5. Restore from Settings after the new instance boots
  6. Re-configure any add-ons as standalone Docker containers

The backup restores your automations, integrations, dashboards, and entity history. Add-ons don't transfer, so plan to set up Mosquitto, Z2M, and other services as separate containers.

Docker Container to HA OS

Same process in reverse. Create a backup from the Docker instance, install HA OS on your target hardware, and restore during onboarding. The HA OS onboarding wizard has a "Restore from backup" option on the first screen. Moving to HA OS is generally easier since you gain the add-on store instead of losing it.

Already Have Smart Home Devices?

Running Docker or HA OS? Our free scan tells you which of your existing devices work with Home Assistant and what to expect during migration.

Scan Your Devices Free

Takes about 2 minutes. No account needed.