🚀 在 VS Code 中取得

在容器內偵錯 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 - DjangoDocker: 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:找到模式時要採取的動作。可以是 debugWithChromeopenExternally

  • pattern:如果應用程式記錄的訊息與上面顯示的不同,請將 dockerServerReadyAction 物件的 pattern 屬性設定為符合該訊息的 JavaScript 正則運算式。正則運算式應包含對應於應用程式正在接聽的連接埠的擷取群組。

  • uriFormat:依預設,Docker 擴充功能會開啟瀏覽器的主要頁面 (無論應用程式如何判斷)。如果您希望瀏覽器開啟特定頁面,例如上面的範例,則應將 dockerServerReadyAction 物件的 uriFormat 屬性設定為格式字串,其中包含兩個字串 token,以指示協定和連接埠替換。

如何在 Django 或 Flask 應用程式中啟用熱重新載入

當您為 Django 或 Flask 選取 Docker: 將 Docker 檔案新增至工作區 時,我們會為您提供針對靜態部署設定的 Dockerfile 和 tasks.json。每次您變更應用程式程式碼時,都需要重建並重新執行容器。熱重新載入可讓您在容器繼續執行時,視覺化應用程式程式碼中的變更。透過這些步驟啟用熱重新載入

針對 Django 應用程式

  1. 在 Dockerfile 中,註解掉將應用程式程式碼新增至容器的行。

    #ADD . /app
    
  2. tasks.json 檔案的 docker-run 工作中,建立具有 volumes 屬性的新 dockerRun 屬性。此設定會建立從目前工作區資料夾 (應用程式程式碼) 到容器中 /app 資料夾的對應。

    {
      "type": "docker-run",
      "label": "docker-run: debug",
      "dependsOn": [
        "docker-build"
      ],
      "dockerRun": {
        "volumes": [
          {
            "containerPath": "/app", "localPath": "${workspaceFolder}"
          }
        ]
      },
      ...
    }
    
  3. 透過移除 --noreload--nothreading 來編輯 python 屬性。

    {
      ...
      "dockerRun": {
        "volumes": [
          {
            "containerPath": "/app", "localPath": "${workspaceFolder}"
          }
        ]
      },
      "python": {
        "args": [
          "runserver",
          "0.0.0.0:8000",
        ],
        "file": "manage.py"
      }
    }
    
  4. 選取 Docker: Python – Django 啟動組態,然後按下 F5 以組建並執行您的容器。

  5. 修改並儲存任何檔案。

  6. 重新整理瀏覽器並驗證已進行變更。

針對 Flask 應用程式

  1. 在 Dockerfile 中,註解掉將應用程式程式碼新增至容器的行。

    #ADD . /app
    
  2. 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}"
          }
        ]
      },
      ...
    }
    
  3. 透過移除 --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"
      }
    }
    
  4. 選取 Docker: Python – Flask 啟動組態,然後按下 F5 以組建並執行您的容器。

  5. 修改並儲存任何檔案。

  6. 重新整理瀏覽器並驗證已進行變更。

如何一起組建和執行容器

  1. 在先前提及的 tasks.json 檔案中,依賴於 docker-build 工作。此工作是 tasks.jsontasks 陣列的一部分。例如
"tasks":
[
  {
    ...
  },
  {
    "label": "docker-build",
    "type": "docker-build",
    "dockerBuild": {
        "context": "${workspaceFolder}",
        "dockerfile": "${workspaceFolder}/Dockerfile",
        "tag": "YOUR_IMAGE_NAME:YOUR_IMAGE_TAG"
    }
  }
]

提示:由於相依性清楚地說明 docker-build 作為其相依性,因此名稱必須符合此工作。您可以視需要變更名稱。

  1. JSON 中的 dockerBuild 物件允許下列參數

    • context:Docker 組建內容,從中呼叫您的 Dockerfile
    • dockerfile:要執行的 Dockerfile 路徑
    • tag:要組建的映像名稱及其版本標籤
  2. 總體而言,用於組建和偵錯 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"
            }
          }
        ]
      }
      

後續步驟

深入了解