From 1e717326b4a3a0a59ccb596f4c22001af65b3d12 Mon Sep 17 00:00:00 2001 From: sebthom Date: Mon, 24 Aug 2020 20:11:52 +0200 Subject: [PATCH] Replace minideb:buster with debian/buster-slim. Improve build config --- .travis.yml | 11 +++- README.md | 4 +- build-image.sh | 146 +++++++++++++++++++++++++++++------------------ image/Dockerfile | 49 ++++++++-------- image/run.sh | 6 ++ 5 files changed, 135 insertions(+), 81 deletions(-) diff --git a/.travis.yml b/.travis.yml index 11aacf3..188f0db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,21 @@ # https://github.com/travis-ci/travis-yml/blob/master/schema.json language: bash # using 'bash' instead of 'minimal' to prevent https://travis-ci.community/t/job-stuck-booting/4976 -sudo: true +addons: + apt: + packages: + - dos2unix + services: - docker + cache: directories: - $HOME/.trivy/cache + env: global: DOCKER_REGISTRY=docker.io @@ -29,11 +35,12 @@ before_script: #- printenv | sort - mkdir -p "$TRIVY_CACHE_DIR" + script: - echo "$DOCKER_PASSWORD" | docker login -u="$DOCKER_USERNAME" "$DOCKER_REGISTRY" --password-stdin && if [[ "$TRAVIS_BRANCH" == "master" ]]; then DOCKER_PUSH=1 bash ./build-image.sh; - curl -X POST https://hooks.microbadger.com/images/vegardit/openldap/${MICROBADGER_TOKEN} || true; + curl -X POST https://hooks.microbadger.com/images/$DOCKER_REPO/$MICROBADGER_TOKEN || true; else bash ./build-image.sh; fi diff --git a/README.md b/README.md index dd94ae1..e0fd19e 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,9 @@ # vegardit/openldap What is it? -Opinionated docker image based on [minideb](https://github.com/bitnami/minideb) (Debian 10 "buster") to run an [OpenLDAP 2.4](https://www.openldap.org/doc/admin24/) server. +Opinionated docker image based on the [Debian](https://www.debian.org/) docker image [`debian:buster-slim`](https://hub.docker.com/_/debian?tab=tags&name=buster-slim) to run an [OpenLDAP 2.4](https://www.openldap.org/doc/admin24/) server. + +It is automatically built **daily** to include the latest OS security fixes. To keep the image light and simple, it does not configure TLS. Instead we recommend configuring a [Traefik 2.x](https://traefik.io) [TCP service](https://docs.traefik.io/routing/services/#configuring-tcp-services) with e.g. an auto-renewing [Let's Encrypt configuration](https://docs.traefik.io/https/acme/) in front of the OpenLDAP service. diff --git a/build-image.sh b/build-image.sh index c8f50a2..5fcdfc6 100644 --- a/build-image.sh +++ b/build-image.sh @@ -8,71 +8,109 @@ # https://github.com/vegardit/docker-openldap # -set -e -x +set -e -u -x + +############################## +# execute script with bash if loaded with other shell interpreter +############################## if [ ! -n "$BASH" ]; then /usr/bin/env bash "$0" "$@"; exit; fi -DOCKER_REGISTRY=${DOCKER_REGISTRY:-docker.io} -DOCKER_REPO=${DOCKER_REPO:-vegardit/openldap} +set -o pipefail -last_commit_date=$(date -d @$(git log -1 --format="%at") --utc +"%Y%m%d_%H%M%S") +trap 'echo >&2 "$(date +%H:%M:%S) Error - exited with status $? at line $LINENO:"; pr -tn $0 | tail -n+$((LINENO - 3)) | head -n7' ERR -docker build $(dirname $0)/image \ + +############################## +# specify target docker registry/repo +############################## +docker_registry=${DOCKER_REGISTRY:-docker.io} +docker_repo=${DOCKER_REPO:-vegardit/openldap} + + +############################## +# determine directory of current script +############################## +project_root=$(readlink -e $(dirname "${BASH_SOURCE[0]}")) + + +############################## +# ensure Linux new line chars +############################## +# env -i PATH="$PATH" -> workaround for "find: The environment is too large for exec()" +env -i PATH="$PATH" find "$project_root/image" -type f -exec dos2unix {} \; + + +############################## +# build the image +############################## +docker build "$project_root/image" \ + --pull \ --compress \ + `# using the current date as value for BASE_LAYER_CACHE_KEY, i.e. the base layer cache (that holds system packages with security updates) will be invalidate once per day` \ + --build-arg BASE_LAYER_CACHE_KEY=$(date +%Y%m%d) \ --build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ --build-arg GIT_BRANCH="${GIT_BRANCH:-$(git rev-parse --abbrev-ref HEAD)}" \ --build-arg GIT_COMMIT_DATE="$(date -d @$(git log -1 --format='%at') --utc +'%Y-%m-%d %H:%M:%S UTC')" \ --build-arg GIT_COMMIT_HASH="$(git rev-parse --short HEAD)" \ --build-arg GIT_REPO_URL="$(git config --get remote.origin.url)" \ - `# using the current date as value for BASE_LAYER_CACHE_KEY, i.e. the base layer cache (that holds system packages with security updates) will be invalidate once per day` \ - --build-arg BASE_LAYER_CACHE_KEY=$(date +%Y%m%d) \ - -t $DOCKER_REPO:latest \ - -t $DOCKER_REPO:latest-buster \ - -t $DOCKER_REPO:${last_commit_date} \ - -t $DOCKER_REPO:${last_commit_date}-buster \ + -t $docker_repo:latest \ "$@" -# + +############################## # perform security audit using https://github.com/aquasecurity/trivy -# -mkdir -p ${TRIVY_CACHE_DIR:-$HOME/.trivy/cache} -docker run --rm \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v ${TRIVY_CACHE_DIR:-$HOME/.trivy/cache}:/root/.cache/ \ - aquasec/trivy --no-progress --exit-code 0 --severity HIGH,CRITICAL $DOCKER_REPO:${last_commit_date} -docker run --rm \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v ${TRIVY_CACHE_DIR:-$HOME/.trivy/cache}:/root/.cache/ \ - aquasec/trivy --no-progress --ignore-unfixed --exit-code 1 --severity HIGH,CRITICAL $DOCKER_REPO:${last_commit_date} -sudo chown -R $USER:$(id -gn) $TRIVY_CACHE_DIR || true - -# -# determine effective LDAP version and apply tags -# -ldap_version=$(docker run $DOCKER_REPO:${last_commit_date} "dpkg -s slapd | grep 'Version:' | grep -oP 'Version: \K\d+\.\d+\.\d+'") -docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REPO:${ldap_version%.*}.x #2.4.x -docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REPO:${ldap_version%.*}.x-buster #2.4.x -docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REPO:${ldap_version%%.*}.x #2.x -docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REPO:${ldap_version%%.*}.x-buster #2.x - -# -# push image with tags to remote docker registry -# -if [[ "${DOCKER_PUSH:-0}" == "1" ]]; then - docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:latest - docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:latest-buster - docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version} #2.4.47 - docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version}-buster #2.4.47 - docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%.*}.x #2.4.x - docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%.*}.x-buster #2.4.x - docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%%.*}.x #2.x - docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%%.*}.x-buster #2.x - - docker push $DOCKER_REGISTRY/$DOCKER_REPO:latest - docker push $DOCKER_REGISTRY/$DOCKER_REPO:latest-buster - docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version} #2.4.47 - docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version}-buster #2.4.47 - docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%.*}.x #2.4.x - docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%.*}.x-buster #2.4.x - docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%%.*}.x #2.x - docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%%.*}.x-buster #2.x +############################## +if [[ $OSTYPE != cygwin ]] && [[ $OSTYPE != msys ]]; then + trivy_cache_dir=${TRIVY_CACHE_DIR:-$HOME/.trivy/cache} + mkdir -p "$trivy_cache_dir" + docker run --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v "$trivy_cache_dir:/root/.cache/" \ + aquasec/trivy --no-progress --exit-code 0 --severity HIGH,CRITICAL $docker_repo:latest + docker run --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v "$trivy_cache_dir:/root/.cache/" \ + aquasec/trivy --no-progress --ignore-unfixed --exit-code 1 --severity HIGH,CRITICAL $docker_repo:latest + sudo chown -R $USER:$(id -gn) "$trivy_cache_dir" || true fi + + +############################## +# determine effective LDAP version and apply tags +############################## +# LC_ALL=en_US.utf8 -> workaround for "grep: -P supports only unibyte and UTF-8 locales" +ldap_version=$(docker run --rm $docker_repo:latest "dpkg -s slapd | grep 'Version:' | LC_ALL=en_US.utf8 grep -oP 'Version: \K\d+\.\d+\.\d+'") +docker image tag $docker_repo:latest $docker_repo:${ldap_version%.*}.x #2.4.x +docker image tag $docker_repo:latest $docker_repo:${ldap_version%%.*}.x #2.x + + +############################## +# push image with tags to remote docker registry +############################## +if [[ "${DOCKER_PUSH:-0}" == "1" ]]; then + docker image tag $docker_repo:latest $docker_registry/$docker_repo:latest + docker image tag $docker_repo:latest $docker_registry/$docker_repo:${ldap_version} #2.4.47 + docker image tag $docker_repo:latest $docker_registry/$docker_repo:${ldap_version%.*}.x #2.4.x + docker image tag $docker_repo:latest $docker_registry/$docker_repo:${ldap_version%%.*}.x #2.x + + docker push $docker_registry/$docker_repo:latest + docker push $docker_registry/$docker_repo:${ldap_version} #2.4.47 + docker push $docker_registry/$docker_repo:${ldap_version%.*}.x #2.4.x + docker push $docker_registry/$docker_repo:${ldap_version%%.*}.x #2.x +fi + + +############################# +# remove untagged images +############################# +# http://www.projectatomic.io/blog/2015/07/what-are-docker-none-none-images/ +docker rmi $(docker images -f "dangling=true" -q) || true + + +############################# +# display some image information +############################# +echo "" +docker images "$docker_repo" +echo "" +docker history "$docker_repo:latest" diff --git a/image/Dockerfile b/image/Dockerfile index 39c24ef..30e26cd 100644 --- a/image/Dockerfile +++ b/image/Dockerfile @@ -6,16 +6,17 @@ # https://github.com/vegardit/docker-openldap # -# built daily: -# https://hub.docker.com/r/bitnami/minideb/tags?page=1&name=buster -FROM bitnami/minideb:buster +# https://hub.docker.com/_/debian?tab=tags&name=buster-slim +ARG BASE_IMAGE=debian:buster-slim -# built monthly: -# https://hub.docker.com/_/debian?tab=tags&page=1&name=buster-slim -# FROM debian:buster-slim +FROM ${BASE_IMAGE} LABEL maintainer="Vegard IT GmbH (vegardit.com)" +USER root + +SHELL ["/bin/bash", "-c"] + # if set to 1 debug tools are added to the image (htop,less,mc,vim) ARG DEBUG_BUILD=0 @@ -27,16 +28,15 @@ ARG LC_ALL=C ARG BASE_LAYER_CACHE_KEY -SHELL ["/bin/bash", "-c"] - RUN \ - apt-get update -y && \ - # https://github.com/phusion/baseimage-docker/issues/319 - apt-get install -y apt-utils 2> >( grep -v 'debconf: delaying package configuration, since apt-utils is not installed' >&2 ) && \ + set -x && \ + ############################################################ + echo "Installing OS updates..." && \ + apt-get -y update && \ + apt-get -y upgrade && \ ############################################################ if [ "${DEBUG_BUILD}" = "1" ]; then \ echo "Installing debugging tools..." && \ - apt-get update -y && \ apt-get install --no-install-recommends -y libcomerr2 mc && \ apt-get install --no-install-recommends -y htop less procps vim && \ echo -e 'set ignorecase\n\ @@ -80,13 +80,11 @@ set mouse-=a' > ~/.vimrc; \ /var/log/{apt,alternatives.log,bootstrap.log,dpkg.log} \ /tmp/* /var/tmp/* -VOLUME ["/etc/ldap/slapd.d", "/var/lib/ldap"] - ARG BUILD_DATE -ARG GIT_REPO_URL ARG GIT_BRANCH ARG GIT_COMMIT_HASH ARG GIT_COMMIT_DATE +ARG GIT_REPO_URL LABEL \ org.label-schema.schema-version="1.0" \ @@ -94,15 +92,6 @@ LABEL \ org.label-schema.vcs-ref=$GIT_COMMIT_HASH \ org.label-schema.vcs-url=$GIT_REPO_URL -RUN \ - echo "GIT_REPO: $GIT_REPO_URL" > /opt/build_info && \ - echo "GIT_BRANCH: $GIT_BRANCH" >> /opt/build_info && \ - echo "GIT_COMMIT: $GIT_COMMIT_HASH @ $GIT_COMMIT_DATE" >> /opt/build_info && \ - cat /opt/build_info - -COPY ldifs /opt/ldifs -COPY run.sh /opt/run.sh - # Default configuration: can be overridden at the docker command line ENV \ DEBUG_RUN_SH=0 \ @@ -126,6 +115,18 @@ ENV \ LDAP_OPENLDAP_UID='' \ LDAP_OPENLDAP_GID='' +COPY ldifs /opt/ldifs +COPY run.sh /opt/run.sh + +RUN \ + echo "GIT_REPO: $GIT_REPO_URL" > /opt/build_info && \ + echo "GIT_BRANCH: $GIT_BRANCH" >> /opt/build_info && \ + echo "GIT_COMMIT: $GIT_COMMIT_HASH @ $GIT_COMMIT_DATE" >> /opt/build_info && \ + echo "IMAGE_BUILD: $BUILD_DATE" >> /opt/build_info && \ + cat /opt/build_info + +VOLUME ["/etc/ldap/slapd.d", "/var/lib/ldap"] + EXPOSE 389 ENTRYPOINT ["/bin/sh", "-c"] diff --git a/image/run.sh b/image/run.sh index 898ba96..499a6b9 100644 --- a/image/run.sh +++ b/image/run.sh @@ -9,8 +9,14 @@ # set -e -u + +############################## +# execute script with bash if loaded with other shell interpreter +############################## if [ -z "${BASH_VERSINFO:-}" ]; then /usr/bin/env bash "$0" "$@"; exit; fi + set -o pipefail + trap 'echo >&2 "$(date +%H:%M:%S) Error - exited with status $? at line $LINENO:"; pr -tn $0 | tail -n+$((LINENO - 3)) | head -n7' ERR if [ "${DEBUG_RUN_SH:-}" == "1" ]; then