Cannot get kubectl environment variables on deploy

10/8/2019

I have a docker container with a few environment variables setup. I know that in a typical use case, React is unable to read these variables as the process.env variables are replaced during transpiling.

I am trying to work around this without having to spin up a back-end server by using a plugin called react-env.

The core idea is to create a .env file which can be written to using a bash script. The bash script will copy any environmental variables to the .env file. The plugin will generate a env.js file which then will be consumed by the React application at runtime.

Dockerfile

FROM node:9

# Install yarn
RUN npm install yarn

# Install serve.js
RUN yarn global add serve

# Create app directory
WORKDIR /usr/app

# Copy all necessary files and grant permissions.
# - yarn.lock
# - package.json
# - .env
# - docker-entrypoint.sh
COPY . /usr/app/
COPY yarn.lock /usr/app
COPY package.json /usr/app
COPY .env /usr/app
COPY docker-entrypoint.sh /usr/app/docker-entrypoint.sh
RUN chmod 777 /usr/app/docker-entrypoint.sh

# Install dependencies.
RUN printf "\n" >> /usr/app/.env
RUN echo 'REACT_APP_GCP_PROJECT_ID='$GCP_PROJECT_ID >> /usr/app/.env //READ ENVIRONMENTAL VARIABLE HERE
RUN yarn

# Build application.
RUN yarn build

# Set entrypoint of application.
ENTRYPOINT [ "/usr/app/docker-entrypoint.sh" ]

docker-entrypoint.sh

serve build

App.jsx

...

console.log(env("GCP_PROJECT_ID"));

...

Inspect Console

'' //Empty string.

However, after making the image and deploying the application, the console outputs an empty string of the environmental variable.

Manually exec into the and running the echo command correctly does work:

Querying manually:

# echo 'REACT_APP_GCP_PROJECT_ID='$GCP_PROJECT_ID
REACT_APP_GCP_PROJECT_ID=SOME_VALUE

but

# cat .env
REACT_APP_SETUP="OK"
REACT_APP_GCP_PROJECT_ID=

How can I get my pod environmental variables into my .env file before React runs?

-- Carrein
docker
dockerfile
kubernetes
reactjs

1 Answer

10/8/2019

It looks like $GCP_PROJECT_ID is not defined in the build environment, and thus it isn't included in the echo command when it runs at build time. (I presume this is because you are having kubectl define it).

Assuming that you expect that $GCP_PROJECT_ID does not exist in the build environment and is instead something you are trying to copy from at the time your container executes (as indicated by your exec example), your problem is that the quoting of the RUN line

RUN echo 'REACT_APP_GCP_PROJECT_ID='$GCP_PROJECT_ID >> /usr/app/.env

Is interpreting $GCP_PROJECT_ID during the build, which of course is the empty string. In your test in the shell inside the container, it appears that $GCP_PROJECT_ID actually exists in the environment and all is well.

You need to actually quote the $GCP_PROJECT_ID variable to get it included into /usr/app/.env, like so (instead of being interpreted as an empty string!):

RUN echo 'REACT_APP_GCP_PROJECT_ID=$GCP_PROJECT_ID' >> /usr/app/.env

Of course, if you need the literal string which is the value of $GCP_PROJECT_ID to be included in the .env file, your only alternative may be to actually do the echo into .env at the beginning of the container execution (e.g. at the top of docker-entrypoint.sh, and remove all the related code from your Dockerfile).


If I am wrong about you having kubectl define it when the process starts, an alternative solution would require you to ensure that the docker build itself has access to that environment variable. You can do this with the --build-arg argument, such as:

docker build --build-arg GCP_PROJECT_ID=[correct value] .

In this case, you need to add an argument command to the Dockerfile, like so:

ARG GCP_PROJECT_ID

at some point before the RUN command.

-- robsiemb
Source: StackOverflow