Is there another way to init react env in the dockerfile ?
FROM node:14.19 as base
ARG REACT_APP_VERSION
ARG REACT_APP_WEBSITE_NAME
ARG REACT_APP_BACKEND_BASE_URL
ARG REACT_APP_BI_BASE_URL
ARG REACT_APP_DEFAULT_DEPARTEMENT_CODE
ENV REACT_APP_VERSION $REACT_APP_VERSION
ENV REACT_APP_WEBSITE_NAME $REACT_APP_WEBSITE_NAME
ENV REACT_APP_BACKEND_BASE_URL $REACT_APP_BACKEND_BASE_URL
ENV REACT_APP_BI_BASE_URL $REACT_APP_BI_BASE_URL
ENV REACT_APP_DEFAULT_DEPARTEMENT_CODE $REACT_APP_DEFAULT_DEPARTEMENT_CODE
WORKDIR /app
COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm install
COPY . .
FROM base as development
CMD ["npm", "start"]
FROM base as build
RUN npm run build
FROM nginx:alpine as production
COPY nginx.conf /etc/nginx/conf.d/configfile.template
COPY --from=build /app/build /usr/share/nginx/html
ENV HOST 0.0.0.0
EXPOSE 8080
CMD sh -c "envsubst '\$PORT' < /etc/nginx/conf.d/configfile.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
Actually I have all variables declared at the top on the Dockerfile and I have to pass each .env variable in arg
. But I don't like this way. I'm searching another way to do that. I'm using cloud build for my pipeline production deployment so maybe there is a way to do something with it ?
CodePudding user response:
You don't need to replicate all your args as env, if they are only required for the build process. They will be seen as env variable during build. Afterwards, when you run the container they are gone though.
This is enough, for the first stage:
FROM node:14.19
ARG REACT_APP_VERSION="unknown" \
REACT_APP_WEBSITE_NAME="" \
REACT_APP_BACKEND_BASE_URL="" \
REACT_APP_BI_BASE_URL="" \
REACT_APP_DEFAULT_DEPARTEMENT_CODE="" \
NODE_ENV="production"
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build
For your second stage you can use nginx templates dir, it will do envsubst
for you and copy the templates into the conf.d
directory, removing the template suffix.
It will run the following script amongst others: https://github.com/nginxinc/docker-nginx/blob/master/entrypoint/20-envsubst-on-templates.sh
So you can create templates with variable placeholders and put them in /etc/nginx/templates
.
In your case, you want to put /etc/nginx/templates/default.conf.template
.
FROM nginx:alpine
ENV HOST 0.0.0.0 PORT=8080
EXPOSE 8080
COPY nginx.conf /etc/nginx/templates/default.conf.template
COPY --from=0 /app/build /usr/share/nginx/html
That way, you can also keep the default entrypoint and command. You don't have to set your own.
I would also suggest using the unprivileged version of the nginx. It runs on 8080 by default. https://hub.docker.com/r/nginxinc/nginx-unprivileged. This image is generally useful if you plan to drop capabilities, which is advised for production.