Search code examples
dockervscode-devcontainer

VSCode devcontainer workflow and file organization: best practice to build "production container"


I have a Python project that I am developing inside a devcontainer. The source code tree looks like this:

---.devcontainer
     |--- .devcontainer.json
     |--- Dockerfile
     |--- requirements.txt
---src
    |--- file1.py
    |--- file2.py

The problem is that it is supposed to be released into a "production container," which involves its own Dockerfile and packaging scripts.

My questions are:

  1. Where should I put the "production container" Dockerfile and packaging scripts?
  2. Where should I create the production container? Should I run docker build inside the dev container?
  3. When should I run docker build to build the production container?

Solution

  • The Dockerfile should be named exactly Dockerfile, with no extension, and be in the root of your project directory (next to pyproject.toml). This is the default location docker build expects to find it.

    There is not a similar canonical location for build scripts. It's common enough to keep them in the project root also, or to have a build or bin or docker directory that contains them.

    It looks like VSCode doesn't automatically mount the Docker socket into a dev container and so you wouldn't be able to run docker commands by default. You'd have to make sure to both mount the socket and install the Docker CLI. It's probably easier to run docker build directly on the host system.

    (While you're there, consider using the Python preinstalled on your MacOS or Linux host for ordinary development, or non-container tools like Hatch or Pyenv that can maintain alternate Python installations.)

    You need to run docker build whenever you need an updated copy of the image. I'd generally recommend this for local integration testing. You'll frequently have an automated build system that will build the image for you when you commit to source control, so you won't typically need to manually build-push-deploy an image. Similarly, I'd use your developer tools to run ordinary unit tests (pytest, hatch test as a wrapper) without involving containers at all.