Setting up Visual Studio Code with Docker as a development environment for Python

Bernd Bornhausen
6 min readJan 24, 2022

If you are like me, you are always looking to include something new into your toolbox. In this case, I am not putting only one tool into the box, but three!

And as mentioned in the title, I am talking about Visual Studio Code (VSC), Python, and Docker!

In this article, I do not want to discuss why choosing one integrated development environment(IDE) over another, and yes, I know some say VSC is not a full-blown IDE, or why to pick Python instead of Java or any other programming/scripting language.

Instead, I would like to show you how to set up VSC to start a Python development environment to be used for example for test automation. Complete with linting and debugging capabilities. This will be the basis for future articles where I will showcase the screenplay pattern, for example, robot framework, chat-ops integration, or the integration with testproject.io including our very own selenium grid.

So here we go:
The first thing we need to do is to install VSC and Docker Desktop, I will not go into the details as it is rather straightforward.
Tip: Check the option to start docker at startup, unless you want to explicitly start the docker service every time by hand.

Having installed both VSC and Docker we can start building our development environment. For this, we create a folder that will hold all our data related to the project, i.e. VSC configuration files and the Source Code itself. For the moment we will keep our code in a folder that will be shared between the host and the docker container; later we will utilize GIT to store and retrieve our source code.
Using the command line, navigate to the place where you want to create your project and create a folder, I named my one basic_docker_setup and created it in my C:\DEV\ folder. This can be done using the ‘File Explorer’ as well. I am using Windows as my OS, but I am pretty sure that this example works as well on Linux or Mac.

Now, ‘cd’ into the folder and enter the command ‘code .’. This will open Visual Studio Code with your folder as base folder and the screen should look like this:

Visual Studio Code Startup

We answer the question if we trust the author with ‘yes I trust’ for obvious reasons 😊

Once that is out of the way, you will be on the welcome page of VSC; let the fun begin!

Setting up Docker within VSC

As you have Docker installed, you might have noticed a pop-up in the lower right corner asking you if you want to install the Docker extension.

Of course! So hit the install button and install the Docker extension in order to launch Docker commands from VSC; that’s why we are here, right?

If you missed that pop-up or it did not show, or you want to install other extensions, you can go over to the extensions section (Ctrl+Shift+x) and search/install extensions to your liking. You might ask yourself if you should install the Python extension which provides you with syntax highlighting and other goodies.
The answer is: It depends.
If you would like to develop Python code on your local system, in that case, the answer is yes. If you ‘only’ plan to use Python within the docker container, the answer is no. I will leave it to not be installed as I will be developing using the Docker container only.

Returning to the Explorer section (Ctrl+Shift+e) we can now start to prepare our Docker environment!
One way to do so is to use the built-in commands like ‘Docker: Add Docker Files to Workspace’ via the command interface (Ctrl+Shift+p). That would create a Dockerfile in the workspace based on the language that we picked. From there you can modify the Dockerfile to your needs. The next step would be to create a ‘Remote-Container’ configuration, as we want to launch the Dockerfile as our development environment and not ‘only’ as a running container as we would do with a ‘docker run’ command.

As I went through this process of using build-in commands and customizing the appropriate files to my needs, we can skip that step and dive directly into the configuration!

The first thing we need to do is to create a new folder with the name ‘.devcontainer’. The ‘.’ is important!
This folder tells VSC that we are not doing development locally, but using a remote Docker container.

Within this folder, we create a file called ‘Dockerfile’ with no extension. This will be the build script for our development container, the same way as we would do for a ‘normal’ Docker configuration. In fact, VSC uses the same Docker configurations and tools in the background.

My Dockerfile looks like this:

#The base image for the container 
FROM python:3.9-slim-buster

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

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

# Copy python requirements to the docker container and install
COPY requirements.txt .
RUN python -m pip install -r requirements.txt

#create a non root user to access the container
RUN adduser -u 5678 —-disabled-password --gecos “” vscode

In order for VSC to use this Dockerfile to build your environment, you need to add a configuration file called ‘devcontainer.json’.

In this file, you are referring to the Dockerfile you will be using and where to find it. The parameter “context” takes care of the latter:

"build": {"dockerfile": "Dockerfile","context": "."}

In the next article I will be moving from using a single Dockerfile to a Docker-Compose file in order to launch multiple docker images at the same time, so stay tuned.

The ‘devcontainer.json’ file is also used to add VSC-specific configuration to the Docker container. In this case, I am installing the Pylance and the Python extension so that it is available within VSC once I launch the container:

"extensions": ["ms-python.python","ms-python.vscode-pylance"]

It is also used to configure the linter etc. for Python like Black, Pylint, etc.

"settings": {"editor.formatOnSave": true,"python.formatting.provider": "black","python.defaultInterpreterPath": "/usr/local/bin/python","python.languageServer": "Pylance","python.linting.enabled": true,"python.linting.pylintEnabled": true,"python.linting.pycodestyleEnabled": true,"python.formatting.autopep8Path": "/usr/local/bin/autopep8","python.formatting.blackPath": "/usr/local/bin/black","python.formatting.yapfPath": "/usr/local/bin/yapf","python.linting.banditPath": "/usr/local/bin/bandit","python.linting.flake8Path": "/usr/local/bin/flake8","python.linting.mypyPath": "/usr/local/bin/mypy","python.linting.pycodestylePath": "/usr/local/bin/pycodestyle","python.linting.pydocstylePath": "/usr/local/bin/pydocstyle","python.linting.pylintPath": "/usr/local/bin/pylint"

The complete file I am using looks like this:

"name": "Python 3","build": {"dockerfile": "Dockerfile","context": "."},"extensions": ["ms-python.python","ms-python.vscode-pylance"],"remoteUser": "vscode","settings": {"editor.formatOnSave": true,"python.formatting.provider": "black","python.defaultInterpreterPath": "/usr/local/bin/python","python.languageServer": "Pylance","python.linting.enabled": true,"python.linting.pylintEnabled": true,"python.linting.pycodestyleEnabled": true,"python.formatting.autopep8Path": "/usr/local/bin/autopep8","python.formatting.blackPath": "/usr/local/bin/black","python.formatting.yapfPath": "/usr/local/bin/yapf","python.linting.banditPath": "/usr/local/bin/bandit","python.linting.flake8Path": "/usr/local/bin/flake8","python.linting.mypyPath": "/usr/local/bin/mypy","python.linting.pycodestylePath": "/usr/local/bin/pycodestyle","python.linting.pydocstylePath": "/usr/local/bin/pydocstyle","python.linting.pylintPath": "/usr/local/bin/pylint"}}

The last file we need to create is the requirements.txt file holding the Python modules we want to have installed within the container. A very basic one that is used as a base for all my development work would look like this:

pylintpycodestyleblack

Now that the configuration part is out of the way, the only thing we need to do now is to start the container!

For that, we open the command palette (Ctrl+Shift+P or F1) and select the command:

Remote-containers: Rebuild and Reopen in Container

This will close the current view of VSC and reopen the editor in the remote container, in that case, our Docker container.

This might take a few instances as the container base image will be downloaded from docker-hub and our Python modules will be installed.
If all went well, we should be presented with a VSC session within the container:

File explorer in the dev container

From here on, you can start your development within the container.

Next steps:

  • Move away from Dockerfile to use a Docker-Compose file in order to start multiple containers
  • Configure GIT for source control
  • Using a remote docker host to start our container

--

--

Bernd Bornhausen

IT guy with 15+ years experience in Quality Assurance aka testing. My motto: Why keep your knowlegde when you can share it with others?