概要
共同での研究や開発において、環境の違いによる問題を回避するために
統一された便利なDocker
コンテナ環境を持つことには利点があると思われます。
また、VSCodeを用いて作業を行うことで、
コードの変更や動作確認、デバッグなどが行いやすくなると考えられます。
本記事では、github
から取得できるCLAM
リポジトリについて、
Dockerコンテナ
構築手順を用意し、
コンソール
またはVSCode
から扱えるような手順を紹介しております。
CLAMは2020年にハーバード大学医学部ブリガム・アンド・ウイメンズ病院 病理部のMing Y.Lu氏らが発表した、スライド画像から特徴量を抽出し、スライド単位のラベルを用いて弱教師あり学習でクラス分類を行うスクリプトです。
今回の例はCLAM
ですが、CLAM
以外でも、DockerとVSCodeを連携させた
環境が用意されていないリポジトリを、共同で使ってみたい場合などの参考になればと思います。
なお、GPU
を用いない場合と用いる場合の両方に対応できるよう記載しております。
(Docker
がGPU
をサポートするためには、
事前にnvidia-container-toolkit
をインストールしている必要があります)
環境構築用ファイル作成手順
手順1
CLAM
のリポジトリをクローン
git clone https://github.com/mahmoodlab/CLAM.git
手順2
取得したCLAM
リポジトリに移動し、docker
ディレクトリを作成
cd CLAM
mkdir docker
手順3
docker
ディレクトリに、Dockerfile
やdocker-compose.yml
等で参照する環境変数を設定するシェルファイルinit_env.sh
を作成
init_env.sh
#!/bin/bash
set -euo pipefail
# 本ファイルのあるディレクトリの1つ上のディレクトリに移動
cd $(dirname $0)/..
REPLACE_USERNAME=$(echo $USER |sed 's/\./_/g')
# ホストのユーザー名がrootの場合、REPLACE_USERNAME="developer"に指定
if [ "$USER" = "root" ]; then
REPLACE_USERNAME="developer"
fi
# .envファイルがない場合、下記内容の環境変数ファイルを作成
if [ ! -f .env ]; then
cat <<EOT > .env
COMPOSE_PROJECT_NAME=clam_${REPLACE_USERNAME}
USERNAME=$REPLACE_USERNAME
HOST_UID=`id -u`
HOST_GID=`id -g`
EOT
fi
手順4
docker
ディレクトリにDockerfile
を作成
apt-get install
やpip install
などの項目はCLAM
のenv.yml
をベースに作成します。
Dockerfile
# ベースイメージ (CPUの場合)
FROM ubuntu:22.04 AS base
# ベースイメージ (GPUの場合[Nvidia])
# FROM nvidia/cuda:12.1.0-devel-ubuntu22.04 AS base
# 時刻設定(東京)
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# システムパッケージ更新とbuild-essential, python3.10関連パッケージ
# 及び、OpenSlide, OpenCV関連パッケージのインストール
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y build-essential python3.10 python3.10-distutils python3-pip libopenslide-dev libgl1 git
## GPUの場合に下記を設定 (CUDA関連追加設定)
# CUDAホームディレクトリを環境変数CUDA_HOMEに設定
# ENV CUDA_HOME=/usr/local/cuda
# CUDAの実行可能ファイル(例: nvcc)ディレクトリを環境変数PATHに追加。これにより、nvccなどをコマンドとして直接実行可能に
# ENV PATH=$CUDA_HOME/bin:$PATH
# CUDAライブラリ(例:cuDNN)があるディレクトリを動的ライブラリの検索パスに追加。これにより、アプリケーションがCUDAライブラリをロード可能。
# ENV LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH
# Pytorchで使用するGPUアーキテクチャを指定
# ENV TORCH_CUDA_ARCH_LIST="6.0;6.1;7.0;7.5;8.0;8.6"
# CLAMのenv.ymlに合わせてpipパッケージをインストール
RUN pip install --upgrade pip &&\
pip install ipykernel &&\
pip install pandas pyyaml opencv-python matplotlib scikit-learn scipy tqdm &&\
pip install timm==0.9.8 torch torchvision tensorboardx &&\
pip install openslide-python &&\
pip install h5py &&\
pip install git+https://github.com/oval-group/smooth-topk.git
# 言語設定(日本語)
RUN apt update && apt install -y language-pack-ja && update-locale LANG=ja_JP.UTF-8
RUN apt install -y fonts-takao fonts-takao-gothic fonts-takao-pgothic fonts-takao-mincho
ENV LANG jp_JP.UTF-8
ENV XMODIFIERS @im=fcitx
ENV GTK_IM_MODULE fcitx
ENV QT_IM_MODULE fcitx
ENV LC_CTYPE ja_JP.UTF-8
# dev(開発用)
FROM base AS dev
# 開発などで良く用いられるLinuxツール+nodejs(markdownlintインストール用)
RUN apt update && apt install -y \
curl \
gnupg \
sudo \
nano \
vim \
wget \
&& apt purge -y nodejs \
&& curl -sL https://deb.nodesource.com/setup_22.x | bash - \
&& apt install -y nodejs \
&& apt clean && rm -rf /var/lib/apt/lists/*
# コードの書式等チェック用linter, formatter, testerインストール
RUN pip install \
codespell==2.3.0 \
pytest==8.2.1 \
ruff
# マークダウンファイル(README.mdなど)の書式チェック用
RUN npm install -g --save-dev markdownlint-cli2@0.13.0
# シンボリックリンク作成("python OOO.py"でコマンド実行できるようにするため)
RUN ln -s /usr/bin/python3 /usr/bin/python
# ipykernelの設定(jupyter notebook等を用いる場合、別途インストールが必要)
RUN python -m ipykernel install --user --name=sysmtem-python --display-name "Python(system)"
# 開発用ユーザー追加
ARG USERNAME=developer
ARG USER_UID
ARG USER_GID
# ホストのユーザーID,グループIDをコンテナ内のIDに割り当てるが、
# コンテナ環境で既存のグループID、ユーザーIDの場合は、
# ユーザーID=1000, グループID=1000を割り当て
RUN USER_GID=$(getent group $USER_GID >/dev/null && echo 1000 || echo $USER_GID) \
&& USER_UID=$(getent passwd $USER_UID >/dev/null && echo 1000 || echo $USER_UID) \
&& groupadd --gid $USER_GID $USERNAME \
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
&& echo "$USERNAME ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME
# 指定したユーザー名でコンテナをビルド
USER $USERNAME
CMD ["usr/bin/bash"]
手順5
CLAM
のトップディレクトリに移動し、docker-compose.yml
を作成
docker-compose.yml
# プロジェクト名。コンテナ名等のprefixとして付与される
name: clam
# コンテナ全体の設定
services:
# service内の1つのサービス名(任意名)
dev:
# コンテナにホストと同等の特権を持たせる
privileged: true
# Dockerのimage名
image: clam:dev-${USERNAME}
# docker build条件
build:
# コンテナビルドの基準になるディレクトリ
# `docker-compose.yml`から見て`Dockerfile`が格納されたディレクトリパス
# `docker-compose.yml`が`clam/`にあり、`Dockerfile`は`clam/docker`にあるため、
# `docker`を指定
context: docker
# Dockerfileの指定
dockerfile: Dockerfile
# ビルドの際のステージを指定(開発用の部分が不要の場合はbase)
# 他のステージをDockerfileに追加しtargetに指定してもOK
target: dev
args:
- USER_UID=${HOST_UID}
- USER_GID=${HOST_GID}
# nvidiaのGPU(id=0を指定)を用いる場合
# deploy:
# resources:
# reservations:
# devices:
# - driver: "nvidia"
# capabilities: ["gpu"]
# nvidia-smiで確認できるGPU IDを指定
# device_ids: ["0"]
user: "${HOST_UID}:${HOST_GID}"
# ホスト側のネットワークを指定
# 別途ポートを指定する場合、`network_mode:`は記載せず、
# 代わりに`ports:`を記載し`- "8888:8888"`(ホストのポート:コンテナのポート)
# のようにポート番号を指定する
network_mode: "host"
# ボリューム設定
volumes:
# ホストのカレントディレクトリをコンテナ内の/workspaces/clamにマウント
# (ホストでの変更を動的にコンテナに反映)
- .:/workspaces/clam
# ホストのデバイスディレクトリをコンテナ内の/devにマウント
# (GPUやUSBデバイスへのアクセス用)
- /dev:/dev
# コンテナ内の作業ディレクトリ
working_dir: /workspaces/clam
# 対話型操作用
stdin_open: true
# docker execでアクセス用
tty: true
# bash -c "tail -f /dev/null"はコンテナをバックグラウンドで起動し続けるため
# コンテナ内で常にJupyter等の他のプロセスを起動する場合は必要なし
command: >
bash -c "tail -f /dev/null"
手順6
開発に用いるVSCode
のDev Container機能
用に.devcontainer
ディレクトリを用意し、
ホストと同様にssh
やgit
を使用するための補足用docker-compose.yml
を作成
docker-compose.yml
services:
dev:
user: developer
# コンテナ内のdeveloperユーザーがsshやgitを使用できるように指定
volumes:
- ~/.ssh:/home/developer/.ssh:ro
- ~/.gitconfig:/home/developer/.gitconfig
手順7
.devcontainer
ディレクトリに、
VSCode
のDev Container機能
用のdevcontainer.json
を用意
devcontainer.json
{
"name": "clam",
"dockerComposeFile": [
"../docker-compose.yml",
"docker-compose.yml"
],
"service": "dev",
"workspaceFolder": "/workspaces/clam",
"containerEnv": {
"SHELL": "/bin/bash"
},
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.mypy-type-checker",
"charliermarsh.ruff",
"DavidAnson.vscode-markdownlint"
]
}
}
}
devcontainer.json
について補足
・dockerComposeFile
には.devcontainer
にある
docker-compose.yml
とCLAM
ディレクトリの直下にあるdocker-compose.yml
を指定
・service
にはdocker-compose.yml
で指定してあるdev
を指定
・workspaceFolder
には、コンテナ内の作業ディレクトリのパスを指定
・containerEnv
では、コンテナ内の環境変数を設定
・
"customizations": {
"vscode": {
"extensions": [
には、VSCode
にインストールする拡張機能を指定
(python
系に加え、今回は書式をチェックするもの等指定)
手順8
トップディレクトリにREADME.md
を作成し、
環境構築手順が分かるようにする。
README.md例
CLAM
環境構築
Docker
コンテナでの使用を想定した手順です
1. リポジトリを取得
git clone https://github.com/mahmoodlab/CLAM.git
2. .env
ファイルの作成
ホストのUID
及びGID
を使用するために、.env
ファイルを作成します
./docker/init_env.sh
3. Dockerイメージのビルド及びコンテナの起動
下記2つの方法があります。(VSCode
推奨)
[VSCode
の拡張機能(Dev Container
)を用いた方法]
下記を実施することで、VSCodeのDev Containerを使用し環境構築を行うことができます
・VSCode
でプロジェクトのルートディレクトリを開く
・Ctrl
とShift
を押しながらP
を押してコマンドパレットを開く
・コマンドパレットからReopen in Container(コンテナーで再度開く)
を選択する
・コンテナ内の環境が開く
[Docker compose
を用いた方法]
docker compose build dev
docker compose run dev
上記実行後に、別のウインドウ又はタブからコンテナに入ります
docker exec -it コンテナ名 /bin/bash
環境構築手順
作成したファイルを用いて環境の構築を実施します
方法1 (VSCode
)
-
VSCode
でCLAM
リポジトリを開く
-
Ctrl & Shift + P
で開くメニューから、
Dev Containers: Reopen in Container
(コンテナで再度開く)を選択
- 新たにコンテナ内の処理ウインドウが開きます
このウインドウのコンソールから、
create_patches_fp.py
などのCLAM
のプログラムを実行します
- コンテナ外のコンソールから、コンテナの稼働状況を確認
PS D:\OOO\CLAM> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3b8e557ab872 clam:dev-OOO "/bin/sh -c 'echo Co…" 3 hours ago Up 3 hours clam_developer-dev-1
方法2 (docker compose
コマンド)
- コンソールにて、
CLAM
ディレクトリから、docker compose build dev
を実行
root@OOOOO:/mnt/d/OOOOO/CLAM# docker compose build dev
[+] Building 1014.2s (16/16) FINISHED docker:default
=> [dev internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 2.39kB 0.0s
=> [dev internal] load metadata for docker.io/library/ubuntu:22.04 2.5s
=> [dev internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [dev base 1/6] FROM docker.io/library/ubuntu:22.04@sha256:0e5e4a57c2499249aafc3b40fcd541e9a456aab7296681a3994d631587203f97 4.4s
=> => resolve docker.io/library/ubuntu:22.04@sha256:0e5e4a57c2499249aafc3b40fcd541e9a456aab7296681a3994d631587203f97 0.0s
=> => sha256:0e5e4a57c2499249aafc3b40fcd541e9a456aab7296681a3994d631587203f97 6.69kB / 6.69kB 0.0s
=> => sha256:3d1556a8a18cf5307b121e0a98e93f1ddf1f3f8e092f1fddfd941254785b95d7 424B / 424B 0.0s
=> => sha256:97271d29cb7956f0908cfb1449610a2cd9cb46b004ac8af25f0255663eb364ba 2.30kB / 2.30kB 0.0s
=> => sha256:6414378b647780fee8fd903ddb9541d134a1947ce092d08bdeb23a54cb3684ac 29.54MB / 29.54MB 3.0s
=> => extracting sha256:6414378b647780fee8fd903ddb9541d134a1947ce092d08bdeb23a54cb3684ac 1.1s
=> [dev base 2/6] RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime 3.5s
=> [dev base 3/6] RUN apt-get update && apt-get upgrade -y && apt-get install -y build-essential python3.10 python3.10-d 148.8s
=> [dev base 4/6] RUN pip install --upgrade pip && pip install ipykernel && pip install pandas pyyaml opencv-python matplo 775.2s
=> [dev base 5/6] RUN apt update && apt install -y language-pack-ja && update-locale LANG=ja_JP.UTF-8 9.8s
=> [dev base 6/6] RUN apt install -y fonts-takao fonts-takao-gothic fonts-takao-pgothic fonts-takao-mincho 7.8s
=> [dev dev 1/6] RUN apt update && apt install -y curl gnupg sudo nano vim wget && apt purge -y nodej 27.7s
=> [dev dev 2/6] RUN pip install codespell==2.3.0 pytest==8.2.1 ruff 4.6s
=> [dev dev 3/6] RUN npm install -g --save-dev markdownlint-cli2@0.13.0 10.7s
=> [dev dev 4/6] RUN ln -s /usr/bin/python3 /usr/bin/python 0.5s
=> [dev dev 5/6] RUN python -m ipykernel install --user --name=sysmtem-python --display-name "Python(system)" 0.9s
=> [dev dev 6/6] RUN USER_GID=$(getent group 0 >/dev/null && echo 1000 || echo 0) && USER_UID=$(getent passwd 0 >/dev/null && 0.5s
=> [dev] exporting to image 17.0s
=> => exporting layers 17.0s
=> => writing image sha256:75c16e5d90aaafc5ccf569ca8f55ec640f939a6f56a08b3bfaf7c03eafcec396 0.0s
=> => naming to docker.io/library/clam:dev-developer
2. docker images
でイメージが作成されていることを確認
root@AlzaPC:/mnt/d/OOO/CLAM# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
clam dev-OOO ceb4480de052 4 hours ago 10.3GB
ubuntu 22.04 97271d29cb79 2 months ago 77.9MB
continuumio/anaconda3 latest de606c8c8d2d 9 months ago 4.45GB
docker/welcome-to-docker latest c1f619b6477e 12 months ago 18.6MB
3.docker compose run dev
でコンテナを起動
root@AlzaPC:/mnt/d/OOO/CLAM# docker compose run dev
4.コンテナに入る際は、別のタブなどからコンソールを開き、下記を実行
docker exec -it コンテナ名(clam-OOO) /bin/bash
5.下記のようにdocker
内の作業環境が開きます
ここから、create_patches_fp.py
などのCLAM
のプログラムを実行します
developer@docker-desktop:/workspaces/clam$
環境構築方法は以上になります。
構築した環境でCLAM
のコードを実行することができます。
実際に構築した例について、githubに公開しておりますので、ご参考にしていただけましたら幸いです。