12

I am trying to integrate the Remote - Containers with my docker-compose.yaml.

However, my compose file is making use of the variable substitution feature.

services:
    command: yarn server
    environment:
        MONGO_URI: mongodb://database:27017/todo
    ports:
        - ${SERVER_PORT}:3000
        - ${SERVER_DEBUG_PORT}:9320

Typically I set these variables from a Makefile that wraps the docker-compose commands I run to start my development environment.

How can I set these environment variables before the extension creates the Dev Container via docker-compose?

I've attempted to use the initializeCommand in the following ways.

devcontainer.json

"initializeCommand": ". ./env.sh"
"initializeCommand": "source env.sh"

I also attempted to use remoteEnv in the devcontainer.json.

I also attempted to set settings.terminal.integrated.env.linux.

jshbrntt
  • 5,134
  • 6
  • 31
  • 60
  • 3
    Were you ever able to figure this out? This is still an issue for me. I replied to a GitHub issue but I'm unsure the VSCode team is even aware this is a problem. You can technically use a `.env` file but in our codebase we actually commit the `.env` file and keep a separate `.env.secrets` file for secrets. – dimiguel Mar 29 '22 at 00:27
  • 1
    Cross posted a bug report on the appropriate GitHub repository. https://github.com/microsoft/vscode-dev-containers/issues/1385 – jshbrntt Mar 31 '22 at 13:17
  • Can you use /etc/profile? – Carson Apr 04 '22 at 14:04
  • @Carson, that seemed promising, but adding "export MYVAR=something" to /etc/profile did not allow variable to added in my case. – Teghan Nightengale Jun 30 '22 at 22:15

1 Answers1

6

It doesn't seem possible to pass env created in the initializeCommand as env variable to the docker build command. My solution is to create an env file in the initializeCommand and pass it with the build context.

Here is the .devcontainer/devcontainer.json

{
  "build": {
    "dockerfile": "Dockerfile",
    "args": {
      "USERNAME": "${localEnv:USER}"
    }
  },
  "initializeCommand": "echo -e \"USERNAME=$USER\nUSER_UID=$(id -u $USER)\nGROUPNAME=$(id -gn $USER)\nGROUP_GID=$(id -g $USER)\" > .devcontainer/.env"
}

And in the Dockerfile

FROM xxx

ARG USERNAME=user
USER root

# Copy the .env file to the container
COPY .env /tmp/.env
# Source to use it
RUN source /tmp/.env && rm /tmp/.env && \
    if getent passwd $USERNAME; then userdel -f $USERNAME; fi && \
    if getent group $GROUPNAME; then groupdel $GROUPNAME; fi && \
    if getent group $GROUP_GID; then TMP_NAME=$(getent group $GROUP_GID | cut -d: -f1); groupdel $TMP_NAME; fi; \
    groupadd --gid $GROUP_GID $GROUPNAME && \
    useradd --uid $USER_UID --gid $GROUP_GID -m $USERNAME && \
    echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME && \
    chmod 0440 /etc/sudoers.d/$USERNAME && \
    chown $(eval echo ~$USERNAME) && \
    chmod 755 $(eval echo ~$USERNAME)

USER $USERNAME
Tom Yu
  • 131
  • 1
  • 6
  • I found need to use '.' instead of 'source'. This error when using source: `> [builder 7/7] RUN source /app/.env.secrets && rm /app/.env.secrets && ... /bin/sh: 1: source: not found` – Case Larsen Mar 30 '23 at 19:35
  • hey @Tom, thank you for sharing! this could be a great trick to achieve what i need to do i.e. run the container with a custom uid and gid, available at launch time. do you have any update on this? i mean, is this approach still valid, or you've found another solution? thanks in advance! – Equinox23 May 25 '23 at 15:31