Bake smartthings-local into the dev Docker image

The dev container was relying on HA's runtime pip-install of manifest.json
requirements, which only fires when the integration is set up and needs
outbound network access at that exact moment; a container that had been
running since before the smartthings-local migration kept the old code
loaded in memory and never went through that install path, so restarting
it failed once it picked up the new manifest.json.

Repurpose the stale MQTT-bridge-era Dockerfile (its own code was already
deleted from this repo) to build on the official HA image with
smartthings-local pre-installed, and point docker-compose.yml at it via
`build: .`. Verified end-to-end: rebuilt the image, recreated the
container, and confirmed both live appliances (fridge, dishwasher)
reconnect and discover entities with no runtime install needed.
This commit is contained in:
Marc Billow
2026-07-07 22:38:38 -05:00
parent fd61e882d1
commit 4c1497f5ba
3 changed files with 14 additions and 33 deletions
+8 -30
View File
@@ -1,31 +1,9 @@
FROM python:3.11-slim
FROM ghcr.io/home-assistant/home-assistant:stable
WORKDIR /app
# Python deps first so layer cache survives code changes
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Application code
COPY main.py .
COPY samsung_appliance/ ./samsung_appliance/
# /config holds the ab0b0ac4 client cert + key. Mount from the host so
# secrets aren't baked into the image.
RUN mkdir -p /config
# Unbuffered stdout so docker logs is live
ENV PYTHONUNBUFFERED=1
# Defaults — override in .env or `docker run -e …`. Per-appliance
# keys (APPLIANCE_COUNT, APPLIANCE_<n>_*) have no universal default
# and must be set in .env.
ENV CERT_PATH=/config/ab0b0ac4_fullchain.pem \
KEY_PATH=/config/ab0b0ac4.key \
HA_DISCOVERY_PREFIX=homeassistant \
HEALTH_INTERVAL_S=60 \
HEARTBEAT_INTERVAL_S=600
# No port — bridge is outbound-only (DTLS UDP to appliance, MQTT to broker).
CMD ["python", "main.py"]
# Home Assistant normally installs a custom integration's manifest.json
# requirements itself at integration setup, but that depends on the
# container having outbound network access at exactly that moment and
# repeats the install attempt on every container recreate. Baking
# smartthings-local into the image keeps the dev container usable
# offline and avoids relying on that runtime install path.
RUN pip3 install --no-cache-dir "smartthings-local>=0.1.0"
+4 -2
View File
@@ -76,11 +76,13 @@ Entities appear under one HA device per appliance, named `Samsung Appliance (<ip
### Docker Compose dev environment
```sh
docker compose up -d
docker compose up -d --build
docker compose logs -f
```
Runs the official `home-assistant/home-assistant:stable` image with `network_mode: host` (required, since DTLS is UDP and won't traverse Docker's bridge NAT to reach LAN appliances) and `custom_components/localthings/` bind-mounted read-only into `ha_config/custom_components/`. Bump `custom_components.localthings` to `debug` in `ha_config/configuration.yaml` for verbose protocol logging.
The `Dockerfile` builds on the official `home-assistant/home-assistant:stable` image and pre-installs `smartthings-local`, so the dependency is present at container start instead of depending on HA's own runtime pip-install step (which needs outbound network access at exactly the moment the integration loads, and repeats on every container recreate). Re-run with `--build` whenever the pinned `smartthings-local` version changes.
`docker-compose.yml` sets `network_mode: host`, which is required since DTLS is UDP and won't traverse Docker's bridge NAT to reach LAN appliances, and bind-mounts `custom_components/localthings/` read-only into `ha_config/custom_components/`. Bump `custom_components.localthings` to `debug` in `ha_config/configuration.yaml` for verbose protocol logging.
### Tests
+2 -1
View File
@@ -1,6 +1,7 @@
services:
homeassistant:
image: ghcr.io/home-assistant/home-assistant:stable
build: .
image: localthings-ha-dev
container_name: localthings-ha
# host networking is required — DTLS runs over UDP and won't
# traverse Docker's bridge NAT to reach LAN appliances.