New releases
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
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.
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.
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.
These are stored results of separate checks, not real-time data. An unknown status means the check has not been performed yet.
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
Result of a dedicated Docker image scan, not a Compose configuration check.
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.
Upstream Compose changes relative to the verified recipe.
Pinned image tags checked for newer versions.
From observation to action
The recipe already pins the latest known release. The steps below show the evidence retained for that version.
2026.8.32026.8.3Open this release on GitHub ↗ The link is evidence to review, not proof of compatibility.
The version numbers do not cross a major compatibility boundary. No compatibility verdict has been recorded.
No image-tag change is currently planned.
Manual steps after the pull. Release-specific migration steps still come from the release notes and installation guide.
No version change is currently planned. The recipe includes a backup procedure. Restore has been tested.
An exact Fully verified check for this target was recorded on 2026-08-31.
The status shows how fully the published recipe meets each level's requirements.
A minimal setup for a local network or access through a VPN.
The recipe covers every requirement at this level.
A public deployment with protected access and backups.
You still need to add: domain, https via reverse proxy, off-server backup.
A setup designed for predictable operations and observability.
You still need to add: separate database, external monitoring, cpu and memory limits.
Tailored to your server
Answer five questions and download a ready-to-run Home Assistant bundle.
Screenshots have not been added yet.
Read the full guide first: it explains external access, backups, and data locations.
cp .env.example .envdocker compose up -ddocker compose psMinimum: 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
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.
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.
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”.
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.
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.
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.
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.
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.
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.
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.
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 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.
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.
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 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.
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.
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
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
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.