running devcontainer/cli from within a devcontainer
Hi,
sorry upfront for a long description. My use case is to provide a unified development experience to my team, requiring a minimal system installation, ideally only docker (desktop) and vscode with remote containers extension.
We use a monorepo setup, with multiple subprojects that have different dependancies, i.e.
monorepo_root/
project1/
project2/
I was hoping I can set up a devcontainer in the monorepo_root, which would include devcontainer cli to launch project specific devcontainers, i.e.
monorepo_root/
.devcontainer/
devcontainer.json
project1/
.devcontainer/
devcontainer.json
project2/
.devcontainer/
devcontainer.json
monorepo_root devcontainer would include docker-from-docker and node features, and I would install devcontainer cli as part of postCreateCommand, i.e.
"features": {
"ghcr.io/devcontainers/features/docker-from-docker:1": {},
"ghcr.io/devcontainers/features/node:1": {},
},
"postCreateCommand": "npm install -g @devcontainers/cli"
I would then like to be able to launch specific project devcontainers from within monorepo_root devcontainer, i.e.
vscode ➜ /workspaces/monorepo_root $ devcontainer up --workspace-folder project1
The issue im experiencing is due to docker bind mounts from within a devcontainer, i.e. when I run the above command devcontainer cli fails because source=/workspaces/monorepo_root does not exist on the host.
I had a similar issue with deploying services with docker-compose from within the devcontainer which I could work around with an environment variable, i.e. in devcontainer.json:
"containerEnv": {
"REPO_ROOT": "${localWorkspaceFolder}",
},
"features": {
"ghcr.io/devcontainers/features/docker-from-docker:1": {},
"ghcr.io/devcontainers/features/node:1": {},
},
"postCreateCommand": "npm install -g @devcontainers/cli"
and in docker-compose.yml
volumes:
- '${REPO_ROOT-.}/project1:/app'
However, devcontainer cli mounts the --workspace-folder by default.
- Is there any work around I could use?
- Is my thinking and setup not supported?
- Would a supported scenario always require devcontainer cli and hence node installation on the host system?
Thanks, Wiktor
full devcontainer cli log
vscode ➜ /workspaces/monorepo_root $ devcontainer up --workspace-folder project1
[10 ms] @devcontainers/cli 0.24.1. Node.js v18.12.1. linux 5.15.49-linuxkit arm64.
[2746 ms] Start: Run: docker buildx build --load --build-arg BUILDKIT_INLINE_CACHE=1 -f /tmp/devcontainercli-vscode/container-features/0.24.1-1669132764626/Dockerfile-with-features -t vsc-project1-XXX --target dev_containers_target_stage --build-arg --add-host=host.docker.internal:host-gateway --build-arg _DEV_CONTAINERS_BASE_IMAGE=vscode_dev /workspaces/monorepo_root
[+] Building 0.8s (13/13) FINISHED
=> [internal] load build definition from Dockerfile-with-features 0.0s
=> => transferring dockerfile: 5.23kB 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 34B 0.0s
=> [internal] load metadata for mcr.microsoft.com/devcontainers/base:ubu 0.7s
=> [base 1/1] FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04@sha 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 111B 0.0s
=> CACHED [vscode_dev 1/6] RUN apt-get update && apt-get install --n 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:831d199b53291cf3508704546fdddc506297dc6276c3e 0.0s
=> => naming to docker.io/library/vsc-project1-e375df294837921ccb151d03fa1c8f 0.0s
=> exporting cache 0.0s
=> => preparing build cache for export 0.0s
[4282 ms] Start: Run: docker run --sig-proxy=false -a STDOUT -a STDERR --mount type=bind,source=/workspaces/monorepo_root,target=/workspaces/monorepo_root -l devcontainer.local_folder=/workspaces/monorepo_root/project1 -e APP_PORT=5000 -e GIT_EDITOR=vi --env-file ../.env.local --entrypoint /bin/sh vsc-project1-XXX-uid -c echo Container started
docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /workspaces/monorepo_root.
See 'docker run --help'.
Error: Command failed: docker run --sig-proxy=false -a STDOUT -a STDERR --mount type=bind,source=/workspaces/monorepo_root,target=/workspaces/monorepo_root -l devcontainer.local_folder=/workspaces/monorepo_root/project1 -e APP_PORT=5000 -e GIT_EDITOR=vi --env-file ../.env.local --entrypoint /bin/sh vsc-project1-XXX-uid -c echo Container started
trap "exit 0" 15
exec "$@"
while sleep 1 & wait $!; do :; done -
at Coe (/usr/local/share/nvm/versions/node/v18.12.1/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:1893:1355)
at oT (/usr/local/share/nvm/versions/node/v18.12.1/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:1893:1291)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async _oe (/usr/local/share/nvm/versions/node/v18.12.1/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:1899:2128)
at async Zf (/usr/local/share/nvm/versions/node/v18.12.1/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:1899:3278)
at async iue (/usr/local/share/nvm/versions/node/v18.12.1/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:2019:15058)
at async nue (/usr/local/share/nvm/versions/node/v18.12.1/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:2019:14812)
{"outcome":"error","message":"Command failed: docker run --sig-proxy=false -a STDOUT -a STDERR --mount type=bind,source=/workspaces/monorepo_root,target=/workspaces/monorepo_root -l devcontainer.local_folder=/workspaces/monorepo_root/project1 -e APP_PORT=5000 -e GIT_EDITOR=vi --env-file ../.env.local --entrypoint /bin/sh vsc-project1-XXX-uid -c echo Container started\ntrap \"exit 0\" 15\n\nexec \"$@\"\nwhile sleep 1 & wait $!; do :; done -","description":"An error occurred setting up the container."}
- Is there any work around I could use?
You can modify the default mount using "workspaceMount" in the devcontainer.json.
- Is my thinking and setup not supported?
It's not supported, maybe we could add a CLI option for the host's path to the repository root.
- Would a supported scenario always require devcontainer cli and hence node installation on the host system?
Do you need the container containing the dev container CLI to be a dev container itself? You could build the image with devcontainer build, push it to a container registry and then pull and start it with the Docker CLI without the need for the dev container CLI.
Closing due to lack of activity.