在容器內偵錯 Python
將 Docker 檔案新增至 Python 專案時,會新增工作和啟動組態,以啟用在 Docker 容器內偵錯應用程式。為了適應 Python 專案的各種案例,某些應用程式可能需要額外設定。
設定 Docker 容器進入點
您可以透過在 tasks.json
中設定屬性來設定 Docker 容器的進入點。當您第一次使用 Docker: 將 Docker 檔案新增至工作區... 命令時,VS Code 會自動設定容器進入點。
範例:設定 Python 模組的進入點
{
"tasks": [
{
"type": "docker-run",
"label": "docker-run: debug",
"dependsOn": ["docker-build"],
"python": {
"module": "myapp"
}
}
]
}
範例:設定 Python 檔案的進入點
{
"tasks": [
{
"type": "docker-run",
"label": "docker-run: debug",
"dependsOn": ["docker-build"],
"python": {
"args": ["runserver", "0.0.0.0:8000", "--nothreading", "--noreload"],
"file": "manage.py"
}
}
]
}
自動啟動瀏覽器至應用程式的進入頁面
您可以選取 Docker: Python - Django 或 Docker: Python - Flask 啟動組態,以自動啟動瀏覽器至應用程式的主要頁面。預設會啟用此功能,但您可以透過在 launch.json
中設定 dockerServerReadyAction
物件來明確設定此行為。
此功能取決於應用程式的幾個方面
- 應用程式必須輸出至偵錯主控台或 Docker 記錄。
- 應用程式必須記錄「伺服器已就緒」訊息。
- 應用程式必須提供可瀏覽的頁面。
以下是使用 dockerServerReadyAction
啟動瀏覽器以開啟 about.html
頁面的範例,其基於特定的伺服器訊息模式
{
"configurations": [
{
"name": "Docker: Python - Django",
"type": "docker",
"request": "launch",
"preLaunchTask": "docker-run: debug",
"python": {
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
],
"projectType": "django"
},
"dockerServerReadyAction": {
"action": "openExternally",
"pattern": "Starting development server at (https?://\\S+|[0-9]+)",
"uriFormat": "%s://127.0.0.1:%s/about.html"
}
}
]
}
注意:在
pattern
屬性中找到的 regex 只是嘗試擷取類似「在https://127.0.0.1:8000
啟動開發伺服器」的記錄訊息。它適用於 http 或 https、任何主機名稱和任何連接埠的 URL 變化。
重要的 dockerServerReadyAction 物件屬性
-
action
:找到模式時要採取的動作。可以是debugWithChrome
或openExternally
。 -
pattern
:如果應用程式記錄的訊息與上面顯示的不同,請將 dockerServerReadyAction 物件的pattern
屬性設定為符合該訊息的 JavaScript 正則運算式。正則運算式應包含對應於應用程式正在接聽的連接埠的擷取群組。 -
uriFormat
:依預設,Docker 擴充功能會開啟瀏覽器的主要頁面 (無論應用程式如何判斷)。如果您希望瀏覽器開啟特定頁面,例如上面的範例,則應將 dockerServerReadyAction 物件的uriFormat
屬性設定為格式字串,其中包含兩個字串 token,以指示協定和連接埠替換。
如何在 Django 或 Flask 應用程式中啟用熱重新載入
當您為 Django 或 Flask 選取 Docker: 將 Docker 檔案新增至工作區 時,我們會為您提供針對靜態部署設定的 Dockerfile 和 tasks.json
。每次您變更應用程式程式碼時,都需要重建並重新執行容器。熱重新載入可讓您在容器繼續執行時,視覺化應用程式程式碼中的變更。透過這些步驟啟用熱重新載入
針對 Django 應用程式
-
在 Dockerfile 中,註解掉將應用程式程式碼新增至容器的行。
#ADD . /app
-
在
tasks.json
檔案的docker-run
工作中,建立具有volumes
屬性的新dockerRun
屬性。此設定會建立從目前工作區資料夾 (應用程式程式碼) 到容器中/app
資料夾的對應。{ "type": "docker-run", "label": "docker-run: debug", "dependsOn": [ "docker-build" ], "dockerRun": { "volumes": [ { "containerPath": "/app", "localPath": "${workspaceFolder}" } ] }, ... }
-
透過移除
--noreload
和--nothreading
來編輯 python 屬性。{ ... "dockerRun": { "volumes": [ { "containerPath": "/app", "localPath": "${workspaceFolder}" } ] }, "python": { "args": [ "runserver", "0.0.0.0:8000", ], "file": "manage.py" } }
-
選取 Docker: Python – Django 啟動組態,然後按下 F5 以組建並執行您的容器。
-
修改並儲存任何檔案。
-
重新整理瀏覽器並驗證已進行變更。
針對 Flask 應用程式
-
在 Dockerfile 中,註解掉將應用程式程式碼新增至容器的行。
#ADD . /app
-
在
tasks.json
檔案的docker-run
工作中,編輯現有的 dockerRun 屬性,方法是在env
屬性中新增FLASK_ENV
以及volumes
屬性。此設定會建立從目前工作區資料夾 (應用程式程式碼) 到容器中/app
資料夾的對應。{ "type": "docker-run", "label": "docker-run: debug", "dependsOn": [ "docker-build" ], "dockerRun": { "env": { "FLASK_APP": "path_to/flask_entry_point.py", "FLASK_ENV": "development" }, "volumes": [ { "containerPath": "/app", "localPath": "${workspaceFolder}" } ] }, ... }
-
透過移除
--no-reload
和--no-debugger
來編輯 python 屬性。{ ... "dockerRun": { "env": { "FLASK_APP": "path_to/flask_entry_point.py", "FLASK_ENV": "development" }, "volumes": [ { "containerPath": "/app", "localPath": "${workspaceFolder}" } ] }, "python": { "args": [ "run", "--host", "0.0.0.0", "--port", "5000" ], "module": "flask" } }
-
選取 Docker: Python – Flask 啟動組態,然後按下 F5 以組建並執行您的容器。
-
修改並儲存任何檔案。
-
重新整理瀏覽器並驗證已進行變更。
如何一起組建和執行容器
- 在先前提及的
tasks.json
檔案中,依賴於docker-build
工作。此工作是tasks.json
中tasks
陣列的一部分。例如
"tasks":
[
{
...
},
{
"label": "docker-build",
"type": "docker-build",
"dockerBuild": {
"context": "${workspaceFolder}",
"dockerfile": "${workspaceFolder}/Dockerfile",
"tag": "YOUR_IMAGE_NAME:YOUR_IMAGE_TAG"
}
}
]
提示:由於相依性清楚地說明 docker-build
作為其相依性,因此名稱必須符合此工作。您可以視需要變更名稱。
-
JSON 中的
dockerBuild
物件允許下列參數- context:Docker 組建內容,從中呼叫您的 Dockerfile
- dockerfile:要執行的 Dockerfile 路徑
- tag:要組建的映像名稱及其版本標籤
-
總體而言,用於組建和偵錯 Flask 應用程式的 VS Code 設定可以是
-
launch.json
{ "version": "0.2.0", "configurations": [ { "name": "Debug Flask App", "type": "docker", "request": "launch", "preLaunchTask": "docker-run: debug", "python": { "pathMappings": [ { "localRoot": "${workspaceFolder}", "remoteRoot": "/app" } ], "projectType": "flask" }, "dockerServerReadyAction": { "action": "openExternally", "pattern": "Running on (http?://\\S+|[0-9]+)", "uriFormat": "%s://127.0.0.1:%s/" } } ] }
-
tasks.json
{ "version": "2.0.0", "tasks": [ { "type": "docker-run", "label": "docker-run: debug", "dependsOn": ["docker-build"], "dockerRun": { "containerName": "YOUR_IMAGE_NAME", "image": "YOUR_IMAGE_NAME:YOUR_IMAGE_TAG", "env": { "FLASK_APP": "path_to/flask_entry_point.py", "FLASK_ENV": "development" }, "volumes": [ { "containerPath": "/app", "localPath": "${workspaceFolder}" } ], "ports": [ { "containerPort": 5000, "hostPort": 5000 } ] }, "python": { "args": ["run", "--host", "0.0.0.0", "--port", "5000"], "module": "flask" } }, { "label": "docker-build", "type": "docker-build", "dockerBuild": { "context": "${workspaceFolder}", "dockerfile": "${workspaceFolder}/Dockerfile", "tag": "YOUR_IMAGE_NAME:YOUR_IMAGE_TAG" } } ] }
-
後續步驟
深入了解