水底

ScalaとかC#とかk8sとか

ローカルのVSCodeから、ローカルに置いたソースコードをリモートのDocker上で動かす方法

TL;DR;

  • 現状、vscode-remote-development-containerは DOCKER_HOST で指定するdocker over sshに対応しきれていない
  • sshでリモートのdockerソケットをローカルにフォワーディング
  • amaya382/sssh を利用して、ローカルにあるソースコードディレクトリをリモートにマウント
  • vscode-remote-development-containerでローカルにフォワードされたdockerソケットを利用して起動
    • vscode-remote-development-sshは利用しない

現状

vscode-remote-developmentにより、ssh越し (vscode-remote-development-ssh) やdockerコンテナ内 (vscode-remote-development-container) の環境をローカルとほぼに同等に扱いつつVSCodeからファイルの編集やデバッグが行えるようになっています。しかしながら、vscode-remote-development-sshvscode-remote-development-containerを組み合わせて使うことは出来ず、例えば「sshした先のdockerコンテナ内」といった環境を簡単には扱うことが出来ません。また、最近では DOCKER_HOST やホスト指定オプション (-H) にsshプロトコルを指定することによりローカルのdocker clientから越しのdocker daemonを操作することが可能ですが、この方法はまだvscode-remote-development-containerではサポートされていません。また、vscode-remote-development-sshはあくまでリモートにあるソースコードをリモートで動かすことを目的としているため、ローカルのファイルを利用する手段も提供されていません。

必要なもの

ローカル

リモート (ssh先)

その他

  • ローカルからリモートへssh接続できること

のみです。純粋なローカル→リモートのsshプロトコルしか利用しません。

方法

1. ssh越しのdocker daemonに接続する

まず、vscode-remote-development-containerをssh越しのdocker daemonに接続するためにsshでリモートのdockerソケットをローカルにフォワーディングします。

ssh -fNL [<ssh_opts_such_as_port_number>] localhost:<local_port>:/var/run/docker.sock <remote_host>

バインドするポート番号 (local_port) は何でも良いですが、後述の .vscode/settings.json - docker.host と合わせる必要があります。本サンプルでは 22222 であることを前提に進めます。

この内容については以下の公式ドキュメントに従っています。

2. ローカルのディレクトリをリモートにマウントする

2.1. fuseの設定

リモートのfuseの設定 (/etc/fuse.conf) を調整し、 user_allow_other を有効にします。再起動等は不要です。

2.2. ローカルのディレクトリをリモートにマウント

amaya382/sssh を利用します。

ssshはまだプロトタイプのため、利用方法が変わる可能性があります。リポジトリのREADMEも参照してください。

# サンプルプロジェクト
git clone git@github.com:amaya382/vscode-remote-docker-over-ssh.git

# マウント用ツール
git clone git@github.com:amaya382/sssh.git
cd sssh
./sssh --volume <local_dir>:<remote_dir> [<ssh_opts_such_as_port_number>] <remote_host>

本サンプルではサンプルプロジェクトをリモートに持っていくため、 local_dir../vscode-remote-docker-over-ssh を指定することを前提で進めます。実際にはリモートで利用したいソースファイルのあるディレクトリを指定することになります。相対パスでも絶対パスでも問題ありません。 また、 remote_dir は重複しなければどこでも問題ありませんが、後述の devcontainer.json - workspaceMount と合わせる必要があります。本サンプルでは /tmp/mnt/my-project であることを前提に進めます。

ssshssh のラッパーになっているため、sshそのもののオプションもそのまま利用できます。

3. VSCodeをリモートのdockerに繋いで動かす

先程cloneした設定済みのサンプルを利用します。

これをVSCodeで開き、vscode-remote-development-containerを利用してコンテナ内で開きます。このサンプルでは .vscode/settings.json - docker.host の設定により、docker接続先が「リモートのdockerソケットがバインドされたローカルのポート」になるため、つまるところリモートのdocker daemonに接続されます。また、 .devcontainer/devcontainer.json - workspaceMount の設定により、vscode-remote-development-containerでコンテナを立ち上げる際に、指定したディレクトリ (ここでは sssh でマウントしたディレクトリ) が自動的にマウントされます。これにより、vscode-remote-development-containerで開くと、ローカルのVSCodeからローカルに置いたソースコードをリモートのDocker上で利用可能な状態となります。後は好きに弄れます。サンプルでは、VSCodepythonのextensionを入れデバッガから main.py を動かすことで、リモートで動くコンテナ上で実行され、コンテナのホスト名が表示されるはずです。

補足

どういうわけか、初めて開くタイミングやVSCodeをリロードしたタイミングでvscode-remote-development-containerの接続がコケることがあります。そのときはretryすると繋がるようです。また、 .devcontainer/devcontainer.json の設定を変更した際は、vscode-remote-development-containerで利用するコンテナをrebuildする必要があります。

参考