Try agent mode in VS Code!
Dismiss this update
When adding Docker files to a Python project, tasks and launch configurations are added to enable debugging the application within a container. To accommodate the various scenarios of Python projects, some apps may require additional configuration.
You can configure the entry point of the container by setting properties in tasks.json
. VS Code automatically configures the container entry point when you first use the Containers: Add Docker Files to Workspace... command.
{
"tasks": [
{
"type": "docker-run",
"label": "docker-run: debug",
"dependsOn": ["docker-build"],
"python": {
"module": "myapp"
}
}
]
}
{
"tasks": [
{
"type": "docker-run",
"label": "docker-run: debug",
"dependsOn": ["docker-build"],
"python": {
"args": ["runserver", "0.0.0.0:8000", "--nothreading", "--noreload"],
"file": "manage.py"
}
}
]
}
You can select the Containers: Python - Django or Containers: Python - Flask launch configurations to automatically launch the browser to the main page of the app. This feature is enabled by default, but you can configure this behavior explicitly by setting the dockerServerReadyAction
object in launch.json
.
This feature depends on several aspects of the application:
Here is an example of using dockerServerReadyAction
to launch the browser to open the about.html
page based on a specific server message pattern:
{
"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://localhost:%s/about.html"
}
}
]
}
Note: The regex found in the
pattern
attribute simply attempts to capture a logged message similar to "Starting development server athttp://localhost:8000
". It accommodates variations in the url for http or https, any host name, and any port.
action
: The action to take when the pattern is found. Can be debugWithChrome
or openExternally
.
pattern
: If the application logs a different message than shown above, set the pattern
property of the dockerServerReadyAction object to a JavaScript regular expression that matches that message. The regular expression should include a capture group that corresponds to the port on which the application is listening.
uriFormat
: By default, the Container Tools extension will open the main page of the browser (however that is determined by the application). If you want the browser to open a specific page like the example above, the uriFormat
property of the dockerServerReadyAction object should be set to a format string with two string tokens to indicate the protocol and port substitution.
When you select Containers: Add Docker Files to Workspace for Django or Flask, we provide you a Dockerfile and tasks.json
configured for static deployment. Each time you make changes to your app code, you need to rebuild and re-run your container. Hot reloading allows you to visualize changes in your app code as your container continues to run. Enable hot reloading with these steps:
In the Dockerfile, comment out the line that adds app code to the container.
#ADD . /app
Within the docker-run
task in the tasks.json
file, create a new dockerRun
attribute with a volumes
property. This setting creates a mapping from the current workspace folder (app code) to the /app
folder in the container.
{
"type": "docker-run",
"label": "docker-run: debug",
"dependsOn": [
"docker-build"
],
"dockerRun": {
"volumes": [
{
"containerPath": "/app", "localPath": "${workspaceFolder}"
}
]
},
...
}
Edit the python attribute by removing --noreload
and --nothreading
.
{
...
"dockerRun": {
"volumes": [
{
"containerPath": "/app", "localPath": "${workspaceFolder}"
}
]
},
"python": {
"args": [
"runserver",
"0.0.0.0:8000",
],
"file": "manage.py"
}
}
Select the Containers: Python – Django launch configuration and hit F5 to build and run your container.
Modify and save any file.
Refresh the browser and validate changes have been made.
In the Dockerfile, comment out the line that adds app code to the container.
#ADD . /app
Within the docker-run
task in the tasks.json
file, edit the existing dockerRun attribute by adding a FLASK_ENV
in the env
property as well as a volumes
property. This setting creates a mapping from the current workspace folder (app code) to the /app
folder in the container.
{
"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}"
}
]
},
...
}
Edit the python attribute by removing --no-reload
and --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"
}
}
Select the Containers: Python – Flask launch configuration and hit F5 to build and run your container.
Modify and save any file.
Refresh the browser and validate changes have been made.
tasks.json
file, there is a dependency on the docker-build
task. The task is part of the tasks
array in tasks.json
. For example:"tasks":
[
{
...
},
{
"label": "docker-build",
"type": "docker-build",
"dockerBuild": {
"context": "${workspaceFolder}",
"dockerfile": "${workspaceFolder}/Dockerfile",
"tag": "YOUR_IMAGE_NAME:YOUR_IMAGE_TAG"
}
}
]
Tip: As the dependency clearly states docker-build
as its dependency, the name has to match this task. You can change the name, if desired.
The dockerBuild
object in the JSON allows for the following parameters:
Overall, a VS Code setup for building and debugging your Flask application can be:
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://localhost:%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"
}
}
]
}
Learn more about: