Skip to content

Instantly share code, notes, and snippets.

@jose4125
Created March 18, 2020 16:26
Show Gist options
  • Select an option

  • Save jose4125/2c70d11bfa4bc7879d67e2a5a71248d8 to your computer and use it in GitHub Desktop.

Select an option

Save jose4125/2c70d11bfa4bc7879d67e2a5a71248d8 to your computer and use it in GitHub Desktop.
Dockerfile multiple stage (dev, test, prod)
## Stage 1 (production base)
# This gets our prod dependencies installed and out of the way
FROM node:8-slim as base
# set this with shell variables at build-time.
# If they aren't set, then not-set will be default.
ARG CREATED_DATE=not-set
ARG SOURCE_COMMIT=not-set
# labels from https://github.com/opencontainers/image-spec/blob/master/annotations.md
LABEL org.opencontainers.image.authors=jose4125@gmail.com
LABEL org.opencontainers.image.created=$CREATED_DATE
LABEL org.opencontainers.image.revision=$SOURCE_COMMIT
LABEL org.opencontainers.image.title="Node.js Dockerfile"
LABEL org.opencontainers.image.licenses=MIT
LABEL com.bretfisher.nodeversion=$NODE_VERSION
ENV NODE_ENV=production
RUN apk add --no-cache tini curl
EXPOSE 8080
WORKDIR /app
COPY package*.json ./
# we use npm ci here so only the package-lock.json file is used
RUN npm config list \
&& npm ci \
&& npm cache clean --force
ENV PATH /app/node_modules/.bin:$PATH
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini", "--"]
CMD ["node", "server.js"]
## Stage 2 (development)
# we don't COPY in this stage because for dev you'll bind-mount anyway
# this saves time when building locally for dev via docker-compose
FROM base as dev
ENV NODE_ENV=development
# NOTE: these apt dependencies are only needed
# for testing. they shouldn't be in production
RUN apt-get update -qq && apt-get install -qy \
ca-certificates \
bzip2 \
curl \
libfontconfig \
--no-install-recommends
RUN npm config list \
&& npm install --only=development
USER node
CMD ["nodemon", "server.js"]
## Stage 3 (testing)
# use this in automated CI
# it has prod and dev npm dependencies
# In 18.09 or older builder, this will always run
# In BuildKit, this will be skipped by default
FROM dev as test
COPY . .
# run linters as part of build
# be sure they are installed with devDependencies
RUN eslint .
# run unit tests as part of build
RUN npm test
RUN npm audit
# aqua microscanner, which needs a token for API access
# note this isn't super secret, so we'll use an ARG here
# https://github.com/aquasecurity/microscanner
ARG MICROSCANNER_TOKEN
ADD https://get.aquasec.com/microscanner /
USER root
RUN chmod +x /microscanner
RUN /microscanner $MICROSCANNER_TOKEN --continue-on-failure
## Stage 4 (pre-prod)
FROM test as pre-prod
RUN rm -rf ./tests && rm -rf ./node_modules
## Stage 6 (default, production)
# this will run by default if you don't include a target
# it has prod-only dependencies
# In BuildKit, this is skipped for dev and test stages
FROM base as prod
COPY --from=pre-prod /app /app
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
USER node
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment