Linux & Docker

ラズパイDockerで自宅サービス|Portainer複数コンテナGUI管理

更新: 佐々木 まい
Linux & Docker

ラズパイDockerで自宅サービス|Portainer複数コンテナGUI管理

Portainer CEは、Raspberry Pi 4やPi 5で複数の自宅サービスを動かすときに、稼働中のコンテナやボリューム、ネットワークを1画面で見渡せるようにする管理基盤です。

Portainer CEは、Raspberry Pi 4やPi 5で複数の自宅サービスを動かすときに、稼働中のコンテナやボリューム、ネットワークを1画面で見渡せるようにする管理基盤です。
Dockerを日常的に扱うインフラ実務の知見を、自宅ラズパイのスマートホーム運用へそのまま持ち込めるので、導入はCLIで最小限に抑え、以後の操作はブラウザに集約できます。
実際の構成もシンプルで、Dockerは3手順で入れ、https://ラズパイIP:9443 を開いてStacksにcomposeを貼り付ければ、Pi-holeやNextcloudをまとめて立ち上げられます。
SDカード寿命、ARM64非対応イメージ、自動起動の設定漏れといったラズパイ特有の地雷も先回りで潰し、『手順通りやったのに動かない』を避ける流れにしてあります。

完成イメージ:1台のラズパイで複数サービスをGUI管理する全体像

Portainerを入れると、1台のラズパイの中で動いているDocker資産を、ブラウザ上の1画面で見渡せるようになります。
コンテナ、イメージ、ボリューム、ネットワークがまとまって見えるので、どのサービスが生きていて、どれが落ちているのかを毎回コマンドで掘り返す必要がありません。
自宅運用では、この一覧性がそのまま安心感につながります。

Portainerが解決するもの:複数コンテナの状態が一目でわかる

PortainerはDockerのWeb UIとして、稼働中のコンテナだけでなく、イメージやボリューム、ネットワークまでまとめて表示します。
ラズパイにPi-holeとHome Assistantを同居させていたとき、コマンド運用では「どのコンテナが落ちたか」を特定するだけで少し手間取りましたが、Portainerを入れてからはダッシュボードの赤い表示で異常にすぐ気づけるようになりました。
複数サービスを並べて動かすほど、状態確認が1画面で済む価値は大きくなります。

CLIで導入・GUIで運用という分担の考え方

設計の核は「導入はCLI、運用はGUI」です。
Docker本体の導入やPortainerコンテナの起動まではコマンドで行い、その後のデプロイ、再起動、ログ確認、更新はブラウザに寄せます。
業務でKubernetesやDockerを扱っていても、自宅では重い運用基盤を持ち込みすぎないほうが扱いやすい。
軽さと一覧性を優先してPortainerに落ち着くのは、過剰なツールを避ける判断として自然です。

管理画面は https://ラズパイのIP:9443 で開けます。
HTTPSで使え、エージェント連携用に8000番も使うため、接続先の役割が分かりやすいのも利点です。
Portainer CEは無料で、アイドル時のCPU負荷も小さいので、4GB以上のラズパイ4/5なら他サービスと同居させても運用しやすいでしょう。

自宅で同居させやすい定番サービスの例

Dockerの強みは、1台のラズパイに複数の役割を閉じ込めて整理できることです。
自宅で同居させやすい定番としては、DNSレベルで広告をブロックするPi-hole、自前クラウドストレージとして使えるNextcloud、スマートホーム機器をまとめるHome Assistantが挙げられます。
これらは単体でも便利ですが、コンテナとして切り分けておくと、止める・直す・入れ替える作業がずっとやりやすくなります。

Portainer上では、こうしたサービスを個別のコンテナとして並べて扱えるため、構成全体の見通しがよくなります。
どのサービスがどのネットワークに属しているか、どのボリュームにデータを持っているかが見えると、バックアップや再構築の段取りも組みやすい。
ラズパイ1台を小さな家庭内インフラとして育てるなら、まずこの形を描いてみてください。

前提と必要なもの:ラズパイ・OS・ストレージの選定

Raspberry Pi 4 なら RAM 4GB 以上、できれば Pi 5 を選ぶと、Docker で複数コンテナを並べたときの余裕が出ます。
2GB モデルでも単体サービスは動きますが、ログ、データベース、管理画面を同時に抱えるとすぐ窮屈になるため、最初から 4GB 以上を実用ラインとして見ておくと構成が安定します。
筆者も小容量機で始めて、後からメモリ不足に悩まされたことがあるので、ここは少し余裕を持たせる選び方がおすすめです。

推奨するラズパイ機種とRAM容量

Raspberry Pi 4 の 4GB 以上、または Pi 5 を選ぶのが扱いやすい構成です。
自宅サーバーでは Docker 本体に加えて、Portainer、各種サービス、バックグラウンドの更新処理が同時に走るため、メモリ消費がじわじわ効いてきます。
2GB モデルだと起動はしても余白が少なく、再起動やイメージ更新のたびに待たされやすいので、最初から 4GB 以上にしておくと気持ちよく運用できます。
筆者が複数コンテナを組んだ環境でも、この差はかなり体感しやすいものでした。

64bit OSを選ぶ理由とブートメディア

OS は 64bit 版の Raspberry Pi OS Bookworm か、Ubuntu Server 22.04/24.04 の ARM64 版を使います。
最近の Docker イメージは ARM64 前提が増えており、32bit だと起動できないケースが出やすいからです。
Docker 導入をスムーズに進めるなら、最初から 64bit を選んでおく判断が実務的でしょう。
さらに、ブートメディアは SD カードより USB-SSD を推奨します。
Docker のデータは /var/lib/docker 配下に書き込みが集中するため、SD カードは消耗しやすく、長期運用ではファイルシステム破損の火種になりやすいからです。
実際に SD カードブートで運用していたラズパイが書き込み過多で壊れ、以降は USB-SSD ブートへ切り替えたところ、そこからは安定して動きました。
ボリュームや DB を SSD 側に置いておくと、劣化の回避と読み書き性能の向上を同時に得られるので、自宅サーバーには向いています。

ARM64対応イメージかをDocker Hubで確認する

ARM64 対応かどうかは、Docker Hub のイメージ説明で linux/arm64 が含まれているかを確認します。
ここを見落とすと、起動時に exec format error で止まり、原因調査に時間を取られます。
とくに Raspberry Pi では x86 向けイメージをそのまま流用しがちなので、タグの確認を先に済ませておく流れが安全です。
筆者は Ubuntu Server と Raspberry Pi OS の両方で構築しましたが、Docker を素直に動かしやすいのは 64bit OS 側でした。
まず土台を ARM64 に揃え、SSD 上にデータを置き、対応イメージだけを選ぶ。
この順番にしておくと、後の手順はかなり楽になります。

手順1:DockerとPortainerを3つのコマンドで導入する

DockerとPortainerは、最初の3手順を順番に押さえるだけで、ラズパイ上のコンテナ管理環境をすぐ整えられます。
Dockerは公式スクリプトで入れ、使うユーザーをdockerグループに追加して、Portainerは設定を残すためのnamed volume付きで起動します。
ここで各オプションの意味まで理解しておくと、あとから再構築するときの迷いが減るでしょう。

Dockerを公式スクリプトで入れる

Docker本体は、公式の便利スクリプトを使うのが手早い方法です。
curl -fsSL https://get.docker.com -o get-docker.sh で取得して sudo sh get-docker.sh を実行すれば、必要なパッケージをまとめて導入できます。
ARM64でも適切なパッケージが自動で選ばれるので、手元でアーキテクチャを細かく指定する必要はありません。
ここは手順を短くして、導入後の確認に時間を回しましょう。

