<p>I have a node.js Project which I run as Docker-Container in different environments (local, stage, production) and therefor configure it via <code>.env</code>-Files. As always advised I don't store the <code>.env</code>-Files in my remote repository which is Gitlab. My production- and stage-systems are run as kubernetes cluster.</p>

<p>What I want to achieve is an automated build via Gitlab's CI for different environments (e.g. stage) depending on the commit-branch (named stage as well), meaning when I push to origin/stage I want an Docker-image to be built for my stage-environment with the corresponding <code>.env</code>-File in it.</p>

<p>On my local machine it's pretty simple, since I have all the different <code>.env</code>-Files in the root-Folder of my app I just use this in my <code>Dockerfile</code></p>

<pre><code>COPY .env-stage ./.env
</code></pre>

<p>and everything is fine.</p>

<p>Since I don't store the .env-Files in my remote repo, this approach doesn't work, so I used Gitlab CI Variables and created a variable named <code>DOTENV_STAGE</code> of type <code>file</code> with the contents of my local <code>.env-stage</code> file.</p>

<p>Now my problem is: How do I get that content as .env-File inside the docker image that is going to be built by gitlab since that file is not yet a file in my repo but a variable instead?</p>

<p>I tried using <code>cp</code> (see below, also in the <code>before_script</code>-section) to just copy the file to an <code>.env</code>-File during the build process, but that obviously doesn't work.</p>

<p>My current build stage looks like this:</p>

<pre><code>image: docker:git

services:
  - docker:dind

build stage:
  only:
    - stage
  stage: build
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - cp $DOTENV_STAGE .env
    - docker pull $GITLAB_IMAGE_PATH-$CI_COMMIT_BRANCH || true
    - docker build --cache-from $GITLAB_IMAGE_PATH/$CI_COMMIT_BRANCH --file=Dockerfile-$CI_COMMIT_BRANCH -t $GITLAB_IMAGE_PATH/$CI_COMMIT_BRANCH:$CI_COMMIT_SHORT_SHA .
    - docker push $GITLAB_IMAGE_PATH/$CI_COMMIT_BRANCH
</code></pre>

<p>This results in </p>

<pre><code> Step 12/14 : COPY .env ./.env
 COPY failed: stat /var/lib/docker/tmp/docker-builder513570233/.env: no such file or directory
</code></pre>

<p>I also tried <code>cp $DOTENV_STAGE .env</code> as well as <code>cp $DOTENV_STAGE $CI_BUILDS_DIR/.env</code> and <code>cp $DOTENV_STAGE $CI_PROJECT_DIR/.env</code> but none of them worked.</p>

<p>So the part I actually don't know is: Where do I have to put the file in order to make it available to docker during build?</p>

<p>Thanks</p>

<p>You should avoid copying <code>.env</code> file into the container altogether. Rather feed it from outside on runtime. There's a dedicated prop for that: <a href="https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option" rel="noreferrer">env_file</a>. </p>

<pre><code>web:
  env_file:
    - .env
</code></pre>

<p>You can store contents of the <code>.env</code> file itself in a <a href="https://docs.gitlab.com/ee/ci/variables/#masked-variables" rel="noreferrer">Masked Variable</a> in the GitLabs CI backend. Then dump it to <code>.env</code> file in the runner and feed to Docker compose pipeline.</p>
