Running Docker Compose in Codespaces

Using the built-in docker-compose configuration in GitHub Codespaces is limited. It’s better to run docker-compose inside the Codespace but this requires a docker-in-docker setup which is finicky.

Here’s how to use docker-compose from Codespaces so that everything is set up when the codespace is created.

In .devcontainer/devcontainer.json:

{
    "name": "My Space",
    // The dockerfile will be at te root of the project
    "build": {"dockerfile": "../Dockerfile"},
    // Your code path from the .devcontainer directory
    "workspaceFolder": "../app",
    // List of ports that you want to preview
    "forwardPorts": [1234, 5678],
    // Script to run to bootstrap the app when the space is created
    "postCreateCommand": ". ../path_to_setup_script.sh",
    // Automatically start the app in subsequent sessions
    "postStartCommand": "cd app && docker-compose start",
    // Privileged flag is needed to run docker-in-docker, the volume
    // is needed or docker build will fail
    "runArgs": ["--volume=/var/lib/docker", "--privileged"],
    "postCreateCommand": ". /app/scripts/codespaces.sh"
}

In DockerFile at the root of the project:

FROM alpine:3.15.4

RUN apk update
RUN apk add --no-cache git
RUN apk add --no-cache docker-engine
RUN apk add --no-cache docker-cli
RUN apk add --no-cache docker-compose

ADD ./app /app

EXPOSE 8000
EXPOSE 35729
EXPOSE 3000
EXPOSE 1313

In your setup script:

# Assumes docker-compose.yaml is at the root /app root
cd app
# This setup script depends on running some code in other containers
dockerd &
# Ugh yes there's no nice way to wait until dockerd is ready
sleep 5
# Do whatever setup you need
docker-compose up -d
docker-compose exec {some command to run migrations etc}
# If you need to use docker for this setup script you must stop all containers
# otherwise, any servers running in docker will not have their ports
# forwarded properly by codespaces.
docker-compose stop

See also: