docker contextで複数サーバーのDockerをローカルから一元管理する方法|ssh contextの設定とTLS接続の実践手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Docker > docker contextで複数サーバーのDockerをローカルから一元管理する方法|ssh contextの設定とTLS接続の実践手順
「検証サーバーと本番サーバー、それぞれでDockerを操作するたびにSSHでログインし直している...」
サーバーが増えるほど、この手間は比例して増えていきます。DOCKER_HOST=ssh://...を毎回設定するのも使えますが、スクリプトに埋め込んだ瞬間に管理が難しくなります。

この記事では、docker contextコマンドを使って複数のDockerホストをローカルのPCから一元管理する方法を解説します。SSH contextの作成・切り替えから複数ホストの運用Tips、TLS接続によるセキュアな設定まで、RHEL 9.4 / Ubuntu 24.04 LTSで動作確認した実機の出力例とともに紹介します。

この記事のポイント

・ docker context createでSSH contextを作成し、複数Dockerホストを名前で切り替えられる
・ docker context useで対象ホストに切り替えると、以降のdockerコマンドが全てリモートに向く
・ ~/.ssh/configとの組み合わせで接続先の管理をシンプルに一元化できる
・ DOCKER_CONTEXT環境変数でスクリプト・CI/CDにも安全に組み込める


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜdocker contextが必要なのか?

複数のLinuxサーバーでDockerを運用していると、次のような問題が出てきます。

・操作のたびにSSHでログインし直す手間がある
DOCKER_HOST=ssh://user@hostを毎回設定するとスクリプトが複雑になる
・本番サーバーを操作しているつもりで検証サーバーを触っていた——という操作ミスが起きやすい

docker contextはこれらの問題をまとめて解決します。接続先に名前を付けて管理し、docker context use prodのような一言で切り替えられる仕組みです。

環境変数との違いは明確です。DOCKER_HOSTはシェルセッション限定で、スクリプトに書くと接続先がハードコードされます。docker contextはDockerのクライアント設定として永続化されるため、シェルを再起動しても引き継がれます。操作対象のサーバーが一目でわかる状態を維持できるのが最大のメリットです。

docker contextの基本構成と仕組み

contextの設定ファイルは ~/.docker/contexts/ 以下にJSON形式で保存されます。docker context lsで現在の一覧を確認できます。

# docker contextの一覧を確認する $ docker context ls NAME DESCRIPTION DOCKER ENDPOINT ERROR default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock

初期状態ではdefaultコンテキストのみ存在します。*が付いているのが現在選択中のコンテキストです。

なお、Docker Desktopがインストールされている環境では desktop-linux というコンテキストが自動追加されることがあります。このコンテキストはDocker Desktopが管理するソケットを指しており、defaultと混同しないよう注意してください。

SSH contextでリモートサーバーに接続する

SSH contextはDockerデーモンをTCPで外部公開せずに利用できるため、TLS証明書の準備が不要でセキュアに接続できます。現場での利用率が最も高い接続方式です。

1. 事前準備(SSH鍵認証と接続確認)

SSH contextはパスワード認証では動作しません。事前にSSH鍵認証でパスワードなしに接続できることを確認してください。

# SSH鍵認証で接続確認(パスワード入力なしで接続できればOK) $ ssh ec2-user@10.0.1.100 "docker version --format '{{.Server.Version}}'" 26.1.3 # SSH鍵が設定されていない場合は追加する $ ssh-copy-id ec2-user@10.0.1.100

また、リモートサーバーの操作ユーザーがdockerグループに所属していることを確認します。

# リモートサーバーでgroupsコマンドを実行して確認する $ ssh ec2-user@10.0.1.100 "groups" ec2-user adm wheel systemd-journal docker # dockerグループに所属していない場合は追加する(追加後はSSHを再接続すること) $ ssh ec2-user@10.0.1.100 "sudo usermod -aG docker ec2-user"

2. SSH contextを作成する

docker context createで新しいコンテキストを追加します。--dockerオプションにSSH接続先を指定します。

# 本番サーバー用のSSH contextを作成する $ docker context create prod-web \ --description "Production web server" \ --docker "host=ssh://ec2-user@10.0.1.100" prod-web Successfully created context "prod-web" # 検証サーバー用のSSH contextも作成する $ docker context create staging \ --description "Staging server" \ --docker "host=ssh://deploy@192.168.10.20" staging Successfully created context "staging" # 一覧で確認する $ docker context ls NAME DESCRIPTION DOCKER ENDPOINT ERROR default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock prod-web Production web server ssh://ec2-user@10.0.1.100 staging Staging server ssh://deploy@192.168.10.20

