17
25

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.

【Windows10Home】DockerによるPython開発環境の構築

Posted at

Windows 10 Homeで特定バージョンのPython保持しなければならなくなったので、その際やったことを記事にまとめます。
オーソドックスにWSL2でDockerを動かし、コンテナ上にPython環境を構築してみようと思います。

対象読者

開発初心者の方。特にPython。
そもそもWSLって? Dockerって名前は聞いたことあるけど、実際どんなものなの? という方にも(なるべく)理解してもらえる(といいなぁ)よう、頑張ります。

対象マシン

Windows 10 Home
x64システムの場合、バージョン 1903 以降、ビルド 18362 以上が必要です。

そもそも

なぜ特定バージョンのPythonを保持しなければならなくなったのかといえば、そのバージョンでしか(まともに)動かない機械学習Modelを作ってしまったからです。
だからPythonのアップデートはしたくないんだけど、別のModelでは別のバージョンを使いたい……なんてことは、Pythonの開発をやっていると稀によくあります。
pyenvなどでも1つのマシンに異なるバージョンを保持することができますが、Dockerのコンテナにプロジェクトの開発環境をまるっと保持してしまえばよりシンプルに、かつ移植性も高い環境を構築できるため、こちらを採用しました。
(ぶっちゃけpyenvよくわかってない)

でもその前に

ただ、初心者は特にですが、必要性がなければこんなことをする必要もないです。
機械学習といえばGPUだ! Ubuntuだ! となりいきなり壮大な環境構築を頑張ろうとして躓いて嫌になって……。てなるのも悲しいので。
それでもPythonの開発ではライブラリの導入を含めたトライ&エラーが頻発します。
そのたびにインストール&アンインストールを繰り返しているとローカルの開発環境がぐっちゃぐちゃに汚れ、このライブラリどこにパス通ってるんだ……? なんてことにもしばしば。
そうなったら新規一転、開発環境を仮想化してしまうのも手です。

あとは自然言語処理でMeCab使いたいけど、Windowsだと文字コードでバグりまくる……という場合も、簡単にLinux系の環境を用意できるのも利点ですね。
開発初心者の方はこんな風に、必要に迫られた段階でステップアップとして取り組むと良いと思います。

用語

何となく仮想環境を構築したい理由はわかったよ。じゃあWSLって? Dockerって? という方に。

  • Dockerとは
    仮想化技術の一つです。
    非常に手軽にWEBサーバーやAPサーバー、DBサーバーをデプロイできることからWEB開発の現場では広く使われている(らしい)技術です。おれWEB畑じゃないからね。
    Hyper-VやVirtualBoxと何が違うの? と思われる方がいるかもしれませんが、これらは物理マシンのネットワークスイッチなどをエミュレートできるのに対し、DockerではベースとなるOSと完全に分離せず、OSのカーネル上にコンテナを配置する形をとります。
    (前者をホスト型仮想化、後者をコンテナ型仮想化といいます)
    例えばHyper-Vではホストとは異なるOSを積んだり、個別にネットワークアダプタを割り当てることが可能ですが、それらの点でいうとDockerは劣ります。
    なのになぜDockerを使うのかと言われれば、やはりその軽量さ、手軽さが大きな理由でしょうか。
    DockerではOS上にほかのプロセスと切り離された環境にコンテナを作るので、仮想環境の動作をホスト型仮想化よりも少ないリソースで実現できるのです。

  • WSL(2)とは
    Windows Subsystem for Linuxの略で、そのまんま、Windows上でLinuxを動かすための技術です。
    じゃあやっぱHyper-Vでいいじゃん! って感じですが、Windows 10 HomeじゃHyper-V使えないし、さらにいうとHyper-Vより少ないリソースでLinuxを動かすことができて、んでもって動作も軽量軽快。
    個人的に一番違いを感じるのは起動ですね。
    また今回はDocker Desktop for Winodwsという製品を使いたいのですが、本来こちらはHyper-Vの仮想化とネットワークを利用します。
    前述の通りHomeではHyper-Vが使えないのですが、WSL2にUbuntuをインストールすることで、Docker Desktop for Windowsのバックエンドとして機能させることができるのです。

要はWSL2でUbuntuを動かして、そこにDockerをインストールするってことですね。

環境のイメージ

以上を踏まえ、今回はこんなイメージの環境を構築してみたいと思います。
やっと図が出てきた。

環境のイメージ.png

ホストのWindowsでWSL2を起動し、そこでUbuntuを動かします。UbuntuやDockerの制御はPowerShell等からでもできるのですが、今回はWindows Terminalからコントロールします。
そのUbuntu上にDocker(Docker Desktop for Windows)を導入。
Docker上にコンテナを配置し、それらを開発環境として利用します。
今回はAnacondaのDockerイメージをDockerHubから引っ張ってきます。DockerHubってのはDockerのコンテナを公開できる、GitHubみたいなもんだね。
んでAnacondaのコンテナでJupyter Labを動かし、Windowsのブラウザから操作したりプロジェクトをVS Codeでいじくったりできるようになろうってのが今回の目標です。

ちょっと注意

ここまで言っておいて水差すつもりはないんですけど、製品版のWindowsではWSL2をバックエンドとしたDockerコンテナではGPUを使えません。
(2021年3月19日現在)
Insider Previewならできるのですが、そちらは自己責任となりますのでご注意を。
自分はGPUを使うプロジェクトに関してはローカルでやりくりしています。

WSL2のインストール

やぁ、前置きがウルトラ長くなってしまった。
まずはWSL2のインストールからはじめましょ。
公式ドキュメント:https://docs.microsoft.com/ja-jp/windows/wsl/install-win10

コマンドラインからのインストールは現在(2021/3/19)プレビュー版でしか利用できないようです。

PowerShellの起動

Windowsの検索機能で「PoweShell」と入力します。表示されたアイコンを右クリックし、「管理者として実行」を選んでください。
02_PowerShellの起動.png

Linux用Windowsサブシステム、仮想マシンの機能の有効化

起動したPowerShellから下記のコマンドを入力し、必要な機能を有効化します。
Linux用Windowsサブシステム

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

仮想マシンの機能

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

どちらもすぐに処理は完了すると思います。

Linuxカーネル更新プログラムパッケージのダウンロード

以下のリンクからLinuxカーネル更新プログラムパッケージをダウンロードします。
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

ダウンロードしたパッケージをダブルクリックし、インストールします。
手順に従って進み、以下の画面となればOKです。
スクリーンショット 2021-03-22 102422.png

WSL2を既定のバージョンとして設定

再度管理者としてPowerShellを開いて、次のコマンドを実行します。

wsl --set-default-version 2

新たにLinux系OSをインストールする際に使用するWSLの規定バージョンを2に指定しています。

これでひとまずWSL2の準備は完了。

Ubuntuのインストール

続いてはWSL2に乗っけるOS(Linuxディストリビューション)をインストールします。
WSL2ではDebian GNU/Linuxなどのディストリビューションも利用可能とのことですが、今回は機械学習の開発環境を構築することが目的なのでよく使われるUbuntuを使うことにします。
バージョンは16.04 LTS / 18.04 LTS / 20.04 LTSから選びます。
自分は20.04 LTSをインストールしますが、それ以外のバージョンでも手順は同じ(はず)です。

Microsoft StoreからUbuntuをダウンロード

スタートメニューから「Microsoft Store」を開き、検索窓に「Ubuntsu」と入力します。
(MSのアカウントでサインインしていなくてもDLできました)
004.png

画面右上の「インストール」ボタンをクリックします。
05.png

Ubuntuの起動

インストールが完了すると「インストール」のボタンが「起動」に変わっているので、クリックしてUbuntuを起動します。
06.png

Ubuntuを起動すると初期化が行われ、続いてユーザー名とパスワードの入力が求められます。
ご自身のものを入力してください。

あとちなみにスタートメニューに「Ubuntu 20.04 LTS」が追加されていると思います。
08.png

起動状況の確認

念のためPowerShellからUbuntuの起動状況を確認しましょう。
(別に管理者権限で開かなくてもいいです)
以下のコマンドを実行してください。

wsl --list --verbose

これはWSLにインストールされているLinuxディストリビューションの一覧と起動状況、使用するWSLのバージョンを表示するコマンドです。

09.png
Ubuntu-20.04がVERSION「2」としてインストールされていますね。
大丈夫そうです。

Windows Terminalのインストール(おまけ)

これはオプションなので別にやらなくてもいいんですけど、自分はUbuntuの操作はWindows Terminalから行っています(結構使いやすい)。
Windows TerminalもMicrosoft Storeからインストールできますできます。
(検索窓に「Windows Terminal」と入力してください)
10.png

用途としてはUbuntuの制御がメインなので、起動時にUbuntuのシェルが立ち上がるよう規定値を変更します。
タブの「▽」をクリックし、「設定」を選択してください。
11.png

「Setting.json」というjsonファイルが開かれます。
上のほうに「defaultProfile」という項目があります。
ここに起動時に立ち上げたいシェルのguidを入力することで規定値を変更することができます。
12.png

少しスクロールすると「profiles」→「list」というところに各シェルの情報が格納されているのがわかります。
Ubuntuがインストールされていれば「"name": "Ubuntu-20.04"」の項目があるはずなので、そのguidをコピーし、先ほどのdefaultProfileの値に貼り付けます。
13.png

これでWindows Terminalを起動するとデフォルトでUbuntuのシェルが立ち上がるようになりました。
14.png

Docker Desktop for Windowsのインストール

