VSCode Remote Development は Remote {Containers, WSL, SSH} の3つをパックした拡張機能です。

  • 開発PCからシームレスにリモートPC(実行環境)に繋いで開発ができます。
  • 実行環境が同じにできるため、新規開発者が簡単に参加できます。
  • 開発PCと実行環境を分離できるので、SDKのバージョン管理が楽になります。

全体像

便利そうと思ったら、インストールしてみましょう。

Remote Contaners

Dockerコンテナを実行環境にできるようになります。 プロジェクトディレクトリに置いた devcontainer.json ファイルでツールやランタイムを制御できます。 プロジェクトのファイルはマウントしてもいいしコンテナにコピーしてもいいし、コンテナ内のを利用できます。 VScodeの拡張機能はコンテナ内にインストールされます。 それにより、実行環境の機能(ツールやファイルシステム)が使用できたり、別コンテナに繋ぐだけで環境の切り替えがシームレスに行えて便利です。 もちろんVSCodeの補完やデバッグなどもローカル開発時と同じレベルで使えます。

注意事項 開発PCと実行環境でファイルの改行コードが違う場合は注意が必要です。 Gitの機能を使って改行コードを統一しておきましょう。

クイックスタート:既存のコンテナ編

既存のコンテナをフルタイムの開発環境と使用する方法は、

  1. コマンドパレットから Remote-Containers: Open Folder inContainer... を実行するか、 左下にある緑色のクイックアクションステータスバーアイテムをクリックします。

    quick actions Status bar item

  2. 次に、ベースとなる開発コンテナをリストから選ぶか、選択したディレクトリにあるDockerfileやDocker Composeファイルを使用します。 リストに表示されるコンテナは vscode-dev-containersリポジトリ のものです。

    注意事項* Alpine Linuxコンテナを使用する場合、 glibc に依存している一部の拡張機能が使用できません。

  3. 選択すると、VSCodeが設定ファイルをコンテナ内に作成します。(.devcontainer/devcontainer.json)

  4. そして、VSCodeはリロードされ開発コンテナをビルドし始めます。 初回はコンテナのビルドに時間がかかります。2回目以降はキャッシュがあるので早いでしょう。

  5. ビルドが終わると、VSCodeは開発コンテナに接続した状態になります。

    Note 公式ドキュメントにはマルチルートワークスペースやマルチコンテナ環境について記載があります。 VSCode使いこなしてないので、マルチルートワークスペースを知らないので必要になったら思い出します。 マルチコンテナは1つのVSCodeウィンドウで扱えないけど、Docker Composeのコンテナに1度で複数VSCodeを立ち上げて繋げることはできるみたいです。

クイックスタート:Gitリポジトリ編

