在容器中除錯 Python
將 Docker 檔案新增到 Python 專案時,會新增任務和啟動配置以在容器中啟用應用程式除錯。為了適應各種 Python 專案場景,某些應用程式可能需要額外的配置。
配置容器入口點
您可以透過在 tasks.json 中設定屬性來配置容器入口點。當您第一次使用 Containers: Add Docker Files to Workspace... 命令時,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"
}
}
]
}
自動將瀏覽器啟動到應用程式的入口頁面
您可以選擇 Containers: Python - Django 或 Containers: Python - Flask 啟動配置,以自動將瀏覽器啟動到應用程式的主頁。此功能預設啟用,但您可以透過在 launch.json 中設定 dockerServerReadyAction 物件來明確配置此行為。
此功能取決於應用程式的幾個方面
- 應用程式必須輸出到除錯控制檯或 Docker 日誌。
- 應用程式必須記錄“伺服器就緒”訊息。
- 應用程式必須提供一個可瀏覽的頁面。
這是一個使用 dockerServerReadyAction 根據特定的伺服器訊息模式將瀏覽器啟動到開啟 about.html 頁面的示例
{
"configurations": [
{
"name": "Containers: 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://:%s/about.html"
}
}
]
}
注意:
pattern屬性中的正則表示式只是嘗試捕獲類似於“Starting development server athttps://:8000”的日誌訊息。它適應 http 或 https、任何主機名和任何埠的 URL 變化。
重要的 dockerServerReadyAction 物件屬性
-
action:找到模式時要執行的操作。可以是debugWithChrome或openExternally。 -
pattern:如果應用程式記錄的訊息與上面顯示的不同,請將 dockerServerReadyAction 物件的pattern屬性設定為與該訊息匹配的 JavaScript 正則表示式。正則表示式應包含一個捕獲組,該捕獲組對應於應用程式正在偵聽的埠。 -
uriFormat:預設情況下,容器工具擴充套件將開啟瀏覽器的主頁(無論應用程式如何確定)。如果您希望瀏覽器開啟一個特定頁面,如上例所示,dockerServerReadyAction 物件的uriFormat屬性應設定為一個包含兩個字串標記的格式字串,用於指示協議和埠替換。
如何在 Django 或 Flask 應用程式中啟用熱過載
當您為 Django 或 Flask 選擇 Containers: Add Docker Files to Workspace 時,我們會為您提供一個配置為靜態部署的 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}" } ] }, ... } -
編輯 python 屬性,刪除
--noreload和--nothreading。{ ... "dockerRun": { "volumes": [ { "containerPath": "/app", "localPath": "${workspaceFolder}" } ] }, "python": { "args": [ "runserver", "0.0.0.0:8000", ], "file": "manage.py" } } -
選擇 Containers: Python – Django 啟動配置,然後按 F5 來構建和執行容器。
-
修改並儲存任何檔案。
-
重新整理瀏覽器並驗證更改是否已生效。
對於 Flask 應用程式
-
在 Dockerfile 中,註釋掉將應用程式程式碼新增到容器的那一行。
#ADD . /app -
在
tasks.json檔案中的docker-run任務中,透過在env屬性中新增FLASK_ENV以及一個volumes屬性來編輯現有的 dockerRun 屬性。此設定建立了從當前工作區資料夾(應用程式程式碼)到容器中/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}" } ] }, ... } -
編輯 python 屬性,刪除
--no-reload和--no-debugger。{ ... "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" } } -
選擇 Containers: 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:構建上下文,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://:%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" } } ] }
-
後續步驟
瞭解更多關於