After installing Rhasspy on a Raspberry Pi 3B and seeing it struggle, I decided to move everything to a beefier Jetson Nano. While I was at it, took the opportunity to switch to docker to avoid some of the systemd wrangling.
Rhasspy provides speech recognition, speech-to-intent, and text-to-speech. Installation is mostly the same as before:
docker run -d -p 12101:12101 \ --name rhasspy \ --restart unless-stopped \ -v "$HOME/.config/rhasspy/profiles:/profiles" \ --device /dev/snd:/dev/snd \ --device /dev/bus/usb:/dev/bus/usb \ synesthesiam/rhasspy-server:latest \ --user-profiles /profiles \ --profile en
With the Nano, I needed to add
--device /dev/bus/usb:/dev/bus/usb so USB devices like ReSpeaker are also accessible inside the container.
Home Assistant (Hass) is the “smart home” platform and among other things provides: intent handling, automation, location-based services, etc. Hass has docker installation instructions:
docker run --init -d --name="home-assistant" -e "TZ=America/New_York" -v /PATH_TO_YOUR_CONFIG:/config --net=host homeassistant/home-assistant:stable
We’ll change this to:
docker run -d -p 8123:8123 \ --name hass \ --restart unless-stopped \ -v $HOME/.homeassistant:/config \ -e "TZ=Asia/Nicosia" \ homeassistant/home-assistant:stable
- Shorten the name to “hass”, just because typing “home-assistant” is tedious
unless-stoppedrestart policy- the docker daemon will automatically (re-)start it
$HOME/.homeassistantlike when doing manual install
- Value after
TZ=with the appropriate name from “tz database” time zones
hostnetworking on Linux means we don’t need to forward any ports for the frontend like
-p 8123:8123, but doesn’t seem to work with
docker network(see below)
Both Hass and Rhasspy are running in containers, but they can’t talk to eachother yet. The “old” way to connect two containers was to use
--link. The new way is using “networks”. First, create a network called “smart-home”:
docker network create smart-home
To each of the
docker run commands we then add
--network smart-home. For Hass, we also remove
--net=host and add
-p 8123:8123 (for the web frontend). Restart the containers and we can confirm that Rhasspy can talk to the “hass” container:
docker exec -it rhasspy bash # Install ping (or some other command) apt install -y inetutils-ping ping hass
Now, when connecting Rhasspy to Hass, for Hass URL use
With everything on docker we don’t really need systemd to start the individual services, just the docker daemon itself.
We supply both our containers with
--restart unless-stopped so the daemon will launch them as soon as it starts (unless we manually stop them). We just need to make sure the docker daemon starts at boot:
sudo systemctl enable docker sudo reboot # Wait for it to reboot ssh jetson-nano.local # Try Rhasspy TTS to make sure Rhasspy is running: curl -X POST -d "hello world" http://localhost:12101/api/text-to-speech
docker ps should output something similar to:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e797909decb6 synesthesiam/rhasspy-server:latest "/run.sh --user-prof…" 32 hours ago Up About a minute 0.0.0.0:12101->12101/tcp rhasspy 06cf50964e98 homeassistant/home-assistant:stable "/bin/entry.sh pytho…" 33 hours ago Up About a minute 0.0.0.0:8123->8123/tcp hass
Be careful about using
docker ps to verify everything is starting at boot. If the daemon didn’t start,
docker ps will start it- along with the containers.
With multiple containers and so many options things are starting to get hairy. We can reign things in with docker compose. Create
docker-compose.yml with mostly the same contents as the
docker run commands:
version: '3' services: hass: image: "homeassistant/home-assistant:stable" restart: unless-stopped volumes: - "$HOME/.homeassistant:/config" ports: - "8123:8123" environment: - TZ=Asia/Nicosia rhasspy: image: "synesthesiam/rhasspy-server:latest" restart: unless-stopped volumes: - "$HOME/.config/rhasspy/profiles:/profiles" ports: - "12101:12101" devices: - "/dev/snd:/dev/snd" - "/dev/bus/usb:/dev/bus/usb" command: --user-profiles /profiles --profile en
We don’t need the
--network option because the desired networking is implicitly provided by compose.
Install docker compose and launch our containers:
# Install pre-requisites sudo apt install -y python-pip libffi-dev libssl-dev # Install docker-compose sudo pip install docker-compose # Start containers. `-d` for detached mode docker-compose up -d
If you check Rhasspy, you may see the following problem:
HomeAssistantIntentHandler Can't contact server Unable to reach your Home Assistant server at http://hass:8123. Is it running?
Rhasspy starts before Hass is ready and listening. If you test further you’ll find that it has already retried and connected. This behavior aligns with the “docker ethos” of fault-tolerant containers. Should it really bother you, feel free to investigate the rickety world of container dependencies: