Dockerを用いたPythonの開発環境構築

作成: 2020年11月19日

更新: 2020年11月20日

概要

Docker(+VSCode)を用いたPythonの環境構築方法をまとめる.自分用の備忘録.

利点

Pythonは環境構築が難しいがDockerを使えばコマンド1つで環境が再現できる.
また上手くいかなくなっても最悪環境ごと破棄し作り直せる.
formatterやlinterを同時に導入することできれいなコードが半強制的に作られる.

Dockerの導入

Windowsの場合WSL2とDockerの導入 を参考

VSCodeのインストール

以下のリンクからインストール
Download Visual Studio Code - Mac, Linux, Windows

開発方法

参考: 【venv不要】Remote Containersで作る最強のPython開発環境【VSCode/Docker】 - Qiita

各種設定ファイルの設定

以下のようにディレクトリ,ファイルを作成します.${project}は実際のディレクトリ名が入ります.

${project}
    ├── .github
    │   └── workflows
    │       └── lint.yml
    ├── .devcontainer
    │   ├── Dockerfile
    │   └── devcontainer.json
    ├── .vscode
    │   └── extensions.json
    ├── pyrightconfig.json
    ├── requirements.txt
    └── src
        ├── tests
        │         └── test_example.py
        ├── main.py
        .
        .

また各ファイルは以下のように設定します.

.devcontainer/Dockerfile
FROM python:3.7.7-slim RUN apt update \ && apt install -y --no-install-recommends \ apt-utils \ git \ gcc \ build-essential \ && pip install --no-cache-dir \ autopep8 \ flake8 \ pytest \ && apt autoremove -y \ && apt clean -y \ && rm -rf /var/lib/apt/lists/*

"python:3.7.7-slim"のところは適切なバージョンを設定してください.ここでプロジェクトに直接関わらないライブラリ群のlinterとしてflake8, formatterとしてautopep8をテスト用にpytestをインストールしています.

.devcontainer/devcontainer.json
{ "name": "project-name", "dockerFile": "Dockerfile", "settings": { "terminal.integrated.shell.linux": "/bin/bash", "python.pythonPath": "/usr/local/bin/python", "python.linting.pylintEnabled": false, "python.linting.flake8Enabled": true, "python.linting.flake8Args": [ "--ignore=E402", "--max-line-length", "120" ], "python.formatting.provider": "autopep8", "python.formatting.autopep8Args": [ "--ignore", "E402", "--max-line-length", "120" ], "[python]": { "editor.formatOnSave": true } }, "extensions": [ "ms-python.python", "ms-pyright.pyright" ], "postCreateCommand": "pip install -r requirements.txt", }

"name": "project-name",のproject-nameにはgithubのリポジトリ名を入れます.
ここでlinterとしてflake8, formatterとしてautopep8を指定し,オプションで1行あたりの推奨文字数79文字から120文字に変更しています.
--ignoreオプションで402を無視しています.これは以下のようなimportを許容します.
参考: Python スクリプトの親ディレクトリをパスに追加する - Qiita

import sys, os
pardir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(pardir)
import main

他にもいくつか規約を無視できるが要検証
(参考: pycodestyle(pep8) エラーコードチートシート - Qiita)
またextensionsにはVSCodeのpython用拡張と静的型解析を可能にするpyrightの拡張が入っています.これによりDocker起動時に自動でこれらの拡張がインストールされます.
またpostCreateCommandによりrequirements.txtに記述されているパッケージが自動でインストールされます.

.vscode/extensions.json
{ "recommendations": [ "ms-vscode-remote.remote-containers" ] }

ここではVSCode起動時にrecommendationsとして表示させるextensionsを指定しています.remote-containers拡張はVSCodeでDockerを起動する拡張です.VSCodeの左隅が緑色になりそこをクリックすることでDockerのコンテナ作成,リビルドなどができます.

pyrightconfig.json
{ "include": [ "src" ], "reportTypeshedErrors": false, "reportMissingImports": true, "reportMissingTypeStubs": false, "pythonVersion": "3.7", "pythonPlatform": "Linux", "executionEnvironments": [ { "root": "src" } ] }

Pythonで静的型解析を行うための設定です.(この辺りは参考記事受け売りなので要検証)

numpy==1.17.4

必要なパッケージをバージョンとともに記述します.(numpyは例)

.github/workflows/python.yml
name: Python on: pull_request jobs: flake8: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Setup Python uses: actions/setup-python@v2 with: python-version: 3.7.7 - name: Install dependencies run: | python -m pip install --upgrade pip pip install flake8 pytest if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Run flake8 run: | flake8 src --count --max-line-length=120 --statistic

参考: GitHub ActionsでのPythonの利用 - GitHub ヘルプ
プルリクエスト時にflake8によるコードチェックとpytestによるテストを行い,プルリクエスト画面に結果を乗せる.python-versionはプルリクエストで用いるバージョンによって要変更.
またflake8では命名規則をチェックしないので注意.Pythonのコーディング規約PEP8での命名規則は以下.

対象 規則 備考
パッケージ snake_case アンダースコアなしを推奨
モジュール snake_case アンダースコアなしを推奨
クラス PascalCase
例外 PascalCase
クラス変数 PascalCase
メソッド snake_case 内部メソッドは頭にアンダースコア
引数 snake_case 予約語と被るときは末尾にアンダースコア
変数 snake_case 内部変数は頭にアンダースコア
定数 SNAKE_CASE
src/tests/test_example.py
# Example test is required because pytest has Exit Code 5 when no tests running def test_example(): assert True

pytestはテストケースが1つもないと正常に終了しないでエラーを返すので1つは必ずテストケースを用意する.

Docker起動

設定ファイルの記述が終わったらVSCodeを該当のディレクトリにて起動します.するとrecommendとしてremote-containers拡張が出るはずなのでインストールします.すると画面の右隅が緑色になるのでクリックします.
出てくるコマンドのリストから「Remote-Containers: Open Folder in Container...」を選びます.
フォルダ選択画面がでたら、プロジェクトのディレクトリを選ぶ.
コンテナが作成されるのでしばらく待ちます.
コンテナが作成し終わったらCtrl+Shift+@でターミナルを開くと以下のようにbashになってディレクトリがworkspacesになったらOK.
Pythonが入っているか確かめます.

> Python -V
# Python 3.7.7