From fc1eeb714e2c5f8ae6d43d68d98d65f7e27ea6c7 Mon Sep 17 00:00:00 2001 From: markus-li Date: Sun, 16 Oct 2022 19:41:45 +0800 Subject: [PATCH] feat: added Dockerfile --- .gitignore | 1 + Dockerfile | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ docker.sh | 67 ++++++++++++++++++++++++++++++++++++++++ init.sh | 14 +++++++++ 4 files changed, 171 insertions(+) create mode 100644 Dockerfile create mode 100755 docker.sh create mode 100755 init.sh diff --git a/.gitignore b/.gitignore index e8ee373..02f87c1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ tsconfig.tsbuildinfo /node_modules /lib /cache +/tmp diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..df52fb3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,89 @@ +ARG ARCH=amd64 +ARG NODE_VERSION=16 +ARG OS=bullseye-slim +ARG ICONIFY_API_VERSION=3.0.0 +ARG SRC_PATH=./ + +#### Stage BASE ######################################################################################################## +FROM ${ARCH}/node:${NODE_VERSION}-${OS} AS base + +# This gives node.js apps access to the OS CAs +ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt + +# This handles using special APT sources during build only (it is safe to comment these 3 following lines out): +RUN cp /etc/apt/sources.list /etc/apt/sources.list.original +COPY tmp/sources.list /tmp/sources.list.tmp +RUN ([ -s /tmp/sources.list.tmp ] && mv -f /tmp/sources.list.tmp /etc/apt/sources.list && cat /etc/apt/sources.list) || (cat /etc/apt/sources.list) + +# Add temporary CERTs needed during build (it is safe to comment the following 1 line out): +COPY tmp/build-ca-cert.crt /usr/local/share/ca-certificates/build-ca-cert.crt + +# Install tools, create data dir, add user and set rights +RUN set -ex && \ + apt-get update && \ + apt-get install --no-install-recommends -y \ + ca-certificates \ + bash \ + curl \ + nano \ + git && \ + npm install --location=global pnpm && \ + mkdir -p /data/iconify-api && \ + deluser --remove-home node && \ + useradd --home-dir /data/iconify-api --uid 1000 --shell /bin/bash iconify-api && \ + chown -R iconify-api:root /data/iconify-api && chmod -R g+rwX /data/iconify-api && \ + apt-get clean && \ + rm -rf /tmp/* && \ + # Restore the original sources.list + ([ -s /etc/apt/sources.list.original ] && mv /etc/apt/sources.list.original /etc/apt/sources.list) && \ + # Remove the temporary build CA cert + rm -f /usr/local/share/ca-certificates/build-ca-cert.crt + +# Set work directory +WORKDIR /data/iconify-api + +#### Stage iconify-api-install ######################################################################################### +FROM base AS iconify-api-install + +# Make CERTAIN peer dependencies are installed, otherwise this will very likely fail + +COPY ${SRC_PATH} /data/iconify-api/ +COPY init.sh /init.sh + +RUN cp -fR /data/iconify-api/src/config /data/config_default && \ + pnpm install + +#### Stage RELEASE ##################################################################################################### +FROM iconify-api-install AS RELEASE +ARG BUILD_DATE +ARG BUILD_VERSION +ARG BUILD_REF +ARG ICONIFY_API_VERSION +ARG ARCH +ARG TAG_SUFFIX=default + +LABEL org.label-schema.build-date=${BUILD_DATE} \ + org.label-schema.docker.dockerfile="Dockerfile" \ + org.label-schema.license="MIT" \ + org.label-schema.name="Iconify API.js" \ + org.label-schema.version=${BUILD_VERSION} \ + org.label-schema.description="Node.js version of api.iconify.design" \ + org.label-schema.url="https://github.com/iconify/api.js" \ + org.label-schema.vcs-ref=${BUILD_REF} \ + org.label-schema.vcs-type="Git" \ + org.label-schema.vcs-url="https://github.com/iconify/api.js" \ + org.label-schema.arch=${ARCH} \ + authors="Vjacheslav Trushkin" + +RUN rm -rf /tmp/* + +# Env variables +ENV ICONIFY_API_VERSION=$ICONIFY_API_VERSION + +# Expose the listening port of Iconify API +EXPOSE 3000 + +# Add a healthcheck (default every 30 secs) +HEALTHCHECK CMD curl http://localhost:3000/ || exit 1 + +ENTRYPOINT ["/init.sh"] diff --git a/docker.sh b/docker.sh new file mode 100755 index 0000000..4faa23b --- /dev/null +++ b/docker.sh @@ -0,0 +1,67 @@ +#!/bin/bash -e +# This file is used to build the Docker image +# Examples: +#./docker.sh +#./docker.sh arm64v8 + +# To test the docker image a command like this can be used: +#docker run --rm -p 3123:3000 --name iconify-api -v $(realpath "../iconify-cache"):/data/iconify-api/cache -v $(realpath "../iconify-config"):/data/iconify-api/src/config iconify/iconify-api:latest +#docker run --rm -p 3123:3000 --name iconify-api -v /absolute/path/iconify-cache:/data/iconify-api/cache -v /absolute/path/iconify-config:/data/iconify-api/src/config iconify/iconify-api:latest +ICONIFY_API_REPO=$(realpath "./") +BUILD_SOURCE=$(realpath "./") +SHARED_DIR=$BUILD_SOURCE/../shared +DOCKERFILE=$(realpath "./Dockerfile") +REPO_BRANCH="dev3" +SRC_PATH="./" +if [ -z "$1" ]; then + ARCH=amd64 + # ARCH=arm64v8 +else + ARCH=$1 +fi +echo "Starting to build for arch: $ARCH" +echo "Build BASE dir: $BUILD_SOURCE" +if [ ! -s "./package.json" ] && [ -s "./iconify-api.js/package.json" ]; then + # If the repo is not the same as where the Docker file is located, + # this will fix all paths + ICONIFY_API_REPO=$(realpath "./iconify-api.js/") + SRC_PATH="iconify-api.js/" + cd $ICONIFY_API_REPO + git checkout $REPO_BRANCH + cd $BUILD_SOURCE +fi + +export ICONIFY_API_VERSION=$(grep -oE "\"version\": \"(\w*.\w*.\w*(-\w*)?)" $ICONIFY_API_REPO/package.json | cut -d\" -f4) + +echo "iconify-api.js version: ${ICONIFY_API_VERSION}" + +mkdir -p $BUILD_SOURCE/tmp + +# If we need a different APT package list during the build, this will fetch it +# This is useful in case a local APT cache is used. +if [ -s $SHARED_DIR/sources-build.list ]; then + cp -f $SHARED_DIR/sources-build.list $BUILD_SOURCE/tmp/sources.list +else + rm -f $BUILD_SOURCE/tmp/sources.list + touch $BUILD_SOURCE/tmp/sources.list +fi + +# If we need an extra CA root cert during the build, this will fetch it +# This is useful in case connections go through eg. a Squid proxy to cache npm packages. +if [ -s $SHARED_DIR/build-ca-cert.crt ]; then + cp -f $SHARED_DIR/build-ca-cert.crt $BUILD_SOURCE/tmp/build-ca-cert.crt +else + rm -f $BUILD_SOURCE/tmp/build-ca-cert.crt + touch $BUILD_SOURCE/tmp/build-ca-cert.crt +fi + +time docker build --rm=false \ + --build-arg ARCH=$ARCH \ + --build-arg ICONIFY_API_VERSION=${ICONIFY_API_VERSION} \ + --build-arg BUILD_DATE="$(date +"%Y-%m-%dT%H:%M:%SZ")" \ + --build-arg TAG_SUFFIX=default \ + --build-arg SRC_PATH="$SRC_PATH" \ + --file $DOCKERFILE \ + --tag iconify/iconify-api:latest --tag iconify/iconify-api:${ICONIFY_API_VERSION} $BUILD_SOURCE + +rm -fR $BUILD_SOURCE/tmp diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..7b1f81f --- /dev/null +++ b/init.sh @@ -0,0 +1,14 @@ +#!/bin/bash -e +# This file is included in the Docker image +exit_func() { + echo "SIGTERM detected" + exit 1 +} +trap exit_func SIGTERM SIGINT + +echo "Initializing Iconify API.js..." +cd /data/iconify-api +# Only copy files which don't exist in target +cp -rn /data/config_default/. /data/iconify-api/src/config/ +pnpm build +node lib/index.js