17
26

More than 1 year has passed since last update.

VScodeでdockerの開発環境(python)を使う。

Last updated at Posted at 2021-10-26

Ubuntu20.04.3LTS
Docker version 20.10.7
docker-compose version 1.29.1
nvidia-docker2(sudo apt-get install -y nvidia-docker2でNvidia Container Toolkitが導入される)
VScode 1.61.1
RTX 3060 Driver Version: 470.74

python機械学習の開発環境をどうするか。
Anaconda:事業展開するときに有償ライセンスが必要かも知れない。
Docker Desktop:事業展開するときに有償ライセンスが必要かも知れない。
という背景から、ライセンスが緩いdockerとdocker-compose を使った方がいい?という動機。
最新の開発環境は、dockerで提供されるケースが増えているという助言も。
CUDAやcuDNN、tensorflowのバージョン合わせに疲れたこともある。

できれば、VScodeを使ってGUIで操作したという動機。

ここでは、VScodeの実行ボタンを押して、コンテナ内のpython上で実行させることを記述。
参考 https://qiita.com/Yuki_Oshima/items/d3b52c553387685460b0

実は、以下の作業全部クロームリモートデスクトップを使って、遠隔でWindowsPCからやっていました。
https://qiita.com/katakaku/items/dafc5bcbebf443f75f9b

VScodeの拡張機能

VScodeのプロジェクトはフォルダ単位で管理される。ローカル(ホスト)とリモート(コンテナ)を行き来するので、どちらにいるのか気をつけておく。(左下の緑のリモートマークに注目)
以下の拡張機能をホスト側(通常インストールして開いた画面)でインストールする。
image.png
いつの間にか名前が変わっていた(Remote -> Dev)
image.png

image.png
dockerの拡張機能を入れるとタブからコンテナ一覧を見たり、起動・削除ができるようになる。また、ファイルメニューからdockerfileを右クリックするとビルドできるが、今回の流れでは操作しない。コンテナのターミナルを起動することもできるが、混乱するので慣れるまでは使わない。

image.png

プロジェクトフォルダを開く

dockerfileやdocker-compose.ymlがあるフォルダを開く。するとホストのファイルが表示される。dockerfileとdocker-compose.ymlの記載例は下の方にあります。その他、pythonのライブラリを一括でインストールするのに便利なrequirementsファイル、pythonのテスト用のファイルや(今回の流れでは無くても良いですが)学習管理サイトWeights&Biases(wandb)の設定ファイルなどが有ります。
image.png image.png

コンテナのなかに入る

左下の「リモートウィンドウを開きます」image.png を押す。
ここから、Reopen in Containerを選ぶ。
image.png
すると、VScodeがdocker用の設定ファイルを作るベースを聞いてくる。Dockerfileのみの場合は、Dockerfile。docker-compose.ymlがあるならFrom docker-compose.ymlを選ぶ。
image.png
すると、左下のマークが替わり、コンテナに接続される。コンテナ内(リモート)の状態だ。
image.png
image.png

ホスト側のプロジェクトフォルダが、コンテナ内の/workspaceフォルダにデフォルトでマウントされる。このフォルダ内のファイルに対する変更や新規作成はホスト側に反映される。

同時に隠しフォルダ.devcontainerが作成されその下にdevcontainer.jsonとdocker-compose.ymlが作成される。docker-compose.ymlは既存のと重複するが、隠しファイル内に作成されたものは、VScodeに必要な記述だけ記載するのが良いと思う。

image.png

コンテナ内でpythonファイルの実行

エクスプローラーからpythonのファイルを選ぶと実行ボタンがない。
image.png
メニューの実行からデバッグの開始やデバッグなしで実行を選ぶと、拡張機能がないと表示されるので、pythonの拡張をインストールする。ホストに拡張をインストールしていてもリモートのコンテナにはインストールしていないので必要になる。
image.png

image.png
拡張がインストールされると、右上に実行ボタンが表示されるようになった。
ちなみに最近、実行ボタンの色が緑から白に変わったようだ。

image.png
実行ボタンがうまく機能しない場合はpythonインタプリターの指定を確認する。

左下のimage.pngを押すと、pythonのパスが複数表示される。これらは、ホスト側ではなく、リモート(コンテナ)側のパスである。

image.png

端末からwhich pythonを実行して一致するものを選ぶ。(今回の場合pythonとpython3はどちらも一緒)
image.png

ホスト側に戻る

左下のボタンを押し、「リモート接続を終了する」を選ぶ。
image.png

VScodeが作業開始待ちの初期状態に戻る。
docker拡張のタブを見てみると、先ほどのコンテナが休止しているのが分かる。pruneボタンを押すと休止中のコンテナの削除ができる。
image.png

コンテナ用の拡張がビルド時にインストールされるように設定する

dockerfileなどを変更して再ビルドを繰り返すとき、拡張が自動で入る方が楽です。この場合、隠しフォルダ内のdevcontainer.jsonに拡張機能の識別子を記述します。
image.png
識別子は拡張をクリックした画面の詳細情報のなかに記載がある。
image.png

コンテナ内で一般ユーザーとして実行する

コンテナ内でマウントしたファイルを操作すると、所有者がrootに変わってしまい面倒だが、自分のdockerの使い方が違うのか?下に示すdockerfileの記述で一般ユーザーとしてファイル作成・上書きができる。コンテナ内のユーザー名はホスト側のユーザー名と異なっても大丈夫。コンテナ内で作成したファイルは、ホスト側から見るとホストの所有になる。ls -laで確認する。

