Docker VSCode Python Tutorial – Run your Application in a Container

If you ever wanted to create your own Python application in Docker VSCode, here is what you need to do. We will cover all necessary steps, the VSCode extensions you need, and how debugging works. Because with the right VSCode extensions it’s very easy and comfortable to develop an application in a container.

I’m developing my Python Applications in Docker Containers on Windows 10. But you can also follow this tutorial if you’re running Mac OS or Linux, just skip the following section for Windows.

Set up our VSCode environment on Windows 10

First, we need to install and set up our Development Environment. Because we want to run our Python application in a Linux Docker container with VSCode. Linux containers are lightweight and highly customizable. And they can run in very large and scaled environments, such as Kubernetes or Cloud Provider Services.

Install Windows Subsystem for Linux

Because we can’t run Linux containers natively on a Windows Operating System, we need to install our development environment with WSL2 (Windows Subsystem for Linux in version 2). It is a small virtual machine that runs a full Linux OS inside Windows 10. So, you can use it to develop, run and test your Docker Container locally, which makes development pretty easy.

To install Windows Subsystem for Linux on your Windows 10 machine, just follow the instructions in the official documentation.

Install Docker Desktop

The next step is installing Docker Desktop. So Docker Desktop is an application that connects to our default WSL2 machine and manages Docker Containers. It is not required to run containers on your virtual Linux OS but highly recommended. Because it makes the management of Linux Containers on Windows 10 very easy. With the right extensions in VSCode, we can later add some features that will make the build and debugging process for our Containers so much easier.

Again, just follow the official instructions to install Docker Desktop.

Add the right VSCode extensions for Python and Docker

There are also some VSCode Extensions, which I highly recommend. You can simply just search for them in VSCode Extensions, download and install them.

  • Docker – Makes it easy to create, manage, and debug containerized applications.
  • Remote WSL – Open any folder in the Windows Subsystem for Linux (WSL) and take advantage of Visual Studio Code’s full feature set.

Connect to WSL2 in VSCode

It’s very easy to run VSCode remotely on WSL2. You can just click on the Remote Connection Icon in VSCode, or open VSCode with the “code” command from your Windows Terminal Application. Let’s try the second method and create a new project folder for the application and open this remote workspace in VSCode.

If you execute the following commands in the WSL terminal, VSCode should open on your Windows 10 and automatically connect to your remote WSL workspace.

mkdir ~/vscode-docker-python

code vscode-docker-python

If you’re successfully connected to your WSL machine, you’ll see it in the bottom statusbar.

Build a simple Python application

Finally, we can now start developing our application. This should be the easy part for you. I don’t have any good example projects, so we will write a very simple application that will just add two numbers and output the result.

Create a new file and selection our Python interpreter

Let’s create a new Python file called app.py and place it in our workspace folder. If you get a message to select your Python Interpreter, you can simply select it. Because we need to tell WSL how we want to run Python programs. If you don’t get a message, but you want to select your standard Python interpreter, only for this workspace folder you can create a new file called .vscode/settings.json inside your workspace folder.

This is our main application script app.py

a = 5
b = 3

c = a + b

print(f"{a} + {b} is {c}")

print("program exited.")

Set the Python interpreter in .vscode/settings.json

{
    "python.pythonPath": "/usr/bin/python3"
}

Test our Python application without a container

To test and run our application without a container, we can simply execute the following command in the terminal. Or, if you have set up your Python interpreter correctly, you can also run it with F5 in VSCode and debug it.

python3 app.py

Build our first Docker Container

But of course, we want to deploy this Python application inside a Docker container with VSCode. The Docker extension in VSCode has a pretty comfortable function to generate all necessary files automatically for us. Don’t worry I will explain all the things the extension does, so you could also create all these files manually.

Generate Dockerfiles

To generate all files, press F1 and select “Add Docker Files to Workspace“. Simply follow the instructions, add your app.py as your main script and skip Docker-Compose.

How our Docker container is structured