バックエンド環境が準備できたところで、Dockerをインストールしましょう。
公式ドキュメント:https://docs.docker.jp/docker-for-windows/install.html

インストーラーのダウンロード

インストーラーはDocker Hubからダウンロードできます。
https://hub.docker.com/editions/community/docker-ce-desktop-windows/

「Get Docker」をクリックするとダウンロードが始まります。
特にSign upしなくてもDLできます。

インストール

ダウンロードしたインストーラーをダブルクリックして起動します。
「Install required Windows Components for WSL 2」にチェックし、「OK」をクリックします。
16.png

完了です。
17.png

試しにDockerを起動してみましょう。
もちろん空っぽです。
このあとコンテナ入れるので、チュートリアルはスキップして良いです。
18.png

Dockerディスク領域の変更(オプション)

Docker Desktopをインストールすると問答無用でシステムドライブに仮想環境が作られます。
↑の手順でもマウントするパスの指定とかなかったしね。
コンテナを立てていくとCドライブの容量を圧迫してしまうので、データドライブに領域を移します。

なおWSLのインストール一覧は下記のコマンドで確認することができます。

wsl --list

Windows Terminalでの実行結果です。このとき接続先のシェルはPowerShellにしてください。
(先の手順でデフォルトがUbuntuになっているので)
領域を移したいのはこの「docker-desktop-data」ってやつです。
19.png

ちなみに上記のイメージの実態は %LocalAppData%\Docker\wsl\distro\ext4.vhdx というものです。
エクスプローラーで %LocalAppData%\Docker\wsl\distro と入力すると、 ext4.vhdx というファイルがあります。
(多分デフォルトだと C:\Users\(ユーザー名)\AppData\Local\Docker\wsl\distro とかじゃないかな)
あ、ちなみに vhdx は VirtualHardDisk って意味ね。

Docker / WSLの停止

まずはDocker Desktopを停止します。
タスクバーの「△」を選択し、Dockerのクジラみたいなアイコンを右クリックすると操作一覧が表示されるので「Quit Docker Desktop」を選択します。
20.png

続いてPowerShellで下記のコマンドを実行します。

wsl --shutdown

念のため起動状況を確認します。

wsl --list --verbose

STATEがすべて「Stopped」になっていればOKです。
21.png

データのエクスポート

docker-desktop-data の移動先のフォルダを作っておきます。
データドライブに D:\01_Docker というフォルダを予めつくっておきました。フォルダ名は気にしないでください。

下記のコマンドで、上記フォルダの中に docker-desktop-data.tar というファイルをエクスポートします。

wsl --export docker-desktop-data  D:\01_Docker\docker-desktop-data.tar

コンテナは空っぽの状態なんで、すぐに終わります。

docker-desktop-dataの登録の解除

WSLにおけるdocker-desktop-dataの登録を解除します。

wsl --unregister docker-desktop-data

.tarファイルのインポート

上記でデータドライブにエクスポートしておいた.tarファイルをインポートします。
D:\01_Docker フォルダの直下に data フォルダを作成します。
下記のコマンドを実行し、 D:\01_Docker\docker-desktop-data.tar ファイルを D:\01_Docker\data フォルダにインポートします。

> wsl --import docker-desktop-data D:\01_Docker\data D:\01_Docker\docker-desktop-data.tar

D:\01_Docker\data フォルダに ext4.vhdx が作成されています。
22.png

WSL / Dockerの起動

WSLとDockerを起動しましょう。
WSLはPowerShellで wsl と入力すれば起動します。
DockerはアイコンをクリックすればOK。

Dockerコンテナの作成

ちょっと話が脇道にズレてしまいましたが、いよいよ最終目的である仮想開発環境を構築しましょう!
冒頭のイメージ図でもふれたとおり、今回はDocker HubからAnacondaのコンテナをダウンロードします。

作業フォルダの準備~Dockerfileの作成

Dockerではコンテナを作るときに Dockerfile というファイルを作成し、そこにどんな構成のコンテナとするか~といった情報をコードとして記述します。
コンテナを立ち上げる時にDockerがこのファイルを参考にセットアップしてくれるんですね。

まずはそのコンテナにおける作業フォルダを作成します。
本格的な運用をする場合には1プロジェクトにつき1コンテナとすることが多いので、コンテナ名=プロジェクト名するのが分かりやすいでしょう。
今回は D:\Project\202103_TestProject というフォルダを作成しました。
ここでは半角英数にしておいたほうが賢明です。
特に スペースは全角半角問わずやめておいたほうが良いでしょう。

作成したフォルダの直下で右クリック→新規作成→テキストドキュメントを選択します。
01.png

作成したファイル名を「Dockerfile」に変更します。
このとき、 「.txt」の拡張子を削除します。
Dockerfileに拡張子はないのです。
03.png

