code-serverをUbuntuにインストール:NginxとHTTPSでブラウザからVS Codeをリモート利用する

Ubuntu tutorial - IT technology blog
Ubuntu tutorial - IT technology blog

code-serverが必要な場面は?

筆者がcode-serverを使い始めたきっかけは、カフェでiPadを使ってステージングサーバーをデバッグしなければならなかった時のことです——VS Codeを直接インストールできない環境で、コードベースはVPS上にありました。いくつかのリモートIDEソリューションを試した末に辿り着いたのがcode-serverです。理由はシンプルで、それはまさにVS Code本体であり、ブラウザ上でそのまま動作し、拡張機能もターミナルも完備、クライアント側への追加インストールは一切不要です。

code-serverが向いている場面:

  • 複数のデバイス(ノートPC、iPad、会社のPC)からプログラミングしたい
  • ローカルマシンより高性能なVPSリソースをビルド・コンパイルに活用したい
  • 本番環境にできるだけ近い開発環境が必要——同じOS、同じ依存関係
  • 同僚がファイルをやり取りせずにサーバー上で直接コードレビューできる

code-serverのインストール

システム要件

Ubuntu 20.04または22.04(LTS)が対象です。最小RAMは1GBですが、実際のところTypeScript language server単体で300〜500MBを消費するため、複数の拡張機能を同時に使うなら2GBあると快適に動作します。ディスクは最低2GBの空き容量が必要で、拡張機能やワークスペースを追加することを考えると5GB程度あれば安心です。帯域幅はそれほど要求されず、1 Mbpsあれば通常利用には十分です。

インストールスクリプトを使った高速インストール

curl -fsSL https://code-server.dev/install.sh | sh

スクリプトがディストリビューションを自動検出し、適切なパッケージリポジトリを追加してバイナリをインストールします。Ubuntuではapt、Fedoraではdnfと自動的に切り替わるため、手動操作は一切不要です。インストール後はバージョンを確認しましょう:

code-server --version

.debパッケージを使った手動インストール(バージョン管理が必要な場合)

VERSION="4.95.3"
wget https://github.com/coder/code-server/releases/download/v${VERSION}/code-server_${VERSION}_amd64.deb
sudo dpkg -i code-server_${VERSION}_amd64.deb

詳細設定

デフォルト設定ファイル

設定ファイルを生成するために一度実行します:

code-server --config ~/.config/code-server/config.yaml

デフォルトの内容はこのようになります:

bind-addr: 127.0.0.1:8080
auth: password
password: your-password-here
cert: false

重要bind-addr: 127.0.0.1のままにしておきましょう——ローカル接続のみを許可します。Nginxが外部へのHTTPS公開を担当します。SSL設定が完了する前に0.0.0.0に直接バインドしないでください。

より強力なランダムパスワードを生成する:

PASSWORD=$(openssl rand -base64 16)
echo "あなたのパスワード: $PASSWORD"
sed -i "s/password: .*/password: $PASSWORD/" ~/.config/code-server/config.yaml

code-serverをsystemdサービスとして起動する

sudo systemctl enable --now code-server@$USER
sudo systemctl status code-server@$USER

Nginxリバースプロキシの設定

ここは多くの方がつまずきやすいポイントです。code-serverはエディターのリアルタイム同期にWebSocketを使用しているため、NginxUpgradeヘッダーの設定が必要です。この設定が欠けていると、エディターは表示されてもターミナルやライブ同期が機能しません。

Nginx設定ファイルを作成します:

sudo nano /etc/nginx/sites-available/code-server
server {
    listen 80;
    server_name code.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name code.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/code.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/code.yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:8080/;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection upgrade;
        proxy_set_header Accept-Encoding gzip;
        proxy_http_version 1.1;
    }
}

サイトを有効化し、設定をテストしてリロードします:

sudo ln -s /etc/nginx/sites-available/code-server /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

セキュリティの強化

code-serverにはデフォルトのパスワード認証がありますが、このエディターにはサーバー上への直接ターミナルアクセス機能があります——一度侵害されればサーバー全体が危険にさらされます。念のため、いくつかの防御層を追加するのが筆者の習慣です:

IPアクセス制限(固定IPから利用する場合):

location / {
    allow 203.0.113.10;   # あなたのIPアドレス
    deny all;
    proxy_pass http://localhost:8080/;
    proxy_set_header Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection upgrade;
    proxy_http_version 1.1;
}

HTTP Basic Authの追加(多層防御——二重の認証):

sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd your_username

NginxのlocationブロックにBasic Auth設定を追加します:

auth_basic "Code Server";
auth_basic_user_file /etc/nginx/.htpasswd;

筆者のステージング環境での最終構成:IPホワイトリスト+Basic認証+code-serverのパスワード認証。三重の防護はやりすぎに見えるかもしれませんが、サーバーのrootターミナルアクセスがある以上、リスクを冒したくないのが本音です。

動作確認とモニタリング

接続とWebSocketのテスト

https://code.yourdomain.comにアクセスしてパスワードを入力すると、ブラウザ上でVS Codeが起動します。エディターは表示されるのにターミナルが応答しない場合、WebSocketがブロックされている可能性が高いです。Nginxのログを確認しましょう:

# HTTP 101 = WebSocketハンドシェイク成功
sudo tail -f /var/log/nginx/access.log | grep " 101 "

code-serverのログ確認

# サービスログをリアルタイムで追跡
sudo journalctl -u code-server@$USER -f

# デバッグ時の詳細ログ
code-server --log-level debug

リソースの監視

TypeScript、ESLint、Pylanceはかなりのメモリを消費します——TypeScript language server単体で大規模なプロジェクト作業時に300〜500MBを占有することもあります。以下のコマンドで確認できます:

ps aux | grep code-server | awk '{print $2, $4, $6, $11}'

RAMが1GBしかないサーバーの場合は、Node.jsプロセスのメモリを制限しましょう:

sudo systemctl edit code-server@$USER

以下を貼り付けます:

[Service]
Environment="NODE_OPTIONS=--max-old-space-size=512"
Restart=on-failure
RestartSec=5s

変更を適用します:

sudo systemctl daemon-reload
sudo systemctl restart code-server@$USER

日常的な活用のヒント

  • GitHubによる設定同期:VS CodeのSettings Syncを有効にしてGitHubでログインするだけで、ローカルマシンとcode-server間で拡張機能と設定が自動同期されます。ゼロから再インストールする手間が省けます
  • 組み込みのポートフォワーディング:サーバー上でWebアプリを開発してブラウザで直接確認したい時は、エディター下部のPortsタブを使いましょう——手動でSSHトンネルを設定せずにポートをローカルマシンへフォワードできます
  • 専用サブドメインの使用:code-serverはdomain.com/codeのようなパスではなく、code.domain.comのような専用サブドメインに配置しましょう——Service Workerを使う拡張機能で発生する問題を回避できます
  • 定期バックアップ~/.local/share/code-server/ディレクトリにインストール済みの拡張機能とワークスペースの状態が格納されています——このディレクトリをバックアップするだけで、必要な時にすぐ復元できます

Share: