code-serverでブラウザからVSCode Anywhere!

code-serverでブラウザからVSCode Anywhere!
Page content

VSCodeをChromebookから使える?

Visual Studio Code (VSCode) を、私はOS XとLinuxにて愛用している。統合開発環境としてはあまり使い込んでないが。snapが使える環境では、VSCodeをMicrosoft公式版snapで導入する選択肢も最近増えたようだ。

先月、このVSCodeをウェブブラウザ経由で利用できるサーバ版「code-server」がOSSで登場、というニュースを見つけ、

なぬーっ!?と驚いた私は、ChromebookからもVSCode使いたい衝動を抑えきれず、code-serverを既存のVPSにセットアップしてみたのでここに導入手順をメモします。

code-serverの使用感は実際のところ快適だ。このブログ記事をcode-server上で打っているくらい。主な感想として:

  1. 「headlessのLinuxデスクトップで通常のVSCodeを動かし、その画面へChrome Remote Desktop経由でChromebookからアクセス」という構成を作ったこともある。それと比較すると、code-serverを用いるサーバ・クライアント構成のほうがはるかに反応が良い
  2. code-serverの編集対象には、サーバ側での手慣れた手段 (mount) でローカル以外のストレージも容易に設定できるので、自分用のファイル編集の踏み台として、code-serverひとつ立てておくと便利

code-server導入手順

今回の導入環境は次の通り。

項目内容
VPS環境1vCPU, メモリ: 1GB, OS: Ubuntu 18.04 LTS
導入ドメインの例code.example.com

0. Coderとcode-serverの関係

まずはサービスとソフトウェアの関係性を確認。オンラインでVSCodeを提供するサービス (SaaS) として「Coder」が存在しており、

そのOSS版が「code-server」という位置づけになっている。Coderのサイトの「HOST YOURSELF」ボタンは、次のGitHubページにリンクしている。

1. code-serverをお試し

code-serverにはDocker版も用意されているが、今回はサーバリソースが少ない関係でバイナリ版を利用する。Releasesにアクセスして最新の「code-serverN.NNN-vscN.NN.N-linux-x64.tar.gz」をダウンロードし、次のようにして~/bin/code-serverで実行できるようにする (意図としては、code-serverを別バージョンに差し替えても実行パスを同じにするため)。

cd ~/bin
wget https://github.com/cdr/code-server/releases/download/……-linux-x64.tar.gz
tar xvzf code-serverN.NNN-vscN.NN.N-linux-x64.tar.gz
ln -s ./code-serverN.NNN-vscN.NN.N-linux-x64/code-server .

次に、Getting StartedのBinariesにある手順にしたがえば、code-serverを起動させ、https://localhost:8443 での動作確認ができる。

参考: code-serverの起動オプション一覧

$ ~/bin/code-server --help
Usage: code-server [options]

Run VS Code on a remote server.

Options:
  -V, --version                output the version number
  --cert <value>
  --cert-key <value>
  -e, --extensions-dir <dir>   Set the root path for extensions.
  -d --user-data-dir <dir>     	Specifies the directory that user data is kept in, useful when running as root.
  --data-dir <value>           DEPRECATED: Use '--user-data-dir' instead. Customize where user-data is stored.
  -h, --host <value>           Customize the hostname. (default: "0.0.0.0")
  -o, --open                   Open in the browser on startup.
  -p, --port <number>          Port to bind on. (default: 8443)
  -N, --no-auth                Start without requiring authentication.
  -H, --allow-http             Allow http connections.
  -P, --password <value>       Specify a password for authentication.
  --disable-telemetry          Disables ALL telemetry.
  --install-extension <value>  Install an extension by its ID.
  --bootstrap-fork <name>      Used for development. Never set.
  --extra-args <args>          Used for development. Never set.
  -h, --help                   output usage information

2. Nginxでリバプロ

code-serverへは、ブラウザから暗号化通信でアクセスしたいし、SSL証明書はオレオレではなく認証済みのものにしたい。そのため、(サーバに導入済の) Nginxのリバースプロキシ機能を有効化し、code-server自体はhttpで、Nginxとブラウザの間をhttpsで通信させることにする。

Nginx Reverse Proxyにある設定ファイルの内容を基本に、次の4要素を加えた、code.example.com用のNginx設定ファイルは以下のようになる。

  1. httpアクセスはhttpsへリダイレクトする
  2. https://code.example.com へのアクセスをBASIC認証で制限する
  3. SSL証明書は、Let’s Encrypt発行のワイルドカード版 (*.example.com) を使う
  4. /favicon.ico (ファビコン) へのアクセスはcode-serverではなくファイルへ向かわせる (サーバの/var/www/code.example.com/favicon.icoには、お好みのアイコンファイルを設置しておく)
server {
	listen 80;
	server_name code.example.com;
	return 301 https://$host$request_uri;
}
server {
	listen 443 ssl http2;
	server_name code.example.com;
	ssl on;
	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
	location = /favicon.ico {
		root /var/www/code.example.com;
	}
	location / {
		proxy_pass http://localhost:8443;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection upgrade;
		proxy_set_header Accept-Encoding gzip;
		auth_basic "Restricted";
		auth_basic_user_file /etc/nginx/htpasswd_example.com;
	}
}

3. code-serverを本格起動

Nginxのリバースプロキシを有効化した状態で、code-serverを次のように起動する。

$ ~/bin/code-server --allow-http --no-auth /home/USER/project

次に https://code.example.com/ へブラウザでアクセスし、BASIC認証を経て、まさにVSCodeそのものの画面が描画されれば導入完了。ブラウザを全画面表示にすると没入感が高まる。

もし異常があれば、Nginxのログなどを見ながらトラブルシューティングをどうぞ……。

使いこなしの小技

他のファイルシステムを編集

サーバに他のファイルシステムをmountしておき、そのmountポイントを含むディレクトリを、code-serverの初期ディレクトリに指定することで、code-serverを通じてmount元のファイルを編集することができる。

私が実践しているのは、次のような、rcloneを用いたDropboxのmount。Dropboxの場合は、本家のコマンドライン版Dropboxデーモンを動かしてもよいだろう。mountについては他の方法 (例: autossh+sshfs) でも問題なく可能だろうし、VSCode Anywhere構想が広がります。

$ rclone --daemon --vfs-cache-mode=writes mount dropbox:/SOMEDIR/ /home/USER/mnt/Dropbox/
$ ~/bin/code-server --allow-http --no-auth /home/USER/mnt/Dropbox &

拡張機能はどうなるの?

code-serverで、VSCodeの特徴である拡張機能 (Extensions) をどう扱うかについては、たとえば次の記事が詳しいようだ。

私の場合は、普段のVSCodeの環境を見ながらcode-serverへ拡張機能を一度手動でインストールすることで同期させ、一応は落ち着いている。

追記 (2019-04-25): 拡張機能の同期にsshcodeを応用できる

上記のように構築した、恒久的にcode-serverを動かしておきたいサーバに対し、一度、普段のVisual Studio Code (VSCode) を利用している手元のMacやLinuxの環境から、次のsshcodeを実行する。すると、sshcodeの賢い機能により、手元のVSCodeの拡張機能がサーバ側に同期されるようだ。正直、変態過ぎます! (褒)