こんにちは、てつです!
前回の第3回連載では、GitHub Actions(ギハブアクションズ:GitHubが提供する自動化プラットフォーム)の「CI(継続的インテグレーション)」を使い、設定ファイルの自動構文チェックに挑戦しましたね。これで、エラーのある不完全なコードが自宅サーバーに届く前にGitHub側で自動的に弾かれるという、鉄壁の盾が手に入りました。
しかし、構文チェックが通ったあと、皆さんはどうしていますか? 「よし、エラーはないな。じゃあ Tera Term を開いて、自宅サバにSSHログインして、ディレクトリを移動して、docker compose pull して docker compose up -d……」
――正直、この作業、毎回やるの面倒くさくないですか?
今回は、その退屈なルーティン作業から完全に卒業します。 目指すのは、PCの使い慣れたエディタで設定を書き換え、git push したその瞬間に、自宅サーバーのコンテナが全自動で最新化される自動化環境です。
これはIT業界の最前線で 「GitOps(ギットオプス:Gitのリポジトリを『真実の基準』としてサーバーに自動反映させる運用手法)」 や 「CD(継続的デプロイ:変更を自動で本番環境に適用する仕組み)」 と呼ばれる、プロのインフラエンジニアが大規模システムを運用する時とまったく同じ手法です。
「趣味の自宅サーバー」を、一気に「現場レベルのプロ仕様」へと進化させましょう!
1. なぜ手動更新を卒業し、自宅サーバーを「GitOps」で自動化するのか?
具体的な手順に入る前に、なぜプロの現場がSSHログインによる手動更新を嫌い、GitHub Actionsによる自動化(GitOps)にこだわるのか、その理由(Why)をインフラエンジニアの視点で解説します。
原因はシンプルで、「人間は必ずミスをするから」です。
●手動運用のリスク(本番環境でのタブー)
サーバーに直接入ってコマンドを叩く運用は、「作業ディレクトリを間違えた」「本番用のコマンドなのに、テスト用の古いオプションを付けて実行してしまった」「コンテナを落としたまま起動し忘れた」といった、悲惨なオペレーションミスを引き起こす最大の原因になります。
そのため、モダンな開発現場では「人間が本番サーバーにSSHで直接入って作業すること」自体が原則禁止されているケースがほとんどです。
●GitOpsを取り入れるメリット
「サーバーの状態を書き換える権利」を人から奪い、Gitリポジトリ(GitHubなど)のコードが正であるとして、機械に自動反映させます。これにより、誰がいつ変更したかの履歴が100%残り、万が一の時もGitの履歴を戻すだけで一瞬で元の状態に復旧(ロールバック)できるようになります。
今回は、前回構築した「Self-hosted Runner(セルフホステッド・ランナー:自宅サーバー内で待機するGitHub専用の実行エージェント)」という自動化ロボットに、この「コンテナの自動化デプロイ」の大役を任せます。
2. GitHub Actionsによる自動化を始める前の環境チェック
今回の作業を進めるにあたり、以下の前提条件が整っているか確認してください。不安な方は、過去の連載記事の内部リンクから復習しておくとスムーズです!
- 自宅サーバー(Linux OS)が動いており、Docker / Docker Compose が導入されていること
docker-compose.ymlなどの設定ファイルが、GitHubのプライベートリポジトリで管理されていること(→[第2回記事へのリンク])- 自宅サーバー内に「Self-hosted Runner」が構築され、GitHub側で「Idle(待機中)」になっていること(→[第3回記事へのリンク])
今回は特別な外部ツールを追加しません。前回用意した自動化ロボットに、新しい指示書(ワークフローファイル)を1枚渡すだけです。
3. 【ステップ解説】git pushで自宅サーバーを自動更新する手順
それでは、具体的に設定を進めていきましょう!
作業1:GitHub側に「自動デプロイ指示書(ワークフロー)」を作成する
まずは、GitHubリポジトリに新しくデプロイ(配置・反映)用のワークフローファイルを作成します。 お使いのPCのエディタ(VS Codeなど)で、リポジトリ内の .github/workflows/ ディレクトリ配下に、新しく deploy.yml というファイルを作成してください。
ファイルを作成したら、以下のコードをそのまま貼り付けます。プログラミングやインフラ初心者の方でも意味が理解できるよう、1行ずつ細かく解説を入れています。
name: Auto Deploy to Home Server # 1行目:この自動化処理(ワークフロー)の名前です。GitHubの画面上で表示されます。
on: # 3行目:自動化を実行する「タイミング(イベント)」を設定するブロックです。
push: # 4行目:コードがリポジトリに「push(送信)」された時をトリガーにします。
branches: ["main"] # 5行目:対象とするブランチをメインの「main」ブランチに指定しています。
jobs: # 7行目:ここから下に、具体的な自動化タスク(ジョブ)を書いていきます。
deploy: # 8行目:今回のタスクに「deploy(デプロイ)」という名前をつけました。
runs-on: self-hosted # 9行目:【超重要】前回構築した、自宅サーバー内の「Self-hosted Runner」を指定します。これにより、インターネット上のクラウドではなく、あなたの自宅サーバーの中で直接コマンドが実行されます。
steps: # 11行目:実行する具体的な手順(ステップ)を上から順番に並べていきます。
- name: Checkout code # 12行目:このステップの名前です。最新のコードをサーバー内に持ってきます。
uses: actions/checkout@v4 # 13行目:GitHubが公式提供している、リポジトリの最新コードをダウンロードするための定番テンプレートを呼び出しています。
- name: Deploy Containers # 15行目:このステップの名前です。実際に自宅のコンテナを最新化します。
run: | # 16行目:「|(パイプ)」を書くことで、以下に複数行のLinuxコマンドをまとめて実行できます。
docker compose down # 17行目:一度、古いコンテナを安全に停止・削除します。
docker compose up -d # 18行目:最新に書き換わった設定ファイルを元に、バックグラウンド(-dオプション)でコンテナを再起動します。
ファイルを保存したら、一度コミットしてpushしておきましょう。 (※まだこの時点では自宅サーバー側の権限設定が必要なため、GitHub上でエラー(赤マーク)になっても大丈夫です!)
作業2:自宅サーバー側の「Docker操作権限」を設定する
ここが一番の踏ん張りどころです。
自宅サーバーの中で動いているGitHub Actionsのロボット(Self-hosted Runner)は、セキュリティ上、システムを壊さないようにかなり制限された一般ユーザーとして動いています。
しかし、コンテナを操作する docker コマンドを実行するには、通常は管理者権限(root権限)が必要です。このままだと、ロボットが「権限がないのでコンテナを動かせません!」とエラーを出してしまいます。
これを解決するために、社会人の組織でいう「Docker操作の決裁権限」をロボットに与えてあげましょう。
自宅サーバーに一時的にSSHログインし、以下のコマンドを1行ずつ実行してください。
# 1. サーバー内に「docker」という権限グループがあるか確認(通常は自動で作られています)
getent group docker
# 2. ロボットを実行しているユーザーを、dockerグループに参加させる
# ※$USERの部分は、現在ログインしているユーザー名、またはRunnerを動かしているユーザー名に変えてください
sudo usermod -aG docker $USER
【重要】 グループの設定を反映させるため、自宅サーバー側で動いている Self-hosted Runnerのサービス(またはスクリプト)を必ず一度再起動 してください。
これで、ロボットが管理者を通さずに、安全に docker compose コマンドを実行できるようになりました!設定が終わったら、SSHクライアント(ターミナル)の画面を完全に閉じてください。
作業3:運命の動作確認!SSHログインなしでコンテナを反映する
さあ、いよいよ感動の瞬間です。本当にSSHなしで自宅サーバーが書き換わるかテストしましょう!
1.PC側で、管理しているリポジトリの docker-compose.yml を開きます。
2.サービスに影響がない部分(例:環境変数の値や、テスト用のコメント行など)を1箇所だけ小さく書き換えて保存します。
3.ターミナル(PC側)を開き、お馴染みの3点セットでGitHubへpushします!
git add .
git commit -m "chore: test auto deploy"
git push origin main
4.GitHubのリポジトリ画面を開き、「Actions」タブを確認します。
黄色い「実行中」のマークが回り始め……数十秒後、すべてのステップが鮮やかな緑色のチェックマーク(Success)に変われば大成功です!
ブラウザから自宅サーバーのサービスにアクセスしてみてください。SSHログインを一切していないのに、変更内容が完璧に反映されているはずです。
「自分がPCでコードを書いてプッシュしただけで、自宅の機械が裏で勝手に動いてくれた」というこの感覚、めちゃくちゃワクワクしませんか?
4. プロのインフラエンジニア視点:なぜこの自動化はセキュリティが「鉄壁」なのか?
今回の仕組み、実は利便性だけでなくセキュリティ面でも凄まじい恩恵があります。
通常の自動化(CD)でよくある手法は、GitHub側から自宅サーバーに対して「SSHで接続しに行ってコマンドを叩く」というアプローチです。しかしこれを行うには、以下のような大きなリスクが伴います。
- 自宅ルーターのポート開放(22番ポートなど)を行い、世界中にSSHの入口を晒さなければならない。
- GitHub側に、自宅サバの秘密鍵を登録(Secrets管理)しなければならない。
しかし、今回導入したSelf-hosted Runner方式(アウトバウンド接続方式:内側から外側へ通信を確立する方式)は全く異なります。
インターネット側から自宅サーバーへ接続しに来るのではなく、サーバーの中にいるロボットが、内側からGitHubに対して「何か私にできる指示(ジョブ)はありますか?」と定期的に御用聞きに行っている状態です。
つまり、自宅ルーターのポート開放は「1箇所も不要(すべて閉じたままでOK)」。外からの侵入経路を完全にシャットアウトした安全な状態をキープしたまま、プロ顔負けの全自動デプロイ環境を実現しているのです。
これぞ、現場のインフラエンジニアが唸る「プロ仕様」の設計思想です。
5. まとめと次回の予告:次はDiscord/Slackへの運用監視通知!
お疲れ様でした!
手動でSSHログインしてコンテナをガチャガチャ動かす退屈な日々は、今日で終わりです。あなたのホームラボは、Gitのプッシュひとつで自律的に進化する「大人の秘密基地」へと昇格しました。
こうして「CI(自動チェック)」と「CD(自動デプロイ)」が揃ったことで、自宅サーバーのDevOps環境の土台は完璧に完成しました。
しかし、こうして全自動化が進むと、今度は新たな欲が出てきませんか? 「自動デプロイが成功したのか失敗したのか、毎回GitHubの画面をブラウザで見に行くのすら面倒だな……」
そこで次回の第5回は、自動化の実行結果を、皆さんが普段使い慣れている「Discord」や「Slack」へ即座にプッシュ通知する【運用監視・通知編】をお届けします!(→[第5回記事へのリンク予定])
これができれば、スマホをポケットに入れているだけで、地球の裏側にいても自宅サーバーの状態を1秒で把握できるようになります。次回もお楽しみに!
6. 補足:よくある詰まりポイントとエラーハンドリング(トラブルシューティング)
自宅環境のOSのバージョンやユーザー権限によっては、初回にエラーが出ることがあります。万が一赤マークが出て止まってしまった場合は、エラーメッセージの「単語」に注目してみましょう。
① permission denied(権限エラー)が出て止まる場合
- 注目すべき場所:GitHub Actionsの実行ログを開き、下の方にある
connect: permission deniedやPermission deniedという文字。 - 原因:作業2の「Docker操作権限」がロボット(Runner)に正しく付与されていない、または付与した後にRunnerのサービスが再起動されていない可能性が高いです。
- 対策:自宅サーバー側で
groupsコマンドを叩き、Runnerを実行しているユーザーが本当にdockerグループにいるか確認してください。設定後は必ずsudo systemctl restart actions-runner(または./svc.sh restart)でロボットを再起動させて組織変更を認識させましょう。
② docker: command not found(コマンド未検出)と叱られる場合
- 注目すべき場所:
not found(見つからない)という単語。 - 原因:ロボットが自宅サーバー内で「dockerってコマンド、どこに置いてあるの?」と迷子になっています。環境変数(PATH:コマンドの置き場所を記録したルート案内)の参照先が、一般ユーザーとRunnerの間でズレている場合に発生します。
- 対策:自宅サーバー側で
which dockerと叩き、出力されたフルパス(例:/usr/bin/docker)を確認します。そして、deploy.ymlのコマンド部分をdocker composeではなく、/usr/bin/docker composeのように絶対パス(フルネーム)で書き換えて再度pushしてみてください。
★あなたの自宅サーバーは無事にSSHを卒業できましたか?
「プッシュして動いた時、ニヤニヤが止まらなかった!」「ここで別のエラーが出た!」など、ぜひX(旧Twitter)やコメントで教えてくださいね。皆さんのホームラボ報告、楽しみに待ってます!

情報の出典(ソース)
- GitHub Actions 公式ドキュメント(About self-hosted runners)
- Docker Documentation(Post-installation steps for Linux)
-scaled.png)

コメント