1. はじめに
「リモートサーバー上のDockerで、GUIアプリケーションをサクッと使いたい…」
リモートマシン上でDockerコンテナを扱う際、こんなことはありませんか?
- クラウド上の強力なGPUマシンで機械学習のツールを動かし、結果をGUIでインタラクティブに確認したい。
- データセンターにあるサーバーや、物理的にアクセスしにくいエッジデバイスのGUIを、手元のPCでさっと操作したい。
- ROSのrvizやシミュレータなど、開発中に頻繁に利用するGUIツールを、リモートから直接立ち上げたい。
その都度、VNCをセットアップしたり物理コンソールにアクセスしたりするのは面倒です。
「GUIウィンドウが一つ、手元のPCに表示されればいいだけなのに…」
そんな悩みを解決するのが、この記事で紹介するSSHの「X11フォワーディング」 です。この機能を使えば、リモートマシン上のDockerコンテナで起動したGUIアプリを、まるでローカルアプリのように手元のPCで操作できます。
設定は驚くほどシンプル。一度環境を整えれば、あなたのリモート開発はもっと快適になるはずです!
2. この記事で実現できること
できること
-
SSH接続したサーバー 上で起動したDockerコンテナ内のGUIアプリ(例:
gedit
,Firefox
,xeyes
など)が手元のPC(Mac, Windows, Linux) の画面にウィンドウとして表示され、直接操作できるようになります。
やらないこと
- Dockerに関する解説
- X11に関する詳細な解説
3. 仕組みの簡単な解説:X11フォワーディングとは?
この技術の鍵はX11フォワーディング です。
これは、GUIの表示情報(「ここにウィンドウを描画して」「このボタンをクリックしたよ」といった情報)を、暗号化されたSSHトンネルを通じて安全に手元のPCに転送する仕組みです。
これにより、サーバー側は計算処理に集中し、描画は手元のPCが担当するため、軽快な操作感が得られます。
認証には.Xauthority
ファイル(通称 "マジッククッキー")が使われ、許可されたユーザーだけがGUIを表示できる仕組みになっています。
4. 環境構築
Step1: サーバー側(SSH接続先)の設定
まず、リモートサーバー側でSSH接続経義由のGUI表示を許可します。多くの場合、デフォルトで有効になっていますが、念のため確認しましょう。
SSH設定ファイルの編集
サーバーにログインし、/etc/ssh/sshd_config
ファイルを管理者権限で編集します。
sudo nano /etc/ssh/sshd_config
設定の確認と変更
ファイル内で以下の項目がyes
になっていることを確認してください。もしno
になっていたり、行頭に#
がついてコメントアウトされていたりしたら、修正して#
を削除します。
X11Forwarding yes
SSHデーモンの再起動
設定を反映させるために、SSHデーモンを再起動します。
sudo systemctl restart sshd
これでサーバー側の準備は完了です。
Step2: クライアント側(手元のPC)の設定
次に、GUI情報を受け取って表示する手元のPCを設定します。
この記事ではUbuntuをメインターゲットとしていますが、Windows/Macでも同様のことが可能です。
Windows / Mac の場合 (クリックで展開)
WindowsやMacは、標準ではX Window System(GUIの仕組み)が動作していません。そのため、Xサーバーの役割を果たすアプリケーションをインストールする必要があります。
方法1: SSHコマンドで直接接続する
まずは、設定ファイルを使わずにコマンドで直接接続する方法です。-Y
オプションを付けてSSH接続します。
ssh -Y user@your-remote-server-ip
このコマンドで接続したターミナル上で、後述するdocker run
コマンドを実行するとGUIアプリが表示されます。
方法2: SSH接続設定を簡略化する (推奨)
毎回コマンドにオプションを付けるのは面倒なので、~/.ssh/config
ファイルに設定を記述して簡略化しましょう。
お好みのエディタでファイルを開きます。
nano ~/.ssh/config
以下の内容を追記します。
# my-serverという名前で接続する際の設定
Host my-server
HostName your-remote-server-ip # サーバーのIPアドレス or ホスト名
User user # ログインユーザー名
ForwardX11 yes
ForwardX11Trusted yes
ForwardX11Trusted yes
は、セキュリティ上の制限を緩和し、一部のアプリケーションで発生する問題を回避するために推奨されます。
設定後はこちらのコマンドだけで接続できます。
ssh my-server
5. 接続テスト
DockerコンテナからGUIアプリを起動
いよいよコンテナを起動します。
ここでは例として、目がマウスポインタを追いかける古典的なアプリxeyes
を動かしてみましょう。
起動コマンド
クライアント(手元のPC)のターミナルから、設定した名前 (my-server
) を使ってSSH接続し、続けてdocker run
コマンドを実行します。
# まずはSSH接続
ssh my-server
# HOST --> my-server
# 接続先のサーバー上でDockerコマンドを実行
docker run --rm -it \
--env="DISPLAY" \
--net=host \
--volume="$HOME/.Xauthority:/root/.Xauthority:rw" \
ubuntu \
bash -c "apt-get update && apt-get install -y x11-apps && xeyes"
Docker compose を利用する場合 (クリックで展開)
docker runコマンドのオプションは長くなりがちです。
docker-compose.ymlファイルに設定をまとめておくと、コマンドがシンプルになり管理が楽になります。
docker-compose.yml
services:
xeyes-app:
image: ubuntu
environment:
- DISPLAY=${DISPLAY}
network_mode: "host"
volumes:
- ~/.Xauthority:/root/.Xauthority:rw
command: >
bash -c "apt-get update && apt-get install -y x11-apps && xeyes"
このコマンドが成功すると、イメージのダウンロードとアプリのインストールが実行された後、ホストPCの画面にxeyes
のウィンドウが表示されるはずです。
コマンドの解説
-
--env="DISPLAY"
: コンテナに表示先の情報(DISPLAY環境変数)を引き継ぎます。 -
--net=host
: コンテナのネットワークをホスト(サーバー)と共有します。これにより、コンテナはSSHが確立したX11の通信経路を簡単に見つけることができます。 -
--volume="$HOME/.Xauthority:/root/.Xauthority:rw"
: X11の認証情報ファイル.Xauthority
をコンテナ内にマウントし、GUI表示の許可を与えます。
7. トラブルシューティング
うまく表示されない場合は、以下の点を確認してみてください。
-
Can't open display
やInvalid MIT-MAGIC-COOKIE-1 key
と表示される
.Xauthority
ファイルが原因かもしれません。SSHサーバーは、このファイルに認証情報を書き込もうとします。もし何らかの理由で~/.Xauthority
がディレクトリになっていると、書き込みに失敗してエラーになります。
rm -rf ~/.Xauthority
で一度削除してからSSH接続し直すと、ファイルとして再生成されて解決することがあります。 -
クライアント側(手元PC)のXサーバーは起動していますか?
(Windows/Macの場合) VcXsrvやXQuartzの起動忘れはよくある原因です。 -
ファイアウォールでブロックされていませんか?
サーバーやクライアントのファイアウォールが、X11で使われるポート(通常6000番台)の通信をブロックしていないか確認してください。
8. 今後の課題(よりセキュアな方法)
今回の方法では、利便性のためにコンテナのネットワークをホストと共有する--net=host
オプションを使用しました。
これは最も簡単な方法ですが、コンテナの分離というDockerの利点を少し損ないます。
これについては、また別の機会に掘り下げてみたいと思います。
9. まとめ
今回は、SSHのX11フォワーディング機能を使って、リモートDockerコンテナのGUIアプリを手元で操作する方法をご紹介しました。
この方法を使えば、サーバーリソースをフルに活用しながら、使い慣れたGUIツールで快適なリモート開発環境を構築できます。
ぜひ、あなたの開発ワークフローに取り入れてみてください!