From: Thomas B. Date: Tue, 15 Apr 2025 19:46:17 +0000 (+0200) Subject: feat: build non-root image variants (#310) X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=ef4b8cc59eecbf0e25c66c7f3c464594cc310761;p=roundcube-roundcubemail-docker.git feat: build non-root image variants (#310) Adds an additional stage to the Dockerfile to create images with default user www-data. The apache webserver listens on unprivileged port 8000 instead of 80. Publish all variants with an additional tag ending in `-nonroot` for distinction. Refs: #306 --- diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 542dcd9..07357b6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,14 +30,32 @@ jobs: test-files: 'apache-postgres' docker-tag: roundcube/roundcubemail:1.6.x-apache,roundcube/roundcubemail:1.6.10-apache,roundcube/roundcubemail:latest-apache,roundcube/roundcubemail:latest test-tag: roundcube/roundcubemail:latest-apache + target: 'root' - variant: 'fpm' test-files: 'fpm-postgres' docker-tag: roundcube/roundcubemail:1.6.x-fpm,roundcube/roundcubemail:1.6.10-fpm,roundcube/roundcubemail:latest-fpm test-tag: roundcube/roundcubemail:latest-fpm + target: 'root' - variant: 'fpm-alpine' test-files: 'fpm-postgres' docker-tag: roundcube/roundcubemail:1.6.x-fpm-alpine,roundcube/roundcubemail:1.6.10-fpm-alpine,roundcube/roundcubemail:latest-fpm-alpine test-tag: roundcube/roundcubemail:latest-fpm-alpine + target: 'root' + - variant: 'apache' + test-files: 'apache-postgres' + docker-tag: roundcube/roundcubemail:1.6.x-apache-nonroot,roundcube/roundcubemail:1.6.9-apache-nonroot,roundcube/roundcubemail:latest-apache-nonroot,roundcube/roundcubemail:latest-nonroot + test-tag: roundcube/roundcubemail:latest-apache-nonroot + target: 'nonroot' + - variant: 'fpm' + test-files: 'apache-postgres' + docker-tag: roundcube/roundcubemail:1.6.x-fpm-nonroot,roundcube/roundcubemail:1.6.9-fpm-nonroot,roundcube/roundcubemail:latest-fpm-nonroot + test-tag: roundcube/roundcubemail:latest-fpm-nonroot + target: 'nonroot' + - variant: 'fpm-alpine' + test-files: 'apache-postgres' + docker-tag: roundcube/roundcubemail:1.6.x-fpm-alpine-nonroot,roundcube/roundcubemail:1.6.9-fpm-alpine-nonroot,roundcube/roundcubemail:latest-fpm-alpine-nonroot + test-tag: roundcube/roundcubemail:latest-fpm-alpine-nonroot + target: 'nonroot' steps: - name: Checkout repository uses: actions/checkout@v4 @@ -65,6 +83,7 @@ jobs: platforms: "linux/arm64,linux/arm/v6,linux/arm/v7,linux/386,linux/amd64," push: true tags: ${{ matrix.docker-tag }} + target: ${{ matrix.target }} # does not work linux/arm/v5 AND linux/mips64le - composer does not support mips64le or armv5 nor does the php image support them on the alpine variant - name: Run tests diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 50577d7..baa06e9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,12 +20,28 @@ jobs: - variant: 'apache' test-files: 'apache-postgres' docker-tag: roundcube/roundcubemail:test-apache + target: 'root' - variant: 'fpm' test-files: 'fpm-postgres' docker-tag: roundcube/roundcubemail:test-fpm + target: 'root' - variant: 'fpm-alpine' test-files: 'fpm-postgres' docker-tag: roundcube/roundcubemail:test-fpm-alpine + target: 'root' + - variant: 'apache' + test-files: 'apache-postgres' + docker-tag: roundcube/roundcubemail:test-apache-nonroot + target: 'nonroot' + http-port: '8000' + - variant: 'fpm' + test-files: 'fpm-postgres' + docker-tag: roundcube/roundcubemail:test-fpm-nonroot + target: 'nonroot' + - variant: 'fpm-alpine' + test-files: 'fpm-postgres' + docker-tag: roundcube/roundcubemail:test-fpm-alpine-nonroot + target: 'nonroot' steps: - name: Checkout repository uses: actions/checkout@v4 @@ -39,11 +55,12 @@ jobs: username: ${{ secrets.DOCKER_PULL_USERNAME }} password: ${{ secrets.DOCKER_PULL_PASSWORD }} - - name: Build image for "${{ matrix.variant }}" - run: cd ${{ matrix.variant }} && docker buildx build ./ -t ${{ matrix.docker-tag }} + - name: Build image for "${{ matrix.variant }} / ${{ matrix.target }}" + run: cd ${{ matrix.variant }} && docker buildx build ./ -t ${{ matrix.docker-tag }} --target ${{ matrix.target }} - name: Run tests env: ROUNDCUBEMAIL_TEST_IMAGE: ${{ matrix.docker-tag }} + HTTP_PORT: ${{ matrix.http-port || '80' }} run: | set -exu; for testFile in ${{ join(matrix.test-files, ' ') }}; diff --git a/apache/Dockerfile b/apache/Dockerfile index 1b1bec3..c27ad14 100644 --- a/apache/Dockerfile +++ b/apache/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.1-apache +FROM php:8.1-apache as root LABEL maintainer="Thomas Bruederli " LABEL org.opencontainers.image.source="https://github.com/roundcube/roundcubemail-docker" @@ -122,7 +122,24 @@ RUN set -ex; \ rm -rf /usr/src/roundcubemail/installer; \ chown -R www-data:www-data /usr/src/roundcubemail/logs; \ # Create the config dir - mkdir -p /var/roundcube/config /var/roundcube/enigma + mkdir -p /var/roundcube/config /var/roundcube/enigma; \ + chown -R www-data:www-data /var/roundcube; \ + chmod +t /var/roundcube ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["apache2-foreground"] + + +#### non-root stage + +FROM root as nonroot + +# Prepare locale config for locale-gen +RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen; \ + /usr/sbin/locale-gen + +RUN sed -i 's/^Listen 80$/Listen 8000/' /etc/apache2/ports.conf + +EXPOSE 8000 + +USER 33:33 \ No newline at end of file diff --git a/apache/docker-entrypoint.sh b/apache/docker-entrypoint.sh index e493b51..95174b4 100755 --- a/apache/docker-entrypoint.sh +++ b/apache/docker-entrypoint.sh @@ -189,9 +189,8 @@ if [[ "$1" == apache2* || "$1" == php-fpm || "$1" == bin* ]]; then : "${ROUNDCUBEMAIL_LOCALE:=en_US.UTF-8 UTF-8}" - if [ -e /usr/sbin/locale-gen ] && [ ! -z "${ROUNDCUBEMAIL_LOCALE}" ]; then - echo "${ROUNDCUBEMAIL_LOCALE}" > /etc/locale.gen - /usr/sbin/locale-gen + if [ -e /usr/sbin/locale-gen ] && [ ! -f /etc/locale.gen ] && [ ! -z "${ROUNDCUBEMAIL_LOCALE}" ]; then + echo "${ROUNDCUBEMAIL_LOCALE}" > /etc/locale.gen && /usr/sbin/locale-gen fi if [ ! -z "${ROUNDCUBEMAIL_ASPELL_DICTS}" ]; then diff --git a/apache/nonroot-add.txt b/apache/nonroot-add.txt new file mode 100644 index 0000000..1e02d1f --- /dev/null +++ b/apache/nonroot-add.txt @@ -0,0 +1,3 @@ +RUN sed -i 's/^Listen 80$/Listen 8000/' /etc/apache2/ports.conf + +EXPOSE 8000 diff --git a/fpm-alpine/Dockerfile b/fpm-alpine/Dockerfile index 689b4b0..0e6fba8 100644 --- a/fpm-alpine/Dockerfile +++ b/fpm-alpine/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.1-fpm-alpine +FROM php:8.1-fpm-alpine as root LABEL maintainer="Thomas Bruederli " LABEL org.opencontainers.image.source="https://github.com/roundcube/roundcubemail-docker" @@ -110,7 +110,16 @@ RUN set -ex; \ rm -rf /usr/src/roundcubemail/installer; \ chown -R www-data:www-data /usr/src/roundcubemail/logs; \ # Create the config dir - mkdir -p /var/roundcube/config /var/roundcube/enigma + mkdir -p /var/roundcube/config /var/roundcube/enigma; \ + chown -R www-data:www-data /var/roundcube; \ + chmod +t /var/roundcube ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["php-fpm"] + + +#### non-root stage + +FROM root as nonroot + +USER 82:82 \ No newline at end of file diff --git a/fpm-alpine/docker-entrypoint.sh b/fpm-alpine/docker-entrypoint.sh index e493b51..95174b4 100755 --- a/fpm-alpine/docker-entrypoint.sh +++ b/fpm-alpine/docker-entrypoint.sh @@ -189,9 +189,8 @@ if [[ "$1" == apache2* || "$1" == php-fpm || "$1" == bin* ]]; then : "${ROUNDCUBEMAIL_LOCALE:=en_US.UTF-8 UTF-8}" - if [ -e /usr/sbin/locale-gen ] && [ ! -z "${ROUNDCUBEMAIL_LOCALE}" ]; then - echo "${ROUNDCUBEMAIL_LOCALE}" > /etc/locale.gen - /usr/sbin/locale-gen + if [ -e /usr/sbin/locale-gen ] && [ ! -f /etc/locale.gen ] && [ ! -z "${ROUNDCUBEMAIL_LOCALE}" ]; then + echo "${ROUNDCUBEMAIL_LOCALE}" > /etc/locale.gen && /usr/sbin/locale-gen fi if [ ! -z "${ROUNDCUBEMAIL_ASPELL_DICTS}" ]; then diff --git a/fpm/Dockerfile b/fpm/Dockerfile index bb2f425..1b20af5 100644 --- a/fpm/Dockerfile +++ b/fpm/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.1-fpm +FROM php:8.1-fpm as root LABEL maintainer="Thomas Bruederli " LABEL org.opencontainers.image.source="https://github.com/roundcube/roundcubemail-docker" @@ -122,7 +122,20 @@ RUN set -ex; \ rm -rf /usr/src/roundcubemail/installer; \ chown -R www-data:www-data /usr/src/roundcubemail/logs; \ # Create the config dir - mkdir -p /var/roundcube/config /var/roundcube/enigma + mkdir -p /var/roundcube/config /var/roundcube/enigma; \ + chown -R www-data:www-data /var/roundcube; \ + chmod +t /var/roundcube ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["php-fpm"] + + +#### non-root stage + +FROM root as nonroot + +# Prepare locale config for locale-gen +RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen; \ + /usr/sbin/locale-gen + +USER 33:33 \ No newline at end of file diff --git a/fpm/docker-entrypoint.sh b/fpm/docker-entrypoint.sh index e493b51..95174b4 100755 --- a/fpm/docker-entrypoint.sh +++ b/fpm/docker-entrypoint.sh @@ -189,9 +189,8 @@ if [[ "$1" == apache2* || "$1" == php-fpm || "$1" == bin* ]]; then : "${ROUNDCUBEMAIL_LOCALE:=en_US.UTF-8 UTF-8}" - if [ -e /usr/sbin/locale-gen ] && [ ! -z "${ROUNDCUBEMAIL_LOCALE}" ]; then - echo "${ROUNDCUBEMAIL_LOCALE}" > /etc/locale.gen - /usr/sbin/locale-gen + if [ -e /usr/sbin/locale-gen ] && [ ! -f /etc/locale.gen ] && [ ! -z "${ROUNDCUBEMAIL_LOCALE}" ]; then + echo "${ROUNDCUBEMAIL_LOCALE}" > /etc/locale.gen && /usr/sbin/locale-gen fi if [ ! -z "${ROUNDCUBEMAIL_ASPELL_DICTS}" ]; then diff --git a/templates/Dockerfile-alpine.templ b/templates/Dockerfile-alpine.templ index 310ca84..a68c349 100644 --- a/templates/Dockerfile-alpine.templ +++ b/templates/Dockerfile-alpine.templ @@ -1,4 +1,4 @@ -FROM php:8.1-%%VARIANT%% +FROM php:8.1-%%VARIANT%% as root LABEL maintainer="Thomas Bruederli " LABEL org.opencontainers.image.source="https://github.com/roundcube/roundcubemail-docker" @@ -110,7 +110,16 @@ RUN set -ex; \ rm -rf /usr/src/roundcubemail/installer; \ chown -R www-data:www-data /usr/src/roundcubemail/logs; \ # Create the config dir - mkdir -p /var/roundcube/config /var/roundcube/enigma + mkdir -p /var/roundcube/config /var/roundcube/enigma; \ + chown -R www-data:www-data /var/roundcube; \ + chmod +t /var/roundcube ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["%%CMD%%"] + + +#### non-root stage + +FROM root as nonroot + +USER 82:82 \ No newline at end of file diff --git a/templates/Dockerfile-debian.templ b/templates/Dockerfile-debian.templ index 57a96ec..06ee4fc 100644 --- a/templates/Dockerfile-debian.templ +++ b/templates/Dockerfile-debian.templ @@ -1,4 +1,4 @@ -FROM php:8.1-%%VARIANT%% +FROM php:8.1-%%VARIANT%% as root LABEL maintainer="Thomas Bruederli " LABEL org.opencontainers.image.source="https://github.com/roundcube/roundcubemail-docker" @@ -122,7 +122,22 @@ RUN set -ex; \ rm -rf /usr/src/roundcubemail/installer; \ chown -R www-data:www-data /usr/src/roundcubemail/logs; \ # Create the config dir - mkdir -p /var/roundcube/config /var/roundcube/enigma + mkdir -p /var/roundcube/config /var/roundcube/enigma; \ + chown -R www-data:www-data /var/roundcube; \ + chmod +t /var/roundcube ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["%%CMD%%"] + + +#### non-root stage + +FROM root as nonroot + +# Prepare locale config for locale-gen +RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen; \ + /usr/sbin/locale-gen + +%%NONROOT_ADD%% + +USER 33:33 \ No newline at end of file diff --git a/templates/docker-entrypoint.sh b/templates/docker-entrypoint.sh index e493b51..95174b4 100644 --- a/templates/docker-entrypoint.sh +++ b/templates/docker-entrypoint.sh @@ -189,9 +189,8 @@ if [[ "$1" == apache2* || "$1" == php-fpm || "$1" == bin* ]]; then : "${ROUNDCUBEMAIL_LOCALE:=en_US.UTF-8 UTF-8}" - if [ -e /usr/sbin/locale-gen ] && [ ! -z "${ROUNDCUBEMAIL_LOCALE}" ]; then - echo "${ROUNDCUBEMAIL_LOCALE}" > /etc/locale.gen - /usr/sbin/locale-gen + if [ -e /usr/sbin/locale-gen ] && [ ! -f /etc/locale.gen ] && [ ! -z "${ROUNDCUBEMAIL_LOCALE}" ]; then + echo "${ROUNDCUBEMAIL_LOCALE}" > /etc/locale.gen && /usr/sbin/locale-gen fi if [ ! -z "${ROUNDCUBEMAIL_ASPELL_DICTS}" ]; then diff --git a/tests/docker-compose.test-apache-postgres.yml b/tests/docker-compose.test-apache-postgres.yml index 578d931..0967a0a 100644 --- a/tests/docker-compose.test-apache-postgres.yml +++ b/tests/docker-compose.test-apache-postgres.yml @@ -3,9 +3,11 @@ version: "2" services: roundcubemail: image: ${ROUNDCUBEMAIL_TEST_IMAGE:-roundcube/roundcubemail:latest-apache} + ports: + - 80:${HTTP_PORT:-80} healthcheck: # To make it obvious in logs "ping=ping" is added - test: ["CMD", "curl", "--fail", "http://localhost/?ping=ping"] + test: ["CMD", "curl", "--fail", "http://localhost:${HTTP_PORT:-80}/?ping=ping"] interval: 2s timeout: 3s retries: 30 @@ -55,6 +57,8 @@ services: roundcubedb: condition: service_healthy command: /tests/run.sh + environment: + - ROUNDCUBE_URL=http://roundcubemail:${HTTP_PORT:-80}/ volumes: - ./run.sh:/tests/run.sh:ro working_dir: /tests diff --git a/update.sh b/update.sh index 1887cbb..e0ee96f 100755 --- a/update.sh +++ b/update.sh @@ -31,6 +31,12 @@ for variant in apache fpm fpm-alpine; do s/%%CMD%%/'"${CMD[$variant]}"'/; ' $template | tr '¬' '\n' > "$dir/Dockerfile" + if [[ -f "$dir/nonroot-add.txt" ]]; then + sed -i -e '/%%NONROOT_ADD%%/ {' -e 'r '"$dir/nonroot-add.txt" -e 'd' -e '}' $dir/Dockerfile + else + sed -i 's/%%NONROOT_ADD%%//' $dir/Dockerfile + fi + echo "✓ Wrote $dir/Dockerfile" done