4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

VS Codeの開発環境:既存のコンテナをRemote-Containersとして利用する

Last updated at Posted at 2020-05-06

Python3の実行環境をDockerで用意するという記事を書いたのだが、これに少し追加情報

環境

Windows PC + Docker Desktop

lintに困る

Dockerを実行環境としてVS Codeで開発を行うのは快適なのだが一つ問題点がある。lintだ。
VS CodeからはWindowsのPythonを見ているので、ここにpip等でモジュールが入っていないとlintで怒られる。
かと言ってWindows側に綺麗に入れるのは面倒くさいし、それをしたくないからコンテナを実行環境にしているわけである。
Interpreterとしてコンテナ内部のPythonを指定したいのだ。
ググること1分もたたずに、答えが見つかりました。

VS Code Remote Development Extension

名前もそのままでした。いつものようにExtensionとして入れれば準備OK。
本家のマニュアルも非常に充実しているが、充実しすぎてて迷子になってしまう。
なので、既存で既に動いているコンテナにどうやって繋ぐか、という点に絞る。

とりあえずやってみる

こういう構成で始めます。

test2
│  docker-compose.yml
└─app
    │  Dockerfile
    └─src
         | test.py
docker-compose.yml
version: '3.7'
services:
  remotedev:
    build:
      context: ./app
      dockerfile: Dockerfile
    container_name: remotedev
    command: /bin/sh -c "while :; do sleep 10; done"

まずVS codeで上記のフォルダを開いておく。何かしょうもないことを間違っている気はするがこうしないとFrom docker-compose.ymlの選択肢が出てこない。
VS codeにExtensionを入れると左下にこんなのが出てくるのでクリックする。
remote-dev-status-bar.png
次にRemote-Containers: Open Folder in Container..を選ぶ
1.PNG
フォルダを選ぶダイアログが出てくるのでdocker-compose.ymlがあるフォルダを選ぶ(ここではtest2)
更に次のような選択肢が出てくるのでFrom docker-compose.yml
を選ぶ
2.PNG
この時点で新しいコンテナが自動的に作成されている。

c:\source\test2>docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
c7586573d867        test2_remotedev     "/bin/sh -c 'while s…"   8 minutes ago       Up 8 minutes                                 remotedev

このコンテナが上記のdocker-compose.ymlをベースにRemote Containersとして使えるようにしたものである。
最初はこれがどういう設定で立ち上がってきているのかよく理解できなかった。

docker-compose.ymlを重ねて使う

さて元のフォルダ(test2)を見てみる。

test2
│  docker-compose.yml
├─.devcontainer
│      devcontainer.json
│      docker-compose.yml
└─app
    │  Dockerfile
    └─src
        │  test.py

.devcontainerという新しいフォルダにdevcontainer.jsonとdocker-compose.ymlが自動で生成されている。
うまく行くと何をやっているのかさっぱりわからなかったのだが、ひょんなことから失敗してコマンドがわかった。
いろいろやってるっぽいが結局これを実行している

docker-compose -f c:\source\test2\docker-compose.yml -f c:\source\test2\.devcontainer\docker-compose.yml

ここの説明が非常にわかりやすい。
※docker-composeで複数環境を構築
まぁ、要するに後に設定した方で上書きされるということである。
何が書いてあるかというとこんな感じ(長いので一部コメントは消してます)

.devcontainer/docker-compose.yml
version: '3.7'
services:
  # Update this to the name of the service you want to work with in your docker-compose.yml file
  remotedev:
#...省略
    volumes:
      # Update this to wherever you want VS Code to mount the folder of your project
      - .:/workspace:cached
#...省略
    # Overrides default command so things don't shut down after the process ends.
    command: /bin/sh -c "while sleep 1000; do :; done"

大したことは無くてvolumesで"test2"をコンテナ内の"/workspace"にマウントしているだけである。
**command:**はコンテナが落ちないようにするためのものである
実際コンテナ内部はこんな感じ