Then, you should see some new files in your workspace folder. Because the Python Docker extension creates a complete environment for you in VSCode. It creates a Dockerfile, a requirements.txt, a .dockerignore, and some .vscode configuration files for you.

  • Dockerfile – This is the main file that contains all instructions how to generate and build the Docker image file
  • requirements.txt – Includes all necessary libraries and plugins that should be installed inside the Docker image
  • .dockerignore – All files that should not be included inside the Docker image
  • .vscode/launch.json – How to launch the application, debug it, etc.
  • .vscode/tasks.json – Any tasks that should be run by VSCode before the launch tasks

Let’s take a closer look at the Dockerfile.

# For more information, please refer to https://aka.ms/vscode-docker-python
FROM python:3.8-slim-buster

# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE=1

# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED=1

# Install pip requirements
COPY requirements.txt .
RUN python -m pip install -r requirements.txt

WORKDIR /app
COPY . /app

# Creates a non-root user with an explicit UID and adds permission to access the /app folder
# For more info, please refer to https://aka.ms/vscode-docker-python-configure-containers
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app
USER appuser

# During debugging, this entry point will be overridden. For more information, please refer to https://aka.ms/vscode-docker-python-debug
CMD ["python", "app.py"]

The first line with the FROM python:3.8-slim-buster statement defines our base image. Because we want to build our application on top of a base Linux distribution image. In this example, the python:3.8-slim-buster is a small and lightweight Debian Image with Python 3.8 installed.

The ENV PYTHONDONTWRITEBYTECODE=1 will stop Python from generating .pyc files in the container which we don’t need.

COPY requirements.txt and RUN python -m pip install -r requirements.txt will copy our requirements.txt file inside the container and install all packages that are described here. This is just a plain text file where you can list all pip packages with a specific version you need inside your container.

WORKDIR /app and COPY . /app set’s our work directory inside the container and copies the entire project folder (except files that are defined in the .dockerignore) into the container.

RUN adduser -u 5678 –disabled-password –gecos “” appuser && chown -R appuser /app and USER appuser is highly recommended for security reasons. Because it limits the permissions and user id that the application is using inside the container. This can help to prevent privilege escalation if our application has security vulnerabilities.

CMD [“python”, “app.py”] will execute the python command to run our application inside the container. The container automatically exits, when our python script exits.

Build the Docker image file and run it

The Docker extension in VSCode allows us to simply build the Docker image with a right click on the Dockerfile and select “Build Image”.

Open a new Terminal and type docker image list. Because then we can see a new entry called vscodedockerpython (the project folder name). We can also simply run this container and see that our application is running successfully!

What about debugging inside the container

The Docker extension in VSCode is absolutely beautiful! Because it also allows us to debug our application inside the container with no effort. In the past, I needed to install and use debugging libraries and extensions in Python, but this is not needed anymore. The extension is smart enough to rewrite our entry point file with a debugger automatically.

You simply just need to click on “Start debugging” and it works!

This is only possible, because the Docker extensions created the two files .vscode/launch.json and .vscode/tasks.json.

{
    "configurations": [
        {
            "name": "Docker: Python - General",
            "type": "docker",
            "request": "launch",
            "preLaunchTask": "docker-run: debug",
            "python": {
                "pathMappings": [
                    {
                        "localRoot": "${workspaceFolder}",
                        "remoteRoot": "/app"
                    }
                ],
                "projectType": "general"
            }
        }
    ]
}
{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "docker-build",
            "label": "docker-build",
            "platform": "python",
            "dockerBuild": {
                "tag": "vscodedockerpython:latest",
                "dockerfile": "${workspaceFolder}/Dockerfile",
                "context": "${workspaceFolder}",
                "pull": true
            }
        },
        {
            "type": "docker-run",
            "label": "docker-run: debug",
            "dependsOn": [
                "docker-build"
            ],
            "python": {
                "file": "app.py"
            }
        }
    ]
}

Set breakpoints and analyzing variables

This also supports breakpoints and analyzing variables natively inside the Container! Which is absolutely powerful and key to write complex applications in Python.

Leave a Comment

I accept the Privacy Policy