GitHubのトレンドを眺めていたら、home-assistant/core が上のほうに来ていました。スター9万近い有名どころなので今さら説明する話でもないんですが、自分はいつも「Home Assistant OS を丸ごと焼く」やり方でしか触ったことがなくて、Coreだけをpipで入れるとどうなるのか、実はちゃんとやったことがなかったんですよね。
公式ドキュメントを見ると Home Assistant Core は pip install homeassistant して hass と打つだけ、と書いてあります。ラズパイでも動くくらいなので軽いはず。じゃあ使い捨てのコンテナに放り込んで、Webの初期設定画面が出るところまで見てみよう、という軽い気持ちで始めました。
結論から言うと、UIが出るまでにけっこう沼りました。しかもハマりどころが全部きれいに一本の線で繋がっていて、個人的にはそこが面白かったので、順番に残しておきます。
試した環境
- ホストはWindows + Docker Desktop、検証は使い捨ての
python:3.14-slimコンテナの中だけ - コンテナ内: Python 3.14.6 / pip 26.1.2
- 対象:
homeassistant==2026.7.2(このとき最新のリリース)
Home Assistant Core は requires-python >=3.14.2 になっていて、思ったよりずっと攻めたバージョン要求でした。なので素直に python:3.14-slim を使っています。「3.14でwheelが揃ってなくてビルドで死ぬのでは」と身構えたんですが、そこは杞憂でした。
$ pip install --no-cache-dir "homeassistant==2026.7.2"
...
Successfully installed homeassistant-2026.7.2 aiohttp-3.14.1 SQLAlchemy-2.0.51 ...
=== install elapsed: 32s ===
32秒。C拡張の PyRIC だけソースからビルドされましたが一瞬で、あとは全部wheelでした。ここまでは拍子抜けするほど順調です。
ただ、Successfully installed ... の一覧をよく見ると、home-assistant-frontend(Web UIの本体)が入っていない。ここが後で効いてきます。pip install homeassistant は本当にコア部分だけで、frontendや各連携の依存は「初回起動時にhass自身がその場でインストールする」設計なんですよね。知ってはいたつもりですが、改めて挙動を見ると面白い。
初回起動でいきなりrecovery modeに落ちる
hass を起動して、ホストから http://127.0.0.1:<公開ポート>/ を叩いてみます。ところが、いつまで待っても 404 が返ってくる。ログを見に行くと、こうなっていました。
[homeassistant.bootstrap] Home Assistant initialized in 6.56s
[homeassistant.components.http] Now listening on port 8123
...
[homeassistant.setup] Error during setup of component frontend: No module named 'hass_frontend'
[homeassistant.bootstrap] Detected that frontend did not load. Activating recovery mode
「6.56秒で初期化してポート8123でlistenした」と言っているのに、frontendが No module named 'hass_frontend' で落ちて recovery mode に入ってしまっている。だから / は404。
不思議だったのが、pip show home-assistant-frontend を打つとちゃんと Version: 20260624.5 と出るんです。パッケージ自体は(起動中にhassが /root/.local に入れていた)。それなのにimportできない。
タネはこれでした。hassが動いている最中に frontend を ~/.local へインストールしても、すでに起動しているそのプロセスからは import hass_frontend できない(起動時のsys.pathに載っていないタイミングで取りに行ってしまう)。パッケージは物理的には存在するのにインポートに失敗し、HAは「frontendが無い」と判断してrecovery modeへ、というわけです。
同じログに、もう一つ不穏な行がありました。
error: command 'gcc' failed: No such file or directory
Unable to install package pymicro-vad==1.0.1
Unable to install package pyspeex-noise==1.0.2
[homeassistant.setup] Setup failed for 'cloud': Requirements for assist_pipeline not found
slimイメージには gcc が無いので、音声まわり(assist_pipeline)のC拡張がビルドできず、cloud のセットアップも巻き添えで失敗しています。この時点では「音声機能は使わないしいいか」と軽く流したんですが、これが後で刺さります。
一度落として立て直すと、今度はUIが出る
frontendの依存は初回起動時にもう ~/.local へ入り終わっています。ということは、hassを一度止めてもう一度起動すれば、今度は最初から hass_frontend を取り込めるはず。試すと当たりでした。
$ hass -v # 2回目の起動
...
/ -> 302
/onboarding.html -> 200
/ が302で /onboarding.html へ飛ぶようになりました。ブラウザで開くと、ちゃんと初期設定画面(オンボーディング)が出ます。ホスト側のChromeのロケールを見てか、最初から日本語でした。

ここから先は普通にウィザードが進みます。ユーザー作成の画面でアカウントを作り、

そのあとは「自宅の場所(LeafletのOSM地図)」→「国(日本を選択)」→「匿名の分析データを送るか(今回は全部オフ)」→「完了」と進んで、進捗バーが100%になりました。ここまでは、拍子抜けするくらいスムーズです。
ダッシュボードが「Loading data」から進まない
「完了」を押すとダッシュボード(/)に飛ぶんですが……画面が 「Loading data」から一向に進まない。リロードしても、ブラウザを開き直しても同じ。アプリの殻は出ているのにデータが来ない、という一番モヤモヤするやつです。
バックエンドのログを見て、ようやく腑に落ちました。
[homeassistant.components.websocket_api.http.connection] Error handling message:
Unknown error (unknown_error) Demo User from 172.17.0.1
...
File ".../assist_pipeline/audio_enhancer.py", line 8, in <module>
from pymicro_vad import MicroVad
ModuleNotFoundError: No module named 'pymicro_vad'
フロントが起動時に投げるWebSocketメッセージの処理の中で、assist_pipeline の audio_enhancer.py が pymicro_vad をimportしようとして落ちている。そう、最初に「音声は使わないしいいか」と流した、gccが無くてビルドできなかったあのモジュールです。
assist_pipeline は default_config に含まれているので、音声を一切使うつもりが無くても初期状態で有効になっていて、フロントの初期ロードがそこに触れた瞬間に毎回エラーになる。結果、ダッシュボードのデータ取得が完了せず「Loading data」で止まる。「音声機能が無効になるだけ」では済まず、UIごと固まるのが誤算でした。
gccを入れて、最後はlibstdc++で一悶着
原因がはっきりしたので、素直に gcc(build-essential)を入れて、欠けていた2つのC拡張を自分でビルドします。
$ apt-get install -y build-essential # gcc 14.2.0、約10秒
$ pip install --user "pymicro-vad==1.0.1" "pyspeex-noise==1.0.2"
Successfully installed pymicro-vad-1.0.1 pyspeex-noise-1.0.2
ビルドは通った。よし、と思って import を確認すると、まだ落ちる。
$ python -c "import pymicro_vad"
ImportError: .../micro_vad_cpp...so: undefined symbol: _ZTVN10__cxxabiv117__class_type_infoE
_ZTVN10__cxxabiv117__class_type_infoE はC++のABIシンボルで、要はC++の標準ライブラリ(libstdc++)がリンクされていない .so になっている、という定番のやつです。今回はコンテナも使い捨てなので、深追いせず LD_PRELOAD で libstdc++ を先読みさせて逃げました。
# ここは正直やっつけ。恒久対応というより「使い捨て環境で先に進むための回避」です
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6 hass -v
この状態でhassを立て直したら、WebSocketのエラーがきれいに消えて、ダッシュボードが Loading data を抜けて /home/overview まで来てくれました。

「ようこそDemo Userさん」と出て、リビングルーム・台所・寝室のエリアやサイドバーが並ぶ、見慣れた画面。ここまで来てようやく一息つけました。
つまずきを並べてみると
振り返ると、詰まった3か所は全部「slimイメージにgccが無い」に根っこが繋がっていました。
| 症状 | 直接の原因 | 今回の対処 |
|---|---|---|
| 初回起動でrecovery mode(/が404) | 起動中に入れたfrontendを同プロセスがimportできない | 依存が揃った状態でhassを再起動 |
| ダッシュボードがLoading dataで停止 | assist_pipelineがpymicro_vadをimportして失敗(gcc無しでビルド不可) | build-essentialを入れてビルド |
| ビルド後もimportがundefined symbol | C++拡張がlibstdc++未リンク | LD_PRELOADでlibstdc++を先読み(暫定) |
試してみての所感
pip install homeassistant が32秒で終わった時点では「なんだ簡単じゃん」と思ったんですが、そのあとが本番でした。とはいえ、詰まった原因はどれも Home Assistant のせいというより、自分が極端に軽いslimイメージを選んだことに由来していて、公式が用意している Home Assistant Container(gccやビルド依存を最初から含むイメージ)を素直に使えば、この沼はほぼ踏まないはずです。今思えば「Coreをslimに手で入れる」という縛りを自分でかけた結果ですね。
学びとして大きかったのは、Home Assistantが依存を起動時に動的インストールする設計だという点。おかげで初回と2回目で挙動が変わるし、default_config が有効な限り「使わないつもりの音声機能」の依存欠けがUI全体を止めうる。ここは動かしてみて初めて体感できました。
自分の使い方としては、ちゃんと運用するなら公式のContainerイメージ一択で、slimに手入れするのは「中で何が起きているか観察する」用途に留めるかな、というのが正直なところ。ここは好みが分かれるところですが、こういう「軽い環境で動かして裏側を覗く」遊びは、たまにやると仕組みの理解がぐっと進むのでおすすめです。
もっと良いやり方(特にlibstdc++まわりのスマートな解決策)があったら教えてください。