3. コンテキストを切り替えてリモート操作する

docker context useでコンテキストを切り替えます。切り替え後は全てのDockerコマンドがリモートホストに向きます。

# prod-webコンテキストに切り替える $ docker context use prod-web prod-web Current context is now "prod-web" # 以降のdockerコマンドは全てprod-webサーバーで実行される $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a3f9d1b2c4e5 nginx:1.25 "/docker-entrypoint.…" 2 hours ago Up 2 hours 0.0.0.0:80->80/tcp web-nginx 7b8e4f6a1c09 mysql:8.0 "docker-entrypoint.s…" 3 hours ago Up 3 hours 3306/tcp db-mysql # 現在どのコンテキストが選択されているか確認する(*印) $ docker context ls NAME DESCRIPTION DOCKER ENDPOINT ERROR default Current DOCKER_HOST based configuration unix:///var/run/docker.sock prod-web * Production web server ssh://ec2-user@10.0.1.100 staging Staging server ssh://deploy@192.168.10.20

現在選択中のコンテキストには*が付きます。コマンド実行前にdocker context lsで操作対象を必ず確認する習慣をつけると、本番誤操作のリスクを大幅に下げられます。

4. デフォルトコンテキストに戻すには

ローカルのDockerに戻したい場合はdefaultコンテキストに切り替えます。

# ローカル(default)に戻す $ docker context use default default Current context is now "default" # 不要になったコンテキストを削除する(削除前に別のcontextに切り替えること) $ docker context rm staging staging

複数サーバーの運用Tips

SSH設定ファイルで接続先をシンプルに管理する

コンテキストのSSH接続先には~/.ssh/configのホスト名エイリアスが使えます。IPアドレスを直接書くより管理が楽になり、鍵ファイルや接続オプションを設定ファイルで一元管理できます。

# ~/.ssh/config に接続先を定義する Host prod-web HostName 10.0.1.100 User ec2-user IdentityFile ~/.ssh/prod_key.pem Port 22 Host staging HostName 192.168.10.20 User deploy IdentityFile ~/.ssh/staging_key

~/.ssh/configを設定した後は、コンテキストの作成をホスト名エイリアスだけでシンプルに書けます。

# ~/.ssh/config のホスト名エイリアスを使ってcontextを作成する $ docker context create prod-web \ --description "Production web server" \ --docker "host=ssh://prod-web" $ docker context create staging \ --description "Staging server" \ --docker "host=ssh://staging"

DOCKER_CONTEXT変数でスクリプトに組み込む

シェルスクリプトやCI/CDパイプラインで対象ホストを指定したい場合、DOCKER_CONTEXT環境変数が使えます。docker context useを実行せずに一時的にコンテキストを切り替えられるため、スクリプト終了後に元のコンテキストへ戻す手間がなくなります。

# 環境変数でコンテキストを一時指定する(docker context useを変更しない) $ DOCKER_CONTEXT=prod-web docker ps $ DOCKER_CONTEXT=staging docker images # デプロイスクリプトへの組み込み例 #!/bin/bash set -eu TARGET_CONTEXT=${1:-staging} echo "Deploying to context: ${TARGET_CONTEXT}" DOCKER_CONTEXT=${TARGET_CONTEXT} docker compose -f docker-compose.prod.yml pull DOCKER_CONTEXT=${TARGET_CONTEXT} docker compose -f docker-compose.prod.yml up -d echo "Deploy completed on ${TARGET_CONTEXT}."

優先順位は「DOCKER_HOST環境変数 > コマンドラインの--contextフラグ > DOCKER_CONTEXT環境変数 > docker context useの設定」の順です。スクリプトとコマンドラインを混用する場面では、意図せず別のコンテキストで動いていないかを確認してください。

Dockerコンテナの実践的な活用をもっと体系的に学びたい方には、Dockerコンテナ実践ガイド(docker.linuxmaster.jp)もあわせてご参照ください。SSH contextを含むリモート運用や複数環境の設計を体系的に解説しています。

TLS contextの設定(セキュアなTCP接続)

