boilerplate-nestjs-api-crud/Dockerfile
2023-04-17 10:20:39 +08:00

184 lines
7.2 KiB
Docker

# ------------------------------------------------------------------------------
# Dockerfile based on Price's best practice
# - using multi-stage builds
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Standard Args (with default values) for Price's docker image
# ------------------------------------------------------------------------------
ARG org_label_schema_vendor="Price.com.hk"
ARG org_label_schema_schema_version=1.0
ARG org_label_schema_name=unknown
ARG org_label_schema_version=unknown
ARG org_label_schema_vcs_url=unknown
ARG org_label_schema_vcs_ref=unknown
ARG org_label_schema_build_date=unknown
ARG org_label_schema_description
ARG maintainer="it.web@price.com.hk"
# -----------------------------------------------------------------------------
# Application Args/Envs
# -----------------------------------------------------------------------------
ARG NODEJS_VERSION="18.12"
ARG SUITE_VERSION="bullseye-slim"
ARG APP_ROOT="/home/node/app"
ARG APP_VERSION="not-yet-set"
ARG APP_PORT=3000
# ------------------------------------------------------------------------------
# Build the base image layer with Docker multi-stage builds
# - Install necessary packages as to add cache layer
# ------------------------------------------------------------------------------
FROM node:${NODEJS_VERSION}-${SUITE_VERSION} AS base
# -----------------------------------------------------------------------------
# Install required software package
# -----------------------------------------------------------------------------
RUN apt update -y \
# - health check & timezone
&& apt install -y curl tzdata dumb-init
# -----------------------------------------------------------------------------
# Purge / Clean up
# -----------------------------------------------------------------------------
RUN apt-get clean autoclean \
&& apt-get autoremove --yes \
&& rm -rf \
/var/lib/{apt,dpkg,cache,log}/ \
/tmp/*
# ------------------------------------------------------------------------------
# Build the NodeJS Application with Docker multi-stage builds
# - Making node_modules, separate from source as to add cache layer
# ------------------------------------------------------------------------------
FROM base AS nodejs_build
ARG APP_ROOT
RUN mkdir -p ${APP_ROOT} && chown node:node ${APP_ROOT}
WORKDIR ${APP_ROOT}
# Set the user for building operation
USER node
# ----- Install dependencies packages
# NOTE: Should not use `--ignore-optional --production` options
# because of TS or Bable is used.
COPY package.json yarn.lock ${APP_ROOT}/
RUN yarn install
# ---- Copy application source codes and build
COPY src ${APP_ROOT}/src
COPY tsconfig*.json .eslint*.js .prettierrc ${APP_ROOT}/
RUN yarn build
# NOTE: run install with `--ignore-optional --production` options again
# will remove non-production packages
RUN yarn install --ignore-optional --production
# ------------------------------------------------------------------------------
# Make the Final image
# ------------------------------------------------------------------------------
FROM base
# ------------------------------------------------------------------------------
# Arguments / Environment variables
# ------------------------------------------------------------------------------
# - Standard args and Envs
ARG org_label_schema_vendor
ARG org_label_schema_schema_version
ARG org_label_schema_name
ARG org_label_schema_version
ARG org_label_schema_vcs_url
ARG org_label_schema_vcs_ref
ARG org_label_schema_build_date
ARG org_label_schema_description
ARG maintainer
# - Application specific
ARG APP_ROOT
ENV APP_ROOT=${APP_ROOT}
ARG APP_PORT
ENV APP_PORT=${APP_PORT}
# -----------------------------------------------------------------------------
# Copy the 'image_files' directory to overrwrite root directory.
# Note: It is good to do after the main section
# -----------------------------------------------------------------------------
COPY ./image_files/fsroot /
# -----------------------------------------------------------------------------
# Provisioning (as root)
# For docker-entrypoint, it needed to change the owner to node
# -----------------------------------------------------------------------------
RUN chmod g+w -R /docker-entrypoint.d /docker-entrypoint.sh \
&& chown -R node:node /docker-entrypoint.d /docker-entrypoint.sh \
&& chmod ug+x /docker-entrypoint.sh
# ------------------------------------------------------------------------------
# Setup APP_ROOT for Node.js
# ------------------------------------------------------------------------------
RUN mkdir -p ${APP_ROOT} && chown node:node ${APP_ROOT}
WORKDIR ${APP_ROOT}
USER node
# ------------------------------------------------------------------------------
# Copy necessary files
# ------------------------------------------------------------------------------
COPY --chown=node:node --from=nodejs_build ${APP_ROOT}/dist ${APP_ROOT}/dist
COPY --chown=node:node --from=nodejs_build ${APP_ROOT}/node_modules ${APP_ROOT}/node_modules
COPY --chown=node:node --from=nodejs_build ${APP_ROOT}/package.json ${APP_ROOT}/yarn.lock ${APP_ROOT}/
# ------------------------------------------------------------------------------
# TODO: Remove TS or any other source code if the image is 'release'
# ------------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Expose ports
# -----------------------------------------------------------------------------
EXPOSE ${APP_PORT}
# -----------------------------------------------------------------------------
# Healthcheck (Optional for service)
# -----------------------------------------------------------------------------
HEALTHCHECK --interval=10s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:${APP_PORT}/healthcheck || exit 1
# -----------------------------------------------------------------------------
# Setting the Label and Args
# Shoukd be placed at the end (just before CMD) to avoid
# regenerating the cache layer above
# -----------------------------------------------------------------------------
LABEL org.label-schema.vendor=$org_label_schema_vendor \
org.label-schema.schema-version=$org_label_schema_schema_version \
org.label-schema.name=$org_label_schema_name \
org.label-schema.version=$org_label_schema_version \
org.label-schema.vcs-url=$org_label_schema_vcs_url \
org.label-schema.vcs-ref=$org_label_schema_vcs_ref \
org.label-schema.build-date=$org_label_schema_build_date \
org.label-schema.description=$org_label_schema_description \
maintainer=$maintainer
ENV ENABLE_DUMMY_DAEMON=false
ENV APP_ENV="production"
# Set the LOG_LEVEL will override application logger level.
# Default "" mean unset
# See 30-prepare-env.sh for details
ENV LOG_LEVEL=""
ENV LOG_IN_JSON_FMT=false
ARG APP_VERSION
ENV APP_VERSION=${APP_VERSION}
# -----------------------------------------------------------------------------
# Command or Entrypoint
# -----------------------------------------------------------------------------
CMD [ "dumb-init", "sh", "-c", "/docker-entrypoint.sh" ]