質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

uWSGI

uWSGIは、PythonでWebサービスを動かすアプリケーションサーバの一つです。WSGI(Web Server Gateway Interface)アプリケーションコンテナの一種で、WSGIに則ったDjangoやFlaskなどで動かすことができます。

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

Q&A

0回答

1730閲覧

docker-composeで構築したマルチコンテナ「Nginx」「uWSGI+Django」「Postgres」において、VSCodeでDjangoのデバッグができない件

dissy1q84

総合スコア26

docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

uWSGI

uWSGIは、PythonでWebサービスを動かすアプリケーションサーバの一つです。WSGI(Web Server Gateway Interface)アプリケーションコンテナの一種で、WSGIに則ったDjangoやFlaskなどで動かすことができます。

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

0グッド

0クリップ

投稿2021/08/19 09:14

要点

docker-composeを使ってマルチコンテナ「Nginx」「uWSGI+Django」「Postgres」を構成し、
これらをVSCodeと拡張機能のRemote-Containerを利用してビルド、コンテナ起動し、
「uWSGI+Django」コンテナ内でuwsgi --socket :8001 --module config.wsgiを実行してデプロイして、
ブラウザからlocalhost:8001にアクセスしてDjangoのデフォルトページを表示する、
というところまで環境を確立しました。

イメージ的にはこちらの記事の最初の方にある図で、GunicornをuWSGIに置き換えたような構成です。
https://zenn.dev/dsonoda/articles/dbe14ca8af617ed85b1f

ここまでは正常に動作しています。

次に、「uWSGI+Django」コンテナ内でのDjangoのデバッグ環境を構築しようと試みていますが、
Django内蔵サーバーで動かしたときのデバッグ方法は公式ドキュメントをはじめ色々と
情報があるものの、Nginx+uWSGIで動かしたときのデバッグ方法に関する情報が見つけられず、
自分なりに色々試したのですが、まだ確立できていません。

こうすればできるのでは、という情報がありましたらご教示いただきたくお願いします。

すでに試したこと

(開発環境とソースコードは後述の見出し「開発環境とソースコード」に記載しています)

まず、VSCodeの公式ドキュメントを読み込んだところ、いくつかデバッグ手法があるようでした。
それぞれのデバッグ手法とそれについてのコメントは下記のとおりです。

  1. Pythonのデバッグについて一番詳しく書いてあるが、コンテナ内でのデバッグ方法について触れられていない

https://code.visualstudio.com/docs/python/debugging
2. Djangoのデバッグについて書いてあるが、同様にコンテナ内での利用について触れられていない
https://code.visualstudio.com/docs/python/tutorial-django#_create-a-debugger-launch-profile
3. コンテナのデバッグに言及しているが、tasks.jsonを使ってビルドも含めた一連の処理を一括で行うやり方のようで、一筋縄にいかなさそうだった
https://code.visualstudio.com/docs/containers/quickstart-python#_build-run-and-debug-the-container
4. docker-composeを使ったpythonのデバッグ方法ということで、自分のニーズに一番近い情報だった
https://code.visualstudio.com/docs/containers/docker-compose#_python

上記の中で、自分のニーズに一番近い情報だった4番のやり方を実践してみることにしました。
昨年、VSCodeのpython拡張機能に取り込まれたdebugpyというデバッグ手法を使用しているみたいです。
debugpyパッケージの公式ドキュメントはこちらです。
https://github.com/microsoft/debugpy

まず、デバッガ構成ファイルlaunch.jsonを下記のようにします。VSCodeの公式ドキュメントほぼそのままで、remoteRootのみ修正しました。

json

1{ 2 "version": "0.2.0", 3 "configurations": [ 4 { 5 "name": "Python: アタッチ", 6 "type": "python", 7 "request": "attach", 8 "connect": { 9 "host": "localhost", 10 "port": 5678 11 }, 12 "pathMappings": [ 13 { 14 "localRoot": "${workspaceFolder}", 15 "remoteRoot": "." 16 } 17 ] 18 } 19 ] 20}

