4

I'm trying to pass a server URL to a React APP running in a Docker container. It is used when sending HTTP requests in the app, accessed like this: process.env.server_url for server_url. This is stored as en environment variable on the host machine.

I've tried setting the variable directly in my Dockerfile: ENV server_url=${server_url} which I figured does not work, since the ${server_url} is for ARGS defined in the Dockerfile.

Instead, I tried to pass it as an argument on build, as was mentioned here: Pass environment variables to Dockerfile during build time: docker build --buil-arg server_url=$server_url. However, trying to recreate what was given in the accepted answer:

FROM node:9 as build-deps

WORKDIR /temp

RUN echo $var1

ADD package*.json  ./
RUN npm install

ADD . ./

RUN npm run build

# Stage 2 - the production environment
FROM nginx:1.12-alpine

COPY --from=build-deps /temp/build /usr/share/nginx/html

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

and running docker build --build-arg var1=hello . yielded in an empty line in STDOUT. The variable is definately not being set correctly.

I instead tried using docker compose as mentioned here Pass host environment variables to dockerfile. This seemingly works, docker exec -it container-name printenv actually shows that the environment variable is present, but it is still undefined when accessed through React.

The only way I have actually been able to get the a value in React is by hardcoding the value in my Dockerfile: ENV server_url=12.34.56.78.

I am very confused, since I expected the docker compose solution to work due to actually seeing the variable in the image. I suspect this might have something to do with my layered build and using nginx for serving the web app, but I'm afraid I don't know why or how to solve this.

Any help would be nice, thank you.

vegarab
  • 147
  • 2
  • 8
  • Possible duplicate of [How do I set environment variables during the build in docker](https://stackoverflow.com/questions/39597925/how-do-i-set-environment-variables-during-the-build-in-docker) – LinPy Sep 02 '19 at 10:25
  • @LinPy Possibly, however I think Adiii's answer makes it clearer that you need to define the ARG you are passing in the Dockerfile. Not sure wha the convention on this is here on SO – vegarab Sep 02 '19 at 10:35

1 Answers1

3

You need to define ARG in Dockerfile before passing to build command.

So the var1 will only be available in Dockerfile, will not available in App.

So to make it available in your App, you have to pass ARG value to ENV

ARG var1
RUN echo $var1
ENV server_url=$var1

Or if you want to have some default value if missed to pass during build time so this will work as a default value.

FROM alpine
ARG var1=default_value
RUN echo $var1
Adiii
  • 54,482
  • 7
  • 145
  • 148
  • Thank you! That did the trick. I am otherwise convinced that I should use docker-compose anyways.. how would I go about getting the same result when not explicitly passing the build arg with docker-compose? – vegarab Sep 02 '19 at 10:23
  • updated. Just set some default value to `ARG` and you will not need to pass explicitly – Adiii Sep 02 '19 at 10:30
  • docker-compose build also supports --build-arg as an argument, I see. Thanks. – vegarab Sep 02 '19 at 10:33