GitHub PRレビューや別ブランチの作業で分離されたリポジトリが欲しくなることがあるでしょう。 そんな時にコンテナ内でクローンすると便利です。

  1. コマンドパレットから Remote-Containers: Clone Repository in Container Volume... を実行します。

  2. 入力ボックスにGit URI、GitHub branch URL、GitHub PR URLを入力します。 (例えば、 microsoft/vscode-remote-try-node

    input url

  3. 入力したリポジトリに .devcontainer/devcontainer.json がない場合は、既存のコンテナ編のようにベースコンテナを聞かれます。

  4. そして、VSCodeはリロードされ開発コンテナをビルドし始めます。 初回はコンテナのビルドに時間がかかります。2回目以降はキャッシュがあるので早いでしょう。

  5. ビルドが終わると、VSCodeはソースを取得した開発コンテナに接続した状態になります。

    git status

devcontainer.jsonファイル

VSCodeのコンテナ設定はdevcontainer.jsonファイルに記載します。(デバッグ設定で使うlaunch.jsonみたいなもんらしい) 指定した拡張機能をコンテナ起動時にインストールしたり、post-createコマンドで準備したりできる。 devcontainer.jsonはローカルのプロジェクトルートに .devcontainer.json を置くか、 .devcontainer/devcontainer.json と1階層ディレクトリを掘って配置します。

記載内容の例(nodeコンテナ起動して、eslint拡張機能をインストール)

{
    "image": "mcr.microsoft.com/vscode/devcontainers/typescript-node:0-12",
    "forwardPorts": [ 3000 ],
    "extensions": [
        "dbaeumer.vscode-eslint"
    ]
}

Inspecting volumes

使用しているボリュームをvscodeを使わずに調査をしたい時があると思います。 Remote-Containers:Inspect Volume in Container... コマンドで確認ができます。 もし、 Docker extension をインストールしてるなら、Volumes欄での右クリックから確認できます。

拡張機能の管理

VSCodeの拡張機能は次の2つのうちどちらかで実行されます。

  • クライアントである開発PCのUI側
    • テーマやスニペットみたいなの
  • リモートである実行環境のコンテナ側
    • そうじゃないほとんどのもの

これにより開発PC側の拡張機能は汚染されずに、コンテナ接続時にシームレスに拡張機能を切り替えられます。

拡張機能インストール時にローカル側かコンテナ側かに振り分けれらます。

local extension

container extension

振り分けがうまくできない場合は指定も可能です。(拡張機能開発者が未対応の場合ローカル側にならなかったり) VSCodeの設定に

"remote.extensionKind": {
    "ms-azuretools.vscode-docker": [ "ui" ],
    "msjsdiag.debugger-for-chrome": [ "workspace" ]
}

のように指定します。 ui がローカル側で、 workspace がコンテナ側を強制します。 (無理矢理の対応のため正しく動かないこともあります。)

拡張機能の指定はdevcontainer.jsonに直接書くこともできますが、拡張機能リスト右クリックの Add to devcontainer.json から追加も可能です。

add extension

もし、どのコンテナでも常にインストールしたい拡張機能がある場合はVSCodeの設定の remote.containers.defaultExtensions で指定できます。 GitLensResource Monitorを指定する例。

"remote.containers.defaultExtensions": [
    "eamodio.gitlens",
    "mutantdino.resourcemonitor"
]

ポート開放

コンテナのポートをホストのポートに紐づけるには、2つの方法があります。

コンテナ起動時から常に転送したい場合は devcontainer.jsonforwardPorts を記載します。 3000番ポートと3001番ポートを転送する例。

"forwardPorts": [3000, 3001]

この設定後VSCodeウィンドウのリロードや再起動すると適用されます。

もう1つの方法は一時的に転送したい場合に使用します。 Forward a Port コマンドで指定できます。 Remote ExplorerのForwarded Ports欄で後から確認できます。 VSCode設定で remote.restoreForwardedPorts=trueにすると、設定を記憶することも可能です。

devcontainer.jsonに appPortを書くとポート公開もできます。(転送forwardと公開publish何が違うんだろう?)

"appPort": [ 3000, "8921:5000" ]

また、ポートマッピングはdevcontainer.jsonだけでなく docker-compose.yml での指定も有効です。

ports:
- "3000"
- "8921:5000"

ポート公開の適用はコンテナのリビルドが必要です。 Remote-Containers: Rebuild Containerコマンドで実行できます。

コンテナ内作業

コンテナ内のディレクトリを開くとVSCodeから開いたターミナルウィンドウ(Terminal > New Terminal)はローカルではなくコンテナ内で実行されます。 そのターミナル内では code CLIでファイルやディレクトリを開くことができます。

terminal

デバッグは launch.json で起動すると、アプリケーションはコンテナ内で実行され、デバッガがアタッチされます。 詳しくはdebuggingドキュメントを参照。

コンテナ設定

VSCodeのローカル設定は開発コンテナに接続しているときも利用されます。しかしローカルとコンテナで一部の設定を変更したい時があります。 Preferences.Open Remote Settings コマンドか、設定エディタのリモートタブでコンテナ固有の設定を行うことができます。

devcontainer.json にデフォルトのコンテナ設定を記載することもできます。例えばJavaホームの設定。

"settings": {
    "java.home": "/docker-java-home"
}

Git認証情報の共有

コンテナ起動時にローカルの .gitconfig ファイルをコピーしてくれます。

credential helper利用

リポジトリにHTTPS接続する場合、ローカルでcredential helper 設定が終わっていると自動的にコンテナ内でも利用できます。

SSH Key利用

ローカルでSSH agentが起動していると、コンテナ内へ自動的に転送されます。

GPG Keys共有

自分のコミットにGPG署名をしたい場合は、ローカルの鍵をコンテナと共有することができます。 GPG署名に関してはGitHubドキュメントを参照。

ローカルでGPGを設定するにはWindwosだと Gpg4win、macOSだと GPG Tools、Linuxだと gnupg2を利用します。 そして、コンテナに(Linuxだから)gnupg2をインストールします。例えば

RUN apt-get update && apt-get install gnupg2 -y

このように。 すると、次回コンテナ起動時にGPG keysが共有されています。

コンテナの管理

VSCodeでディレクトリを開いた時にdevcontainer.jsonに記載のコンテナを自動で起動しますが、通常はVSCode終了時にコンテナを自動でシャットダウンします。 終了時のシャットダウンしないようにするには devcontainer.jsonshutdownAction: noneを設定します。

未使用コンテナを整理する場合は Cleaning out unused containers and imagesを参照。

ドットファイルリポジトリ

実行環境コンテナにはいろんなアプリケーションがあるため、ドットファイルをどこかに保存しておくとコンテナにコピーできて便利です。 一般的な方法はドットファイルをGitHubリポジトリに保存し、ユーティリティーを使用してそれを適用することです。 この方法を使用するにはVSCode設定の Dotfiles: * に設定します。

dotfiles

settings.json に直接書く場合

{
    "dotfiles.repository": "your-github-id/your-dotfiles-repo",
    "dotfiles.targetPath": "~/dotfiles",
    "dotfiles.installCommand": "~/dotfiles/install.sh"
}

この設定以降のコンテナ作成時にドットファイルリポジトリが利用されます。

高度なコンテナ設定

See the Advanced Container Configuration article for information on the following topics:

制限事項(2021-05-30現在)

  • Windowsコンテナイメージはまだ未サポート
  • リモートDockerホストは使えるけど、追加設定が必要
  • マルチルートのワークスペースにあるすべてのルート/フォルダーは、下位レベルに設定ファイルがあるかどうかにかかわらず、同じコンテナで開かれます。
  • Linux用の非公式なUbuntu Docker snapパッケージはサポートされていません。お使いのディストリビューションの公式Dockerインストール手順に従ってください。
  • DWindowsのDocker Toolboxは未サポート。
  • ISSHを使用してGitリポジトリをクローンし、SSHキーにパスフレーズが設定されている場合、VS Codeのプルおよび同期機能をリモートで実行するとハングアップすることがあります。この問題を回避するには、パスフレーズのない SSH キーを使用するか、HTTPS を使用してクローンを作成するか、コマンドラインから git push を実行してください。
  • Lローカルのプロキシ設定がコンテナ内で再利用されないため、適切なプロキシ情報が設定されていないと、拡張機能が動作しないことがあります(例えば、グローバルな HTTP_PROXY や HTTPS_PROXY 環境変数に適切なプロキシ情報を設定するなど)。