かみのメモ

コンピュータビジョン・プログラムな話題中心の勉強メモ

VNCでDockerコンテナ内のGUIデスクトップにアクセスしてみた

今回は、DockerコンテナにGUIデスクトップを立ち上げて、TigerVNCnoVNCを使ってリモートログインする方法をまとめてみます。この方法を使うと、ブラウザから簡単にリモートデスクトップ接続できるようになります。

f:id:kamino-dev:20210207230336p:plain:w500
ブラウザでコンテナ内部のデスクトップにアクセスできる

以前の記事X11 Forwardingを使ったGUI環境の作り方を紹介したのですが、複数のウィンドウが立ち上がるアプリを使うときに若干不便なのと遅延が大きいことに不満があって、他の方法を探していました。

その結果、VNCによるリモートデスクトップ環境がよさそうだったので試してみました。

なお、すでに先人が作った素晴らしいイメージがDocker Hubに公開されているので、それらを使えばこの記事で紹介する作業は不要です。探した限り、以下のリポジトリが使い勝手がよさそうです。

ただ、持病の"理解できていないものは使いたくない病"が発症してしまったので、今回は1から簡単なリモートデスクトップ環境を構築してみます。

もくじ

スポンサーリンク

0. 検証環境

ホストは以下の2つを試しました。

  1. Ubuntu 18.04.5 LTS, Docker CE 20.10.2
  2. Windows 10 Pro Insider Preview Build 21292(普通のWindows 10でも動くはず), Docker Desktop for Windows CE 20.10.2

Dockerコンテナのベースイメージはubuntu:20.04です。

1. はじめに

1.1. VNCとは?

f:id:kamino-dev:20210207222536p:plain:w150
VNCのロゴ(From: Virtual Network Computing - Wikipedia

VNCはVirtual Network Computingというリモートデスクトップのソフトウェアです。

VNCは、もともと1999年にイギリスのケンブリッジOlivetti & Oracle Research Lab (ORL)で開発されたもので、オリジナル版はGPLライセンスのもとで公開されています。

ORLはAT&Tケンブリッジ研究所に吸収されましたが、2002年にAT&Tケンブリッジ研究所も解散となりました。その後、開発メンバーはRealVNCという企業を立ち上げ、現在もVNCを利用した事業を展開しているようです。

VNCをもとにした派生ソフトや派生サービスは数多く存在しており、自作OS界隈で有名なQEMUや、リモートデスクトップで有名なTeamViewerにもVNCの技術が組み込まれているそうです。

今回の記事で利用するTigerVNCもそのうちの1つです。

f:id:kamino-dev:20210207223044p:plain:w150
TigerVNCのロゴ(From: TigerVNC - Wikipedia

公式サイト: https://tigervnc.org/

TigerVNCはTightVNCから派生したプロジェクトで、暗号化通信やLinux以外のOSのサポートが追加された一方、画面のリサイズやファイル転送の機能が削られているようです。現在ではFedoraのデフォルトVNCにも採用されています。

1.2. VNC vs X11 Forwarding vs RDP

以前の記事で紹介したX Window SystemのForwardingとの違いですが、X11 Forwardingは主に1つのアプリケーションだけをリモート表示するための仕組みです。こちらはインストールするパッケージが少なくて済み、セットアップが手軽であるという利点があります。基本的にCUIで運用するけど一時的にGUIを確認したい、というケースに適しています。

一方、VNCデスクトップ環境自体をリモート表示します。サーバー側にGNOME, Xfce, KDEなどのGUIデスクトップをインストール・起動しておく必要があり、容量と計算リソースを食いますが、ほぼいつもどおりのデスクトップ環境が実現できます。

また、Microsoftによって開発されたRDP(Remote Desktop Protocol)もVNCと類似の機能を提供するソフトウェアです。こちらは試したことがないので何とも言えません。以下で説明するnoVNCの利点があるので、今回はVNCを使うことにしました。両者の違いはこちらのブログなんかが参考になります。

1.3. noVNCとは?

f:id:kamino-dev:20210207224257p:plain:w120
noVNCのアイコン(From: GitHub - novnc/noVNC: VNC client web application

公式サイト: https://novnc.com/info.html

VNCでは、接続先となるマシン(今回はDockerコンテナ)にVNCサーバーを立て、ローカルマシンにインストールされたVNCクライアントがそこにアクセスすることで、リモートデスクトップを実現します。 しかし、VNCクライアントをインストールするのは面倒ですし、OSごとに使い勝手が変わるのも避けたいです。

そこで、今回はnoVNCを利用します。noVNCはオープンソースで開発されている、ブラウザ上で動作するHTML5製のVNCクライアントです。このnoVNCをサーバー側にインストールして、HTTPサーバーで公開しておけば、クライアント側はブラウザでアクセスするだけでリモートデスクトップ環境を使えるようになります。

2. VNC入りコンテナの作り方

2.1. コンテナの作成

今回はローカルもしくはLAN内からのアクセスだけを想定して、セキュリティ面を気にしない簡素な設定をしていきます。

docker run -d -t --name vnc_test -p 6080:80 --shm-size=512m ubuntu:20.04

noVNCをポート6080に公開することとして、コンテナのポート80を6080にフォワーディングしています。また、必須ではありませんが、sharedメモリのデフォルトサイズ64MBではGUIを使うのに心許ないので、512MBに拡張しています。

なお、noVNCと別に通常のクライアント向けにVNCを公開する場合はそのためのポート設定、SSLを使う場合は追加でSSLポート設定や関連ファイルのマウントが必要になります。

2.2. デスクトップ環境のインストール

いつもどおりコンテナにログインします。

docker exec -it vnc_test bash

まずは、デスクトップ環境をインストールしていきます。

今回は、Linux GUIの中でも軽量であるLXDEを入れることにします。代わりにGNOMEKDEをインストールしてもokです。

DEBIAN_FRONTEND=noninteractive apt install -y lxde

GUIパッケージを入れるときは、インストール中にタイムゾーンや使用するキーボード配列の指定を求められます。その入力が面倒なので、ここではDEBIAN_FRONTEND=noninteractiveを指定して、デフォルト値で設定されるように促しています。

もし手元のキーボードが日本語配列なら、変数を指定せずにインストールを実行して、キーボード配列を指定するべきかもしれません。ただ、結局はnoVNCを使ってブラウザ越しにキーボードイベントが届けられるので、ここでの設定に特に意味はないかもしれません。このあたりの挙動は未検証です。

2.3. TigerVNCのインストール

次に、VNCとしてTigerVNCをインストールします。

apt install -y tigervnc-standalone-server tigervnc-common

2.4. noVNCのインストール

最後に、noVNCとそれを公開するためのwebsockifyをインストールします。

apt install -y novnc websockify

2.5. TigerVNCとnoVNCの起動

インストールが終わったら、VNCとnoVNCを起動します。LXDEは、一緒にインストールされたディスプレイマネージャgdm3が勝手に起動してくれているはずなので何もしなくてもokです。

まずは、VNCの起動です。

USER=root vncserver :1 -geometry 800x600 -depth 24

ログインユーザーをrootとして、ディスプレイ:1に解像度800x600、24bit colorのVNCデスクトップを立ち上げています。パスワード入力が求められると思うので、6-8文字の簡単なパスワードを設定します。

ちなみに、起動中のデスクトップはvncserver -listによって確認でき、削除するときはvncserver -kill :1を実行すればよいです。ログは/root/.vnc/*.logに出力されているので、tail -F /root/.vnc/*.logで監視できます。

次にnoVNCをポート80に公開します。

websockify -D --web=/usr/share/novnc/ 80 localhost:5901

VNCでは"5900+ディスプレイ番号"のポートにサーバーが立つので、ここではlocalhost:5901を指定しています。

以上の設定のあと、Dockerホストでブラウザを立ち上げてlocalhost:6080/vnc.htmlにアクセスすると、noVNCの画面が立ち上がってDockerコンテナ内のGUIデスクトップが表示されます。画面左のメニューで各種設定や、クリップボードの確認・編集も可能です。

f:id:kamino-dev:20210207221610p:plain:w500
noVNCでコンテナ内のデスクトップにアクセスした様子

キーマップやオーディオの細かい挙動は確認できていませんが、とりあえずキー入力とマウス操作は普通に動きました。 ブラウザさえ動けばリモートデスクトップができる、というのは面白いですね。


以上、DockerでVNCを使ってみたという備忘録でした。