From 44a795cf5fafb083b48b70b7952cdebf1e47042e Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Mon, 10 Jan 2022 22:10:42 +1000 Subject: [PATCH] Restructured docker images heirarchy --- .jenkins/Jenkinsfile | 55 ++++++++---- README.md | 21 ++++- docker/Dockerfile | 88 +++---------------- docker/Dockerfile.acmesh | 14 +++ docker/Dockerfile.acmesh-golang | 29 ++++++ docker/Dockerfile.certbot | 68 ++++++++++++++ ...ockerfile.node => Dockerfile.certbot-node} | 6 +- local-build.sh | 55 ++++++++++++ scripts/buildx | 2 + 9 files changed, 239 insertions(+), 99 deletions(-) create mode 100644 docker/Dockerfile.acmesh create mode 100644 docker/Dockerfile.acmesh-golang create mode 100644 docker/Dockerfile.certbot rename docker/{Dockerfile.node => Dockerfile.certbot-node} (62%) create mode 100755 local-build.sh diff --git a/.jenkins/Jenkinsfile b/.jenkins/Jenkinsfile index d1891ea..1883418 100644 --- a/.jenkins/Jenkinsfile +++ b/.jenkins/Jenkinsfile @@ -28,9 +28,12 @@ pipeline { } steps { script { - env.BASE_TAG = 'latest' - env.BUILDX_PUSH_TAGS = "-t docker.io/nginxproxymanager/${IMAGE}:${BASE_TAG}" - env.BUILDX_PUSH_TAGS_NODE = "-t docker.io/nginxproxymanager/${IMAGE}:node" + env.BASE_TAG = 'latest' + env.BUILDX_PUSH_TAGS = "-t docker.io/nginxproxymanager/${IMAGE}:${BASE_TAG}" + env.BUILDX_PUSH_TAGS_ACMESH = "-t docker.io/nginxproxymanager/${IMAGE}:acmesh" + env.BUILDX_PUSH_TAGS_CERTBOT = "-t docker.io/nginxproxymanager/${IMAGE}:certbot" + env.BUILDX_PUSH_TAGS_ACMESH_GOLANG = "-t docker.io/nginxproxymanager/${IMAGE}:acmesh-golang" + env.BUILDX_PUSH_TAGS_CERTBOT_NODE = "-t docker.io/nginxproxymanager/${IMAGE}:certbot-node" } } } @@ -43,15 +46,20 @@ pipeline { steps { script { // Defaults to the Branch name, which is applies to all branches AND pr's - env.BASE_TAG = "github-${BRANCH_LOWER}" - env.BUILDX_PUSH_TAGS = "-t docker.io/nginxproxymanager/${IMAGE}:${BASE_TAG}" - env.BUILDX_PUSH_TAGS_NODE = "${BUILDX_PUSH_TAGS}-node" + env.BASE_TAG = "github-${BRANCH_LOWER}" + env.ACMESH_BASE_TAG = "github-${BRANCH_LOWER}-acmesh" + env.CERTBOT_BASE_TAG = "github-${BRANCH_LOWER}-certbot" + env.BUILDX_PUSH_TAGS = "-t docker.io/nginxproxymanager/${IMAGE}:${BASE_TAG}" + env.BUILDX_PUSH_TAGS_ACMESH = "${BUILDX_PUSH_TAGS}-acmesh" + env.BUILDX_PUSH_TAGS_CERTBOT = "${BUILDX_PUSH_TAGS}-certbot" + env.BUILDX_PUSH_TAGS_ACMESH_GOLANG = "${BUILDX_PUSH_TAGS}-acmesh-golang" + env.BUILDX_PUSH_TAGS_CERTBOT_NODE = "${BUILDX_PUSH_TAGS}-certbot-node" } } } } } - stage('Base Build') { + stage('Base') { environment { BUILDX_NAME = "${IMAGE}_${GIT_BRANCH}_base" } @@ -62,18 +70,27 @@ pipeline { } } } - stage('Other Builds') { - parallel { - stage('Node') { - environment { - BUILDX_NAME = "${IMAGE}_${GIT_BRANCH}_node" - } - steps { - withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'DOCKER_PASS', usernameVariable: 'DOCKER_USER')]) { - sh 'docker login -u "${DOCKER_USER}" -p "${DOCKER_PASS}"' - sh "./scripts/buildx --push -f docker/Dockerfile.node ${BUILDX_PUSH_TAGS_NODE}" - } - } + stage('Acme Clients') { + environment { + BUILDX_NAME = "${IMAGE}_${GIT_BRANCH}_node" + } + steps { + withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'DOCKER_PASS', usernameVariable: 'DOCKER_USER')]) { + sh 'docker login -u "${DOCKER_USER}" -p "${DOCKER_PASS}"' + sh "./scripts/buildx --push -f docker/Dockerfile.acmesh ${BUILDX_PUSH_TAGS_ACMESH}" + sh "./scripts/buildx --push -f docker/Dockerfile.certbot ${BUILDX_PUSH_TAGS_CERTBOT}" + } + } + } + stage('Dev Tools') { + environment { + BUILDX_NAME = "${IMAGE}_${GIT_BRANCH}_node" + } + steps { + withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'DOCKER_PASS', usernameVariable: 'DOCKER_USER')]) { + sh 'docker login -u "${DOCKER_USER}" -p "${DOCKER_PASS}"' + sh "./scripts/buildx --push -f docker/Dockerfile.acmesh-golang ${BUILDX_PUSH_TAGS_ACMESH_GOLANG}" + sh "./scripts/buildx --push -f docker/Dockerfile.certbot-node ${BUILDX_PUSH_TAGS_CERTBOT_NODE}" } } } diff --git a/README.md b/README.md index a0a906f..0da2be6 100644 --- a/README.md +++ b/README.md @@ -17,14 +17,29 @@ This is a base image for use in other images. See Dockerfile for build steps. -The following is compiled/installed: +The following images are built: +**latest** - OpenResty - Lua + +**certbot** - Certbot - Python3 and pip -The following architectures are supported: +**acmesh** _(used in Nginx Proxy Manager v3)_ +- Acme.sh + +**certbot-node** _(used in Nginx Proxy Manager v2)_ +- Certbot +- Python3 and pip +- Nodejs + +**acmesh-golang** _(development for Nginx Proxy Manager v3)_ +- Acme.sh +- Golang + +The following architectures are supported for all images: - amd64 - arm/v7 @@ -33,7 +48,7 @@ The following architectures are supported: ### Usage: ``` -FROM nginxproxymanager/nginx-full +FROM nginxproxymanager/nginx-full:latest ... ``` diff --git a/docker/Dockerfile b/docker/Dockerfile index ebe9b8a..0514655 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,45 +1,3 @@ -############# -# Certbot Builder -############# - -FROM debian:buster-slim as certbotbuilder - -SHELL ["/bin/bash", "-o", "pipefail", "-c"] - -RUN apt-get update -RUN apt-get install -y \ - build-essential \ - curl \ - libaugeas0 \ - python3 \ - python3-dev \ - libffi-dev \ - libssl-dev \ - python3-venv \ - ca-certificates - -ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt - -# Yes, python compilation requires rust. -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y -ENV PATH="/root/.cargo/bin:$PATH" - -# It's all about pip now. -RUN python3 -m venv /opt/certbot/ -ENV PATH="/opt/certbot/bin:$PATH" - -RUN curl -L 'https://bootstrap.pypa.io/get-pip.py' | python3 - -# Handle an extremely specific issue when building the cryptography package for -# 32-bit architectures within QEMU running on a 64-bit host -# Special thanks to https://github.com/JonasAlfredsson/docker-nginx-certbot -RUN if [ "$(getconf LONG_BIT)" = "32" ]; then \ - pip3 install --no-cache-dir -U cryptography==3.3.2; \ - fi - -RUN pip install --no-cache-dir cffi certbot \ - && pip install tldextract - ############# # Nginx Builder ############# @@ -83,26 +41,25 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"] ARG TARGETPLATFORM RUN echo "Base: debian:buster-slim, ${TARGETPLATFORM:-linux/amd64}" > /built-for-arch -# OpenResty uses LuaJIT which has a dependency on GCC +# OpenResty uses LuaJIT which has a dependency on GCC RUN apt-get update \ && apt-get install -y --no-install-recommends \ apache2-utils \ ca-certificates \ curl \ figlet \ + jq \ libncurses6 \ libpcre3 \ libreadline7 \ openssl \ perl \ - python3 \ - python3-distutils \ - python3-venv \ tzdata \ unzip \ zlib1g \ && apt-get clean \ - && rm -rf /var/lib/apt/lists/* + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /var/cache/* /var/log/* /tmp/* /var/lib/dpkg/status-old COPY ./files/.bashrc /root/.bashrc @@ -115,44 +72,25 @@ COPY ./scripts/install-lua /tmp/install-lua COPY --from=nginxbuilder /tmp/openresty /tmp/openresty COPY ./scripts/install-openresty /tmp/install-openresty -ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt - -# Copy certbot -COPY --from=certbotbuilder /opt/certbot /opt/certbot -RUN curl -L 'https://bootstrap.pypa.io/get-pip.py' | python3 \ - && python3 -m venv /opt/certbot/ \ - && ln -s /opt/certbot/bin/certbot /usr/bin/certbot - ARG OPENRESTY_VERSION -ENV OPENRESTY_VERSION=${OPENRESTY_VERSION} \ - CERT_HOME='/data/acme.sh/' \ - PATH="/opt/certbot/bin:$PATH" +ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \ + OPENRESTY_VERSION=${OPENRESTY_VERSION} -# Install openresty, lua +# Install openresty, lua, then clean up file system RUN apt-get update \ - && apt-get install -y \ - gcc \ - make \ - socat \ - git \ + && apt-get install -y gcc make socat git \ && /tmp/install-lua \ && /tmp/install-openresty \ - && rm -f /tmp/install-lua \ - && rm -f /tmp/install-openresty \ && apt-get remove -y make gcc git \ && apt-get autoremove -y \ && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# acme.sh -RUN mkdir -p /data/acme.sh \ - && curl -o /bin/acme.sh 'https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh' \ - && chmod +x /bin/acme.sh + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /var/cache/* /var/log/* /tmp/* /var/lib/dpkg/status-old LABEL org.label-schema.schema-version="1.0" \ org.label-schema.license="MIT" \ org.label-schema.name="nginx-full" \ org.label-schema.description="A base image for use by Nginx Proxy Manager" \ - org.label-schema.url="https://github.com/jc21/docker-nginx-full" \ - org.label-schema.vcs-url="https://github.com/jc21/docker-nginx-full.git" \ - org.label-schema.cmd="docker run --rm -ti jc21/nginx-full:latest" + org.label-schema.url="https://github.com/nginxproxymanager/docker-nginx-full" \ + org.label-schema.vcs-url="https://github.com/nginxproxymanager/docker-nginx-full.git" \ + org.label-schema.cmd="docker run --rm -ti nginxproxymanager/nginx-full:latest" diff --git a/docker/Dockerfile.acmesh b/docker/Dockerfile.acmesh new file mode 100644 index 0000000..eec3d4b --- /dev/null +++ b/docker/Dockerfile.acmesh @@ -0,0 +1,14 @@ +FROM nginxproxymanager/nginx-full:${BASE_TAG:-latest} +LABEL maintainer="Jamie Curnow " + +ARG TARGETPLATFORM +RUN echo "Acme.sh: nginxproxymanager/nginx-full:${BASE_TAG:-latest}, ${TARGETPLATFORM:-linux/amd64}" >> /built-for-arch + +ENV CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt + +# acme.sh +RUN mkdir -p /data/acme.sh \ + && curl -o /bin/acme.sh 'https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh' \ + && chmod +x /bin/acme.sh + +LABEL org.label-schema.cmd="docker run --rm -ti nginxproxymanager/nginx-full:acmesh" diff --git a/docker/Dockerfile.acmesh-golang b/docker/Dockerfile.acmesh-golang new file mode 100644 index 0000000..9d0c6c3 --- /dev/null +++ b/docker/Dockerfile.acmesh-golang @@ -0,0 +1,29 @@ +FROM golang:latest as go +FROM nginxproxymanager/nginx-full:${ACMESH_BASE_TAG:-acmesh} +LABEL maintainer="Jamie Curnow " + +ARG TARGETPLATFORM +RUN echo "Golang: nginxproxymanager/nginx-full:${BASE_TAG:-acmesh}, ${TARGETPLATFORM:-linux/amd64}" >> /built-for-arch + +RUN apt-get update \ + && apt-get install -y wget gcc g++ make git sqlite3 jq \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# copy go from golang +COPY --from=go /usr/local/go /usr/local/go + +ENV GOPATH=/opt/go PATH="/usr/local/go/bin:$PATH:/opt/go/bin" +RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" \ + && chmod -R 777 "$GOPATH" \ + && echo "====> ${TARGETPLATFORM}: $(go version)" + +WORKDIR /root + +# Gotools +RUN if [ "$TARGETPLATFORM" == "" ] || [ "$TARGETPLATFORM" == "linux/amd64" ]; then cd /usr && wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.39.0; fi +RUN go get -u github.com/kyoh86/richgo \ + && go get -u github.com/sonatype-nexus-community/nancy \ + && rm -rf /root/.cache/go-build + +LABEL org.label-schema.cmd="docker run --rm -ti nginxproxymanager/nginx-full:acmesh-golang" diff --git a/docker/Dockerfile.certbot b/docker/Dockerfile.certbot new file mode 100644 index 0000000..4b67073 --- /dev/null +++ b/docker/Dockerfile.certbot @@ -0,0 +1,68 @@ +############# +# Certbot Builder +############# + +FROM debian:buster-slim as certbotbuilder + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN apt-get update +RUN apt-get install -y \ + build-essential \ + curl \ + libaugeas0 \ + python3 \ + python3-dev \ + libffi-dev \ + libssl-dev \ + python3-venv \ + ca-certificates + +ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt + +# Yes, python compilation requires rust. +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +ENV PATH="/root/.cargo/bin:$PATH" + +# It's all about pip now. +RUN python3 -m venv /opt/certbot/ +ENV PATH="/opt/certbot/bin:$PATH" + +RUN curl -L 'https://bootstrap.pypa.io/get-pip.py' | python3 + +# Handle an extremely specific issue when building the cryptography package for +# 32-bit architectures within QEMU running on a 64-bit host +# Special thanks to https://github.com/JonasAlfredsson/docker-nginx-certbot +RUN if [ "$(getconf LONG_BIT)" = "32" ]; then \ + pip3 install --no-cache-dir -U cryptography==3.3.2; \ + fi + +RUN pip install --no-cache-dir cffi certbot \ + && pip install tldextract + +############# +# Final Image +############# + +FROM nginxproxymanager/nginx-full:${BASE_TAG:-latest} +LABEL maintainer="Jamie Curnow " + +ARG TARGETPLATFORM +RUN echo "Certbot: nginxproxymanager/nginx-full:${BASE_TAG:-latest}, ${TARGETPLATFORM:-linux/amd64}" >> /built-for-arch + +# OpenResty uses LuaJIT which has a dependency on GCC +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + python3 \ + python3-distutils \ + python3-venv \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Copy certbot +COPY --from=certbotbuilder /opt/certbot /opt/certbot +RUN curl -L 'https://bootstrap.pypa.io/get-pip.py' | python3 \ + && python3 -m venv /opt/certbot/ \ + && ln -s /opt/certbot/bin/certbot /usr/bin/certbot + +LABEL org.label-schema.cmd="docker run --rm -ti nginxproxymanager/nginx-full:certbot" diff --git a/docker/Dockerfile.node b/docker/Dockerfile.certbot-node similarity index 62% rename from docker/Dockerfile.node rename to docker/Dockerfile.certbot-node index eb671db..0d1c660 100644 --- a/docker/Dockerfile.node +++ b/docker/Dockerfile.certbot-node @@ -1,8 +1,8 @@ -FROM nginxproxymanager/nginx-full:${BASE_TAG:-latest} +FROM nginxproxymanager/nginx-full:${CERTBOT_BASE_TAG:-certbot} LABEL maintainer="Jamie Curnow " ARG TARGETPLATFORM -RUN echo "Node: jc21/nginx-full:${BASE_TAG:-latest}, ${TARGETPLATFORM:-linux/amd64}" >> /built-for-arch +RUN echo "Node: nginxproxymanager/nginx-full:${BASE_TAG:-certbot}, ${TARGETPLATFORM:-linux/amd64}" >> /built-for-arch ENV CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt @@ -17,3 +17,5 @@ RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash - \ COPY ./files/test.js /tmp/test.js RUN node /tmp/test.js \ && rm -f /tmp/test.js + +LABEL org.label-schema.cmd="docker run --rm -ti nginxproxymanager/nginx-full:certbot-node" diff --git a/local-build.sh b/local-build.sh new file mode 100755 index 0000000..943a361 --- /dev/null +++ b/local-build.sh @@ -0,0 +1,55 @@ +#!/bin/bash -e + +BLUE='\E[1;34m' +CYAN='\E[1;36m' +YELLOW='\E[1;33m' +GREEN='\E[1;32m' +RESET='\E[0m' + +DOCKER_IMAGE=nginxproxymanager/nginx-full + +export OPENRESTY_VERSION=1.19.9.1 +export LUA_VERSION=5.1.5 +export LUAROCKS_VERSION=3.3.1 + +# Builds + +echo -e "${BLUE}❯ ${CYAN}Building ${YELLOW}latest ${CYAN}...${RESET}" +docker build \ + --pull \ + --build-arg OPENRESTY_VERSION \ + --build-arg LUA_VERSION \ + --build-arg LUAROCKS_VERSION \ + -t ${DOCKER_IMAGE}:latest \ + -f docker/Dockerfile \ + . + +echo -e "${BLUE}❯ ${CYAN}Building ${YELLOW}acmesh ${CYAN}...${RESET}" +docker build \ + --build-arg BASE_TAG=latest \ + -t ${DOCKER_IMAGE}:acmesh \ + -f docker/Dockerfile.acmesh \ + . + +echo -e "${BLUE}❯ ${CYAN}Building ${YELLOW}certbot ${CYAN}...${RESET}" +docker build \ + --build-arg BASE_TAG=latest \ + -t ${DOCKER_IMAGE}:certbot \ + -f docker/Dockerfile.certbot \ + . + +echo -e "${BLUE}❯ ${CYAN}Building ${YELLOW}acmesh-golang ${CYAN}...${RESET}" +docker build \ + --build-arg BASE_TAG=acmesh \ + -t ${DOCKER_IMAGE}:acmesh-golang \ + -f docker/Dockerfile.acmesh-golang \ + . + +echo -e "${BLUE}❯ ${CYAN}Building ${YELLOW}certbot-node ${CYAN}...${RESET}" +docker build \ + --build-arg BASE_TAG=certbot \ + -t ${DOCKER_IMAGE}:certbot-node \ + -f docker/Dockerfile.certbot-node \ + . + +echo -e "${BLUE}❯ ${GREEN}All done!${RESET}" diff --git a/scripts/buildx b/scripts/buildx index b8ef22a..fc52745 100755 --- a/scripts/buildx +++ b/scripts/buildx @@ -20,6 +20,8 @@ docker buildx build \ --progress plain \ --pull \ --build-arg BASE_TAG \ + --build-arg ACMESH_BASE_TAG \ + --build-arg CERTBOT_BASE_TAG \ --build-arg OPENRESTY_VERSION \ --build-arg LUA_VERSION \ --build-arg LUAROCKS_VERSION \