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:
./configand./appsmount your local directories into the container.dataanduv_cacheare 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 ... ─ Connected to Home Assistant
Hassette is running, and the web UI is available at http://localhost:8126. If you see an error instead of the connected 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
- First Automation: subscribe to events, control devices
- Managing Dependencies: add Python packages to your setup
- Image Tags: pick a stable tag for production
- Troubleshooting: diagnose connection and startup problems