Fully verified90,199

Smart home

Home Assistant

Home Assistant brings lights, sensors, air conditioners, TVs, and vacuums from different vendors into one interface and runs automations on your own server instead of someone else's cloud. More than two thousand integrations, a dashboard with state history, an automation editor, and Android and iOS apps.

Overview

Home Assistant is a smart home server that collects devices from different vendors into one panel and runs automations locally. Lights, sensors, air conditioners, vacuums, TVs, and meters end up in a shared interface where they can be controlled and wired to each other: “half an hour before sunset, turn on the living room lights if somebody is home”.

The key difference from Google Home, Alexa, or Yandex Smart Home is that the logic lives on your own server. Devices keep working when the internet is down or the vendor shuts its cloud service off, and the state history stays in a local database. More than two thousand integrations cover both local protocols (Zigbee, Z-Wave, MQTT, ESPHome, Matter) and cloud APIs.

The recipe runs the official Container install: one container and one Docker volume holding the /config directory, with the panel on 127.0.0.1:8123. This install has no Supervisor, so add-ons, in-panel updates, and automatic discovery of devices on the local network are unavailable — integrations are added by device address, and updates happen by changing the image tag.

Security assessment

The container runs without privileged, host networking, and the Docker socket, with no-new-privileges, and the panel is published on 127.0.0.1 only by default. That is a deliberate trade of convenience: the upstream instructions suggest network_mode: host and privileged: true so that discovery, Bluetooth, and USB adapters work. Such a container gets access to the host’s entire network and nearly all root capabilities, so the recipe leaves it out.

A Home Assistant account controls locks, cameras, and heating, which means the physical security of the home. The panel may only be exposed over HTTPS and only with two-factor authentication enabled in the user profile.

The reverse proxy deserves separate attention. Home Assistant rejects proxied requests until use_x_forwarded_for and trusted_proxies are set in configuration.yaml. Listing too wide a subnet in trusted_proxies lets an attacker spoof the client address and bypass the built-in brute-force protection — only the proxy’s own address belongs on that list.

The /config directory holds access tokens, integration passwords, and a detailed history of life in the home. Backup archives must be encrypted and kept off the server.

Update tracking

These are stored results of separate checks, not real-time data. An unknown status means the check has not been performed yet.

New releases

Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.

Current version 2026.8.3Aug 31, 2026, 8:03 PM UTC

Critical vulnerabilities

Result of a dedicated Docker image scan, not a Compose configuration check.

Found: 2 · Trivy 0.74.0Aug 31, 2026, 8:05 PM UTC
Show 1 CVEs

Breaking updates

A new major version is found by comparing version numbers. A compatibility verdict is entered by hand after reading the release notes and the migration steps.

Not checkedNot checked

compose.yaml

Upstream Compose changes relative to the verified recipe.

Upstream Compose is not trackedNot checked

Outdated Docker images

Pinned image tags checked for newer versions.

All images are currentAug 31, 2026, 8:03 PM UTC

From observation to action

Update plan

The recipe already pins the latest known release. The steps below show the evidence retained for that version.

2026.8.32026.8.3
  1. Open the release evidence

    Open this release on GitHub ↗ The link is evidence to review, not proof of compatibility.

  2. Review the version boundary

    The version numbers do not cross a major compatibility boundary. No compatibility verdict has been recorded.

  3. Prepare image-tag changes

    No image-tag change is currently planned.

  4. Follow the documented migration shape

    Manual steps after the pull. Release-specific migration steps still come from the release notes and installation guide.

  5. Protect the rollback point

    No version change is currently planned. The recipe includes a backup procedure. Restore has been tested.

  6. Verify the updated recipe

    An exact Fully verified check for this target was recorded on 2026-08-31.

Read the update procedure in the installation guide ↓

Specifications

Security and exposure

Installation levels

The status shows how fully the published recipe meets each level's requirements.

Ready