次に、debugpyパッケージのインストールと起動、デバッガからの接続を待ち受ける設定をするため、docker-compose.ymlに下記を設定しました(実際には別ファイルとして作り、メインのdocker-compose.ymlを上書きする形にしています)。こちらもほぼ公式ドキュメントの丸コピーで、サービス名の変更くらいです。

yml

1# docker-compose.yml 2version: '3.8' 3 4services: 5 django: 6 command: ["sh", "-c", "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 manage.py runserver 0.0.0.0:8000 --nothreading --noreload"] 7 ports: 8 - 8000:8000 9 - 5678:5678

しかし、このままだと、Django内蔵サーバーが起動してしまいます。uWSGIのエントリポイントはwsgi.pyファイルとのことなので、config/wsgi.pyに変更したのが下記です(configはDjangoのプロジェクトフォルダ)。
※一応、manage.py runserverのパターンも確認しておこうと思い、別途、NginxとuWSGIを除いたDjango内蔵サーバーを使うコンテナを作成して上記で試しましたが、そのケースはうまくデバッガをアタッチできました。

yml

1# docker-compose.yml 2version: '3.8' 3 4services: 5 django: 6 command: ["sh", "-c", "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 config/wsgi.py"] 7 ports: 8 - 8000:8000 9 - 5678:5678

ただ、このままではuWSGIが起動できない・・・。
そう思いつつも、とりあえず実行してみたところ下記のエラーが。
イメージ説明
このエラーの内容について調べましたが、真の原因はわかりませんでした。

次に、debugpyのドキュメントに「スクリプトではなくモジュールも指定できる」と書いてあったので、下記のように変更しました。これなら、uwsgiコマンドを引数ごと実行できそうで、行けそうな気がします。

yml

1# docker-compose.yml 2version: '3.8' 3 4services: 5 django: 6 command: ["sh", "-c", "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m uwsgi --socket :8001 --module config.wsgi"] 7 ports: 8 - 8000:8000 9 - 5678:5678

しかし、F5でデバッガを実行すると下記エラーが・・・。
イメージ説明
uwsgiの格納場所を調べたところ、/workspace/django/.venv/bin/uwsgiにありましたので、確かに上記のパスには不一致です。uwsgiはpythonのモジュール扱いになると思ったのですが、モジュールは単にpyファイルのことを指すのでしょうか・・・。

以上のように、uwsgiを起動する場合のデバッグ方法がわからず困っています。
開発段階でuWSGIを使う人が少ないのか、ネットには情報がありませんでした(少なくとも私は見つけられませんでした)
断片的な知識の寄せ集めでこのようなことをしようとしているのでちょっと無理があったのかとも反省しつつ、同じことをやろうとしている人(やった人)はきっといると信じつつ、質問をさせていただきました。

開発環境とソースコード

開発環境

  • Windows10 Pro
  • WSL2 + Ubuntu20.04
  • Docker Desktop for Windows 3.5.2(docker-compose 1.29.2)
  • Python 3.8.10
  • Django 3.2.5
  • uWSGI 2.0.19.1
  • Nginx 1.21.1
  • PostgreSQL 13.3-1.pgdg100+1
  • pipenv version 2021.5.29
  • VSCode 1.59.0

VSCode拡張機能:

  • Remote Development(SSH, Containers, WSLを含むパッケージ)
  • Python
  • Docker

※他にもありますが関係ありそうなもののみ列挙しました

ディレクトリ構成

イメージ説明
イメージ説明

ソースコード

前述のディレクトリ構成順に記載。
teratailの文字数制限があるので、関連がありそうなコードを優先的に載せています。

.devcontainer/docker-compose.yml

後述のdocker.compose.ymlを上書き

yml

1version: '3.8' 2services: 3 django: 4 volumes: 5 - .:/workspace:cached 6 command: ["sh", "-c", "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m uwsgi --socket :8001 --module config.wsgi"] 7 ports: 8 - 8001:8001 9 - 5678:5678

django/.vscode/launch.json

json

