user_mda
user_mda

Reputation: 19388

envsubst command getting stuck in a container

I have a requirement that before an application runs, some part of it needs to read the environmental variable. For this I have the following docker file

FROM nodesource/jessie:0.12.7

# install gettext for envsubst
RUN apt-get update
RUN apt-get install -y gettext-base

# cache package.json and node_modules to speed up builds
ADD package.json package.json
RUN npm install

# Add  source files
ADD src src

# Substiture value for backend endpoint env var
RUN envsubst < src/js/envapp.js > src/js/app.js

ADD node_modules node_modules
EXPOSE 8000
CMD ["npm","start"]

The above envsubst line reads (should read) an env variable $MYENV and substitutes it. But when I open the file app.js, its empty. I checked if the environmental variable exists in the container and it does. Any reason its value is not read and substituted? I also tried the same command in teh container and it works. It only does not work when I run the image

Upvotes: 19

Views: 48909

Answers (4)

James Bond
James Bond

Reputation: 2966

I had some issues with envsubst in Docker. For some reasons envsubst doesn't work when I try to copy the output in the same file. For example, this is not working:

RUN envsubst < file.conf > file.conf

But when I when I tried to use a temp file the issue disappeared:

RUN envsubst < file.conf > file.conf.temp && cp -f file.conf.temp file.conf

Upvotes: 3

TheoNeUpKID
TheoNeUpKID

Reputation: 893

I encountered the same issues, and after much research and fishing through the internet. I managed to find a few work arounds to this issue. Below I'll list them and identifiable risks at the time of this "Answer post"

Solutions:

1.) apt-get install -y gettext its a standard GNU package language library, one of these libraries that it includes is envsubst` and I can confirm that it works for docker UBUNTU:latest and it should work for every flavored version.

2.) npm install envsub dependent on the "use case" - this approach would be better supported by node based projects.

3.) enstub cli project lib in my opinion it seems a bit overkill to downloading a custom cli from a random stranger but, it's also another option.

Risk:

  • apt-get install -y gettext:

    1.) gettext - this approach would NOT be ideal for VM's as with any package library, it requires maintenance and updates as time passes. However, this isn't necessary for docker because once an a container is initialized and up and running we can create a bashscript to add the package, substitute env vars and then remove the package.

    2.) It's a bad idea for VM's because it can be used to execute arbitrary code

  • npm install ensub

    1.) envsub - updating packages and this approach wouldn't be ideal if your dealing with a different stack and not using nodejs.

NOTE: There's also a PHP version for those developing a PHP application and it seems to work PHP's cli if you need a custom environment.

Resources:

Upvotes: 13

danday74
danday74

Reputation: 56956

I suggest that since your are using Node, you use the npm envsub module.

This module is well tested and is developed with docker in mind.

It avoids the need for relying on other dependencies when you already have the full Node arsenal at your fingertips.

envsub is described as

envsub is envsubst for NodeJS

NodeJS global CLI module providing file-level environment variable substitution via Handlebars

I am the author of the package. I think you will enjoy it.

Upvotes: 1

Alex da Silva
Alex da Silva

Reputation: 4590

This is likely because $MYENV is not available for envsubst when you run the image.

Each RUN command runs on its own shell.

From the Docker documentations:

RUN (the command is run in a shell - /bin/sh -c - shell form)

You need to source your profile as well, for example if the $MYENV environment variable is available in the .bashrc file, you can modify your Dockerfile like this:

RUN source ~/.bashrc && envsubst < src/js/envapp.js > src/js/app.js

Upvotes: 11

Related Questions