前回はMacOS上でDjangoアプリをVS Codeでデバッグ実行することに成功したので、今回はDocker上のDjangoアプリをVS Codeでデバッグ実行する方法を検証する。
公式ドキュメントは以下
code.visualstudio.com
目的
→ Docker上でもホストOS上と遜色ない環境で、VS Codeで開発ができるのであれば、ローカルにvenvで開発環境を構築する必要がなくなる。
先に検証結果
Docker上のDjangoアプリをVS Codeでデバッグ実行するまでの手順
2.devcontainer.jsonを作成する。
リモート環境のVS Codeの設定を記述する「devcontainer.json」というファイルを作成する。
まずはプロジェクトのルートディレクトリ直下に「.devcontainer」というディレクトリを作成する。
次に、.devcontainer配下に「devcontainer.json」というファイルを作成する。
djangogirls-tutorial-docker/ └── .devcontainer └── devcontainer.json
3.devcontainer.jsonに設定を記述する。
devcontainer.jsonに設定を記述していく。
一から書いていくのは辛いので、ベースとなるテンプレートが欲しいなと思っていたところ、Microsoft公式のリポジトリが存在した。
github.com
この中に「python-3」というテンプレートがあったので、これをベースにすることにした。
https://github.com/microsoft/vscode-dev-containers/blob/master/containers/python-3/.devcontainer/devcontainer.json
最終的にdevcontainer.jsonは以下のようになった。
{ "name": "djangogirls-tutorial-docker", "dockerComposeFile": "../docker-compose.yml", "service": "my-djangogirls-tutorial", "context": "..", "workspaceFolder": "/root/djangogirls-tutorial", "appPort": [ 8000 ], // Set *default* container specific settings.json values on container create. "settings": { "terminal.integrated.shell.linux": "/bin/bash", "editor.cursorSurroundingLinesStyle": "all", "editor.formatOnSave": true, "editor.tabCompletion": "on", "editor.codeActionsOnSave": { "source.organizeImports": true }, "workbench.startupEditor": "newUntitledFile", "git.suggestSmartCommit": false, "files.autoSave": "onFocusChange", "files.exclude": { "**/.mypy_cache": true, }, "git.untrackedChanges": "separate", "csscomb.preset": {}, "todo-tree.tree.showScanModeButton": false, "python.pythonPath": "python3", "python.linting.enabled": true, "python.linting.pylintEnabled": false, "python.linting.flake8Enabled": true, "python.formatting.provider": "black", "python.linting.mypyEnabled": true, "python.formatting.blackPath": "black", "python.linting.flake8Path": "flake8", "python.linting.mypyPath": "mypy", "autoDocstring.startOnNewLine": true, "autoDocstring.docstringFormat": "sphinx", }, // Add the IDs of extensions you want installed when the container is created. "extensions": [ //"donjayamanne.githistory", //"eamodio.gitlens", //"Gruntfuggly.todo-tree", //"jebbs.plantuml", //"mechatroner.rainbow-csv", //"mrmlnc.vscode-csscomb", //"ms-azuretools.vscode-docker", "MS-CEINTL.vscode-language-pack-ja", "ms-python.python", //"ms-vscode-remote.remote-containers", //"ms-vscode-remote.remote-ssh", //"ms-vscode-remote.remote-ssh-edit", //"ms-vscode-remote.remote-wsl", //"ms-vscode-remote.vscode-remote-extensionpack", //"njpwerner.autodocstring", //"oderwat.indent-rainbow", //"streetsidesoftware.code-spell-checker", //"thebarkman.vscode-djaneiro", //"wmaurer.change-case", ] // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. // "postCreateCommand": "pip3 install --user -r requirements.txt", // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. // "remoteUser": "vscode" }
以下、テンプレートから編集した箇所
build
テンプレートでは「build」という項目が存在し、その中にネストさせる形で「dockerfile」、「context」などの設定を書いているが、設定ファイルが不正であるというエラーが発生してしまった。
他のテンプレートを見ると「build」という項目は使用していなかったので、削除してみた。するとエラーが発生しなくなった。
github.com
name
任意のプロジェクト名を書く。
dockerComposeFile
今回はDocker Composeを使用しているので、項目名には「dockerFile」ではなく「dockerComposeFile」を使用する。
service
デバッグ対象のコンテナのサービス名称(docker-compose.ymlに定義したもの)を書く。
context
この設定値が何に使われているのかよく分からなかった。
実験で関係ないパスを指定してみたり、コメントアウトしてみたりしたが、コンテナは正常に起動した。
docker本体の「ビルドコンテキスト」という概念と関係があるのだろうか?
docs.docker.com
とりあえず、以下のテンプレートのコメントを見ると、devcontainer.jsonの1階層上を指定する場合は「..」と書けばよいようなので、倣っておく。
github.com
この項目の意味を理解することは宿題とする。
workspaceFolder
VS Codeのワークスペースのルートディレクトリにしたいコンテナ上のディレクトリのパスを書く。
通常はコンテナ側のマウント先のディレクトリと同じになるはず。
※ 設定しないと以下のように「/」がワークスペースのルートディレクトリとして認識されてしまい、コンテナ上の全てのディレクトリがVS Codeに表示されてしまうので注意。
appPort
DockerのポートフォーワードでホストOS側からアクセスするポートを設定する項目らしい。
Dockerの「EXPOSE」、Docker Composeのportsと意味合いが異なるのかどうか分からないが、指定しておく。
5.launch.jsonに設定を記述する。
基本的には前回の設定と同じでよい。
但し、今回はIPアドレスを「0.0.0.0」で起動する必要があるので、そこだけ設定を追加する。
{ // IntelliSense を使用して利用可能な属性を学べます。 // 既存の属性の説明をホバーして表示します。 // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Python: Django", "type": "python", "request": "launch", "program": "${workspaceFolder}/manage.py", "args": [ "runserver", "--noreload", "--nothreading", "0.0.0.0:8000" ], "django": true } ] }
6.Dockerコンテナにtarとgitをインストールする。
[Dockerfile]
RUN yum install -y tar RUN yum install -y git
tar : VS Codeを解凍するために必要。コマンドが存在しないとコンテナ起動時にエラーが発生するので必須。
git : コンテナ上のVS Codeでgitを使用するために必要。コンテナ上のVS Codeでgitを使用しない場合はなくても問題ない。
7.Dockerfileの「ENTRYPOINT」をコメントアウトする。
コンテナ上でDjangoアプリをVS Code上からデバッグ実行する必要がある。
ただ、既にdocker-entrypoint.shでコンテナ起動時にサーバーを起動するようにしているため、コンテナ起動後にデバッグ実行しようとするとポートが重複して「Error: That port is already in use.」が発生してしまう。
また、Djangoアプリのサーバーはコンテナのメインプロセスであるため、killするとコンテナが停止してしまう。
docs.docker.com
従って、きれいな解決方法ではないが、Dockerfileの「ENTRYPOINT」をコメントアウトして、デバッグ時にVS Code上からサーバーを起動するようにした。
※ マイグレーションもdocker-entrypoint.sh内で行っていたため、コンテナ起動後に手動で実行する必要があるので忘れないように注意。
[Dockerfile]
#ENTRYPOINT /bin/bash ${DEPLOY_DIR}/docker-entrypoint.sh
8.VS Codeでコンテナを起動する。
2.「Remote Development」をインストールすると、VS Codeの画面左下に緑色のボタンが表示されるようになるので、それを押す。
3.「Remote Containers: Reopen in Container」を押す。
4.コンテナの起動・コンテナへのVS Code・extensionsのインストールが完了するまでしばらく待つ。(この時間が結構かかる。)
5.「ENTRYPOINT」をコメントアウトしているので、コマンドラインからコンテナにログインして
$ python3 manage.py migrate
を実行する。
6..Djangoのサーバーをデバッグで起動する。(操作は前回と同じ)
7.ブレークポイントを貼って、ブレークポイントで処理が停止することを確認できればOK
以上