c:\source\test2>docker exec -it remotedev bash
[root@c7586573d867 workspace]# ls
app  docker-compose.yml
[root@c7586573d867 workspace]# ls app/src/
test.py

VS codeはこんな風に見えている。
3.PNG
Extensionを見るとLOCALDEV CONTAINERで分けてあり、DEV CONTAINER側には何もない。
なのでこの状態では普段利用しているPythonのExtensionが全く効いていないわけだ。
ではこのあたりの設定をどうすればよいのかというと、それが**.devcontainer/devcontainer.json**である。
これもコメントだらけなので殆ど省略する

.devcontainer/devcontainer.json
{
	"name": "Existing Docker Compose (Extend)",

	// Update the 'dockerComposeFile' list if you have more compose files or use different names.
	// The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
	"dockerComposeFile": [
		"..\\docker-compose.yml",
		"docker-compose.yml"
	],

	// The 'service' property is the name of the service for the container that VS Code should
	// use. Update this value and .devcontainer/docker-compose.yml to the real service name.
	"service": "remotedev",

	// The optional 'workspaceFolder' property is the path VS Code should open by default when
	// connected. This is typically a file mount in .devcontainer/docker-compose.yml
	"workspaceFolder": "/workspace",

	// Set *default* container specific settings.json values on container create.
	"settings": { 
		"terminal.integrated.shell.linux": null
	},

	// Add the IDs of extensions you want installed when the container is created.
	"extensions": []

// ...省略
}

基本的には**"extensions"**以外は無視して良いんじゃないかと思う。
ここには各extensionの下記の部分を入力すればよい(ms-python.python)
4.PNG
こんな感じ

"extensions": ["ms-python.python","dbaeumer.vscode-eslint"]

最後にこのコンテナをRebuildする
左下の緑の部分をクリックしてRemote-Containers: Rebuild Container
立ち上げてPythonファイルを表示すると
install-linter-message.png
と聞いてくるのでInstallをクリックするとpipでインストールしてくれる。
これで今までPyPDF2やtabulaでimportのところに赤い波線が出てうっとうしかったのだがすっきりした。

※閉じるときは左下の緑をクリックしてClose Remote Connectionから閉じておこう。VS codeをそのまま閉じると次回も接続しに行ってしまう

virtualenvを自動で有効にしているコンテナは気をつけよう

元々centos/python-36-centos7:latestというイメージをベースにしていた。
CentOS7ベースで既にPythonが入っていたのであとはJDK突っ込むだけだったので楽だったのだ。
しかしこれのせいでlintがが有効にならず悩んだ。
Pylintをインストールするか?と聞いてくるところまでは問題なかったが、pipでのpylintのインストールにどうしても失敗する。

(app-root) bash-4.2# /opt/app-root/bin/python /opt/app-root/src/.vscode-server/extensions/ms-python.python-2020.4.76186/pythonFiles/pyvsc-run-isolated.py pip install -U pylint --user
Can not perform a '--user' install. User site-packages are not visible in this virtualenv.

どうやらvirutualenvが有効なってるから無理、ってことらしい。
そこでこのイメージのDockerfileの最後の部分を見てみるとこうなってた
https://github.com/sclorg/s2i-python-container/blob/master/3.6/Dockerfile


# - Create a Python virtual environment for use by any application to avoid
#   potential conflicts with Python packages preinstalled in the main Python
#   installation.
# - In order to drop the root user, we have to make some directories world
#   writable as OpenShift default security model is to run the container
#   under random UID.
RUN source scl_source enable rh-python36 && \
    virtualenv ${APP_ROOT} && \
    chown -R 1001:0 ${APP_ROOT} && \
    fix-permissions ${APP_ROOT} -P && \
    rpm-file-permissions

何か色々面倒なので結局素のCentOS7からBuildすることにした

4
1
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?