LoginSignup
11
16

More than 3 years have passed since last update.

WSL/SSHリモート先で、VSCodeのリモートコンテナ機能を使う

Last updated at Posted at 2020-01-18

update 2020/07/18
- VMを使う場合の最近のやり方→ https://qiita.com/74th/items/2ccfc07bd279aba610b1
- WSL2を使う場合、Docker DesktopがWSL2をサポートしている → https://docs.docker.com/docker-for-windows/wsl/

VSCodeにはリモートコンテナ機能があり、開発をDockerコンテナの中で行うことができる。

image.png

リモートコンテナ機能の標準的な使い方であれば、Docker Desktop for Windows/Mac をインストールして使うのがよい。しかし、Docker Desktopは仮想マシンで動作させるため、ホストOSとは別にメモリを設定する必要がある。

image.png

Windowsの場合は、WSLを使うと、WSL中のLinuxのメモリ容量はホストOSと共有される。メモリ32GB、CPU16コアのマシンでWSL中でリソースを確認すると、以下のように表示される。

wsl.png
wsl2.png

また、リモートSSH機能では、外部のマシン上で開発できるため、ホストコンピュータ(MacBookProとか)のメモリ量に左右されず、使うことができる。

やりかたの要約

  • WSL/リモート上のDockerをTCP(例:ポート9000)でアクセスできるようにする
  • DOCKER_HOST=tcp://remote:9000 を設定し、ホストマシンからdockerコマンドが使えるようにする
    • もしくはsocat TCP-LISTEN:9000,reuseaddr,fork UNIX-CLIENT:/var/run/docker.sockと、unixsocketをTCPにリダイレクトする
  • WSL、リモートSSH先でリポジトリをチェックアウトしておく
  • docker-composeでそのリポジトリのディレクトリをマウントしたDevContainerを作り、コンテナを起動する
  • コマンド"Remote-Container: Attach to Container"を実行して、コンテナに接続する

WSLの準備

WSLでDockerを使うには、WSL 2である必要がある。インストール方法については、公式のドキュメントがあるのでそれを参照する。

公式ドキュメント: https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-install

以下のコマンドでWSL 2をデフォルトのバージョンにしてから、Windows StoreからUbuntuをインストールするとよい。

> wsl --set-default-version 2

Dockerをtcpでサービスする

以下、WSLの中のUbuntuを前提に解説する。CentOS等異なるOSを使う場合には読み替えること。また、リモートSSH先でも同様である。

$ sudo apt update
$ sudo apt install -y docker.io docker-compose
$ sudo gpasswd -a $USER docker

通常はDockerサービスを起動した後にdockerにアクセスできるようになっている。この場合、DockerのAPIへのアクセスはUnixソケットを用いて行われる。

$ sudo service docker start
$ sudo docker ps

Dockerの起動オプションを書き換え、tcpで行えるようにする(以下の例は、すべてのホストに公開する設定になっているため、Firewall中で行う、サービスホスト名を変えるなど対応すること)。

$ vi /etc/default/docker
# TCP 9000
DOCKER_OPTS="-H 0.0.0.0:9000"

$ sudo service docker restart

$ export DOCKER_HOST=tcp://127.0.0.1:9000
$ docker ps

もしくは、socatを使ってUnixソケットをTCPにリダイレクトさせる。

$ socat TCP-LISTEN:9000,reuseaddr,fork UNIX-CLIENT:/var/run/docker.sock &
$ export DOCKER_HOST=tcp://127.0.0.1:9000
$ docker ps

WSLの場合、IPアドレスを調べておく。以下の例では172.19.0.1である(WSL内のサービスにはlocalhostで通常アクセスできるが、そうでない場合もあるため)。

$ ip addr show

20: br-9618f27bf4e9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:b4:05:32:91 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.1/16 brd 172.19.255.255 scope global br-9618f27bf4e9
       valid_lft forever preferred_lft forever
    inet6 fe80::42:b4ff:fe05:3291/64 scope link
       valid_lft forever preferred_lft forever

ホストマシンからWSL/SSHリモート先のDockerにアクセスする

TCPでDockerAPIにアクセスできるようにするには、環境変数DOCKER_HOSTに"tcp://host:port"と設定すればよい。

WSLの場合、先のWSLのIPアドレスを設定する。

PowerShell
> $ENV:DOCKER_HOST = "tcp://172.19.0.1:9000"
> docker ps

SSHリモート先の場合、先のポートフォワーディングを行う。

PowerShell
> $ENV:DOCKER_HOST = "tcp://127.0.0.1:9000"
> ssh -L 9000:127.0.0.1:9000 host
> docker ps
bash
$ export DOCKER_HOST=tcp://127.0.0.1:9000
$ ssh -L 9000:127.0.0.1:9000 host
$ docker ps

この環境変数を設定したうえで、codeコマンドを使い、VSCodeを起動する。
失敗して、リモート先のDockerを認識しない場合、Dockerをインストールする旨のメッセージが表示される。

image.png

以下のようになれば、Dockerを認識できている。

image.png

WSL、リモートホストで、リポジトリをマウントするdocker-composeを作る

開発リポジトリをチェックアウトし、いろいろ仕込みを行う。

docker-compose.yaml
version: "3"
services:
  python:
    build:
      context: .
      dockerfile: ./Dockerfile
    # 使うポートを先に開けておく
    ports: 
      - 8080:8080
    # WSL、リモートSSHのユーザID、グループIDを設定する
    user: "1000:1000"
    environment: 
      HOME: "/home/nnyn/"
    # とりあえずサービスとして起動させたいので、以下のコマンドを仕込む
    command: /bin/sh -c "while sleep 10000; do :; done"
    volumes:
      # チェックアウトしたディレクトリのマウント
      - /home/nnyn/vscode-book-python:/app
      # gitの設定のマウント
      - /home/nnyn/.git:/home/nnyn/.git
      # githubにアクセスする際に.netrcを使ってパスワードの入力を省略している場合は追加する
      - /home/nnyn/.netrc:/home/nnyn/.netrc
      # VSCodeServerのリソースのディレクトリ
      - /home/nnyn/.vscode-container:/home/nnyn/.vscode-server

Linuxではidコマンドを使うと、現在のユーザID、グループIDを取得することができる。開発リポジトリはこのユーザID、グループIDでチェックアウトされているため、このユーザを使うようにする

$ id
uid=1000(nnyn) gid=1000(nnyn) groups=1000(nnyn),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),108(lxd),114(netdev),115(docker)

また、開発リポジトリのディレクトリや、gitの設定などをマウントする。

Dockerfileには、以下のようにgitなどもインストールしたり、拡張機能から使うライブラリも入れている(dev-requirements.txtの部分)。

Dockerfile
FROM python:3.7
RUN apt-get update && apt-get -y install git procps

WORKDIR /app
ADD ./requirements.txt ./
RUN pip install -r requirements.txt
ADD ./dev-requirements.txt ./
RUN pip install -r dev-requirements.txt
dev-requirements.txt
mypy==0.701
pylint==2.3.1
black==19.3b0

これでdocker-composeを起動する。

$ docker-compose up -d
$ docker ps

リモートコンテナ機能でdocker-composeのコンテナにアタッチする

リモート開発タブを開くと、起動したコンテナが確認できる。

image.png

コンテナの右に出る開くボタンを押すと、そのコンテナにアタッチできる。

image.png

アタッチして、異なるディレクトリが開かれた場合には「File: Open Folder...」コマンドを使って、目的のディレクトリを開きなおす。

image.png

これで、WSL、リモートホストであっても、リモートコンテナ機能が使えます!

11
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
16