導入が終わったら、sudo usermod -aG docker $USER で自分のユーザーをdockerグループに追加します。
これを入れておくと、毎回 sudo を付けずに docker コマンドを使えるようになります。
筆者はこのあと再ログインを忘れて permission denied で詰まったことがあり、初心者が同じところで止まりやすいと感じています。
反映には一度ログアウトして再ログインしましょう。

Portainer用のnamed volumeを作る

Portainerは管理画面そのものよりも、設定を消さずに運用できるかが使い勝手を左右します。
docker volume create portainer_data で named volume を先に作っておくと、コンテナを作り直してもダッシュボードの設定やユーザー情報が残ります。
単に起動するだけなら後からでも動きますが、再セットアップのたびに初期設定をやり直すのは手間が大きいものです。
最初に保存先を分けておく設計にしておきましょう。

portainer-ceコンテナを起動しオプションを理解する

Portainer CE は docker run -d -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:.sock -v portainer_data: portainer/portainer-ce:latest の形で起動します。
-v /var/run/docker.sock:.sock は Portainer が Docker API に接続するための窓口で、これがないとコンテナ一覧や管理操作を扱えません。
-v portainer_data: は設定の永続化、-p 9443:9443 はブラウザで開くGUIポート、--restart=always は停止や再起動後に自動で立ち上がるための指定です。

この --restart=always を外していたせいで、停電後に Portainer だけ上がらず困ったことがあります。
Docker の基盤が生きていても、管理画面が復帰しないと状態確認ができず、復旧の手順が一気に面倒になります。
起動オプションは見た目より役割がはっきりしているので、どれも意味を理解して付けるのがおすすめです。
意味のある設定だけを積み上げていきましょう。

手順2:ブラウザでの初期設定とダッシュボードの歩き方

Portainerの初回設定は、ラズパイ上で動いているDockerをブラウザ越しに扱える状態へ整える入口です。
最初にhttps://ラズパイIP:9443へアクセスし、管理者アカウントを作成してからlocal(Docker socket経由)を選ぶ流れを押さえると、その後の画面操作が一気に楽になります。
Containers、Images、Volumes、Networksの役割まで最初に見通せば、どこで何を触るべきか迷いにくくなります。

初回ログインと管理者アカウント作成

Portainer起動後は、母艦PCのブラウザで https://ラズパイIP:9443 を開きます。
自己署名証明書を使っているため警告が出ますが、ローカルネットワーク内でこのラズパイを管理するだけなら、そのまま続行して問題ありません。
警告の意味を先に理解しておくと、後で外部公開を考える場面でも、どこから先が慎重に扱う領域なのか判断しやすくなります。

画面が開いたら、最初に管理者ユーザー名とパスワードを設定します。
ここは後回しにしない方がよく、起動後おおむね5分以内に設定しないとセキュリティ保護のためロックされ、コンテナの再起動が必要になります。
筆者も初回アクセスを後回しにしてタイムアウトでロックされ、結局コンテナを立ち上げ直してやり直したことがあります。
最初の数分で終わる作業なので、ブラウザを開いたらそのまま一気に進めましょう。

ローカルDocker環境を選択する

初回ログインが終わったら、環境選択では local(Docker socket経由) を選びます。
これは起動時にマウントした docker.sock を通して、このラズパイ上のDockerをそのまま管理対象にする設定です。
別のホストや外部のDockerを探しに行かず、いま目の前にある機械を直接操作する形になるので、構成が素直で見通しもよくなります。

この選択を外すと、Portainerを開いたのにコンテナ一覧が期待どおりに出ない、という入り口のつまずきが起きやすくなります。
まず local を選んでおけば、以後の画面はこのラズパイの実体と結びついたまま進むため、設定の意味を確認しながら使えるでしょう。
Docker socket 経由という仕組みを一度つかんでしまうと、管理画面の見え方がかなり整理されます。

コンテナのログ・コンソール・再起動をGUIで操作

