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コンテナの中で行うことができる。
リモートコンテナ機能の標準的な使い方であれば、Docker Desktop for Windows/Mac をインストールして使うのがよい。しかし、Docker Desktopは仮想マシンで動作させるため、ホストOSとは別にメモリを設定する必要がある。
Windowsの場合は、WSLを使うと、WSL中のLinuxのメモリ容量はホストOSと共有される。メモリ32GB、CPU16コアのマシンでWSL中でリソースを確認すると、以下のように表示される。
また、リモート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アドレスを設定する。
> $ENV:DOCKER_HOST = "tcp://172.19.0.1:9000"
> docker ps
SSHリモート先の場合、先のポートフォワーディングを行う。
> $ENV:DOCKER_HOST = "tcp://127.0.0.1:9000"
> ssh -L 9000:127.0.0.1:9000 host
> docker ps
$ export DOCKER_HOST=tcp://127.0.0.1:9000
$ ssh -L 9000:127.0.0.1:9000 host
$ docker ps
この環境変数を設定したうえで、code
コマンドを使い、VSCodeを起動する。
失敗して、リモート先のDockerを認識しない場合、Dockerをインストールする旨のメッセージが表示される。
以下のようになれば、Dockerを認識できている。
WSL、リモートホストで、リポジトリをマウントするdocker-composeを作る
開発リポジトリをチェックアウトし、いろいろ仕込みを行う。
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の部分)。
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
mypy==0.701
pylint==2.3.1
black==19.3b0
これでdocker-composeを起動する。
$ docker-compose up -d
$ docker ps
リモートコンテナ機能でdocker-composeのコンテナにアタッチする
リモート開発タブを開くと、起動したコンテナが確認できる。
コンテナの右に出る開くボタンを押すと、そのコンテナにアタッチできる。
アタッチして、異なるディレクトリが開かれた場合には「File: Open Folder...」コマンドを使って、目的のディレクトリを開きなおす。
これで、WSL、リモートホストであっても、リモートコンテナ機能が使えます!