microsoft / vscode-remote-release

Visual Studio Code Remote Development: Open any folder in WSL, in a Docker container, or on a remote machine using SSH and take advantage of VS Code's full feature set.
https://aka.ms/vscode-remote
Other
3.62k stars 277 forks source link

Remote container is not picking up set environment variables #4585

Closed MAnfal closed 2 years ago

MAnfal commented 3 years ago

I am getting this problem with Laravel. I am trying to set up WWWGROUP and WWWUSER variables to dynamically fetch and persist in the env and the Dockerfile is unable to get them when passed via devcontainer.json through docker-compose.yml to Dockerfile.

I have tried everything containerEnv, remoteEnv, build.args but none pass the environment values down.

This is how my current setup looks like.

docker-compose.yml

# For more information: https://laravel.com/docs/sail
version: '3'
services:
    laravel.test:
        build:
            context: ./docker/dev/8.0
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: sail-8.0/app
        ports:
            - '${APP_PORT:-80}:80'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
        volumes:
            - '.:/var/www/html'
        networks:
            - sail
        depends_on:
            - mysql
            # - pgsql
            - redis
            # - selenium
    # selenium:
    #     image: 'selenium/standalone-chrome'
    #     volumes:
    #         - '/dev/shm:/dev/shm'
    #     networks:
    #         - sail
    mysql:
        image: 'mysql:8.0'
        ports:
            - '${FORWARD_DB_PORT:-3306}:3306'
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
        volumes:
            - 'sailmysql:/var/lib/mysql'
        networks:
            - sail
        healthcheck:
          test: ["CMD", "mysqladmin", "ping"]
#    pgsql:
#        image: postgres:13
#        ports:
#            - '${FORWARD_DB_PORT:-5432}:5432'
#        environment:
#            PGPASSWORD: '${DB_PASSWORD:-secret}'
#            POSTGRES_DB: '${DB_DATABASE}'
#            POSTGRES_USER: '${DB_USERNAME}'
#            POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
#        volumes:
#            - 'sailpostgresql:/var/lib/postgresql/data'
#        networks:
#            - sail
#        healthcheck:
#          test: ["CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}"]
    redis:
        image: 'redis:alpine'
        ports:
            - '${FORWARD_REDIS_PORT:-6379}:6379'
        volumes:
            - 'sailredis:/data'
        networks:
            - sail
        healthcheck:
          test: ["CMD", "redis-cli", "ping"]
    # memcached:
    #     image: 'memcached:alpine'
    #     ports:
    #         - '11211:11211'
    #     networks:
    #         - sail
    mailhog:
        image: 'mailhog/mailhog:latest'
        ports:
            - '${FORWARD_MAILHOG_PORT:-1025}:1025'
            - '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025'
        networks:
            - sail
networks:
    sail:
        driver: bridge
volumes:
    sailmysql:
        driver: local
#    sailpostgresql:
#        driver: local
    sailredis:
        driver: local

Dockerfile

FROM ubuntu:20.04

ARG WWWGROUP

WORKDIR /var/www/html

ENV DEBIAN_FRONTEND noninteractive
ENV TZ=UTC

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt-get update \
    && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 \
    && mkdir -p ~/.gnupg \
    && chmod 600 ~/.gnupg \
    && echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf \
    && apt-key adv --homedir ~/.gnupg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys E5267A6C \
    && apt-key adv --homedir ~/.gnupg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C300EE8C \
    && echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu focal main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
    && apt-get update \
    && apt-get install -y php8.0-cli php8.0-dev \
       php8.0-pgsql php8.0-sqlite3 php8.0-gd \
       php8.0-curl php8.0-memcached \
       php8.0-imap php8.0-mysql php8.0-mbstring \
       php8.0-xml php8.0-zip php8.0-bcmath php8.0-soap \
       php8.0-intl php8.0-readline \
       php8.0-msgpack php8.0-igbinary php8.0-ldap \
       php8.0-redis \
    && php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
    && curl -sL https://deb.nodesource.com/setup_15.x | bash - \
    && apt-get install -y nodejs \
    && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
    && apt-get update \
    && apt-get install -y yarn \
    && apt-get install -y mysql-client \
    && apt-get -y autoremove \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.0

RUN groupadd --force -g $WWWGROUP sail
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail

COPY start-container /usr/local/bin/start-container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY php.ini /etc/php/8.0/cli/conf.d/99-sail.ini
RUN chmod +x /usr/local/bin/start-container

EXPOSE 8000

ENTRYPOINT ["start-container"]

devcontainer.json

{
    "name": "Tailor Docs Dev Environment (VS Code)",

    "dockerComposeFile": "../docker-compose.yml",

    "service": "laravel.test",

    "initializeCommand": "./.devcontainer/init",

    "extensions": [
        "formulahendry.auto-close-tag",
        "eamodio.gitlens",
        "zignd.html-css-class-completion",
        "isudox.vscode-jetbrains-keybindings",
        "christian-kohler.path-intellisense",
        "octref.vetur",
        "dariofuzinato.vue-peek",
        "mikestead.dotenv"
    ],

    "workspaceFolder": "/var/www/html",

    "settings": {
        "terminal.integrated.shell.linux": "/bin/bash"
    },

    "remoteEnv": {
        "WWWGROUP": "${WWWGROUP:-$(id -g)}",
        "WWWUSER": "${WWWUSER:-$UID}"
    }
}
2percentsilk commented 3 years ago

cc @chrmarti @bamurtaugh

MAnfal commented 3 years ago

Sorry, I forgot to provide an update on this. I am adding this just in case someone else faces this. The main idea here was to create a wrapper on laravel sail to create a deployable dev environment for Laravel 8. The above approach wasn't adding the environment variables to the container so ended up sharing the top level Laravel's .env file. Docker easily picks the env from them. I am not sure how this will be solved for the containers but for now, I found a solution that works for myself.

This is what I had to do to make it happen.

Add "initializeCommand": "./.devcontainer/init $(pwd)", in .devcontainer.json.

init file

#!/usr/bin/env bash

FILENAME="$1/.env"

if ! [ -f $FILENAME ]; then
    touch $FILENAME
fi

# New env vars should be added here.

envVars=(
    "WWWUSER=${WWWUSER:-$UID}"
    "WWWGROUP=${WWWGROUP:-$(id -g)}"
    "LARAVEL_SAIL=1"
)

is_addition_needed() {
    for envVar in ${envVars[@]}; do
        if ! grep -Fxq "$envVar" $FILENAME
        then
            return 1
        fi
    done

    return 0
}

add_values() {
    for envVar in ${envVars[@]}; do
        if ! grep -Fxq "$envVar" $FILENAME
        then
            echo "$envVar" >> $FILENAME
        fi
    done
}

# Check if the comments should be added
is_addition_needed
should_add_warnings=$?

if [ $should_add_warnings -eq 1 ];
then
    echo "" >> $FILENAME
    echo "# Begin VSCode devcontainer Environment. DO NOT REMOVE" >> $FILENAME
fi

add_values

if [ $should_add_warnings -eq 1 ];
then
    echo "# End VSCode devcontainer Environment. DO NOT REMOVE" >> $FILENAME
    echo "" >> $FILENAME
fi
chrmarti commented 3 years ago

"remoteEnv" is only passed to the server process inside the container, not to the docker-compose.yml. Using .env or env_file on the service is probably the best approach at the moment. Also the devcontainer.json doesn't support inline command evaluation, so using "initializeCommand" is the only way to run id here.

Not sure what we would ideally do to improve this, but there are several feature requests in this area. Closing as resolved question. Thanks.

MAnfal commented 3 years ago

Hi @chrmarti I understand the resolution but I would suggest using the above information to reproduce it. The main purpose is to get the env in the container but the support is really not there if the container starts from docker-compose.

I tried every configuration for environment in dev container and none worked. Even passing a different env file via env_file command didn't work when I initialized the container using vscode.

I really wanted to avoid polluting the .env since it was used by laravel and I was more or less forced to use this option after a lot of trial and error. It was my last resort.

chrmarti commented 3 years ago

You're right: env_file doesn't work for build args. We could add a way to set --env-file for the docker-compose command, although that overrides .env, so there can be only one env file. That is a limitation of docker-compose.

k8n commented 3 years ago

It appears that docker-compose is invoked from the root of the container which is where docker-compose is looking for the .env file.

My workaround is to add the following to the devcontainer.json: "initializeCommand": "cp $(pwd)/.env /"

There is a number of tickets dealing with this issue (e.g. #3061 #2323). Having the option to provide --project-directory to docker-compose would be ideal.

chrmarti commented 3 years ago

@k8n That sounds like a different problem. Could you open a new issue with steps to reproduce? Appending the config files if possible.

k8n commented 3 years ago

@chrmarti done: #4656

github-actions[bot] commented 2 years ago

Hey @chrmarti, this issue might need further attention.

@MAnfal, you can help us out by closing this issue if the problem no longer exists, or adding more information.

chrmarti commented 2 years ago

Tracking as https://github.com/microsoft/vscode-remote-release/issues/4885.