LoginSignup
0
0

More than 1 year has passed since last update.

docker-composeで建てたコンテナにアタッチしてリモートデバッグする方法

Last updated at Posted at 2022-11-20

実現したこと

クリックで、
image.png
フロントエンド、バックエンド、DBのコンテナが起動。
image.png
ブラウザからエンドポイントへリクエストを送り、ブレークポイントを置いたコードで停止して変数などを確認できる。
image.png

デバッグ環境構築前の構成

以下のようにフロントエンド、バックエンド、DBサーバー用のファイルをディレクトリで分けて、それぞれのDockerfileでフロントエンド、バックエンド、DBそれぞれのコンテナを構成し、qaapp配下のdocker-compose.ymlファイルでdocker-composeによるコンテナの起動を構成していました
バックエンドではフレームワークとしてFastAPIを採用していて、今回はバックエンドに対してデバッグ環境を構築しました。
参考までに、作成しようとしていたものは、qaappというディレクトリ名からも察せられるかもしれませんが、自分で作った問題と答えを投稿できる一問一答管理システムです。

qaapp/
  ├─ frontend/
  │    │ ︙
  │    └ Dockerfile
  ├─ backend/
  │    │ ︙
  │    └ Dockerfile
  ├─ db/
  │    │ ︙
  │    └ Dockerfile
  └─ docker-compose.yml
qaapp/docker-compose.yml
services:
  db:
    container_name: qaapp_db
    build:
      context: ./db
    ports:
      - 13306:3306
    command: --default-authentication-plugin=mysql_native_password
    networks:
      - qaapp

  frontend:
    container_name: qaapp_frontend
    build:
      context: ./frontend
    ports:
      - 8080:80
    networks:
      - qaapp
  
  backend:
    container_name: qaapp_backend
    build:
      context: .
      dockerfile: ./backend/Dockerfile
    volumes:
      - type: bind
        source: ./backend/src
        target: /app/src
      - type: bind
        source: ./backend/main.py
        target: /app/main.py
    tty: true
    ports:
      - 8090:80
    networks:
      - qaapp

networks:
  qaapp:
    driver: bridge
qaapp/backend/Dockerfile
FROM ubuntu:jammy

RUN mkdir app && mkdir app/src

COPY ./backend/Pipfile.lock app
COPY ./backend/run.sh app

RUN apt-get -y update \
    && apt -y update\
    && apt -y install curl \
    && apt-get -y install python3 python3-pip\
    && pip3 install pipenv

RUN cd app && pipenv sync

EXPOSE 80
EXPOSE 8040

CMD cd app && pipenv run uvicorn main:app --host 0.0.0.0 --port 80 --reload

モチベーション

開発途中で効率を上げるためにデバッグを実施したくなりました。
すでにdocker-composeとDockerfileによるコンテナの作成を完了していたので、これらのコンテナに対してattachしてデバッグできるようにすることを目指そうと考えました。

大まかな構成

  1. .vscode/tasks.jsondocker-compose runを実行するtaskを作成
  2. .vscode/launch.jsonpreLaunchTaskで1で作成したtaskを指定ししたデバッグ実行設定を作成
  3. dubugモードでバックエンドアプリケーションを実行するdocker-composeファイルを作成

以下でそれぞれの手順について説明します。

.vscode/tasks.jsonでdocker-compose runを実行するtaskを作成

.vscode/tasks.json
{
	"version": "2.0.0",
	"tasks": [
		{
			"label": "run qaapp",
			"type": "docker-compose",
			"dockerCompose": {
				"up": {
					"detached": true,
					"build": false,
				},
				"files": [
					"${workspaceFolder}/docker-compose.local.debug.yml"
				]
			}
		}
	]
}

filesプロパティで手順3で作成するデバッグ用のdocker-composeファイル(docker-compose.local.debug.yml)を指定しています。

.vscode/launch.jsonでpreLaunchTaskで1で作成したtaskを指定ししたデバッグ実行設定を作成

.vscode/launch.json
{
    "configurations": [
        {
            "request": "attach",
            "type": "python",
            "name": "Attach qaapp backend",
            "preLaunchTask": "run qaapp",
            "connect": {
                "port": 8040,
                "host": "localhost"
            },
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}/backend/",
                    "remoteRoot": "/app/"
                }
            ],
            "justMyCode": false
        }
    ]
}

connect.portがデバッグでattachするためのportです。こちらのportはもともと開放していなかったので、テウン3でデバッグ用のdocker-composeファイル(docker-compose.local.debug.yml)`にこのportを開く設定を追加します。

dubugモードでバックエンドアプリケーションを実行するdocker-composeファイルを作成

docker-compose.local.debug.yml
services:
  db:
    container_name: qaapp_db
    build:
      context: ./db
    ports:
      - 13306:3306
    command: --default-authentication-plugin=mysql_native_password
    networks:
      - qaapp

  frontend:
    container_name: qaapp_frontend
    build:
      context: ./frontend
    ports:
      - 8080:80
    networks:
      - qaapp
  
  backend:
    container_name: qaapp_backend
    build:
      context: .
      dockerfile: ./backend/Dockerfile
    volumes:
      - type: bind
        source: ./backend/src
        target: /app/src
      - type: bind
        source: ./backend/main.py
        target: /app/main.py
    tty: true
    ports:
      - 8090:80
+     - 8040:8040
    networks:
      - qaapp
+   command: [
+     "sh",
+     "-c",
+     "cd app && pipenv install debugpy && pipenv run python -m debugpy --wait-for-client --listen 0.0.0.0:8040 -m uvicorn main:app --reload --host 0.0.0.0 --port 80"
+   ]

networks:
  qaapp:
    driver: bridge

もともとのdocker-composeファイルとの差分で表示しています。
追加したのは手順2の説明で触れたデバッグのためのport開放設定と、デバッグモードでattachを待ち受ける設定でバックエンドアプリケーションを実行するようにDockerfileのCMDを上書きする設定を追加しています。
pipenv run python -m debugpy --wait-for-client --listen 0.0.0.0:8040 -m uvicorn main:app --reload --host 0.0.0.0 --port 80
上のコマンドがポイントです。

参考文献

[vscodeのドキュメント]
https://code.visualstudio.com/docs/containers/reference
tasks.jsonでdocker-compose upする方法を知るために使用
https://code.visualstudio.com/docs/containers/debug-python
vscodeでpythonデバッグを実施するための基本を知るために使用
https://code.visualstudio.com/docs/containers/debug-common
launch.jsonで指定できる各種プロパティの意味を知るために使用
https://qiita.com/kaitolucifer/items/dc58efebd72d72a8feb2
pythonデバッグの基本を知るために使用
https://github.com/tiangolo/fastapi/issues/707
クリティカルなissueがFastAPIのリポジトリに上がっていて、最も参考になった

0
0
1

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
0
0