xyfir
xyfir

Reputation: 33

Webpack app in docker needs environment variables before it can be built

New to docker so maybe I'm missing something obvious...

I have an app split into a web client and a back end server. The back end is pretty easy to create an image for via a Dockerfile:

  1. COPY source
  2. RUN npm install, npm run build
  3. CMD npm run start

The already-built back end app will then access the environment variables at runtime.

With the web client it's not as simple because webpack needs to have the environment variables before the application is built. This leaves me as far as I'm aware only two options:

  1. Require the user to build their own image from the application source
  2. Build the web client on container run by running npm run build in CMD

Currently I'm doing #2 but both options seem wrong to me. What's the best solution?

FROM node:latest
COPY ./server /app/server
COPY ./web /app/web
WORKDIR /app/web
CMD ["sh", "-c", "npm install && npm run build && cd ../server && npm install && npm run build && npm run start"]

Upvotes: 3

Views: 4799

Answers (1)

Jack Gore
Jack Gore

Reputation: 4252

First, it would be a good idea for both the backend server and web client to each have their own Dockerfile/image. Then it would be easy to run them together using something like docker-compose.

The way you are going to want to provide environment variables to the web Dockerfile is by using build arguments. Docker build arguments are available when building the Docker image. You use these by specifying the ARG key in the Dockerfile, or by passing the --build-arg flag to docker build.

Here is an example Dockerfile for your web client based on what you provided:

FROM node:latest

ARG NODE_ENV=dev

COPY ./web /app/web
WORKDIR /app/web

RUN npm install \
    && npm run build

CMD ["npm", "run", "start"]

The following Dockerfile uses the ARG directive to create a variable with a default value of dev.

The value of NODE_ENV can then be overridden when running docker build.

Like so:

docker build -t <myimage> --build-arg NODE_ENV=production .

Whether you override it or not NODE_ENV will be available to webpack before it is built. This allows you to build a single image, and distribute it to many people without them having to build the web client.

Hopefully this helps you out.

Upvotes: 2

Related Questions