devcontainers / spec

Development Containers: Use a container as a full-featured development environment.
https://containers.dev
Creative Commons Attribution 4.0 International
3.62k stars 234 forks source link

Clarity on how docker compose based devcontainers are built #331

Open amitds1997 opened 1 year ago

amitds1997 commented 1 year ago

The spec does not provide clarity on how to specify the build context for a Docker compose build. Considering the following project structure

| .devcontainer
     | devcontainer.json
| docker-compose.yml
| Dockerfile
| requirements.txt

How should I specify the build context? This is a sample repository: https://github.com/amitds1997/devpod-cache-issue.

Reference devcontainer.json:

{
  "name": "Debug service",
  "dockerComposeFile": "../docker-compose.yml",
  "service": "main-app",
  "workspaceFolder": "/root",
  "shutdownAction": "stopCompose",
}

Should it be specified as:

  1. In .devcontainer.json file, or
{
 "build": {
    "context": ".."
  },
}
  1. In docker-compose.yml file (to indicate that it is one directory above from devcontainer.json file where it is used)
version: '3'

services:
  main-app:
    build:
      context: ..
    restart: always
    ports:
    - "5003:5000"
    command: python -m http.server 5000
  1. Or, should it be assumed to be running from the docker-compose.yml's directory?
samruddhikhandale commented 1 year ago

Hi 👋

In .devcontainer.json file, or

According to https://containers.dev/implementors/json_reference/#compose-specific, for docker compose containers, we don't allow that property. build.context is only helpful for images or dockerfile based containers.

In docker-compose.yml file (to indicate that it is one directory above from devcontainer.json file where it is used)

The build.context in the docker-compose.yml file uses the definition from Docker. See https://docs.docker.com/compose/compose-file/build/#context (context defines either a path to a directory containing a Dockerfile, or a URL to a git repository.)

Hence, in your case build should be defined as follows 👇

services:
  main-app:
    build:
      context: .
      dockerfile: Dockerfile

Let us know if this makes sense, or if you have any more questions.

Feel free to take a look at https://github.com/devcontainers/templates/tree/main which has more examples (eg. go-postgres Template)

Also, you can refer to https://containers.dev/guide/dockerfile which explains the use of Images, Dockerfiles, and Docker Compose.

samruddhikhandale commented 1 year ago

One more note, we usually recommend folks to have all their container file configs in .devcontainer folder.

eg.

| .devcontainer
    | devcontainer.json
    | docker-compose.yml
    | Dockerfile
| requirements.txt
amitds1997 commented 1 year ago

Thanks, that makes sense 👍

Follow up questions

  1. Would it be correct to say that devcontainer would set the working directory to the path of the docker compose file for the code structure in the issue description as stated in docker compose doc?

  2. For scenarios where the docker-compose.yml cannot be in the .devcontainer folder (to avoid breaking existing workflows e.g. in CI) what would you recommend?

samruddhikhandale commented 1 year ago
  1. Would it be correct to say that devcontainer would set the working directory to the path of the docker compose file for the code structure in the issue description as stated in docker compose doc?

It would ideally use the workspaceFolder (The path of the workspace folder inside the container.) property from devcontainer.json to determine the working directory.

  1. For scenarios where the docker-compose.yml cannot be in the .devcontainer folder (to avoid breaking existing workflows e.g. in CI) what would you recommend?

I think that should be fine as long as dev container creations are succeeding. We try to recommend users to do it that way, but it's not a compulsion.

amitds1997 commented 1 year ago

It would ideally use the workspaceFolder (The path of the workspace folder inside the container.) property from devcontainer.json to determine the working directory.

Excuse me for not being clear in the question. I meant the working directory for building the docker compose images. Would it follow the convention followed by docker compose (which is the path of the first docker compose file provided) or would it be set to the .devcontainer directory? Because the build context would then be specified relative to this working directory.