ダッシュボードに入ったら、まず Containers メニューを開きます。
ここから各コンテナのログ閲覧、コンソール接続、Start/Stop/Restart が1クリックでできるので、運用の中心になる場所だと考えておくと分かりやすいです。
SSHで入って docker logs を叩く手順を毎回踏まなくてよくなり、画面だけでエラー原因を追える場面が増えます。
実際、GUIのログ画面で異常行を見つけて原因を切り分けられたときは、調査の手戻りが減りました。

同時に、Images、Volumes、Networks の役割も早めに見分けておきましょう。
Images はコンテナの元になるイメージ、Volumes はデータ保持先、Networks はコンテナ同士や外部との通信経路を扱います。
Containers だけを見ていると全体像を取り落としやすいので、最初にこの3つの置き場所を頭に入れておくと、再起動や削除の判断が落ち着いてできます。
おすすめです。
ここを押さえてから触ると、運用の速度が変わります。

手順3:Stacksでdocker-composeから複数サービスを一括デプロイ

Stacksでは、docker-compose.yml をWeb画面のエディタに貼り付けて Deploy を押すだけで、複数サービスをまとめて起動できます。
CLIで1台ずつコンテナを立ち上げる流れから外れるので、Pi-hole+管理DBのような構成も画面操作で扱いやすくなります。
既存の compose 定義をそのまま移植しやすく、スマートホーム一式をまとめて別環境へ持っていくときにも相性がよい方法です。

Stacksにcompose定義を貼り付けてDeploy

Stacksの扱いはシンプルです。
docker-compose.yml を貼り付け、必要な環境変数やパスを整えたら Deploy するだけで、関連するコンテナ群が同時に立ち上がります。
単体コンテナを1つずつ起動するよりも、サービス間の依存関係を compose 定義の中に閉じ込められるため、運用の見通しがよくなるのが利点です。

たとえば Pi-hole と Nextcloud+MariaDB を1つのスタックにまとめれば、ひとまとまりの機能として管理できます。
サービスを増やしたくなったときも、compose 定義に追記して Update the stack するだけで反映できるので、後から機能を足す心理的ハードルが下がります。
実際に既存の docker-compose.yml を貼り付けるだけでスマートホーム一式を移植できると、CLIで個別起動していた頃よりも構成の再現性が高いと感じやすいでしょう。

ボリュームとネットワークをGUIで管理する

永続化の設計では、named volume と bind mount を分けて考えるのが基本です。
named volume はバックアップや移行がしやすく、コンテナ側のデータをまとまりとして扱えます。
DB データやアプリの内部状態のように、ホストの特定パスを意識したくない情報は named volume に寄せると管理が楽になります。

bind mount は、ホスト側の特定パスから直接ファイルを触れるのが強みです。
設定ファイルを手で編集したい場合や、ログをホストの見慣れたディレクトリで追いたい場合に向いています。
設定は bind、DB は named という分け方にしておくと、日々の編集と保守の役割が整理されます。
GUIで定義を見ながら切り替えられるため、どこに何が置かれているかを追いやすい点も。

スタック単位で bridge ネットワークを分けると、サービス間の境界がはっきりします。
同一スタック内ではコンテナ名、つまりサービス名で相互に名前解決できるので、IPアドレスを追いかけずに済みます。
複数スタックを並べる構成でも衝突しにくく、あとから構成を増やすときに整理しやすいです。

複数サービスをリバースプロキシでまとめる

外部公開するサービスは、Nginx Proxy Manager のようなリバースプロキシで前段をまとめるのが安全な定番です。
SSL/TLS 終端と証明書管理を1か所に集約しておけば、各コンテナに個別の公開設定を散らさずに済みます。
直接ポート開放だけで運用すると、公開面が増えやすく反省点も増えるので、入口を一本化したほうが管理しやすいでしょう。

筆者も以前はリバースプロキシを噛ませずに直接ポートを開けてしまい、構成が見えにくくなった経験があります。
そこから HTTPS 終端を集約する形に切り替えると、外向きの通信経路がはっきりし、複数サービスを扱っても迷いにくくなりました。
Pi-hole や Nextcloud のように役割の違うサービスを並べるときほど、この入口の整理が効いてきます。
安全な公開経路を先に決めてからサービスを増やしていく流れにすると、あとで見直す作業も少なくなります。

つまずき対策:SDカード寿命・ARM64非対応・自動起動の落とし穴

ラズパイでDockerを運用すると、起動そのものがこける原因がアプリではなく「イメージの形式」「保存先の置き方」「再起動設定」に潜んでいることが多いです。
見た目は同じコンテナでも、ARM64非対応のイメージや一時領域へのデータ配置が混ざると、初回起動は通っても次の再起動で止まることがあります。
症状ごとに切り分けると、対処は意外なくらい素直です。

ARM64イメージ非対応とexec format error

exec format error が出たとき、真っ先に疑うのはARM64非対応のイメージです。
x86前提のイメージをそのままpullすると、ラズパイのCPUが実行形式を解釈できず、コンテナは起動直後に落ちます。
筆者も以前、x86向けイメージをそのまま試してこのエラーに当たり、それ以来Docker Hubで linux/arm64 タグの有無を先に確認する習慣がつきました。
対応タグがあればそれを選び、なければARM64対応版か代替イメージへ切り替えるのが回り道の少ないやり方です。

ストレージ起因のDocker起動失敗

/var/lib/docker をtmpfs、つまりRAMディスクに置くのは避けたほうがよいです。
SDカードを長持ちさせたい意図でやりがちな設定ですが、Docker側からは書き込み先が永続ストレージではないと見なされ、起動できなくなります。
筆者もSDカード延命のつもりでRAMディスク化を試し、Dockerが上がらなくなって戻した経験があります。
データ領域は必ず永続ストレージに置き、コンテナの実体とメタデータが消えない構成にしましょう。

コンテナ自動起動とボリュームのバックアップ

再起動後にコンテナが上がってこないなら、restart: unless-stopped を各サービスに入れておくのが基本です。
always でも動きますが、手動停止したものまで勝手に戻したくない場面では unless-stopped のほうが扱いやすいでしょう。
ラズパイは停電やメンテで再起動する機会があるので、この設定がないと毎回手で立ち上げ直すことになります。
さらにボリュームの退避は、Portainerを一度停止してからtarで圧縮アーカイブを作る流れを守ってください。
稼働中にコピーするとDBの中身が更新途中のまま入り、不整合を抱えたバックアップになります。
停止してから保存し、終わったら再開する。
これを手順として固定しておくと、SDカード破損への備えとしても安心です。

この記事をシェア

佐々木 まい

IT企業でのシステムエンジニア経験を経て、スマートホーム導入のコンサルティングに転身。Home AssistantやESPHomeを使った自宅オートメーションを日々研究中。

関連記事

Linux & Docker

Proxmox VEは、ブラウザのWeb GUIからVMやLXCコンテナ、バックアップ、スナップショットをまとめて扱える仮想化基盤です。ラズパイ1台に複数サービスを詰め込んで、1つ壊れただけで全部やり直しになるあの面倒さを、1サービス1ゲストに分けて切り離せる形へ変えてくれます。

Linux & Docker

TrueNAS Scaleは、LinuxとZFSを土台にしたNAS構築用のOSで、OpenMediaVaultはDebianベースで軽量に動くNAS向けディストリビューションです。

Raspberry Pi

RetroPieは、Raspberry Pi上で動く無料のレトロゲームOSで、ファミコンからプレステ世代までを1台で遊べるようにする仕組みです。標準で50以上のゲーム機やPCに対応し、Raspberry Pi本体・microSDカード・USB-C電源・HDMIケーブル・コントローラーの5点から始められるので、

Linux & Docker

SSHは、離れたLinuxサーバーやRaspberry Piに安全に入るための基本ですが、最初の1回目で警告が出たり、公開鍵を置いたのに authorized_keys の権限で止まったりして、そこで手が止まる人を筆者は何度も見てきました。