1{ 2 // IntelliSense を使用して利用可能な属性を学べます。 3 4 "version": "0.2.0", 5 "configurations": [ 6 { 7 "name": "Python: アタッチ", 8 "type": "python", 9 "request": "attach", 10 "connect": { 11 "host": "localhost", 12 "port": 5678 13 }, 14 "pathMappings": [ 15 { 16 "localRoot": "${workspaceFolder}", 17 "remoteRoot": "." 18 } 19 ] 20 } 21 ] 22}

docker-setup.sh

sh

1#!/usr/bin/env bash 2 3pipenv --venv > /dev/null || pipenv install --skip-lock --dev --ignore-pipfile

docker-entrypoint.sh

sh

1#!/usr/bin/env bash 2 3# PostgreSQLの準備が整うまで待ってから実行 4if ["$DATABASE" = "postgres" 5then 6 echo "Waiting for postgres..." 7 8 while ! nc -z $DB_HOST $DB_PORT; do 9 sleep 0.1 10 done 11 12 echo "PostgreSQL started" 13fi 14 15if [ -z "${VIRTUAL_ENV}" ]; then 16 source "$(pipenv --venv)/bin/activate" 17fi 18 19python3 manage.py migrate 20 21exec "$@"

django/.devcontainer.json

json

1{ 2 "name": "django", 3 "dockerComposeFile": [ 4 "../docker-compose.yml", 5 "../.devcontainer/docker-compose.yml" 6 ], 7 "service": "django", 8 "shutdownAction": "none", 9 "forwardPorts": [ 10 80 11 ], 12 "extensions": [ 13 "donjayamanne.githistory", 14 "fabiospampinato.vscode-highlight", 15 "ckolkman.vscode-postgres", 16 "ms-python.vscode-pylance", 17 "ms-python.python", 18 "alexcvzz.vscode-sqlite", 19 "ms-azuretools.vscode-docker", 20 "eamodio.gitlens", 21 "visualstudioexptteam.vscodeintellicode", 22 ], 23 "workspaceFolder": "/workspace/django", 24}

django/Pipfile

[[source]] url = "https://pypi.org/simple" verify_ssl = true name = "pypi" [packages] Django = "==3.2.5" psycopg2 = "*" psycopg2-binary = "*" uwsgi = "*" [dev-packages] pylint = "*" autopep8 = "*" pylint-django = "*" pillow = "*" [requires] python_version = "3.8"

.env.development

########## # setting for Django ########## # 0:not debug mode / 1: debug mode DEBUG=1 # Django unique secret key value SECRET_KEY=HIJKLMN # Host names to allow access to django apps DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1] # Database process name DATABASE=postgres # database connection settings DB_ENGINE=django.db.backends.postgresql DB_NAME=app DB_USER=app DB_PASSWORD=password DB_HOST=postgres DB_PORT=5432 ########## # setting for postgres ########## POSTGRES_USER=app POSTGRES_PASSWORD=password POSTGRES_DB=app

docker-compose.yml

yml

1# Composeファイルフォーマット 2version: '3.8' 3 4services: 5 django: 6 container_name: django 7 build: 8 context: . 9 dockerfile: ./django/Dockerfile 10 command: uwsgi --socket :8001 --module config.wsgi 11 volumes: 12 - .:/workspace:cached 13 - ~/.gitconfig:/home/app/.gitconfig 14 - static_data:/workspace/django/static 15 - media_data:/workspace/django/media 16 tty: true 17 stdin_open: true 18 env_file: 19 - ./.env.development 20 depends_on: 21 - postgres 22 expose: 23 - "8001" 24 25 postgres: 26 container_name: postgres 27 image: postgres 28 ports: 29 - "5432:5432" 30 volumes: 31 - postgres_data:/var/lib/postgresql/data 32 env_file: 33 - ./.env.development 34 35 nginx: 36 container_name: nginx 37 build: 38 context: . 39 dockerfile: ./nginx/Dockerfile 40 ports: 41 - "8000:8000" 42 volumes: 43 - ./nginx/conf:/etc/nginx/conf.d 44 - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params 45 - static_data:/workspace/django/static 46 - media_data:/workspace/django/media 47 depends_on: 48 - django 49 50volumes: 51 postgres_data: 52 static_data: 53 media_data:

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問