From b4bf1404eea9753643d77af4937d187ac71f1fd2 Mon Sep 17 00:00:00 2001 From: Robert Kaussow Date: Mon, 18 Jan 2021 21:21:17 +0100 Subject: [PATCH] build multiarch images --- .drone.jsonnet | 197 +++++++++++++++++++++++++++ .drone.yml | 239 ++++++++++++++++++++++++++++----- Dockerfile => Dockerfile.amd64 | 2 +- Dockerfile.arm | 53 ++++++++ Dockerfile.arm64 | 53 ++++++++ manifest-quay.tmpl | 24 ++++ manifest.tmpl | 24 ++++ 7 files changed, 555 insertions(+), 37 deletions(-) create mode 100644 .drone.jsonnet rename Dockerfile => Dockerfile.amd64 (96%) create mode 100644 Dockerfile.arm create mode 100644 Dockerfile.arm64 create mode 100644 manifest-quay.tmpl create mode 100644 manifest.tmpl diff --git a/.drone.jsonnet b/.drone.jsonnet new file mode 100644 index 0000000..8319182 --- /dev/null +++ b/.drone.jsonnet @@ -0,0 +1,197 @@ +local PipelineTest = { + kind: 'pipeline', + name: 'test', + platform: { + os: 'linux', + arch: 'amd64', + }, + steps: [ + { + name: 'markdownlint', + image: 'thegeeklab/markdownlint-cli', + commands: [ + "markdownlint 'README.md'", + ], + }, + ], + trigger: { + ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'], + }, +}; + +local PipelineBuildContainer(arch='amd64') = { + kind: 'pipeline', + name: 'build-container-' + std.split(arch, '_')[0], + platform: { + os: 'linux', + arch: 'amd64', + }, + steps: [ + { + name: 'tags', + image: 'thegeeklab/docker-autotag', + environment: { + DOCKER_AUTOTAG_FORCE_LATEST: 'True', + DOCKER_AUTOTAG_IGNORE_PRERELEASE: 'True', + DOCKER_AUTOTAG_OUTPUT_FILE: '.tags', + DOCKER_AUTOTAG_VERSION: '${DRONE_TAG}', + DOCKER_AUTOTAG_SUFFIX: std.split(arch, '_')[0], + }, + }, + { + name: 'dryrun', + image: 'thegeeklab/drone-docker-buildx:20', + settings: { + dry_run: true, + dockerfile: 'Dockerfile.' + std.split(arch, '_')[0], + platforms: [ + 'linux/' + std.strReplace(arch, '_', '/'), + ], + repo: 'thegeeklab/${DRONE_REPO_NAME}', + username: { from_secret: 'docker_username' }, + password: { from_secret: 'docker_password' }, + }, + depends_on: ['tags'], + when: { + ref: ['refs/pull/**'], + }, + }, + { + name: 'publish-dockerhub', + image: 'thegeeklab/drone-docker-buildx:20', + settings: { + dockerfile: 'Dockerfile.' + std.split(arch, '_')[0], + repo: 'thegeeklab/${DRONE_REPO_NAME}', + username: { from_secret: 'docker_username' }, + password: { from_secret: 'docker_password' }, + }, + when: { + ref: ['refs/heads/main', 'refs/tags/**'], + }, + depends_on: ['tags'], + }, + { + name: 'publish-quay', + image: 'thegeeklab/drone-docker-buildx:20', + settings: { + dockerfile: 'Dockerfile.' + std.split(arch, '_')[0], + registry: 'quay.io', + repo: 'quay.io/thegeeklab/${DRONE_REPO_NAME}', + username: { from_secret: 'quay_username' }, + password: { from_secret: 'quay_password' }, + }, + when: { + ref: ['refs/heads/main', 'refs/tags/**'], + }, + depends_on: ['tags'], + }, + ], + depends_on: [ + 'test', + ], + trigger: { + ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'], + }, +}; + +local PipelineNotifications = { + kind: 'pipeline', + name: 'notifications', + platform: { + os: 'linux', + arch: 'amd64', + }, + steps: [ + { + image: 'plugins/manifest', + name: 'manifest-dockerhub', + settings: { + ignore_missing: true, + username: { from_secret: 'docker_username' }, + password: { from_secret: 'docker_password' }, + spec: 'manifest.tmpl', + }, + when: { + status: ['success'], + }, + }, + { + image: 'plugins/manifest', + name: 'manifest-quay', + settings: { + ignore_missing: true, + username: { from_secret: 'quay_username' }, + password: { from_secret: 'quay_password' }, + spec: 'manifest-quay.tmpl', + }, + when: { + status: ['success'], + }, + }, + { + name: 'pushrm-dockerhub', + pull: 'always', + image: 'chko/docker-pushrm:1', + environment: { + DOCKER_PASS: { + from_secret: 'docker_password', + }, + DOCKER_USER: { + from_secret: 'docker_username', + }, + PUSHRM_FILE: 'README.md', + PUSHRM_SHORT: 'Custom image for nginx HTTP server', + PUSHRM_TARGET: 'thegeeklab/${DRONE_REPO_NAME}', + }, + when: { + status: ['success'], + }, + }, + { + name: 'pushrm-quay', + pull: 'always', + image: 'chko/docker-pushrm:1', + environment: { + APIKEY__QUAY_IO: { + from_secret: 'quay_token', + }, + PUSHRM_FILE: 'README.md', + PUSHRM_TARGET: 'quay.io/thegeeklab/${DRONE_REPO_NAME}', + }, + when: { + status: ['success'], + }, + }, + { + name: 'matrix', + image: 'plugins/matrix', + settings: { + homeserver: { from_secret: 'matrix_homeserver' }, + roomid: { from_secret: 'matrix_roomid' }, + template: 'Status: **{{ build.status }}**
Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.link }}) ({{ build.branch }}) by {{ build.author }}
Message: {{ build.message }}', + username: { from_secret: 'matrix_username' }, + password: { from_secret: 'matrix_password' }, + }, + when: { + status: ['success', 'failure'], + }, + }, + ], + depends_on: [ + 'build-container-amd64', + 'build-container-arm64', + 'build-container-arm', + ], + trigger: { + ref: ['refs/heads/main', 'refs/tags/**'], + status: ['success', 'failure'], + }, +}; + +[ + PipelineTest, + PipelineBuildContainer(arch='amd64'), + PipelineBuildContainer(arch='arm64_v8'), + PipelineBuildContainer(arch='arm_v7'), + PipelineNotifications, +] diff --git a/.drone.yml b/.drone.yml index a5ccc1d..01ee3e9 100644 --- a/.drone.yml +++ b/.drone.yml @@ -15,50 +15,49 @@ steps: trigger: ref: - refs/heads/main - - refs/pull/** - refs/tags/** + - refs/pull/** --- kind: pipeline -name: build-container +name: build-container-amd64 platform: os: linux arch: amd64 steps: -- name: dryrun - image: thegeeklab/drone-docker:19 - settings: - dockerfile: Dockerfile - dry_run: true - password: - from_secret: docker_password - repo: thegeeklab/${DRONE_REPO_NAME} - username: - from_secret: docker_username - when: - ref: - - refs/pull/** - - name: tags image: thegeeklab/docker-autotag environment: DOCKER_AUTOTAG_FORCE_LATEST: True DOCKER_AUTOTAG_IGNORE_PRERELEASE: True DOCKER_AUTOTAG_OUTPUT_FILE: .tags + DOCKER_AUTOTAG_SUFFIX: amd64 DOCKER_AUTOTAG_VERSION: ${DRONE_TAG} + +- name: dryrun + image: thegeeklab/drone-docker-buildx:20 + settings: + dockerfile: Dockerfile.amd64 + dry_run: true + password: + from_secret: docker_password + platforms: + - linux/amd64 + repo: thegeeklab/${DRONE_REPO_NAME} + username: + from_secret: docker_username when: ref: - - refs/heads/main - - refs/tags/** + - refs/pull/** depends_on: - - dryrun + - tags - name: publish-dockerhub - image: thegeeklab/drone-docker:19 + image: thegeeklab/drone-docker-buildx:20 settings: - dockerfile: Dockerfile + dockerfile: Dockerfile.amd64 password: from_secret: docker_password repo: thegeeklab/${DRONE_REPO_NAME} @@ -72,9 +71,9 @@ steps: - tags - name: publish-quay - image: thegeeklab/drone-docker:19 + image: thegeeklab/drone-docker-buildx:20 settings: - dockerfile: Dockerfile + dockerfile: Dockerfile.amd64 password: from_secret: quay_password registry: quay.io @@ -88,27 +87,167 @@ steps: depends_on: - tags -- name: publish-gitea - image: plugins/gitea-release +trigger: + ref: + - refs/heads/main + - refs/tags/** + - refs/pull/** + +depends_on: +- test + +--- +kind: pipeline +name: build-container-arm64 + +platform: + os: linux + arch: amd64 + +steps: +- name: tags + image: thegeeklab/docker-autotag + environment: + DOCKER_AUTOTAG_FORCE_LATEST: True + DOCKER_AUTOTAG_IGNORE_PRERELEASE: True + DOCKER_AUTOTAG_OUTPUT_FILE: .tags + DOCKER_AUTOTAG_SUFFIX: arm64 + DOCKER_AUTOTAG_VERSION: ${DRONE_TAG} + +- name: dryrun + image: thegeeklab/drone-docker-buildx:20 settings: - api_key: - from_secret: gitea_token - base_url: https://gitea.rknet.org - note: CHANGELOG.md - overwrite: true - title: ${DRONE_TAG} + dockerfile: Dockerfile.arm64 + dry_run: true + password: + from_secret: docker_password + platforms: + - linux/arm64/v8 + repo: thegeeklab/${DRONE_REPO_NAME} + username: + from_secret: docker_username when: ref: + - refs/pull/** + depends_on: + - tags + +- name: publish-dockerhub + image: thegeeklab/drone-docker-buildx:20 + settings: + dockerfile: Dockerfile.arm64 + password: + from_secret: docker_password + repo: thegeeklab/${DRONE_REPO_NAME} + username: + from_secret: docker_username + when: + ref: + - refs/heads/main - refs/tags/** depends_on: - - publish-dockerhub - - publish-quay + - tags + +- name: publish-quay + image: thegeeklab/drone-docker-buildx:20 + settings: + dockerfile: Dockerfile.arm64 + password: + from_secret: quay_password + registry: quay.io + repo: quay.io/thegeeklab/${DRONE_REPO_NAME} + username: + from_secret: quay_username + when: + ref: + - refs/heads/main + - refs/tags/** + depends_on: + - tags trigger: ref: - refs/heads/main - - refs/pull/** - refs/tags/** + - refs/pull/** + +depends_on: +- test + +--- +kind: pipeline +name: build-container-arm + +platform: + os: linux + arch: amd64 + +steps: +- name: tags + image: thegeeklab/docker-autotag + environment: + DOCKER_AUTOTAG_FORCE_LATEST: True + DOCKER_AUTOTAG_IGNORE_PRERELEASE: True + DOCKER_AUTOTAG_OUTPUT_FILE: .tags + DOCKER_AUTOTAG_SUFFIX: arm + DOCKER_AUTOTAG_VERSION: ${DRONE_TAG} + +- name: dryrun + image: thegeeklab/drone-docker-buildx:20 + settings: + dockerfile: Dockerfile.arm + dry_run: true + password: + from_secret: docker_password + platforms: + - linux/arm/v7 + repo: thegeeklab/${DRONE_REPO_NAME} + username: + from_secret: docker_username + when: + ref: + - refs/pull/** + depends_on: + - tags + +- name: publish-dockerhub + image: thegeeklab/drone-docker-buildx:20 + settings: + dockerfile: Dockerfile.arm + password: + from_secret: docker_password + repo: thegeeklab/${DRONE_REPO_NAME} + username: + from_secret: docker_username + when: + ref: + - refs/heads/main + - refs/tags/** + depends_on: + - tags + +- name: publish-quay + image: thegeeklab/drone-docker-buildx:20 + settings: + dockerfile: Dockerfile.arm + password: + from_secret: quay_password + registry: quay.io + repo: quay.io/thegeeklab/${DRONE_REPO_NAME} + username: + from_secret: quay_username + when: + ref: + - refs/heads/main + - refs/tags/** + depends_on: + - tags + +trigger: + ref: + - refs/heads/main + - refs/tags/** + - refs/pull/** depends_on: - test @@ -122,6 +261,32 @@ platform: arch: amd64 steps: +- name: manifest-dockerhub + image: plugins/manifest + settings: + ignore_missing: true + password: + from_secret: docker_password + spec: manifest.tmpl + username: + from_secret: docker_username + when: + status: + - success + +- name: manifest-quay + image: plugins/manifest + settings: + ignore_missing: true + password: + from_secret: quay_password + spec: manifest-quay.tmpl + username: + from_secret: quay_username + when: + status: + - success + - name: pushrm-dockerhub pull: always image: chko/docker-pushrm:1 @@ -175,10 +340,12 @@ trigger: - failure depends_on: -- build-container +- build-container-amd64 +- build-container-arm64 +- build-container-arm --- kind: signature -hmac: 98caeb64f7ee52e08b3ad35b4c496b68bcb3e276aac6f08fee75db2e9657aa82 +hmac: cf791bc917fa661d98eacaf3b7e674c1fec3c0c3cd2e42b56d068bea4950fcd8 ... diff --git a/Dockerfile b/Dockerfile.amd64 similarity index 96% rename from Dockerfile rename to Dockerfile.amd64 index 7a2e4a7..fb795ac 100644 --- a/Dockerfile +++ b/Dockerfile.amd64 @@ -1,4 +1,4 @@ -FROM alpine:3.12@sha256:074d3636ebda6dd446d0d00304c4454f468237fdacf08fb0eeac90bdbfa1bac7 +FROM amd64/alpine:3.13 LABEL maintainer="Robert Kaussow " LABEL org.opencontainers.image.authors="Robert Kaussow " diff --git a/Dockerfile.arm b/Dockerfile.arm new file mode 100644 index 0000000..d20834d --- /dev/null +++ b/Dockerfile.arm @@ -0,0 +1,53 @@ +FROM arm32v7/alpine:3.13 + +LABEL maintainer="Robert Kaussow " +LABEL org.opencontainers.image.authors="Robert Kaussow " +LABEL org.opencontainers.image.title="nginx" +LABEL org.opencontainers.image.url="https://gitea.rknet.org/docker/nginx" +LABEL org.opencontainers.image.source="https://gitea.rknet.org/docker/nginx" +LABEL org.opencontainers.image.documentation="https://gitea.rknet.org/docker/nginx" + +ARG GOMPLATE_VERSION +ARG SUPERCRONIC_VERSION +ARG URL_PARSER_VERSION + +# renovate: datasource=github-releases depName=hairyhenderson/gomplate +ENV GOMPLATE_VERSION="${GOMPLATE_VERSION:-v3.8.0}" +# renovate: datasource=github-releases depName=aptible/supercronic +ENV SUPERCRONIC_VERSION="${SUPERCRONIC_VERSION:-v0.1.12}" +# renovate: datasource=github-releases depName=thegeeklab/url-parser +ENV URL_PARSER_VERSION="${URL_PARSER_VERSION:-v0.2.1}" + +RUN addgroup -g 101 -S nginx && \ + adduser -S -D -H -u 101 -h /var/www -s /sbin/nologin -G nginx -g nginx nginx && \ + apk --update add --virtual .build-deps curl && \ + apk --update --no-cache add nginx ca-certificates && \ + rm -rf /var/www/localhost && \ + rm -rf /etc/nginx/conf.d && \ + curl -SsL -o /usr/local/bin/gomplate "https://github.com/hairyhenderson/gomplate/releases/download/${GOMPLATE_VERSION}/gomplate_linux-amd64-slim" && \ + curl -SsL -o /usr/local/bin/supercronic "https://github.com/aptible/supercronic/releases/download/${SUPERCRONIC_VERSION}/supercronic-linux-amd64" && \ + curl -SsL -o /usr/local/bin/url-parser "https://github.com/thegeeklab/url-parser/releases/download/${URL_PARSER_VERSION}/url-parser-linux-amd64" && \ + curl -SsL -o /usr/local/bin/wait-for "https://raw.githubusercontent.com/thegeeklab/wait-for/master/wait-for" && \ + chmod 755 /usr/local/bin/gomplate && \ + chmod 755 /usr/local/bin/supercronic && \ + chmod 755 /usr/local/bin/url-parser && \ + chmod 755 /usr/local/bin/wait-for && \ + touch /run/nginx.pid && \ + chown nginx /run/nginx.pid && \ + chown -R nginx /var/log/nginx && \ + mkdir -p /var/cache/nginx && \ + chown -R nginx /var/cache/nginx && \ + chmod -R 750 /var/cache/nginx && \ + chown -R nginx:nginx /var/www && \ + chmod -R 750 /var/www && \ + apk del .build-deps && \ + rm -rf /var/cache/apk/* && \ + rm -rf /tmp/* + +ADD overlay/ / + +EXPOSE 8080 + +STOPSIGNAL SIGTERM + +CMD ["nginx", "-g", "daemon off;"] diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 new file mode 100644 index 0000000..52081e6 --- /dev/null +++ b/Dockerfile.arm64 @@ -0,0 +1,53 @@ +FROM arm64v8/alpine:3.13 + +LABEL maintainer="Robert Kaussow " +LABEL org.opencontainers.image.authors="Robert Kaussow " +LABEL org.opencontainers.image.title="nginx" +LABEL org.opencontainers.image.url="https://gitea.rknet.org/docker/nginx" +LABEL org.opencontainers.image.source="https://gitea.rknet.org/docker/nginx" +LABEL org.opencontainers.image.documentation="https://gitea.rknet.org/docker/nginx" + +ARG GOMPLATE_VERSION +ARG SUPERCRONIC_VERSION +ARG URL_PARSER_VERSION + +# renovate: datasource=github-releases depName=hairyhenderson/gomplate +ENV GOMPLATE_VERSION="${GOMPLATE_VERSION:-v3.8.0}" +# renovate: datasource=github-releases depName=aptible/supercronic +ENV SUPERCRONIC_VERSION="${SUPERCRONIC_VERSION:-v0.1.12}" +# renovate: datasource=github-releases depName=thegeeklab/url-parser +ENV URL_PARSER_VERSION="${URL_PARSER_VERSION:-v0.2.1}" + +RUN addgroup -g 101 -S nginx && \ + adduser -S -D -H -u 101 -h /var/www -s /sbin/nologin -G nginx -g nginx nginx && \ + apk --update add --virtual .build-deps curl && \ + apk --update --no-cache add nginx ca-certificates && \ + rm -rf /var/www/localhost && \ + rm -rf /etc/nginx/conf.d && \ + curl -SsL -o /usr/local/bin/gomplate "https://github.com/hairyhenderson/gomplate/releases/download/${GOMPLATE_VERSION}/gomplate_linux-amd64-slim" && \ + curl -SsL -o /usr/local/bin/supercronic "https://github.com/aptible/supercronic/releases/download/${SUPERCRONIC_VERSION}/supercronic-linux-amd64" && \ + curl -SsL -o /usr/local/bin/url-parser "https://github.com/thegeeklab/url-parser/releases/download/${URL_PARSER_VERSION}/url-parser-linux-amd64" && \ + curl -SsL -o /usr/local/bin/wait-for "https://raw.githubusercontent.com/thegeeklab/wait-for/master/wait-for" && \ + chmod 755 /usr/local/bin/gomplate && \ + chmod 755 /usr/local/bin/supercronic && \ + chmod 755 /usr/local/bin/url-parser && \ + chmod 755 /usr/local/bin/wait-for && \ + touch /run/nginx.pid && \ + chown nginx /run/nginx.pid && \ + chown -R nginx /var/log/nginx && \ + mkdir -p /var/cache/nginx && \ + chown -R nginx /var/cache/nginx && \ + chmod -R 750 /var/cache/nginx && \ + chown -R nginx:nginx /var/www && \ + chmod -R 750 /var/www && \ + apk del .build-deps && \ + rm -rf /var/cache/apk/* && \ + rm -rf /tmp/* + +ADD overlay/ / + +EXPOSE 8080 + +STOPSIGNAL SIGTERM + +CMD ["nginx", "-g", "daemon off;"] diff --git a/manifest-quay.tmpl b/manifest-quay.tmpl new file mode 100644 index 0000000..5eb1ac9 --- /dev/null +++ b/manifest-quay.tmpl @@ -0,0 +1,24 @@ +image: quay.io/thegeeklab/nginx:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}} +{{#if build.tags}} +tags: +{{#each build.tags}} + - {{this}} +{{/each}} +{{/if}} +manifests: + - image: quay.io/thegeeklab/nginx:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}amd64 + platform: + architecture: amd64 + os: linux + + - image: quay.io/thegeeklab/nginx:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm64 + platform: + architecture: arm64 + os: linux + variant: v8 + + - image: quay.io/thegeeklab/nginx:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm + platform: + architecture: arm + os: linux + variant: v7 diff --git a/manifest.tmpl b/manifest.tmpl new file mode 100644 index 0000000..db63c4b --- /dev/null +++ b/manifest.tmpl @@ -0,0 +1,24 @@ +image: thegeeklab/nginx:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}} +{{#if build.tags}} +tags: +{{#each build.tags}} + - {{this}} +{{/each}} +{{/if}} +manifests: + - image: thegeeklab/nginx:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}amd64 + platform: + architecture: amd64 + os: linux + + - image: thegeeklab/nginx:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm64 + platform: + architecture: arm64 + os: linux + variant: v8 + + - image: thegeeklab/nginx:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm + platform: + architecture: arm + os: linux + variant: v7