LoginSignup
134
156

More than 1 year has passed since last update.

VSCodeでWSL2上のDockerコンテナ内コードをデバッグ

Last updated at Posted at 2021-01-30

はじめに

最近、以下のツールの名前を良く聞くかと思います

・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上のスクリプトを編集しているような感覚で開発を進められます。

特に**「コンテナ上のスクリプトをデバッグできる」**ことは、開発効率化の上で大きなメリットとなります。
本記事ではブレークポイントを打ったデバッグ可能な開発環境をゴールに、構築法を紹介します。

開発時の構成

「メリットは分かったので、どうやって実現するんだ?」と思われる方も多いかと思います。

私の場合、下図のような構成で開発をしています。
image.png

ポイントは、
・ローカル側では、Windows OS上にWSL2を通じてLinux環境が乗り、その上にDockerコンテナが乗る
・構成管理をGitリポジトリに統一(Dockerfileを通じて環境+スクリプト両方を管理)
の2点です。

構成管理に関しては他のやり方(例:DockerHubを環境の構成管理に活用)もありますが、
Gitリポジトリへの統一が、管理をシンプルにする観点からおススメです

本番環境へのデプロイ時は、下図⑤、⑥のように、Gitリポジトリ上のスクリプト&Dockerfileを起点として、プログラムや環境を更新します
※画像はこちらの記事より引用させて頂きました
image.png

手順

WSL2+Docker+VSCodeによる開発環境構築を、下図の手順で進めていきます。
image.png

①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 カーネル更新プログラムをダウンロードし、実行します。成功すれば以下のような画面が出ます
image.png

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です
image.png
※なお、ここでインストールするディストリビューションはWSL2用であり、本番環境で使用するディストリビューション(③-1でDockerコンテナ内にインストール)とは異なる事にご注意ください

Ubuntuコンソールの起動
スタートメニューにディストリビューションのショートカットができているので、クリックします
image.png

ユーザ名とパスワードの入力
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を起動します。
最初はチュートリアルが表示されるので、指示通り進めて以下のような画面が表示されれば完了です。
(チュートリアル用のコンテナは削除して問題ありません)
image.png
設定で、"Use the WSL2 based engine"がチェックされていることを確認します
image.png

Docker Hubの登録
Docker Hubとは、Dockerイメージ(後述)をアップロードするためのクラウド型リポジトリサービスです。
今回はアップロードではなく、③でコンテナ作成時のベースとなるイメージ取得に利用します。

こちらのDocker Hubサイトに飛んで、下図赤枠の登録フォームから指示に従い登録します。
image.png

③Dockerコンテナ作成と環境構築

下図のような手順でDockerコンテナ作成を進めていきます。
image.png
手動構築とDockerfileによる自動構築の2種類がありますが、
自動化による再現性確保の観点から、今回は図中右側のDockerfileを使用します

③-1) ベースとなるImageをDockerHubで検索

OS(Linuxディストリビューション)や基本アプリケーションがインストールされた、ベースとなるImageをDockerHubから取得します。
少し紛らわしいですが、上記フロー図中Imageの、さらにベースとなるImageを探す作業となります。

今回はDebian10+PythonがインストールされたImageを探してみます

Docker Hubのpython関係サイトへのアクセス
先ほど登録したDocker Hubサイトにログインし、下図の"python"部分をクリックします
image.png

該当するタグの検索
下の方にスクロールすると、"3.9.1-buster"などと書かれたタグがたくさんあります。これは
 ・"3.9.1"の部分が、Pythonのバージョンを表す
 ・"buster"の部分が、OSの種類を表す
となります。
image.png

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を格納します。
image.png
この方法により、スクリプトと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の記法に関しては割愛しますが、こちらが分かりやすいです。
今回はシンプルにライブラリインストールのみ行います

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(各種リモートアクセス用アドイン)をインストールします。
image.png

VSCodeからWSL2内にアクセス
WSL2のUbuntuコンソールで下記コマンドを打ち、VSCodeを起動すると、WSL2内にリモートアクセスできます

code .

あるいはVSCodeのRemote Explorerタブから"WSL Targets"を選択し、下図手順でリモートアクセスすることも可能です
image.png

コンテナを開く
開いたリモートウインドウのRemote Explorerタブから"Containers"を選択し、対象のコンテナを開きます
image.png

⑤コンテナ内のスクリプトをデバッグ

本記事のゴールである、コンテナ内スクリプトのデバッグを実行します

Pythonアドインのインストール
Pythonコードをデバッグするためのアドインを、下図の手順でインストールします
image.png
なお、Python以外の言語もデバッグのためのアドインが存在するので、必要に応じインストールしてください(下図はPHP)
image.png

インタプリタの選択
インタプリタ(デバッグに使用するPythonの場所)の選択が求められるので
image.png
③-1で選んだImageのバージョンのPythonを選択します
image.png
インタプリタは下図赤枠部分をクリックすれば後から変えられます
image.png

作業用フォルダを開く
下図の手順で、作業用フォルダ(スクリプトがあるフォルダ=③-4でマウントしたフォルダ)を開きます
image.png

スクリプトを開く
デバッグしたいスクリプトをクリックして開きます
image.png

デバッグを開始
下図の手順でデバッグを開始します。
必要に応じてブレークポイントを打つと、途中でデバッグを止めて変数内容を確認できます
image.png
デバッグを開始して、ブレークポイントの位置で処理が止まれば成功です!
image.png

以上で、Dockerコンテナ上のスクリプトをデバッグできるようになりました!お疲れ様です!
使用感はどうでしょう?とても便利ですよね!(言わせているみたいですが‥笑)

#デバッグ以外にできること
デバッグ以外にも、VSCodeを使ってコンテナ関係の様々な操作を実現できます

Gitでバージョン管理

下図の手順でコンテナ内にGit Graphアドインをインストールすると、GUIでGitによるバージョン管理ができます
image.png
非常にキレイかつ直感的なGUIでブランチを管理できるので、Docker関係なしにおすすめのアドインです。
各種コマンドの使用法はこちらを参照してください
gitgraph_mini.png

VSCodeでWSL2上のスクリプトやDockerfileを編集

④のときと同様に、下図手順でVSCodeからWSL2内にアクセス可能です
image.png

下図の"Open Folder"で、編集したいスクリプトやDockerfileがあるフォルダを開きます
image.png

対象のスクリプトやDockerfileを開くと、GUIで編集可能となります
image.png

VSCode上でコンテナをビルド&RUN

先ほど「今は気にしなくていいです」と言ったdevcontainer.jsonですが、
このファイルを使用すると、GUIでコンテナを作成することができます(docker buildやdocker runコマンドが不要となる)

devcontainer.jsonの作成
VSCodeでDockerコンテナにアクセスする際の設定ファイルである、devcontainer.jsonを作成します。
文法は公式リファレンスこちらが詳しいので、今回は最低限の構成で作成します

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"をクリックします
image.png

ビルドが終わるまで待ち、完了したら下図の手順で一度フォルダを閉じます
image.png

あとは、⑤と同様の手順でデバッグが可能となります

134
156
5

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
134
156