For home

A minimal setup for a local network or access through a VPN.

  • Single server
  • Local access
  • Minimum components

The recipe covers every requirement at this level.

Partial

For a VPS

A public deployment with protected access and backups.

  • Domain
  • HTTPS via reverse proxy
  • Off-server backup

You still need to add: domain, https via reverse proxy, off-server backup.

Not supported

Reliable

A setup designed for predictable operations and observability.

  • Separate database
  • Healthcheck
  • External monitoring
  • CPU and memory limits

You still need to add: separate database, external monitoring, cpu and memory limits.

Tailored to your server

Configuration generator

Answer five questions and download a ready-to-run Home Assistant bundle.

Runs locally
01 Do you have a domain?
02 Which reverse proxy?
03 Server architecture
04 Where should data be stored?

Use an absolute path for a separate disk, such as /srv/home-assistant.

05 Is VPN access required?

Your bundle is ready

The archive is created in your browser. Your answers are never sent anywhere.

Screenshots

Screenshots have not been added yet.

Quick start

Read the full guide first: it explains external access, backups, and data locations.

Prepare settingscp .env.example .env
Launchdocker compose up -d
Check statusdocker compose ps

Step-by-step guide

1. Check the Ubuntu or Debian server

Minimum: 2 CPUs, 1 GB of RAM, and 8 GB of disk. 2 GB of RAM is recommended — consumption grows with the number of integrations, and the history database takes space proportional to the number of devices. You need Ubuntu 22.04+ or Debian 12+ with Docker Engine and Docker Compose v2.24+. No separate database is required: by default Home Assistant writes history to SQLite inside /config.

docker --version
docker compose version

2. Prepare the files and variables

Put compose.yaml, .env.example, backup.sh, restore.sh, and the proxy directory into a directory of their own:

mkdir -p ~/services/home-assistant
cd ~/services/home-assistant
cp .env.example .env
chmod 600 .env

.env defines:

  • HOMEASSISTANT_VERSION — the pinned image tag, identical to the release number;
  • HOMEASSISTANT_BIND — the address the panel is published on, 127.0.0.1 by default;
  • HOMEASSISTANT_PORT — the published port of the panel, 8123 by default;
  • HOMEASSISTANT_CONFIG_VOLUME — the volume holding the /config directory;
  • TZ — the time zone; time-based automations and charts depend on it.

All user data lives in a single volume: configuration.yaml, automations.yaml, the home-assistant_v2.db history database, and the .storage directory with accounts, tokens, and integration settings. No data stays in the recipe directory.

3. Start the container on a VPS

docker compose pull
docker compose up -d
docker compose ps

The first start takes longer than usual: the container unpacks /config and brings the core up. Wait for the healthy state — the healthcheck requests /manifest.json inside the container:

docker compose logs --tail=50 home-assistant

With the default settings no port faces the outside: the panel is bound to 127.0.0.1. On a VPS it should stay that way — grant access either through a reverse proxy with HTTPS (step 6) or over a VPN, by setting HOMEASSISTANT_BIND to the VPN interface address.

4. Complete the onboarding wizard

The panel is reachable locally only, so forward the port over SSH:

ssh -L 8123:127.0.0.1:8123 user@server.example

Open http://localhost:8123. The wizard creates the first account, which becomes the owner of the server. Choose a long password and store it in a password manager: resetting it is only possible by editing files in the volume. Next the wizard asks for the home name, location, and units — sunset and sunrise automations depend on the coordinates.

Enable two-factor authentication right after the wizard: the user avatar in the bottom left corner → “Security” → “Multi-factor authentication”.

5. Access from the local network

The Home Assistant companion apps for Android and iOS need the server’s direct address on the local network. Set the server address in .env and recreate the container:

sed -i 's/^HOMEASSISTANT_BIND=.*/HOMEASSISTANT_BIND=192.168.1.10/' .env
docker compose up -d
docker compose port home-assistant 8123

