DEV Community

Chris Schneider
Chris Schneider

Posted on

Streamline your Workflow with VSCode Dev Containers & Red Hat Images

In this tutorial I’ll describe how I set up my dev environment using VSCode Dev Containers, Python/Poetry/FastAPI/PyTest and Red Hat Base Images.

VSCode’s Dev Containers offer a seamless way to manage project environments. By containerizing your development environment, you achieve a consistent setup across different machines, avoiding the dreaded “it works on my machine” syndrome. This approach keeps your primary OS clean from various project dependencies and ensures your development environment closely resembles the production setup, reducing deployment surprises.

Installing Dev Containers

First, install Docker and the Dev Containers extension in VSCode. If you use Podman, set the Docker path to your podman CLI path:

Specify the podman CLI path. You can determine the path with 'which podman' Specify the podman CLI path. You can determine the path with which podman

Setting up the Dev Container

To setup Dev Containers, create a .devcontainer/devcontainer.json file:

{
    "build": {
        "context": "..",
        "dockerfile": "./Dockerfile"
    },
    "workspaceMount": "source=${localWorkspaceFolder},target=/opt/app-root/src/workspace/,type=bind",
    "workspaceFolder": "/opt/app-root/src/workspace/",
    "customizations": {
        "vscode": {
            "settings": {
                "python.defaultInterpreterPath": "/opt/app-root/bin/python",
                "python.formatting.autopep8Path": "/opt/app-root/bin/autopep8",
                "python.linting.pylintPath": "/opt/app-root/bin/pylint"
            },
            "extensions": [
                "ms-python.python",
                "ms-python.vscode-pylance",
                "ms-python.pylint",
                "ms-python.autopep8",
                "ms-azuretools.vscode-docker"
            ]
        }
    },
    "postCreateCommand": "poetry install --no-interaction --no-ansi --no-root --with dev",
    "runArgs": [
        "--env-file",
        ".env"
    ],
    "forwardPorts": [
        4000
    ]
}
Enter fullscreen mode Exit fullscreen mode

This file specifies the container build context, workspace config and essential Python settings. The postCreateCommand ensures all Poetry dependencies are installed when the container is created. runArgs loads environment variables from a local .env file and forwardPorts allows access to services running in the container.

Next, let’s explore the .devcontainer/Dockerfile to understand how the container is built:

FROM registry.access.redhat.com/ubi9/python-311:latest

# Install terraform & oh-my-zsh
USER root
RUN yum install -y yum-utils && \
    yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo && \
    yum -y install terraform zsh && \
    wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh
USER 1001

# Install poetry
RUN pip install poetry && \
    poetry config virtualenvs.create false

# Set default shell to zsh
ENV SHELL /bin/zsh

# Create workspace dir used by VSCode
RUN mkdir /opt/app-root/src/workspace/

# Expose ports
EXPOSE 4000
Enter fullscreen mode Exit fullscreen mode

As a base container I use Red Hat’s UBI Python image to provide a stable and secure foundation, which brings my dev environment to production. Furthermore, I install Terraform, Oh-My-Zsh and Poetry as a package manager for Python.

In your pyproject.toml file, specify your dependencies, pytest config etc:

[tool.poetry.dependencies]
...

[tool.poetry.dev-dependencies]
autopep8 = "^2.0.4"
pylint = "^3.0.2"
pytest = "^7.4.3"
...

[tool.pytest.ini_options]
python_files = "*_tests.py"
testpaths = ["lib", "tests"]
Enter fullscreen mode Exit fullscreen mode

Running the Dev Container

Now, let’s open the VSCode project in your container:

Running the VSCode project inside the dev container Running the VSCode project inside the dev container

Run, Debug & Test Integration

Next, we can further customize our VSCode setup by enabling linting, pytest-integration and auto-format. Therefore, you can either extend the devcontainer.json or create a .vscode/settings.json file:

{
    "editor.formatOnSave": true,
    "python.linting.enabled": true,
    "python.testing.pytestEnabled": true,
    "python.testing.unittestEnabled": false,
    "python.editor.defaultFormatter": "ms-python.autopep8"
}
We can also specify how VSCode can launch & debug our python app, for example for FastAPI we can use this vscode/launch.json configuration:
{
    "configurations": [
        {
            "name": "Start API",
            "type": "python",
            "request": "launch",
            "module": "uvicorn",
            "args": [
                "main:app",
                "--port",
                "4000",
                "--reload"
            ],
            "justMyCode": true
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

With the setup now complete, you can efficiently run and test your FastAPI project directly from the IDE. This integration offers the convenience of streamlined debugging and testing, enhancing your dev workflow:

Running & debugging the application Running & debugging the application

Running unit tests with pytest Running unit tests with pytest

Top comments (0)