SSHアクセスが使えないネットワーク環境、またはCI/CDサーバーからDockerデーモンに直接接続したい場合、TLSでTCPを保護して接続する方法があります。設定コストはSSHより高いですが、SSHエージェントが使えない自動化環境では有効な選択肢です。

注意:DockerデーモンにTCPを公開するとDockerソケットへのリモートアクセスが可能になります。証明書管理を適切に行い、ポート2376へのアクセスはファイアウォールで制限してください。Linuxのポート確認コマンドとファイアウォール設定も合わせて確認することを推奨します。

# TLS contextを作成する(クライアント証明書・鍵・CA証明書が必要) $ docker context create prod-tls \ --description "Production server (TLS)" \ --docker "host=tcp://10.0.1.100:2376,ca=/path/to/ca.pem,cert=/path/to/cert.pem,key=/path/to/key.pem" prod-tls Successfully created context "prod-tls" # 接続確認 $ docker context use prod-tls $ docker info | grep "Server Version" Server Version: 26.1.3

Dockerデーモン側のTLS公開設定(/etc/docker/daemon.jsontlsverifytlscacert等)と証明書生成手順は公式ドキュメント(Docker Engine — Protect the Docker daemon socket)を参照してください。

トラブルシュート・エラー対処

「Cannot connect to the Docker daemon」が出た時の対処法

SSH contextに切り替えた後にこのエラーが出る場合、原因はSSH接続の問題がほとんどです。

# エラー例 $ docker ps error during connect: Get "http://docker.example.internal/v1.45/containers/json": dial unix /var/run/docker.sock: connect: no such file or directory # まずSSH接続単体で動作確認する $ ssh ec2-user@10.0.1.100 "docker ps" CONTAINER ID IMAGE ... # これが通れば接続自体は問題なし # contextのエンドポイント設定を確認する $ docker context inspect prod-web [ { "Name": "prod-web", "Endpoints": { "docker": { "Host": "ssh://ec2-user@10.0.1.100" } } } ]

よくある原因は以下の3つです。

・SSH鍵がSSH agentに登録されていない(ssh-add ~/.ssh/prod_key.pemで登録)
・リモートユーザーがdockerグループに未所属(sudo usermod -aG docker ユーザー名で追加後に再ログイン)
・SSH agentが起動していない(eval $(ssh-agent)が必要な環境もある)

SSH接続が遅い時の対策(ControlMaster設定)

SSH contextはDockerコマンドごとにSSH接続を確立するため、コマンドの応答に数秒かかることがあります。SSH ControlMasterを設定すると、一度確立した接続を再利用できるため大幅に高速になります。

# ~/.ssh/config にControlMasterを追記する Host prod-web HostName 10.0.1.100 User ec2-user IdentityFile ~/.ssh/prod_key.pem ControlMaster auto ControlPath ~/.ssh/cm_%r@%h:%p ControlPersist 60s # 最後のコマンドから60秒間接続を保持する

この設定後は、最初のコマンドのみSSHのネゴシエーションが発生し、以降のコマンドは既存のソケットを再利用します。docker psdocker logsを連続して実行する場面で体感できる差があります。

本記事のまとめ

docker contextで複数Dockerホストを管理するポイントをまとめます。

やりたいこと コマンド
コンテキスト一覧を確認する docker context ls
SSH contextを作成する docker context create 名前 --docker "host=ssh://user@host"
コンテキストを切り替える docker context use 名前
コンテキストの詳細を確認する docker context inspect 名前
スクリプトで一時的に切り替える DOCKER_CONTEXT=名前 docker ps
コンテキストを削除する docker context rm 名前
・SSH contextはTLS証明書不要で、SSH鍵認証さえあれば即座にリモートDockerを操作できる
~/.ssh/configのホスト名エイリアスと組み合わせることで、接続先の一元管理が実現できる
DOCKER_CONTEXT環境変数でデプロイスクリプトやCI/CDへの組み込みもシンプルに書ける

本記事で紹介したdocker contextの実践的な活用を含め、DockerとLinuxサーバー管理を体系的に学びたい方は、Dockerコンテナ実践ガイド(docker.linuxmaster.jp)をご覧ください。Docker入門から本番運用まで体系的に解説しています。

docker contextを「なぜ使うか」から理解するには、Linuxサーバー構築の「型」が土台になります

contextの切り替えコマンドは覚えられても、「今どのサーバーを操作しているかを常に意識するサーバー管理の型」が身についていなければ、本番誤操作のリスクは下がりません。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。