はじめに
最近、以下のツールの名前を良く聞くかと思います
・Visual Studio Code(コードエディタ、略称「VSCode」)
・WSL2(Windows上にLinux環境を構築)
・Docker(コンテナで環境を分ける)
流行りものの詰め合わせのように見えますが、併用することでシステム開発を大幅効率化できます。
特にPythonにおいては、構成管理や環境差の解決に大きなメリットがあると感じました。
本記事では、これらの組合せによるメリットと使用法を紹介します。
Windowsユーザで**「Docker興味あるのでこの機に試してみたい!」**という方向けに、流れの分かりやすい記事を心がけようと思います!
WSL2とDockerとVSCodeを併用するメリット
併用でどのようなメリットがあるか見ていきましょう
前提
まず大前提として
開発環境がWindows、本番環境がLinux
という構成でないと、これらの併用は意味がありません(そもそも利用できません)
ただし、上記のような構成は多くの企業のシステム開発において一般的と考えられるため、
需要は非常に大きいかと思います。
ではメリットは?
端的に言うと
1. 開発・本番環境の差によるトラブルを防ぐ
2. 操作感を落とすことなく、WindowsPCで開発できる
の2点に集約されるかと思います。
詳細を下記します。
メリット1:開発・本番環境の差によるトラブルを防ぐ
開発環境がWindows、本番環境がLinuxという構成では、
WindowsとLinuxの環境差に由来した様々なトラブル(例:改行コードの違い)
が起こりえます。
今回紹介する方法では、WSL2とDockerを併用する事により、Windows上に本番環境と同等のLinux環境を構築し、環境差を極小化できます。
具体的には、
・WSL2により、Windows上にLinux環境を構築
・Dockerにより、ディストリビューションやPythonライブラリ等の細かいバージョンを合わせ、そのまま本番環境にデプロイ
という方法で、開発環境上に本番環境を再現することが可能です。
メリット2:操作感を落とすことなく、WindowsPCで開発できる
「操作感」というと抽象的ですが、端的に言うと
A. 起動・動作が速い
B. UIで直感的に走査できる
という点において、WSL2、Docker、VSCodeの組合せは非常に優れています。
こちらの記事に大変分かりやすくまとめられておりますが、
Windows上Linux環境構築の選択肢として、WSL2+Dockerは上記「A.起動・動作が速い」を実現する最適な手段となります。
また、「B. UIで直感的に走査できる」に関してはVSCodeはWSL2およびDocker環境での開発を効率化する機能が多く、あたかもWindows上のスクリプトを編集しているような感覚で開発を進められます。
特に**「コンテナ上のスクリプトをデバッグできる」**ことは、開発効率化の上で大きなメリットとなります。
本記事ではブレークポイントを打ったデバッグ可能な開発環境をゴールに、構築法を紹介します。
開発時の構成
「メリットは分かったので、どうやって実現するんだ?」と思われる方も多いかと思います。
ポイントは、
・ローカル側では、Windows OS上にWSL2を通じてLinux環境が乗り、その上にDockerコンテナが乗る
・構成管理をGitリポジトリに統一(Dockerfileを通じて環境+スクリプト両方を管理)
の2点です。
構成管理に関しては他のやり方(例:DockerHubを環境の構成管理に活用)もありますが、
Gitリポジトリへの統一が、管理をシンプルにする観点からおススメです
本番環境へのデプロイ時は、下図⑤、⑥のように、Gitリポジトリ上のスクリプト&Dockerfileを起点として、プログラムや環境を更新します
※画像はこちらの記事より引用させて頂きました
手順
WSL2+Docker+VSCodeによる開発環境構築を、下図の手順で進めていきます。
①WSL2のインストール
WSLの有効化
PowerShellを管理者として開いて下記コマンドを打ち、WSLを有効にします
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
仮想マシン機能の有効化
下記コマンドを打ち、仮想マシンの機能を有効にします
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
Linuxカーネル更新プログラムの適用
こちらのリンクからLinux カーネル更新プログラムをダウンロードし、実行します。成功すれば以下のような画面が出ます
WSL2を既定のバージョンとして設定
下記コマンドを打ち、WSL2を既定のバージョンとして設定します
wsl --set-default-version 2
Linuxディストリビューションのインストール
下記リンクから、好きなLinuxディストリビューション(Ubuntuがおすすめ)をインストールします。
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#step-6---install-your-linux-distribution-of-choice
(2021/11更新)
Microsoft Storeを使用せずとも、Power shellからインストールできるようになりました。
以下のコマンドでインストール可能なディストリビューションを表示させます
wsl --list --online
表示されたディストリビューションから好きなものをインストールします。
例えばUbuntu 20.04をインストールしたい場合以下のコマンドとなります
wsl --install -d Ubuntu-20.04
例えばUbuntu 20.04を使用したい場合、下記画像の「入手」をクリックするとMicrosoft Storeが開くので、指示に従ってインストールを進めればOKです
※なお、ここでインストールするディストリビューションはWSL2用であり、本番環境で使用するディストリビューション(③-1でDockerコンテナ内にインストール)とは異なる事にご注意ください
Ubuntuコンソールの起動
スタートメニューにディストリビューションのショートカットができているので、クリックします
ユーザ名とパスワードの入力
Ubuntuのコンソールが開くので、初期設定が終わるまで待ったのち、ユーザ名とパスワードを入力します。
これでWSL2のインストールは完了ですが、プロキシ環境等ではMicrosoft Storeがうまく開かない事もあるので、以下の操作に進んでください
※プロキシ環境等でMicrosoft Storeが開けない場合
職場のプロキシ環境等では、Microsoft Storeからディストリビューションがダウンロードできない場合があります。
この場合、下記手順で手動でインストールを進めます。
ディストリビューションのダウンロード
こちらのリンクから好きなディストリビューション(Ubuntuがおすすめ)をダウンロードします
ディストリビューションの手動インストール
下記コマンドで、ダウンロードしたディストリビューションをインストールします
("Ubuntu_2004.2020.424.0_x64.appx"の部分はファイル名に合わせ変えてください)
Add-AppxPackage [ダウンロードファイルのあるフォルダ名]\Ubuntu_2004.2020.424.0_x64.appx
これでMicrosoft Storeからインストールした場合と同様、スタートメニューにUbuntuコンソールができるので、起動してユーザ名とパスワードを設定します
※Ubuntuデフォルトユーザの変更
バージョンによってはデフォルトでrootユーザになっていることがあるので、この場合ubuntuのシェルで
sudo adduser [追加したいユーザ名]
でユーザを作成したのち、PowerShell管理者モードで
ubuntu2004 config --default-user [追加したいユーザ名]
と打つことで、作成したユーザをデフォルトユーザに設定することができます("ubuntu2004"の部分はディストリビューション名に合わせ変更。参考)
②Docker Desktopのインストール
WindowsでDockerを利用するためのツールである、Docker Desktopをインストールします。
Docker Desktopのダウンロード
下記リンクから最新版Docker Desktopをダウンロードします
https://docs.docker.com/docker-for-windows/wsl/#download
Docker Desktopのインストール
ダウンロードしたexeを実行し、指示に従ってインストールを進めます
Docker Desktopの起動
インストール完了後Docker Desktopを起動します。
最初はチュートリアルが表示されるので、指示通り進めて以下のような画面が表示されれば完了です。
(チュートリアル用のコンテナは削除して問題ありません)
設定で、"Use the WSL2 based engine"がチェックされていることを確認します
Docker Hubの登録
Docker Hubとは、Dockerイメージ(後述)をアップロードするためのクラウド型リポジトリサービスです。
今回はアップロードではなく、③でコンテナ作成時のベースとなるイメージ取得に利用します。
こちらのDocker Hubサイトに飛んで、下図赤枠の登録フォームから指示に従い登録します。
③Dockerコンテナ作成と環境構築
下図のような手順でDockerコンテナ作成を進めていきます。
手動構築とDockerfileによる自動構築の2種類がありますが、
自動化による再現性確保の観点から、今回は図中右側のDockerfileを使用します
③-1) ベースとなるImageをDockerHubで検索
OS(Linuxディストリビューション)や基本アプリケーションがインストールされた、ベースとなるImageをDockerHubから取得します。
少し紛らわしいですが、上記フロー図中Imageの、さらにベースとなるImageを探す作業となります。
今回はDebian10+PythonがインストールされたImageを探してみます
Docker Hubのpython関係サイトへのアクセス
先ほど登録したDocker Hubサイトにログインし、下図の"python"部分をクリックします
該当するタグの検索
下の方にスクロールすると、"3.9.1-buster"などと書かれたタグがたくさんあります。これは
・"3.9.1"の部分が、Pythonのバージョンを表す
・"buster"の部分が、OSの種類を表す
となります。
OS種類の「"buster"って何やねん!」
と思われる方がいるかと思いますが、これはDebian10の別名です。
各OS名称の詳細は下記となります(参考)
DockerHubでの名称 | 詳細 | メリットとデメリット |
---|---|---|
buster | Debian10+パッケージ色々 | 高速で初期設定も楽だがサイズが大きい |
slim-buster | Debian10 | busterよりサイズ小さいが、自分でパッケージインストールが必要 |
alpine | Alpine | サイズ小さいが、Pythonの動作速度が遅い |
サイズ制約が大きい場合以外は、busterを選択すれば問題ないかと思います。
今回は赤枠で囲んだ、"3.8-buster"を使用するので、この名前を控えておきます。
③-2) Dockerfileとスクリプトの準備
③-1で調べたImageをベースとし、追加でライブラリ等をインストールして実際に使用するImageを作成します。
このライブラリインストールのような、Image作成時(ビルド時)に実行する処理を記載するのが、Dockerfileです。
今回はGit管理された作業用ディレクトリを作成し、その中にスクリプトとDockerfileを格納します。
この方法により、スクリプトとDockerfile(≒環境構築)の構成管理をGitに一元化できます
作業用ディレクトリの作成
今回は
"/opt/python/param_tuning_utility"
フォルダを作業用ディレクトリとして作成し、所有権を操作中のユーザに変更します
sudo mkdir -p /opt/python/param_tuning_utility
sudo chown -R [①で作成したUbuntuユーザ名] /opt/python/param_tuning_utility
※なお、元から存在するparam_tuning_utilityのようなリポジトリをGitHubから取得したい場合、下記コマンドで作業用ディレクトリ内にクローン可能です
sudo mkdir -p /opt/python
cd /opt/python
sudo git clone https://github.com/c60evaporator/param_tuning_utility.git
sudo chown -R [①で作成したUbuntuユーザ名] /opt/python/param_tuning_utility
※注意点として、作業用ディレクトリにWindows上のフォルダをマウントすることも可能ですが、こちらに記載されているようにアクセス速度が遅くなるので、WSL2上のフォルダを作業用ディレクトリとして使用することを推奨します。
Gitリポジトリの作成
下記コマンドで作業用ディレクトリ内にGitリポジトリを作成します
(前の作業でCloneした場合、この作業は不要です)
sudo git init
なお、gitを初めて使う場合メールアドレスとパスワードを求められることがありますが
git config --global user.email "登録したいメールアドレス"
git config --global user.name "登録したい名前"
で登録可能です
Dockerfileの作成
作業用ディレクトリ内にDockerfileを作成します。
以下のように、.devcontainerフォルダを作成し、その下にDockerfileを作成します(.devcontainer.jsonは今は気にせずとも大丈夫です)
作業用フォルダのTop
├── .devcontainer
│ ├── Dockerfile
│ └── devcontainer.json
├── .git
└── 各種Pythonスクリプト
Dockerfileはvimなどを使ってコンソールで編集しても良いですが、こちらの手順でVSCodeで編集することも可能です
Dockerfileの記法に関しては割愛しますが、こちらが分かりやすいです。
今回はシンプルにライブラリインストールのみ行います
# ベースImageの取得
FROM python:3.8-buster
# 必要ライブラリのインストール
RUN pip3 install \
pandas==1.2.0 \
numpy==1.19.3 \
seaborn==0.11.1 \
xgboost==1.3.1 \
scikit-learn==0.24.0 \
bayesian-optimization==1.2.0 \
jupyter==1.0.0 \
mlxtend==0.18.0
ライブラリの管理は仮想環境やrequirement.txtも使用可能ですが、管理をDockerfileに統一するため、今回はそのままpip3(Python3のpip)でインストールします
③-3) buildしてImageを作成
作成したDockerfileをビルドし、コンテナの元となるImageを作成します
ビルドの実行
下記コマンドでビルドを実行します
docker build –t [Image名]:[タグ] --no-cache [Dockerfileを置いたパス]
build時の引数は下記のようになります
引数名 | 内容 |
---|---|
-t | 生成するイメージに名前とタグをつける([Image名]:[タグ]で指定) |
--no-cache | キャッシュ不使用とする。本引数は付加推奨 → キャッシュ使用時は、過去実行したコマンドは無視される(逆に言うと、過去実行したアップデート等が再実行されない恐れがある) |
例(Image名”param_tuning”、タグ”1.0”で、キャッシュ不使用として "/opt/python/param_tuning_utility/.devcontainer"にあるDockerfileをビルド)
docker build -t param_tuning:1.0 --no-cache /opt/python/param_tuning_utility/.devcontainer
※@tfukumoriさんよりコメント頂きましたが、環境によってはbuild時に
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock:
というエラーが発生することがあるようです。
この場合
sudo chmod 666 /var/run/docker.sock
でDockerのソケットにアクセス権限を与えると良いようです。
③-4) runしてコンテナ起動
runコマンドを実行し、Imageからコンテナを作成・起動します
コンテナの作成と起動
下記コマンドでコンテナを作成・起動します
docker run –v [ホスト側作業フォルダ]:[コンテナ側作業フォルダ] --name [コンテナ名] -i -t [Image名]:[タグ] /bin/bash
run時の主な引数は下記のようになります(リファレンス)
引数名 | 内容 |
---|---|
-i | コンテナ起動時に標準入力を受け付ける |
-t | 擬似ターミナル割当 |
-d | コンテナをバックグラウンドで実行する |
-v | マウントを指定(-v [ホスト側のパス]:[コンテナ側のパス]) |
--mount | マウントを指定。volume以外にもbindやtmpfsが指定可能(参考) |
--name | 作成するコンテナに名前を付ける |
例(Image名”param_tuning:1.0”、コンテナ名”pytune”、/opt/python/param_tuning_utilityフォルダをマウントして起動)
docker run -v /opt/python/param_tuning_utility:/opt/python/param_tuning_utility --name pytune -i -t param_tuning:1.0 /bin/bash
④VSCodeからコンテナにアクセス
③で作成したコンテナに、VSCodeからアクセスします。
VSCodeをインストールしていない場合、まずはこちらを参考にインストールしてください
Remote Developmentアドインのインストール
下図の手順で、VSCodeにRemote Development(各種リモートアクセス用アドイン)をインストールします。
VSCodeからWSL2内にアクセス
WSL2のUbuntuコンソールで下記コマンドを打ち、VSCodeを起動すると、WSL2内にリモートアクセスできます
code .
あるいはVSCodeのRemote Explorerタブから"WSL Targets"を選択し、下図手順でリモートアクセスすることも可能です
コンテナを開く
開いたリモートウインドウのRemote Explorerタブから"Containers"を選択し、対象のコンテナを開きます
⑤コンテナ内のスクリプトをデバッグ
本記事のゴールである、コンテナ内スクリプトのデバッグを実行します
Pythonアドインのインストール
Pythonコードをデバッグするためのアドインを、下図の手順でインストールします
なお、Python以外の言語もデバッグのためのアドインが存在するので、必要に応じインストールしてください(下図はPHP)
インタプリタの選択
インタプリタ(デバッグに使用するPythonの場所)の選択が求められるので
③-1で選んだImageのバージョンのPythonを選択します
インタプリタは下図赤枠部分をクリックすれば後から変えられます
作業用フォルダを開く
下図の手順で、作業用フォルダ(スクリプトがあるフォルダ=③-4でマウントしたフォルダ)を開きます
スクリプトを開く
デバッグしたいスクリプトをクリックして開きます
デバッグを開始
下図の手順でデバッグを開始します。
必要に応じてブレークポイントを打つと、途中でデバッグを止めて変数内容を確認できます
デバッグを開始して、ブレークポイントの位置で処理が止まれば成功です!
以上で、Dockerコンテナ上のスクリプトをデバッグできるようになりました!お疲れ様です!
使用感はどうでしょう?とても便利ですよね!(言わせているみたいですが‥笑)
#デバッグ以外にできること
デバッグ以外にも、VSCodeを使ってコンテナ関係の様々な操作を実現できます
Gitでバージョン管理
下図の手順でコンテナ内にGit Graphアドインをインストールすると、GUIでGitによるバージョン管理ができます
非常にキレイかつ直感的なGUIでブランチを管理できるので、Docker関係なしにおすすめのアドインです。
各種コマンドの使用法はこちらを参照してください
VSCodeでWSL2上のスクリプトやDockerfileを編集
④のときと同様に、下図手順でVSCodeからWSL2内にアクセス可能です
下図の"Open Folder"で、編集したいスクリプトやDockerfileがあるフォルダを開きます
対象のスクリプトやDockerfileを開くと、GUIで編集可能となります
VSCode上でコンテナをビルド&RUN
先ほど「今は気にしなくていいです」と言ったdevcontainer.jsonですが、
このファイルを使用すると、GUIでコンテナを作成することができます(docker buildやdocker runコマンドが不要となる)
devcontainer.jsonの作成
VSCodeでDockerコンテナにアクセスする際の設定ファイルである、devcontainer.jsonを作成します。
文法は公式リファレンスやこちらが詳しいので、今回は最低限の構成で作成します
{
//コンテナの表示名
"name": "param_tuning",
//プロジェクトのルート(devcontainer.jsonの2階層上)
"context": "..",
//Dockerfileの名称
"dockerFile": "Dockerfile",
//マウント先
"workspaceMount": "type=bind,source=${localWorkspaceFolder},target=/opt/python/param_tuning_utility"
}
フォルダを開きなおすと、下図のような表示が出てくるので、"Reopen in container"をクリックします
ビルドが終わるまで待ち、完了したら下図の手順で一度フォルダを閉じます
あとは、⑤と同様の手順でデバッグが可能となります