Skip to content

Docker Setup

Run Hassette in a container with Docker Compose.

Prerequisites

  • Docker and Docker Compose installed on the host machine.
  • A running Home Assistant instance with a long-lived access token. See Creating a Home Assistant Token for how to generate one.

Quick Start

Step 1: Create the project

mkdir project_dir && cd project_dir
mkdir -p config apps

project_dir is a placeholder — name the directory whatever you like. config/ holds your token and settings. apps/ holds your automation code.

Step 2: Create docker-compose.yml

services:
  hassette:
    image: ghcr.io/nodejsmith/hassette:latest-py3.13
    container_name: hassette
    restart: unless-stopped
    stop_grace_period: 45s # time for Hassette to shut down apps cleanly before Docker force-kills it
    volumes:
      - ./config:/config
      - ./apps:/apps
      - data:/data
      - uv_cache:/uv_cache
    ports:
      - "8126:8126"
    environment:
      - HASSETTE__LOG_LEVEL=info
      - TZ=America/New_York # Set your timezone
    healthcheck:
      # Keep this pointed at /api/health/live — it stays healthy during HA outages.
      # Using /api/health/ready here causes a restart loop whenever HA restarts.
      test: ["CMD", "curl", "-sf", "http://127.0.0.1:8126/api/health/live"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 60s

volumes:
  uv_cache:
  data:

The image: line pulls Hassette from GitHub Container Registry (ghcr.io) — Docker downloads it automatically on first run. The volumes break down like this:

  • ./config and ./apps mount your local directories into the container.
  • data and uv_cache are named volumes for persistent data and the package cache. Docker Compose creates them automatically — no action needed.

Port 8126 exposes the web UI. It is unauthenticated, so keep it off public networks. Set TZ to your local timezone so scheduled automations fire at the right times.

Step 3: Create config/.env

# config/.env
HASSETTE__TOKEN=your_long_lived_access_token_here
HASSETTE__BASE_URL=http://homeassistant:8123

Replace your_long_lived_access_token_here with your token. Set HASSETTE__BASE_URL to your Home Assistant's address, like http://192.168.1.100:8123 — when in doubt, use the IP address. The container-name form (http://homeassistant:8123) only works when HA also runs in Docker on the same Docker network.

The __ double underscore is how Hassette maps environment variables to nested settings — HASSETTE__TOKEN sets token. Hassette reads /config/.env automatically on startup; you do not need an env_file: directive in the compose file.

Step 4: Start it

docker compose up -d

Check the logs:

docker compose logs hassette -f

You see output like:

INFO hassette ... ─ Hassette is running.

Hassette is running, and the web UI is available at http://localhost:8126. If you see an error instead of this line, head to Troubleshooting.

Write Your First App

Create apps/my_app.py:

from hassette import App, AppConfig


class MyAppConfig(AppConfig):
    greeting: str = "Hello from Docker!"


class MyApp(App[MyAppConfig]):
    async def on_initialize(self):
        self.logger.info(self.app_config.greeting)

App runs your automation logic and gives you access to the bus (subscribes to HA events), the scheduler (runs code on a timer), and the API (calls HA services). AppConfig loads and validates your app's settings from the environment, including config/.env. on_initialize runs once when the app starts.

Two pieces of syntax worth knowing: App[MyAppConfig] pairs your app with its config class — that's how self.app_config knows its type. And lifecycle hooks like on_initialize are async def — Hassette runs the event loop for you, so you can follow the pattern without prior async experience.

Restart the container to pick up the new file:

docker compose restart hassette

Check the logs again. You see Hello from Docker! from your app:

INFO hassette.MyApp.0 ... ─ Hello from Docker!

Having trouble?

If Hassette fails to connect, check HASSETTE__BASE_URL and your token in config/.env. If your app doesn't show up in the logs, see Troubleshooting for app-loading and other common issues.

From here, see First Automation to subscribe to Home Assistant events and control devices.

Next Steps