警告が出ても無視してください。
02.png

Dockerfileの記述

作成したDockerfileに「どんなコンテナを作るのか」という情報を記述していきます。
DOckerfileを選択し右クリック→プログラムから開くを選び、好きなテキストエディタから編集してください。

今回は次のような命令を記述していきます。

FROM continuumio/anaconda3:2019.03

RUN pip install --upgrade pip && pip install Keras && pip install tensorflow

WORKDIR /workdir

EXPOSR 8888

ENTRYPOINT ["jupyter-lab", "--ip=0.0.0.0", "--port=8888", "--no-browzer", "--allow-root", "--NotebookApp.token=''"]

CMD ["--notebook-dir=/workdir"]

一つ一つ見ていきましょう。

FROM continuumio/anaconda3:2019.03

ここでDocker Hubから「2019.03時点のAnaconda3を引っ張って来いよ」と明示しています。

RUN pip install --upgrade pip && pip install Keras && pip install tensorflow

その後実行するコードです。
イメージとしてはcmdから実行すべきコマンドを記述している感じ。

WORKDIR /workdir

命令を実行するときのカレントディレクトリを指定します。
上記によりコンテナに/workdirが作成され、各種命令はこの中で実行されることになります。

EXPOSE 8888

ネットワーク上のポートを指定します。

ENTRYPOINT ["jupyter-lab", "--ip=0.0.0.0", "--port=8888", "--no-browzer", "--allow-root", "--NotebookApp.token=''"]

実行対象に関する設定です。
今回はコンテナ上で起動するJupyter LabをホストのWindowsから利用したいのでそれに関する設定を行っています。
ローカルで完結する環境を想定しているためトークン認証は無効としていますが("--NotebookApp.token=''")、例えばクラウドで立ち上げる等であれば設定が必要でしょう。

CMD ["--notebook-dir=/workdir"]

最後にJupyter labの作業ディレクトリを先ほど作成した/workdirに紐づけます。

以上で命令の記述は完了です!
保存してエディタを閉じます。

docker-compose.ymlファイルの作成

次にアプリケーションを構成するサービスを「Docker-compose.yml」というファイルに記述します。
今回はDockerの起動にはDocker Composeというツールを使用します。
これは複数コンテナを定義し、実行するDockerアプリケーションを管理するためのツールです。

YAMLというファイルにアプリケーションの各サービスの設定を記述することによって、Docker起動時にYAMLファイルを呼び出すだけで簡単にコンテナの生成、起動を行うことができます。

先ほど作成したDockerfileと同じディレクトリに、docker-compose.ymlというファイルを作成してください。

そこに以下のように記述します。

services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile
    image:project01
    ports:
    - "8080:8888"
    volumes:
    - .:/workdir

imageにはご自身のプロジェクト名を入力してください。
また起動対象となるDockerfileもbuild内で指定します。そのためdocker-compose.ymlとDockerfileは同じディレクトリにないといけませんので、注意。
Dockerfileと同じくvolumesには作業ディレクトリとして/workdirを指定しましょう。

ちなみに今回は割愛しますが、docker-compose.ymlファイルを使用しなくとも、シェルからdocker runというコマンドを実行しても起動できますよ。

コンテナの起動

これでコンテナを起動する準備ができました。
Powershellを起動し、カレントディレクトリをDockerfile、docker-icompose.ymlが置かれたフォルダに移動します。

cd D:\Project\202103_TestProject

続いて下記のコマンドを実行します。

docker-compose up

Jupyter Labの起動

WindowsからコンテナのJupyter Labに接続しましょう。
コンテナが起動した状態で任意のブラウザを起動し、localhost:8080と入力してください。
Jupyter Labが起動すれば成功です!
スクリーンショット 2021-03-29 173410.png

Jupyterのナビゲーターを見ればわかる通り、JupyterのカレントディレクトリはそのままDockerfile、docker-compose.ymlが置かれたフォルダとなっています。
このフォルダの中身をコンテナは認識してくれますので、試しにこの直下に「01_Input」「02_Source」「03_Model」「04_Output」というフォルダを作成してみます。
スクリーンショット 2021-03-29 173513.png

Jupyterでも反映されていますね。
スクリーンショット 2021-03-29 173540.png

今度は逆にJupyter LabからPythonのNotebookを作ってみましょう。
「02_Source」に入り、Python Notebookを作成します。
スクリーンショット 2021-03-29 173600.png

Windows側のエクスプローラーから「02_Source」の中を見ると、作成した.ipynbファイル(とチェックポイント)があることが分かります。
スクリーンショット 2021-03-29 173621.png

これで無事WindowsとDockerコンテナの同期が取れていることが確認できました!

お疲れ様です、全作業完了です!
あとはもう、イカしたModelを作りまくって世の中に貢献しちゃってください。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?