containerEnv and remoteEnv issues in devcontainer and devcontainer-feature
related issues:
- https://github.com/microsoft/vscode-remote-release/issues/7766
docs:
- https://containers.dev/implementors/json_reference/
- https://containers.dev/implementors/features/
First test a devcontainer.json:
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-22.04",
"containerEnv": {
"WHATEVER1": "WHATEVER1",
"WHATEVER2": "$WHATEVER1",
"WHATEVER3": "${containerEnv:WHATEVER1}",
"WHATEVER4": "${remoteEnv:R_WHATEVER1}",
"WHATEVER5": "${containerEnv:HOME}",
"WHATEVER6": "${remoteEnv:HOME}",
"WHATEVER7": "$HOME",
"WHATEVER8": "${localEnv:HOME}"
},
"remoteEnv": {
"R_WHATEVER1": "WHATEVER1",
"R_WHATEVER2": "$WHATEVER1",
"R_WHATEVER3": "${containerEnv:WHATEVER1}",
"R_WHATEVER4": "${remoteEnv:R_WHATEVER1}",
"R_WHATEVER5": "${containerEnv:HOME}",
"R_WHATEVER6": "${remoteEnv:HOME}",
"R_WHATEVER7": "$HOME",
"R_WHATEVER8": "${localEnv:HOME}",
"PATH": "${containerEnv:PATH}:WHATEVER/bin"
}
}
build and check the env:
$ env | sort | grep WHATEVER
PATH=/vscode/vscode-server/bin/linux-x64/<...>/bin/remote-cli:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:WHATEVER/bin:/home/vscode/.local/bin
R_WHATEVER1=WHATEVER1
R_WHATEVER2=$WHATEVER1
R_WHATEVER3=WHATEVER1
R_WHATEVER4=${remoteEnv:R_WHATEVER1}
R_WHATEVER5=
R_WHATEVER6=${remoteEnv:HOME}
R_WHATEVER7=$HOME
R_WHATEVER8=/home/ubuntu
WHATEVER1=WHATEVER1
WHATEVER2=$WHATEVER1
WHATEVER3=${containerEnv:WHATEVER1}
WHATEVER4=${remoteEnv:R_WHATEVER1}
WHATEVER5=${containerEnv:HOME}
WHATEVER6=${remoteEnv:HOME}
WHATEVER7=$HOME
WHATEVER8=/home/ubuntu
Then the devcontainer-feature.json, remoteEnv is not allowed, and all the ${*:*} pattern will throw an error:
{
"name": "containerenv",
"id": "containerenv",
"version": "1.0.0",
"description": "",
"containerEnv": {
"WHATEVER1": "WHATEVER1",
"WHATEVER2": "$WHATEVER1",
"WHATEVER7": "$HOME"
},
"installsAfter": [
"ghcr.io/devcontainers/features/common-utils"
]
}
build and check the env:
$ env | sort | grep WHATEVER
WHATEVER1=WHATEVER1
WHATEVER2=WHATEVER1
WHATEVER7=
I have some questions:
-
Is it possible that the
devcontainer-feature.jsonkeep the same logic of containerEnv & remoteEnv withdevcontainer.jsonin the future? Or at least support the${localEnv:*}? -
Check the outputs, have you considered about evaluating these as empty string? Similar with the behavior of shell.
$ env | sort | grep WHATEVER R_WHATEVER4=${remoteEnv:R_WHATEVER1} R_WHATEVER6=${remoteEnv:HOME} WHATEVER3=${containerEnv:WHATEVER1} WHATEVER4=${remoteEnv:R_WHATEVER1} WHATEVER5=${containerEnv:HOME} WHATEVER6=${remoteEnv:HOME}
Yeah, I need to access some credentials in install.sh and for now I had to try to fall back to mounting some kind of file instead of using env vars.
P. S.
devcontainer-feature.json
"containerEnv": {
"ARTIFACTORY_USERNAME": "${localEnv:ARTIFACTORY_USERNAME}",
"ARTIFACTORY_PASSWORD": "${localEnv:ARTIFACTORY_PASSWORD}"
}
remoteContainers-….log
[2024-02-20T20:47:34.686Z] ERROR: failed to solve: rpc error:
code = Unknown
desc = failed to solve with frontend dockerfile.v0: failed to solve with frontend gateway.v0:
rpc error: code = Unknown
desc = failed to process "\"${localEnv:ARTIFACTORY_USERNAME}\"": unsupported modifier (A) in substitution
/tmp/devcontainercli-USERNAME/container-features/0.56.0-1708462050881/Dockerfile.extended
ENV ARTIFACTORY_USERNAME="${localEnv:ARTIFACTORY_USERNAME}"
ENV ARTIFACTORY_PASSWORD="${localEnv:ARTIFACTORY_PASSWORD}"
RUN --mount=type=bind,from=dev_containers_feature_content_source,source=MY_FEATURE_NAME_0,target=/tmp/build-features-src/MY_FEATURE_NAME_0 \
cp -ar /tmp/build-features-src/MY_FEATURE_NAME_0 /tmp/dev-container-features \
&& chmod -R 0755 /tmp/dev-container-features/MY_FEATURE_NAME_0 \
&& cd /tmp/dev-container-features/MY_FEATURE_NAME_0 \
&& chmod +x ./devcontainer-features-install.sh \
&& ./devcontainer-features-install.sh \
&& rm -rf /tmp/dev-container-features/MY_FEATURE_NAME_0
Can't use devcontainer-feature.json:.mounts
"mounts": [
{
"source": "$HOME/.netrc",
"target": "/root/.netrc",
"type": "bind"
}
]
Because it's not mounted when install.sh is executed:
> [dev_containers_target_stage 5/6] \
RUN --mount=type=bind,from=dev_containers_feature_content_source,source=MY_FEATURE_NAME_0,target=/tmp/build-features-src/MY_FEATURE_NAME_0 \
cp -ar /tmp/build-features-src/MY_FEATURE_NAME_0 /tmp/dev-container-features \
&& chmod -R 0755 /tmp/dev-container-features/MY_FEATURE_NAME_0 \
&& cd /tmp/dev-container-features/MY_FEATURE_NAME_0 \
&& chmod +x ./devcontainer-features-install.sh \
&& ./devcontainer-features-install.sh \
&& rm -rf /tmp/dev-container-features/MY_FEATURE_NAME_0:
Hello!
Thanks for providing a detailed description of the issue, very helpful.
Is it possible that the devcontainer-feature.json keep the same logic of containerEnv & remoteEnv with devcontainer.json in the future? Or at least support the ${localEnv:*}?
This request makes sense, moving this issue to the spec repo.