Skip to content

improved Dockerfile using multistage to reduce image size #5187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 76 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,85 @@
FROM node:carbon
# https://blog.hasura.io/an-exhaustive-guide-to-writing-dockerfiles-for-node-js-web-apps-bbee6bd2f3c4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to copy paste the sources of the code you're writing. please remove

# https://codefresh.io/docker-tutorial/node_docker_multistage/

RUN mkdir -p /parse-server
COPY ./ /parse-server/

RUN mkdir -p /parse-server/config
VOLUME /parse-server/config
# ------- Stage 1 - Base ---------
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove useless comments

FROM node:carbon-alpine as base
# apk - https://www.cyberciti.biz/faq/10-alpine-linux-apk-command-examples/
# RUN apk update && apk upgrade && \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why keep those??

# apk add --no-cache git bash
# python make and g++ - add this for bcrypt 3.x

RUN mkdir -p /parse-server/cloud
VOLUME /parse-server/cloud
# ENV, WORKDIR & COPY commands run as USER root
# to change ownership run chown (e.g. chown USER node /parse_server) after every command

# after this refer to workdir using ./
WORKDIR /parse-server

RUN npm install && \
npm run build
# specify multiple volumes in one line - reuse layers during build
VOLUME ["parse-server/config", "parse-server/cloud"]

ENV PORT=1337
# copy all package.json-related files
COPY package.json ./

EXPOSE $PORT

ENTRYPOINT ["npm", "start", "--"]
# ------- Stage 2 - Dependencies ---------
# base image for release stage with only prod dependencies
FROM base AS dependencies
# set npm configs
RUN npm set progress=false && npm config set depth 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the purpose of set depth 0?

There is no affected command: https://docs.npmjs.com/misc/config#depth

# install production packages only
RUN npm install --production


# ------- Stage 3 - Build ---------
FROM dependencies AS build
# install all npm required for build (and testing) - saves build time since prod dependencies are already installed
RUN npm install
# copy all context into WORKDIR (/parse-server) excluding items in .dockerignore
COPY . .
# Need to run build explicitly as npm will not auto run scripts as ROOT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why run as ROOT then? If there's no need, please run unpriviledged

# https://stackoverflow.com/questions/47748075/npm-postinstall-not-running-in-docker
# https://docs.npmjs.com/misc/scripts#user
RUN npm run prepare && npm run postinstall
# list all dir/files - for debugging purposes
# RUN ls -al

# UNIT TESTS
# if you want to perform unit testing, do it in the build stage (tests won't be cached, since the build stage cache is invalidated when files change)
# do not run flow through npm - https://github.com/facebook/flow/issues/3649
# RUN npm test

# ------- Stage 4 - Release ---------
FROM dependencies AS release
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all in all each layer uses the previous one completely, what's the point then?

# lib is the output from babel in the build step
COPY --from=build /parse-server/lib ./lib
# copy required files listed in package.json -> files
COPY /bin ./bin
COPY /public_html ./public_html
COPY /views ./views
# COPY postinstall.js ./
# COPY PATENTS LICENSE *.md ./
# list all dir/files - for debugging purposes
# RUN ls -al

# capture git_commit in label
# This is used in the script in /hooks/build.sh which is a trigger used in dockerhub builds
# ARG SOURCE_COMMIT
# LABEL SOURCE_COMMIT=$SOURCE_COMMIT

# run as non-root. USER node is provided with node images
# https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#non-root-user
USER node

#EXPOSE - informational ony
EXPOSE 1337

# https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/
# start with node, not npm
ENTRYPOINT ["node", "./bin/parse-server", "--"]

# BUILD: docker build -t parse-platform/parse-server:test --build-arg SOURCE_COMMIT=$(git log -1 --format=%H) .
# docker build -t local/parse-server:local --build-arg GIT_COMMIT=$(git log -1 --format=%H) .
# RUN (entrypoint sh): sudo docker run --name parse-server --rm -it --entrypoint sh barakbd/parse-server:test
# to stop at a specific steps add --target flag
# sudo docker build --target release -t barakbd/parse-server:test .
6 changes: 6 additions & 0 deletions hooks/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# https://medium.com/microscaling-systems/labelling-automated-builds-on-docker-hub-f3d073fb8e1
# https://docs.docker.com/docker-hub/builds/advanced/#environment-variables-for-building-and-testing

#!/bin/bash
echo "=> Building the binary with label"
docker build --label SOURCE_COMMIT=$SOURCE_COMMIT -f $DOCKERFILE_PATH -t $IMAGE_NAME .