😎

devcontainerを始めてみる(Remote-SSHを絡めて使うまでの手順)

2024/04/28に公開

やりたいこと

シンプルに上記。

PCにもVMにもいろいろ入れたくないので、基本的にはコンテナに押し込んで作業したい。
PCにWSLいれれば、VMもいらないんだけど、PCにも極力余計なものは入れたくない

なので、VMにいろいろ押し込める。

いろんなサイトを見たけど、シンプルに手順だけ書いたものがなかったので。

事前にやっておくこと

  • VS CodeをPCにインストール
  • VMを作ってPCからsshできるようにしておく
  • VMにDockerをインストールしておく
    • インストールするバージョンとかはここ参照

細かい手順は省略。まぁ、検索すればいっぱい出てくるので。
なお、VS CodeはインストーラーでもzipでもなんでもOK

VMのディストリビューションはお好みで。Dockerがインストールできさえすればよいです。

環境構築

  • VS CodeにDev Containers Extensionをインストール
  • VS CodeにRemote - SSH Extensionをインストール
  • VS CodeのRemote ExplorerにVMを追加しておく

ここも、正直VS Codeの画面からポチポチなので、省略。

いざ手順

今回は以下のような超シンプルな構成のファイルをdevcontainer上で開くまでのお話

VMにソースコードを置いておく。今回は以下のようなサンプル

/tmp/app/
`-- src/
    `-- main.py*

ソースコードをVMに配置する

git cloneでも直接作成しても手段はなんでもいいので、VM上にソースコードを配置する

VS CodeからVMにアクセスする

VS CodeのRemote Explorerから対象のVMにアクセスする

devcontainerで開く

VS Codeでコマンドパレットを表示させて

Dev Containers: Open Folder in Container

を選択

すると、開きたいディレクトリの選択となるのでディレクトリを選択。(今回は/tmp/app)

次に、コンテナイメージのテンプレートを選択するダイアログが出力されるので、選択する(今回はPythonなので、Python3を選択)

次にコンテナイメージのバージョン(タグ)を選択するダイアログが表示されるので、自分が使いたいバージョンを見つけて選択する。

次に、追加でインストールアプリケーションの選択ダイアログが表示されるので適宜選択。追加で何も入れない場合はEnter

SSHログインのダイアログが表示されるので、パスワードを入力してEnter(ssh_configを設定していれば、出力されない場合もある)

このディレクトリを信頼するか確認が表示されるので、Trust Folder & Continueボタンをクリック

すると、コンテナイメージのダウンロードが始まって、buildされ問題ないと、以下のように開ける

あとはここで修正するなりなんなり

注意

shutdownActionにstopContainerを設定しても、コンテナは停止しなかった。
Remote SSHだから?

止める場合、消す場合は、直接か、VS CodeのDev containerの一覧から実施する

補足

コンテナ

devcontainerを使うと以下のようなコンテナが立ち上がります。

CONTAINER ID   IMAGE                                                                          COMMAND                   CREATED         STATUS         PORTS     NAMES
e14922adcbf1   vsc-app-d75b6c3b0007e70845b739c2c7afe797a80311811e7a74948ef4b989486b07af-uid   "/bin/sh -c 'echo Co…"   5 minutes ago   Up 5 minutes             interesting_herschel

このコンテナに指定したディレクトリをbind mountしてる。
以下、docker inspectの抜粋

:略
            "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/tmp/app",
                    "Target": "/workspaces/app"
                },
                {
                    "Type": "volume",
                    "Source": "vscode",
                    "Target": "/vscode"
                }
            ],
:略

vscodeボリュームも作られる。中身は、VS Code serverのバイナリ

コンテナイメージ

REPOSITORY                                                                          TAG       IMAGE ID       CREATED         SIZE
vsc-app-d75b6c3b0007e70845b739c2c7afe797a80311811e7a74948ef4b989486b07af-uid        latest    62867a37caaa   47 hours ago    1.43GB
vsc-app2-79936c7304004dced6c784ae3f3dc29145215ff98340f2f21633efdbe48bd07f-uid       latest    62867a37caaa   47 hours ago    1.43GB

上記のようなコンテナイメージが作成される。ディレクトリを開くたびにイメージが出きるっぽい。vsc-の次が開いてるディレクトリ名になるっぽい

このイメージのビルドに結構時間がかかる。。。
2回目からはベースがあるので早くはなる。

開いたディレクトリ

/tmp/app/
|-- .devcontainer/
|   `-- devcontainer.json
|-- .github/
|   `-- dependabot.yml
`-- src/
    `-- main.py*

devcontainerで開くと.devcontainerディレクトリと.githubディレクトリが追加される。

devcontainer.jsonはdevcontainerの設定。
ディレクトリを開くときに聞かれた、イメージの種別、追加機能の追加などが記載されている。
これを共有しておけば別の人がdevcontainerで開くときに同じ設定で開くことが可能。

dependabot.ymlはGithubのDependabotの設定?(あんま調べてない)

独自イメージを使いたい場合

  • VMにイメージをpullしておく
  • 開きたいディレクトリに.devcontainer/devcontainer.jsonを作成
  • devcontainer.jsonのimageに使いたいイメージ名を指定

こんな感じ。my-httpdとうイメージは事前に作っておいてある。

{
        "name": "HTTPD",
        // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
        "image": "my-httpd"

        // Features to add to the dev container. More info: https://containers.dev/features.
        // "features": {},

        // Use 'forwardPorts' to make a list of ports inside the container available locally.
        // "forwardPorts": [],

        // Use 'postCreateCommand' to run commands after the container is created.
        // "postCreateCommand": "pip3 install --user -r requirements.txt",

        // Configure tool-specific properties.
        // "customizations": {},

        // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
        // "remoteUser": "root"
}

devcontainer.jsonをいじれば色々できそうだけど、とりあえず使うだけならばこれだけでいいはず。

devcontainer.jsonのリファレンス

https://containers.dev/implementors/json_reference/

bind/volume mountする方法

bind mountする場合は以下のmountsの個所を追加してあげる

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
        "name": "MKdocs",
        // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
        "image": "python:3.9.19-slim-bookworm",
:(省略)
        "mounts": [
               {
                 "type": "bind",
                 "source": "/tmp/mkdocs",
                 "target": "${containerWorkspaceFolder}/mkdocs"
               }                 
        ]
}
  • source:
    マウントしたいホスト側のファイル(ディレクトリ)
  • target:
    マウントするコンテナ側のディレクトリ
    ${containerWorkspaceFolder}はworkspaceFolderで設定したディレクトリ。デフォルト/workspace

volume mountする場合は以下

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
        "name": "MKdocs",
        // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
        "image": "python:3.9.19-slim-bookworm",
:(省略)
        "mounts": [
               {
                 "type": "volume",
                 "source": "test_volume",
                 "target": "${containerWorkspaceFolder}/mkdocs"
               }                 
        ]
}

sourceに設定する内容がvolumeに代わるだけ。volumeは事前に作っておく

Port forward

Port forwardについては、コンテナ内で待ち受けるプロセスを上げるとVS Codeが適宜設定してくれる。が、以下の図のような感じで、PC側にForward用のポートが作成される。ポート番号は待ち受けているポート番号と同じ。

パケットキャプチャしてもVM側は反応しなかったので、VMは何もしてない(vscode serverでなんかしてる?)

Discussion