Never use 0.0.0.0: on a VPS that exposes the control panel of your home to the whole internet. Restrict the port to the local subnet:

sudo ufw allow from 192.168.1.0/24 to any port 8123 proto tcp

Automatic device discovery does not work in this recipe: the container lives on an isolated Compose network and never sees the mDNS, SSDP, and DHCP broadcasts. Integrations are added by hand — “Settings” → “Devices & services” → “Add integration”, entering the device IP address. Bluetooth and USB Zigbee or Z-Wave adapters require passing the device into the container and are not part of the recipe.

6. Domain and HTTPS

Ready-made samples live in proxy/Caddyfile, proxy/nginx.conf, and proxy/traefik.yaml; replace home.example.com with your own domain. Caddy obtains the certificate automatically, the Nginx sample assumes a Certbot certificate, and Traefik uses the letsencrypt resolver. The interface runs over WebSocket: in the Nginx sample the Upgrade and Connection headers take care of it, and without them the panel stays blank.

Home Assistant rejects proxied requests by default. Add an http block with your proxy address to configuration.yaml:

docker compose exec home-assistant vi /config/configuration.yaml
http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 127.0.0.1

Only the proxy’s own address belongs in trusted_proxies. An extra subnet in that list lets an attacker spoof the client address and bypass the brute-force protection (http documentation). If the proxy runs in a container, use its Docker network address instead of 127.0.0.1. Check the configuration and restart the server:

docker compose exec home-assistant python -m homeassistant --script check_config -c /config
docker compose restart home-assistant

The panel controls locks and cameras, so publish it only with two-factor authentication enabled, and consider restricting access by IP on the proxy side.

Backup

The data lives in the home-assistant-config volume. The script stops the container while archiving: history is written to SQLite, and a copy of a running database comes out inconsistent.

chmod +x backup.sh restore.sh
./backup.sh

The archive appears in ./backups. It contains access tokens, integration passwords, and the history of your home, so keep the copy off the server and encrypted.

The application has a built-in mechanism of its own: “Settings” → “System” → “Backups”. It stores archives in /config/backups, that is inside the same volume, and protects against a bad configuration edit but not against losing the server. The script and the built-in backups complement each other.

Restore

Restoring completely replaces the volume content with the chosen archive:

./restore.sh ./backups/home-assistant-YYYYMMDDTHHMMSSZ.tar.gz
docker compose ps

Before unpacking, the script creates a safety copy of the current data. The image version in .env must match the one the archive was created with: an older version is not obliged to understand .storage files upgraded by a newer one.

Update

Releases ship monthly and regularly contain breaking integration changes. Always read the Backward-incompatible changes section of your release notes, then:

./backup.sh
sed -i 's/^HOMEASSISTANT_VERSION=.*/HOMEASSISTANT_VERSION=2026.9.0/' .env
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 home-assistant

Updating from the panel is unavailable in this install: without Supervisor the image tag defines the version. The Home Assistant Core update button never appears in the interface.

Rollback

Restore the previous HOMEASSISTANT_VERSION value in .env and run docker compose pull and docker compose up -d. This does not always work: on update Home Assistant migrates the .storage files and the history database schema to the new format, and there is no reverse migration. If the older version refuses to start, restore the archive created before the update:

./restore.sh ./backups/home-assistant-YYYYMMDDTHHMMSSZ.tar.gz
docker compose up -d

The recipe has no separate external database, so every migration is limited to the volume content.

Complete removal

Keep the data: docker compose down. Remove the container and all data permanently:

docker compose down
docker volume rm home-assistant-config
rm -rf ~/services/home-assistant

Separately revoke access in the companion apps and remove the server from their settings: they keep long-lived tokens of their own. If any devices were linked to vendor clouds, unlink them on the vendor’s side.

Sources: Container install, http integration, backups, and release notes.

Troubleshooting

Behind a reverse proxy the panel returns 400: Bad Request

Home Assistant does not trust the X-Forwarded-For header until you allow it explicitly. configuration.yaml needs an http block:

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 172.18.0.1

The address in trusted_proxies is the address the request arrives from inside the container, which is almost never 127.0.0.1. For a proxy on the host it is the Docker network gateway, as in the example above; for a proxy in a container it is that container’s address on the shared network. Take the real value from the log rather than guessing it:

docker compose logs --tail=50 home-assistant | grep -i forwarded

Do not widen the list to the whole subnet: anyone who gets into it can spoof the client address.

The panel loads but stays blank

The interface receives data over WebSocket. If the proxy does not pass the upgrade through, the page loads and hangs. Nginx needs these headers:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Caddy and Traefik do it themselves. To confirm the proxy is at fault, reach 127.0.0.1:8123 directly through an SSH tunnel.

The container never becomes healthy

docker compose ps
docker inspect --format '{{json .State.Health}}' "$(docker compose ps -q home-assistant)"
docker compose logs --tail=100 home-assistant

The first start takes longer than later ones: the healthcheck start_period is 120 seconds. If the container restarts in a loop, an error in configuration.yaml is almost always the cause:

docker compose exec home-assistant python -m homeassistant --script check_config -c /config

When the core cannot read the configuration it comes up in recovery mode: the panel works, but there are no integrations and no automations. That shows in the state field of the /api/config response and in the interface header.

Devices are not discovered automatically

That is expected: the container runs on an isolated Compose network and never receives the mDNS, SSDP, and DHCP broadcasts discovery is built on. Add integrations by hand and enter the device IP address. If you need automatic discovery, you have to switch to network_mode: host — that gives the container access to the host’s entire network, and the recipe deliberately leaves it out.

The owner password is lost

The image ships a script for managing accounts. Stop the container so the database is not edited under a running server, then change the password:

docker compose stop home-assistant
docker compose run --rm home-assistant python -m homeassistant --script auth --config /config list
docker compose run --rm home-assistant python -m homeassistant --script auth --config /config change_password smoke NewPassword
docker compose start home-assistant

Make a backup first. Do not delete the .storage/auth* files: that also removes every user, every companion app token, and every device link.

The history database grows to tens of gigabytes

By default Home Assistant keeps 10 days of history, but with many sensors the home-assistant_v2.db file still grows quickly. Limit the retention and exclude noisy entities in configuration.yaml:

recorder:
  purge_keep_days: 7
  exclude:
    domains:
      - device_tracker
      - sun

The file does not shrink immediately after the edit: space is reclaimed by the recorder.purge action with repack: true.

An integration broke after an update

Check the Backward-incompatible changes section of your release notes: integrations move and change their settings format. The quick fix is to restore the previous tag in .env and run docker compose up -d. If the older version refuses to start because the .storage migration already happened, restore the archive created before the update:

./restore.sh ./backups/home-assistant-YYYYMMDDTHHMMSSZ.tar.gz

Automations fire at the wrong time

Check both time zones: the container TZ from .env and the application’s own zone under “Settings” → “System” → “General”. Sunset and sunrise automations also depend on the coordinates set during onboarding.

docker compose exec home-assistant date

Official sources

Latest release: 2026-08-21 · GitHub Stars: 90,199 · metadata checked Aug 31, 2026, 7:49 PM UTC

Disclaimer

Fossary is an independent informational catalog and is not affiliated with the developers of the listed applications. We collect information from public sources and verify published recipes, but we do not develop, distribute, or control these applications.

A listing or validation status is not a requirement, endorsement, or personal recommendation to use an application. You decide whether it is suitable and use it at your own risk. We do not warrant an application's security, availability, or fitness for purpose and, to the extent permitted by law, are not liable for resulting loss or damage. Review its license, security settings, data processing, and backup procedures before installation.