diff --git a/Dockerfile.alpine b/Dockerfile.alpine new file mode 120000 index 0000000..950d63a --- /dev/null +++ b/Dockerfile.alpine @@ -0,0 +1 @@ +packaging/docker/Dockerfile.alpine \ No newline at end of file diff --git a/packaging/README.md b/packaging/README.md index 370dc9e..7d6ad32 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -122,10 +122,19 @@ You can also build with podman: podman build --no-cache -t service-desk -f ./docker/Dockerfile ../ ``` -Tag the `latest` image with the major and minor version, for example: +For Alpine linux image : + +``` +DOCKER_BUILDKIT=1 docker build -t service-desk-alpine -f ./docker/Dockerfile.alpine ../ +``` + +Tag the defautl and alpine images with the major and minor version, for example: ``` docker tag service-desk:latest ltbproject/service-desk:1.6.1 docker tag service-desk:latest ltbproject/service-desk:1.6 docker tag service-desk:latest ltbproject/service-desk:latest +docker tag service-desk-alpine:latest ltbproject/service-desk:alpine-1.6.1 +docker tag service-desk-alpine:latest ltbproject/service-desk:alpine-1.6 +docker tag service-desk-alpine:latest ltbproject/service-desk:alpine-latest ``` diff --git a/packaging/docker/Dockerfile.alpine b/packaging/docker/Dockerfile.alpine new file mode 100644 index 0000000..0393c2b --- /dev/null +++ b/packaging/docker/Dockerfile.alpine @@ -0,0 +1,281 @@ +ARG VERSION=latest + +ARG SMARTY_VERSION=4.4.1 +ARG SMARTY_URL=https://github.com/smarty-php/smarty/archive/refs/tags/v${SMARTY_VERSION}.tar.gz + +ARG COMPOSER_VERSION=lts +ARG COMPOSER_IMAGE=composer/composer:${COMPOSER_VERSION}-bin + +ARG ALPINE_VERSION=3.20 +ARG PHP_VERSION=8.2 + +ARG PHP_IMAGE=php:${PHP_VERSION}-alpine${ALPINE_VERSION} +ARG BASE_IMAGE=httpd:alpine${ALPINE_VERSION} +# ARG BASE_IMAGE=alpine:${ALPINE_VERSION} + +FROM ${COMPOSER_IMAGE} AS composer + +FROM ${PHP_IMAGE} AS php + +RUN install -m 644 -D /usr/src/php.tar.xz /rootfs/usr/src/php.tar.xz +RUN for f in \ + docker-php-source \ + docker-php-ext-install \ + docker-php-ext-enable \ + docker-php-ext-configure \ + ; do \ + install -m 755 -D /usr/local/bin/$f /rootfs/usr/local/bin/$f; \ + done + +FROM ${BASE_IMAGE} AS base + +ARG MIRROR= +ARG ALPINE_MIRROR=${MIRROR:+${MIRROR}/alpine} + +RUN [ -z "${ALPINE_MIRROR}" ] || \ + sed -e "s#https\?://dl\-cdn\.alpinelinux\.org/alpine#${ALPINE_MIRROR}#g" \ + -i /etc/apk/repositories + +# dependencies required for running "phpize" +# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed) +ENV PHPIZE_DEPS=" \ + autoconf \ + dpkg-dev dpkg \ + file \ + g++ \ + gcc \ + libc-dev \ + make \ + pkgconf \ + re2c \ + " + +# persistent / runtime deps +RUN --mount=type=cache,target=/var/cache/apk \ + set -eux; \ + apk update; \ + apk add \ + bash \ + ca-certificates \ + libcurl \ + openssl \ + tar \ + xz \ + ; + +ENV PHP_INI_DIR=/usr/local/etc/php +RUN mkdir -p "$PHP_INI_DIR/conf.d" + +# Apply stack smash protection to functions using local buffers and alloca() +# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64) +# Enable optimization (-O2) +# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default) +# https://github.com/docker-library/php/issues/272 +# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php) +ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" +ENV PHP_CPPFLAGS="$PHP_CFLAGS" +ENV PHP_LDFLAGS="-Wl,-O1 -pie" + +COPY --from=php /rootfs / + +RUN --mount=type=cache,target=/var/cache/apk \ + --mount=type=cache,target=/tmp/pear \ + --mount=type=cache,target=/root \ + set -eux; \ + apk add --virtual .build-deps \ + $PHPIZE_DEPS \ + bzip2-dev \ + icu-dev \ + freetype-dev \ + libpng-dev \ + libjpeg-turbo-dev \ + libwebp-dev \ + openldap-dev \ + argon2-dev \ + coreutils \ + curl-dev \ + gnu-libiconv-dev \ + libsodium-dev \ + libxml2-dev \ + linux-headers \ + oniguruma-dev \ + openssl-dev \ + readline-dev \ + sqlite-dev \ + apache2-dev \ + ; \ + \ +# make sure musl's iconv doesn't get used (https://www.php.net/manual/en/intro.iconv.php) + rm -vf /usr/include/iconv.h; \ + \ + export \ + CFLAGS="$PHP_CFLAGS" \ + CPPFLAGS="$PHP_CPPFLAGS" \ + LDFLAGS="$PHP_LDFLAGS" \ +# https://github.com/php/php-src/blob/d6299206dd828382753453befd1b915491b741c6/configure.ac#L1496-L1511 + PHP_BUILD_PROVIDER='https://github.com/docker-library/php' \ + PHP_UNAME='Linux - Docker' \ + ; \ + docker-php-source extract; \ + cd /usr/src/php; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ + ./configure \ + --build="$gnuArch" \ + --with-config-file-path="$PHP_INI_DIR" \ + --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \ + \ +# make sure invalid --configure-flags are fatal errors instead of just warnings + --enable-option-checking=fatal \ + \ +# https://github.com/docker-library/php/issues/439 + --with-mhash \ + \ +# https://github.com/docker-library/php/issues/822 + --with-pic \ + \ +# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195) + --enable-mbstring \ +# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself) + --enable-mysqlnd \ +# https://wiki.php.net/rfc/argon2_password_hash + --with-password-argon2 \ +# https://wiki.php.net/rfc/libsodium + --with-sodium=shared \ +# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109) + --with-pdo-sqlite=/usr \ + --with-sqlite3=/usr \ + \ + --with-curl \ + --with-iconv=/usr \ + --with-openssl \ + --with-readline \ + --with-zlib \ + \ +# https://github.com/docker-library/php/pull/1259 + --enable-phpdbg \ + --enable-phpdbg-readline \ + \ +# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear") + --with-pear \ + \ +# bundled pcre does not support JIT on riscv64 until 10.41 (php 8.3+) +# https://github.com/PCRE2Project/pcre2/commits/pcre2-10.41/src/sljit/sljitNativeRISCV_64.c +# https://github.com/php/php-src/tree/php-8.3.0/ext/pcre/pcre2lib + $(test "$gnuArch" = 'riscv64-linux-musl' && echo '--without-pcre-jit') \ + \ +# service-desk + --enable-bcmath \ + --enable-opcache \ + --enable-intl \ + --enable-gd --with-freetype --with-jpeg --with-webp \ + --with-bz2 \ + --with-ldap \ + --with-apxs2 \ + ; \ + make -j "$(nproc)"; \ + find -type f -name '*.a' -delete; \ + make install; \ + find \ + /usr/local \ + -type f \ + -perm '/0111' \ + -exec sh -euxc ' \ + strip --strip-all "$@" || : \ + ' -- '{}' + \ + ; \ + make clean; \ + \ +# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable) + cp -v php.ini-* "$PHP_INI_DIR/"; \ + ln -s "php.ini-production" "$PHP_INI_DIR/php.ini"; \ + \ + cd /; \ + docker-php-source delete; \ + \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-cache $runDeps; \ + \ + apk del --no-network .build-deps; \ + \ +# update pecl channel definitions https://github.com/docker-library/php/issues/443 + pecl update-channels; \ + \ +# smoke test + php --version + + +FROM base AS build + +WORKDIR /build + +ARG SMARTY_VERSION +ARG SMARTY_URL +ARG COMPOSER_IMAGE + +COPY --from=composer /composer /usr/bin/composer + +ADD $SMARTY_URL ./ +RUN set -ex; \ + \ + SMARTY_DIR=/usr/share/php/smarty${SMARTY_VERSION%%.*}; \ + install --owner www-data --group www-data --directory -D "/rootfs${SMARTY_DIR}"; \ + tar xzf *.tar.gz -C "/rootfs${SMARTY_DIR}" --strip-components=2 --verbose --owner www-data --group www-data; + +RUN --mount=type=cache,target=/var/cache/apk \ + set -ex; \ + \ + apk update; \ + apk add git unzip; + +ARG INSTALL_PATHS= +ARG EXCLUDE_PATHS= + +WORKDIR /build/sd +RUN --mount=type=cache,target=/root/.composer \ + --mount=type=bind,target=/build/sd,rw \ + packaging/docker/install; \ + \ + install -p -m 644 -D \ + /usr/local/apache2/conf/httpd.conf \ + /rootfs/usr/local/apache2/conf/httpd.conf; \ + install -p -m 644 -D \ + packaging/docker/apache2.alpine/service-desk.conf \ + /rootfs/usr/local/apache2/conf/extra/httpd-vhosts.conf; \ + sed -i /rootfs/usr/local/apache2/conf/httpd.conf \ + -e "s|^#Include conf/extra/httpd-vhosts.conf|Include conf/extra/httpd-vhosts.conf|g" \ + -e "s#/usr/local/apache2/htdocs#/var/www/htdocs#g" \ + ; \ + :; + +FROM base + +ARG VERSION +ARG BASE_IMAGE + +LABEL org.opencontainers.image.authors='LTB-project.org, ltb-dev@ow2.org' \ + org.opencontainers.image.base.name="${BASE_IMAGE}" \ + org.opencontainers.image.description='Service Desk is a web application to edit LDAP account passwords and status for administrators and support teams' \ + org.opencontainers.image.url='https://ltb-project.org/documentation/service-desk.html' \ + org.opencontainers.image.ref.name='service-desk' \ + org.opencontainers.image.documentation='https://service-desk.readthedocs.io/' \ + org.opencontainers.image.title='service-desk docker image' \ + org.opencontainers.image.source='https://github.com/ltb-project/service-desk/' \ + org.opencontainers.image.vendor='LTB-project.org' \ + org.opencontainers.image.version="${VERSION}" \ + org.opencontainers.image.licenses='GPL-2+' + +COPY --from=build /rootfs / + +WORKDIR /var/www/htdocs + +VOLUME [ "/var/www/templates_c", "/var/www/conf", "/var/www/cache" ] + +EXPOSE 80 + +ENTRYPOINT [ "/entrypoint.sh" ] +CMD [ "httpd-foreground" ] diff --git a/packaging/docker/apache2.alpine/service-desk.conf b/packaging/docker/apache2.alpine/service-desk.conf new file mode 100644 index 0000000..cfbbfe5 --- /dev/null +++ b/packaging/docker/apache2.alpine/service-desk.conf @@ -0,0 +1,27 @@ + + # ServerName sd.example.com + + DocumentRoot /var/www/htdocs + DirectoryIndex index.php + + AddDefaultCharset UTF-8 + + + SetHandler application/x-httpd-php + + + + AllowOverride None + = 2.3> + Require all granted + + + Order Deny,Allow + Allow from all + + + + LogLevel debug + ErrorLog /dev/stderr + CustomLog /dev/stdout combined +