├── Dockerfile ├── README.md ├── docker-compose.yml └── opt └── sample.py /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3 2 | USER root 3 | 4 | RUN apt-get update 5 | RUN apt-get -y install locales && \ 6 | localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 7 | ENV LANG ja_JP.UTF-8 8 | ENV LANGUAGE ja_JP:ja 9 | ENV LC_ALL ja_JP.UTF-8 10 | ENV TZ JST-9 11 | ENV TERM xterm 12 | 13 | RUN apt-get install -y vim less 14 | RUN pip install --upgrade pip 15 | RUN pip install --upgrade setuptools 16 | 17 | RUN python -m pip install jupyterlab 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DockerでPython実行環境を作ってみる 2 | 3 | 使っているパソコンを変えても、開発環境を揃えたい時はDockerを使うと便利。ということでDockerでPython環境を作って色々なところで使いまわせるようにします。 4 | 5 | ## Dockerとは 6 | 7 | Dockerとはシステム開発や運用に最近よく使われるコンテナ技術を提供するサービスの一つです。コンテナとは、アプリケーションの実行に必要な環境をパッケージ化して、いつでもどこからでも実行するための仕組みです。自分のコンピュータの環境を汚すことなく、隔離された環境を作ってそこでプログラムを動かすことができるのでトライアンドエラーも簡単で、その作った環境はシェアすることでどこでも実行できるという点がメリットです。個人的に、M1 Macに最近したのですが、その独自な仕様により今までのIntel Macで使えていたPythonモジュールが使えなくなったりということがあったので、Dockerのコンテナ内でなら過去のプログラムも実行できることがわかり、必要に駆られてこれを使ってみることにしました。 8 | 9 | 10 | ## Step 1. Dockerのインストール 11 | 12 | 環境に合ったDockerをインストールします。ここではDocker Desktopを利用することを想定します。M1用のインストーラーもあります。インストール後はTerminalなどでdocker composeコマンドが使えるようになっていることを確認します。 13 | 14 | 15 | 16 | インストールしたらDocker Desktopを起動してください。 17 | 18 | 19 | ## Step 2. Dockerの設定 20 | 21 | ### ファイル構成 22 | 23 | 次のようなファイル構成をまず作ってください。docker-pythonと書いてあるフォルダ名は好きな名前にして大丈夫です。Dockerfileとdocker-compose.ymlとsample.pyはテキストデータです。 24 | 25 | ``` 26 | docker-python/ 27 | ├ Dockerfile 28 | ├ docker-compose.yml 29 | └ opt/ 30 | └ sample.py 31 | 32 | ``` 33 | 34 | ### Dockerfile 35 | 36 | Dockerfileに次のように記述します。ここでは利用する開発環境を指定し、コンテナ作成時に先にインストールしておきたいOS用のライブラリや、今回のようにPythonを使いたい場合は使いたいPythonのモジュールなどをインストールします。 37 | 38 | ちなみにDockerfileで指定せず、後から自分で追加でインストールすることも可能です。ただ、作られたコンテナを削除して、再度作り直す場合はDockerfileを再度使ってライブラリ等をインストールするので、コンテナを作成するたびに欲しいライブラリ等はここで指定しておくのがいいと思います。 39 | 40 | 最初の行でFROM python:3とあるのは、Dockerが公式で用意しているPythonのコンテナをベースとして読み込んでいるということになります。詳しくは[こちら](https://hub.docker.com/_/python)から。デフォルトで使われる環境はLinuxのDebianのようです。 41 | 42 | 43 | ```docker 44 | FROM python:3 45 | USER root 46 | 47 | RUN apt-get update 48 | RUN apt-get -y install locales && \ 49 | localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 50 | ENV LANG ja_JP.UTF-8 51 | ENV LANGUAGE ja_JP:ja 52 | ENV LC_ALL ja_JP.UTF-8 53 | ENV TZ JST-9 54 | ENV TERM xterm 55 | 56 | RUN apt-get install -y vim less 57 | RUN pip install --upgrade pip 58 | RUN pip install --upgrade setuptools 59 | 60 | RUN python -m pip install jupyterlab 61 | ``` 62 | 63 | この時点で使いたいPythonのモジュールが既に決まっていれば、`RUN python -m pip install requests`のようにモジュールのインストールコマンドを追記していきます。 64 | 65 | 66 | ### docker-compose.yml 67 | 68 | 次にdocker-compose.ymlの中身を書きます。ここでは作成するコンテナの情報を書いていきます。バージョンやコンテナの名前を好きに決めます。working_dirというのはコンテナの中に入った直後の作業フォルダのことで、volumesは自分のコンピュータのどのフォルダとコンテナの中の環境のフォルダと同期するための設定です。ここでは、先に作ったoptという名前のフォルダが、コンテナ上のroot/optフォルダと同期されます。これにより、自分のコンピュータで作ったデータをコンテナ上の環境で読むことができるようになります。 69 | 70 | ```yaml 71 | version: '3' 72 | services: 73 | python3: 74 | restart: always 75 | build: . 76 | container_name: 'python3' 77 | working_dir: '/root/' 78 | tty: true 79 | volumes: 80 | - ./opt:/root/opt 81 | ``` 82 | 83 | ### sample.py 84 | 85 | このファイルには実行したいPythonのプログラムを記述します。 86 | テスト用のものなので、簡単なコードを書いておきます。このPythonファイルを実行する時に、一緒の渡される引数(argument)をdegreesからradiansに変更してターミナルにプリントする簡単な内容です。 87 | 88 | ```python 89 | import math 90 | import sys 91 | 92 | def main(): 93 | val = float(sys.argv[1]) 94 | print(math.radians(val)) 95 | 96 | if __name__ == "__main__": 97 | main() 98 | ``` 99 | 100 | ## Step 3. Dockerイメージの作成、コンテナのビルド、そしてコンテナの起動 101 | 102 | ターミナル(Mac)かGit bashやPowerShell(Win)で次のようにコマンドを打ち、docker-pythonフォルダを作業フォルダにした上でDockerイメージ(仮想環境のテンプレート)の作成し、そのイメージを利用してDockerのコンテナ(テンプレートを利用して作られ実際に実行される仮想環境が入った入れもの)を起動します。Dockerfileとdocker-compose.ymlを自動的に参照しDockerのイメージが作成されます。 103 | 104 | このコマンドによりイメージ作成→コンテナ作成→コンテナ起動となりますが現状はまだコンテナの環境はバックグラウンドで走っている状態です。 105 | 106 | ```bash 107 | $ cd docker-python/ 108 | $ docker compose up -d --build 109 | ``` 110 | 111 | ## Step 4. 作られたイメージとコンテナの確認 112 | 113 | では実際に作られたDockerイメージとコンテナをかくにんしてみます。次のコマンドを打ち、まず現在自分の環境で利用できるイメージのリストを取得します。 114 | 115 | ```bash 116 | $ docker image ls 117 | ``` 118 | 119 | 次のようなメッセージが出ていたら成功です。ここではdocker-python_python3というのが今作ったDockerのイメージの名前となります。コンテナを作るためのテンプレートの名前、みたいに覚えるとわかりやすいかもしれません。 120 | 121 | ```bash 122 | REPOSITORY TAG IMAGE ID CREATED SIZE 123 | docker-python_python3 latest fdca699ff626 13 days ago 1.14GB 124 | ``` 125 | 126 | 次に次のコマンドをうち、現在走っているコンテナのリストを取得します。 127 | 128 | ```bash 129 | $ docker container ls 130 | ``` 131 | 132 | 次のようなメッセージが出てくるかと思います。 133 | 134 | ```bash 135 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 136 | 05a6dee0f4d0 fdca699ff626 "python3" 45 minutes ago Up 45 minutes python3 137 | ``` 138 | 139 | 140 | ## Step 5. コンテナへの接続 141 | 142 | コンテナが走っていることを確認したところで、次のコマンドでコンテナへ接続(コンテナの中の環境に入ってその環境下でコマンドを打てるように)します。python3というのはdocker-compose.ymlで指定したコンテナの名前です。 143 | 144 | ```bash 145 | $ docker compose exec python3 bash 146 | ``` 147 | 148 | これで次からターミナルで打つコマンドはコンテナ内の環境下で実行されるようになります。 149 | 150 | 151 | ## Step 6. Python用のライブラリをインストールする 152 | 153 | 154 | コンテナに接続できたら、まずPythonのバージョンを確認してみます。 155 | 156 | ```bash 157 | $ python --version 158 | ``` 159 | 160 | もし使いたいPythonのモジュールがあればこの時点でインストールしておきます。コンテナ作成時にインストールされている状態にしたければ、Dockerfileにそのインストール用のコマンドを追記しておいてください。コンテナに接続してからインストールされたモジュールは、コンテナとの接続を切り、コンテナを削除した時点で消えるのでテンポラリーなものだと思ってください。 161 | 162 | 個人的におすすめな方法としては、一度テンポラリーにモジュールをインストールして使ってみて、問題なければDockerfileに追記してコンテナ作成時にモジュールが自動インストールされるようにするという流れがいいと思います。 163 | 164 | ```bash 165 | $ python -m pip install numpy 166 | ``` 167 | 168 | ## Step 7. 自分のコンピュータ上のPythonファイルを走らせてみる 169 | 170 | これでPythonの実行環境が作れたので、実際に使ってみましょう。その方法のひとつとして、自分のコンピュータ上にPythonで記述されたテキストファイル(.pyファイル)を作って、それをコンテナ内の環境のPythonで実行しようというものです。 171 | 172 | まずdocker-pythonフォルダのoptフォルダにsample.pyがあることを確認した上で、Dockerのコンテナに接続されている状態で次のコマンドを打ち、現在の作業ディレクトリにあるファイルの一覧を取得します。 173 | 174 | ```bash 175 | $ ls 176 | ``` 177 | 178 | するとsample.pyというファイルが一覧に出てくると思います。これで、自分のコンピュータ上のoptというフォルダと、コンテナ内の環境上のフォルダが同期されていることが確認できたことになります。このフォルダを介してコンテナ内の環境から自分のパソコンのファイルにアクセスができるようになるという寸法です。 179 | 180 | ファイルの存在が確認できたところで、コンテナ内の環境にインストールされたPythonでoptフォルダの中のこのPythonファイルを走らせてみましょう。 181 | 182 | ```bash 183 | $ python sample.py 180.0 184 | ``` 185 | 186 | 結果として3.141592653589793のように円周率の値が出てきたら成功です。 187 | 188 | 189 | ## Step 8. コンテナの削除 190 | 191 | コンテナを使い終わったらコンテナとの接続を切り、いらなくなったコンテナを削除します。まず次のコマンドでコンテナとの接続を切ります。 192 | 193 | ```bash 194 | $ exit 195 | ``` 196 | 197 | その上で次のコマンドでDockerのコンテナを終了し、削除します。 198 | 199 | ```bash 200 | $ docker compose down 201 | ``` 202 | 203 | 次のようなメッセージが出ると思います。 204 | 205 | ```bash 206 | [+] Running 2/2 207 | ⠿ Container python3 Removed 10.4s 208 | ⠿ Network docker-python_default Removed 209 | ``` 210 | 211 | この後に次のようにコマンドを打ち、コンテナのリストから作ったコンテナが消えていたら無事削除できたことになります。 212 | 213 | ```bash 214 | $ docker container ls 215 | ``` 216 | 217 | ## Step 9. 再度コンテナを起動したい場合は 218 | 219 | コンテナはテンプレートであるイメージの中身をコピーして作られるインスタンスのようなものなので、再度コンテナを起動したい場合はStep 3でやったように再度イメージを作り直してそのイメージからコンテナを作成して起動します。あるいはすでにDockerfileとdocker-compose.ymlでイメージを作ってある場合は、--buildオプションを外して次のようなコマンドを入力してすでに作られているDockerイメージからコンテナを作成して起動することができます。 220 | 221 | ```bash 222 | $ docker compose up -d 223 | ``` 224 | 225 | 226 | ## Step 10. いらないイメージの削除 227 | 228 | もしビルドしたイメージもいらな場合は削除します。そのために、先にイメージのリストを取得します。 229 | 230 | ```bash 231 | $ docker image ls 232 | ``` 233 | 234 | 次のようなコマンドでIDを指定して、いらないイメージを削除します。*imageid*には自分のイメージのIDに対応するものをいれてください。 235 | 236 | ```bash 237 | $ docker image rm imageid 238 | ``` 239 | 240 | 241 | ## Step 11. Jupyter Notebookでウェブブラウザ経由でPythonを使ってみる 242 | 243 | Pythonのコードをテストしたい時、特に科学計算などにおいては時にJupyter Notebookのようなブラウザ経由でインタラクティブにPythonコードを走らせることができるツールを使いたいことがあるかもしれません。そのためのステップも載せておきます。ちなみに先に書いたDockerfileにはすでにjupyternotebookがインストールされるようなコマンドが書かれています。 244 | 245 | 先に、Dockerのイメージを削除した場合はイメージを作り直します。ただ今回はコンテナの中に入らず、自分のコンピュータのブラウザからコンテナ内の環境にアクセスすることになるので、次のようなコマンドを使ってイメージだけ作成します。その時ターミナルでは、コマンド入力先が自分のコンピュータ上の作業フォルダになっていることを確認しておいてください。 246 | 247 | ```bash 248 | $ docker compose build 249 | ``` 250 | 251 | これで次のコマンドを入力してイメージがリストアップされていればOKです。 252 | 253 | ```bash 254 | $ docker image ls 255 | ``` 256 | 257 | イメージがあることが確認できたら、次のコマンドでイメージから一時的にコンテナを起動し、起動直後にJupyter Notebookを利用するた目のサーバーをコンテナ内の環境下で立ち上げます。ちなみに$PWDというのはコマンドを入力しようとしているターミナルで現在の作業フォルダの場所を示しています。 258 | 259 | ```bash 260 | $ docker run -v $PWD/opt:/root/opt -w /root/opt -it --rm -p 7777:8888 docker-python_python3 jupyter-lab --ip 0.0.0.0 --allow-root -b localhost 261 | ``` 262 | 263 | すると成功すれば次のようなメッセージが出ると思います。 264 | 265 | ```bash 266 | To access the server, open this file in a browser: 267 | file:///root/.local/share/jupyter/runtime/jpserver-1-open.html 268 | Or copy and paste one of these URLs: 269 | http://46102976db71:8888/lab?token=xxxxxxxxxx 270 | http://127.0.0.1:8888/lab?token=xxxxxxxxxx 271 | 272 | ``` 273 | 274 | Jupyter Notebookを使うためのサーバーがコンテナ内の環境で無事立ち上がりました。ただ、メッセージにはhttp://127.0.0.1:8888 にアクセスしろと書いてありますが、これはコンテナの環境の中で使えるアドレスで、コンテナ環境の外である自分のコンピュータ環境からはこのアドレスにはアクセスできません。アクセスするためには、8888のポートの代わりにコマンドで指定した7777というポートを利用します。コマンドでやっているのはつまりコンテナの環境内で使える8888というポートを自分のコンピュータで使えるように7777というポートにマッピングしたということになります。コマンドの7777の部分は好きな数値に変えてもらって大丈夫です。 275 | 276 | ではウェブブラウザを開き、URL欄に`http://127.0.0.1:7777`と入力してJupyter Notebookのサーバーにアクセスしてみましょう。 277 | 278 | するとToken authentication is enabledというページが出ると思うので、そこに上のメッセージでtoken=に続くコードをコピーしてPassword or tokenの入力欄に入力してLog inボタンを押します。 279 | 280 | うまくいけばJupyter Notebookにログインされ、無事使えるようになります。 281 | 282 | もしブラウザ経由ではなく、`docker run`コマンドで立ち上げたコンテナに接続したい場合は、別のターミナルウィンドウで次のコマンドで接続します。この時*docker-container-id*には`docker container ls`で確認した現在起動しているコンテナのIDを入力します。 283 | 284 | ```bash 285 | $ docker exec -it *docker-container-id* bash 286 | ``` 287 | 288 | サーバーを止めたい場合は、サーバーを起動したターミナルで Controlキー + C を入力します。すると次のようなメッセージが出ます。 289 | 290 | ```bash 291 | Shutdown this Jupyter server (y/[n])? 292 | ``` 293 | 294 | ターミナルに`y`と入力してEnterキーを押しましょう。サーバーが止まり、同時に一時的に作られていたコンテナも削除されます。接続解除とともにコンテナが削除されたのは、`docker run`コマンドを利用したとき`-rm`というオプションを使ったからです。このオプションがないと、接続を解除した時にコンテナが停止した状態で削除されずに残ります。この時、停止されたコンテナは`docker container ls`では表示されなくなるので、確認したい場合は`docker container ls -a`で停止したコンテナも全て表示するようにします。 295 | 296 | 297 | ## Step 12. 停止したコンテナを削除する 298 | 299 | 停止したコンテナそのままにしているとずっと残り続けます。`docker start`コマンドで停止したコンテナを起動させ再利用することも可能ですが、削除したい場合は次のようなステップを踏みます。 300 | 301 | まず次のようなコマンドを入力して停止しているコンテナ含めて全てのコンテナを表示します。 302 | 303 | ```bash 304 | $ docker container ls -a 305 | ``` 306 | 307 | 次のように表示されたら、その中から消したいコンテナのIDを確認します。この場合`5e00e61e8717`がそれに当たります。この値はコンテナを作り直すたびに変わります。 308 | 309 | ```bash 310 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 311 | 5e00e61e8717 docker-python_python3 "jupyter-lab --ip 0.…" 11 seconds ago Exited (0) 6 seconds ago relaxed_wiles 312 | ``` 313 | 314 | 削除したいコンテナのIDが確認できたら、次のコマンドで指定のコンテナを削除します。*container-id*は削除したいコンテナのIDと入れ替えてください。 315 | 316 | ```bash 317 | $ docker container rm container-id 318 | ``` 319 | 320 | 321 | ## おわりに 322 | 323 | 今回はDockerが何かを理解するためにPythonの環境を試しに作って使ってみました。少しは可能性を感じていただけましたでしょうか?プログラムの実行環境をこのように手軽に作れるのは非常に便利だと思います。積極的に使っていきましょう。 324 | 325 | 以上です。お疲れ様でした。 326 | 327 | 328 | 329 | 参考サイト 330 | [dockerで簡易にpython3の環境を作ってみる](https://qiita.com/reflet/items/4b3f91661a54ec70a7dc) -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | python3: 4 | restart: always 5 | build: . 6 | container_name: 'python3' 7 | working_dir: '/root/opt' 8 | tty: true 9 | volumes: 10 | - ./opt:/root/opt -------------------------------------------------------------------------------- /opt/sample.py: -------------------------------------------------------------------------------- 1 | import math 2 | import sys 3 | 4 | def main(): 5 | val = float(sys.argv[1]) 6 | print(math.radians(val)) 7 | 8 | if __name__ == "__main__": 9 | main() 10 | --------------------------------------------------------------------------------