今回使用したdockerfile

イメージはこちらから選ぶ。

tensorflowのイメージでは認証を求められなかったが、pythorchのイメージでは認証を求められイメージのダウンロードが中断した。NGCにログインしてからGenereteAPI Keyを選択。コマンドラインでログインしておく。
image.png

# tensorflowがGPU上で使えるイメージ
FROM nvcr.io/nvidia/tensorflow:21.09-tf2-py3

# ユーザーを作成
ARG UID=1000
RUN useradd -m -u ${UID} user

# 作成したユーザーに切り替える
# このユーザーはRUN, CMD, ENTRYPOINT, docker run, exec の実行ユーザ。
USER ${UID}

# プロジェクトフォルダを/codeに追加する。ユーザー権限で扱えるようchownオプションを使う。
# ADDの実行権者はrootなのでオプションが必要。
ADD  --chown=user:user . /code
# 作成したフォルダに移動し、パッケージリストをインストールする。
WORKDIR /code
RUN pip install -r requirements.txt

# 作成時にホームディレクトリに置きたいファイルがあれば
RUN cp .netrc ~

ここで呼び出しているrequirements.txt。利用したいパッケージを記載。うまく行っている環境があればpip freezeで取得。

requirements.txt
matplotlib
jupyter
wandb

あらかじめ作成しておいた、docker-compose.ymlの記述。
dockerfileで大枠を記載して、docker-compose.ymlで細かな部分を記述する感じ。docker-compose.ymlだけでも書けるらしい。

docker-compose.yml
version: '3'# 3.2とかも記載できる。2,3系では命令が少し異なるらしい
services:
  gpu_test:
    build: .  # ドットはdockerfileの記述を使う意味
    deploy:
      resources:
        reservations:
          devices: # GPUを利用するための記述。ホスト側はドライバだけ入れればいい。cudaとか不要。
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    ports:
     - "8888:8888" #ジュピターノートブック用のポート hostname to 0.0.0.0
    volumes:
     - /media/DATA_drive/DATA:/data:cached # データフォルダをマウント
     - .:/code:cached # ソースコードがあるフォルダをマウント
    
    tty: true


隠しフォルダに作成されたdocker-compose.yml 抜粋

docker-compose.yml

    #volumes:
      # Update this to wherever you want VS Code to mount the folder of your project
      #- .:/workspace:cached 上述のdocker-compose.ymlで記述したためコメントアウト

    # Overrides default command so things don't shut down after the process ends.
    # コンテナが自動終了しないようにするらしい
    command: /bin/sh -c "while sleep 1000; do :; done"

devcontainer.json抜粋

devcontainer.json
	// 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": "/code",# ソースファイルをマウントしたフォルダを指定

	// Add the IDs of extensions you want installed when the container is created.
	"extensions": ["ms-python.python"] # ビルド時に入れたい拡張機能を記述

dockerfileやdocker-compose.ymlを編集した後

ホスト側でdockerの記述を変更して、Reopen in Containerを選ぶと、右下のポップアップでリビルドするか無視するか聞かれるので、Rebuildを選ぶ。
image.png
リモート側で編集して、左下のリモートボタンを押した後Rebuid Containerを選んでも良い。

jupyter notebookの起動

コンテナ内のターミナルから、jupyter notebook で起動。docker-compose.ymlでブラウザに接続するポートの設定ずみ。
表示されたURLをホストのブラウザで開く。hostnameの部分は0.0.0.0に変える必要があった。
image.png
image.png

jupyter notebookのマークダウン文書の翻訳

ブラウザの翻訳機能を使うと、jupyter notebookの計算式部分も翻訳される。これを避けるため、セル単位で翻訳可能な拡張機能(nbTranslate)を使う。これは、nbextensionsの1機能として提供されている。
インストールと設定
https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/install.html
https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/nbTranslate/README.html
を参考に
VS-codeのターミナルを使って

pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user

(うまく行ったら、Dockerfileに記載して永続化する)
jupyter notebookとコマンドをうち、ブラウザでアクセスして、左上のdisableのチェックを外しnbTtranslateにチェックを入れる。
その後、下方のSource言語に英語en ターゲット言語に日本語jaを入れる。(新規の際のデフォルト設定になる)グーグル翻訳エンジンが利用される。(初期設定のファイルはここに作製されるようです。/home/user/.jupyter/nbconfig/notebook.json)
image.png

image.png

拡張機能では他にもいろいろな事ができそうです。
https://qiita.com/simonritchie/items/88161c806197a0b84174

以下のコマンドで一括変換もできると書いてあるがうまく行かない?

jupyter nbconvert --to selectLanguage --NotebookLangExporter.language=ja  FILE.ipynb 

上述とは異なり、dockerfileだけのプロジェクトフォルダを使うとき

Reopen in Containerを実行すると、隠しフォルダのdevcontainer.jsonのみが作成されコンテナに入る。デフォルトでコンテナ内の/workspace/プロジェクトフォルダ名にフォルダが作成され、ホスト側のプロジェクトフォルダがマウントされる。
コンテナ内でこのフォルダの変更はホスト側に反映される。

参考サイト

17
26
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
17
26