From 440b6549ee50848038fa6a71d67833ad0f67bab2 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Sun, 10 Mar 2024 10:08:10 +0000 Subject: [PATCH 1/8] add: nc base image --- docker/dockerfiles/nextcloud-base.Dockerfile | 129 +++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 docker/dockerfiles/nextcloud-base.Dockerfile diff --git a/docker/dockerfiles/nextcloud-base.Dockerfile b/docker/dockerfiles/nextcloud-base.Dockerfile new file mode 100644 index 00000000..b3730cee --- /dev/null +++ b/docker/dockerfiles/nextcloud-base.Dockerfile @@ -0,0 +1,129 @@ +FROM php:8.2-fpm-alpine3.19 + +# keys for oci taken from: +# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys +LABEL org.opencontainers.image.licenses=MIT +LABEL org.opencontainers.image.title="PonderSource Base Nextcloud PHP 8.2 FPM Image" +LABEL org.opencontainers.image.source="https://github.com/pondersource/dev-stock" +LABEL org.opencontainers.image.authors="Mohammad Mahdi Baghbani Pourvahid" + +# entrypoint.sh and cron.sh dependencies. +RUN set -ex; apk add --no-cache \ + git \ + imagemagick \ + rsync \ + ; \ + \ + rm /var/spool/cron/crontabs/root; \ + echo "*/5 * * * * php -f /var/www/html/cron.php" > /var/spool/cron/crontabs/www-data + +# install the PHP extensions we need +# see https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html +RUN set -ex; apk add --no-cache --virtual .build-deps \ + $PHPIZE_DEPS \ + autoconf \ + curl \ + ca-certificates \ + freetype-dev \ + gmp-dev \ + icu-dev \ + imagemagick-dev \ + libevent-dev \ + libjpeg-turbo-dev \ + libmcrypt-dev \ + libmemcached-dev \ + libpng-dev \ + libwebp-dev \ + libxml2-dev \ + libzip-dev \ + openldap-dev \ + pcre-dev \ + postgresql-dev \ + tzdata \ + ; \ + \ + docker-php-ext-configure ftp --with-openssl-dir=/usr; \ + docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp; \ + docker-php-ext-configure ldap; \ + docker-php-ext-install -j "$(nproc)" \ + bcmath \ + exif \ + ftp \ + gd \ + gmp \ + intl \ + ldap \ + opcache \ + pcntl \ + pdo_mysql \ + pdo_pgsql \ + sysvsem \ + zip \ + ; \ + \ + # pecl will claim success even if one install fails, so we need to perform each install separately + pecl install APCu-5.1.23; \ + pecl install imagick-3.7.0; \ + pecl install memcached-3.2.0; \ + pecl install redis-6.0.2; \ + \ + docker-php-ext-enable \ + apcu \ + imagick \ + memcached \ + redis \ + ; \ + rm -r /tmp/pear; \ + \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .nextcloud-phpext-rundeps $runDeps; \ + apk del --no-network .build-deps + +# set recommended PHP.ini settings +# see https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#enable-php-opcache +ENV PHP_MEMORY_LIMIT 512M +ENV PHP_UPLOAD_LIMIT 512M +RUN { \ + echo 'opcache.enable=1'; \ + echo 'opcache.interned_strings_buffer=32'; \ + echo 'opcache.max_accelerated_files=10000'; \ + echo 'opcache.memory_consumption=128'; \ + echo 'opcache.save_comments=1'; \ + echo 'opcache.revalidate_freq=60'; \ + echo 'opcache.jit=1255'; \ + echo 'opcache.jit_buffer_size=128M'; \ + } > "${PHP_INI_DIR}/conf.d/opcache-recommended.ini"; \ + \ + echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ + \ + { \ + echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ + echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ + echo 'post_max_size=${PHP_UPLOAD_LIMIT}'; \ + } > "${PHP_INI_DIR}/conf.d/nextcloud.ini"; \ + \ + mkdir /var/www/data; \ + mkdir -p /docker-entrypoint-hooks.d/pre-installation \ + /docker-entrypoint-hooks.d/post-installation \ + /docker-entrypoint-hooks.d/pre-upgrade \ + /docker-entrypoint-hooks.d/post-upgrade \ + /docker-entrypoint-hooks.d/before-starting; \ + chown -R www-data:root /var/www; \ + chmod -R g=u /var/www + +ENV TZ=Etc/UTC + +VOLUME /var/www/html + +# trust all the certificates: +COPY ./tls/certificates/* /tls/ +COPY ./tls/certificate-authority/* /tls/ +RUN ln -sf /tls/*.crt /usr/local/share/ca-certificates +RUN update-ca-certificates + +CMD ["php-fpm"] From b06af279e25f1556d62356488bb6798282e95925 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Sun, 10 Mar 2024 10:08:28 +0000 Subject: [PATCH 2/8] modify: use new nextcloud base image --- docker/dockerfiles/nextcloud.Dockerfile | 28 ++++++------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/docker/dockerfiles/nextcloud.Dockerfile b/docker/dockerfiles/nextcloud.Dockerfile index f38b66b9..cfa7b247 100644 --- a/docker/dockerfiles/nextcloud.Dockerfile +++ b/docker/dockerfiles/nextcloud.Dockerfile @@ -1,4 +1,4 @@ -FROM pondersource/dev-stock-php-base +FROM pondersource/dev-stock-nextcloud-base # keys for oci taken from: # https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys @@ -7,11 +7,11 @@ LABEL org.opencontainers.image.title="PonderSource Nextcloud Image" LABEL org.opencontainers.image.source="https://github.com/pondersource/dev-stock" LABEL org.opencontainers.image.authors="Mohammad Mahdi Baghbani Pourvahid" -RUN rm --recursive --force /var/www/html -USER www-data +RUN curl --silent --show-error https://getcomposer.org/installer -o /root/composer-setup.php +RUN php /root/composer-setup.php --install-dir=/usr/local/bin --filename=composer && rm /root/composer-setup.php ARG REPO_NEXTCLOUD=https://github.com/nextcloud/server -ARG BRANCH_NEXTCLOUD=v28.0.2 +ARG BRANCH_NEXTCLOUD=v27.1.7 # CACHEBUST forces docker to clone fresh source codes from git. # example: docker build -t your-image --build-arg CACHEBUST="default" . # $RANDOM returns random number each time. @@ -22,24 +22,8 @@ RUN git clone \ --shallow-submodules \ --branch ${BRANCH_NEXTCLOUD} \ ${REPO_NEXTCLOUD} \ - html + . -USER root WORKDIR /var/www/html -# switch php version for Nextloud. -RUN switch-php.sh 8.2 - -ENV PHP_MEMORY_LIMIT="512M" - -RUN curl --silent --show-error https://getcomposer.org/installer -o /root/composer-setup.php -RUN php /root/composer-setup.php --install-dir=/usr/local/bin --filename=composer - -USER www-data -# this file can be overrided in docker run or docker compose.yaml. -# example: docker run --volume new-init.sh:/init.sh:ro -COPY ./scripts/init-nextcloud.sh /init.sh -RUN mkdir -p data; touch data/nextcloud.log - -USER root -CMD /usr/sbin/apache2ctl -DFOREGROUND & tail --follow /var/log/apache2/access.log & tail --follow /var/log/apache2/error.log & tail --follow data/nextcloud.log +RUN find . -type d | grep -i "\.git" | xargs rm -rf From a0f9a02e6c084a3d21b04a0d33fc183de79bd9e5 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Fri, 19 Apr 2024 06:40:19 +0000 Subject: [PATCH 3/8] add: entrypoints for nginx and efss --- docker/scripts/entrypoint/nextcloud.sh | 41 +++++++++++++++ docker/scripts/entrypoint/nginx.sh | 73 ++++++++++++++++++++++++++ docker/scripts/entrypoint/owncloud.sh | 41 +++++++++++++++ 3 files changed, 155 insertions(+) create mode 100755 docker/scripts/entrypoint/nextcloud.sh create mode 100755 docker/scripts/entrypoint/nginx.sh create mode 100755 docker/scripts/entrypoint/owncloud.sh diff --git a/docker/scripts/entrypoint/nextcloud.sh b/docker/scripts/entrypoint/nextcloud.sh new file mode 100755 index 00000000..68d5a387 --- /dev/null +++ b/docker/scripts/entrypoint/nextcloud.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# @michielbdejong halt on error in docker init scripts. +set -e + +# create html directory if it doesn't exist. +if [ ! -d /var/www/html ]; then + mkdir -p /var/www/html +fi + +# if /var/www/html has any files in it, do not copy nextcloud files into it. +if [ -n "$(find /var/www/html -prune -empty -type d 2>/dev/null)" ]; then + echo "/var/www/html is an empty directory, populating it with source codes." + # populate /var/www/html with source codes. + cp -arn /var/www/source/* /var/www/html +else + ls -lsa /var/www/html + echo "/var/www/html contains files, doing noting." +fi + +# fix permissions. +chown -R www-data:root /var/www && chmod -R g=u /var/www + +# update OS certificate store. +mkdir -p /tls + +[ -d "/certificates" ] && \ + cp -f /certificates/*.crt /tls/ \ + && \ + cp -f /certificates/*.key /tls/ + +[ -d "/certificate-authority" ] && \ + cp -f /certificate-authority/*.crt /tls/ \ + && \ + cp -f /certificate-authority/*.key /tls/ + +cp -f /tls/*.crt /usr/local/share/ca-certificates/ || true +update-ca-certificates + +# This will exec the CMD from your Dockerfile, i.e. "npm start" +exec "$@" diff --git a/docker/scripts/entrypoint/nginx.sh b/docker/scripts/entrypoint/nginx.sh new file mode 100755 index 00000000..72dbfe05 --- /dev/null +++ b/docker/scripts/entrypoint/nginx.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# @michielbdejong halt on error in docker init scripts. +set -e + +entrypoint_log() { + if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then + echo "$@" + fi +} + +# copy self signed certificates to /tls and create symbolic link to correct server certificate for this container. +mkdir -p /tls + +[ -d "/certificates" ] && \ + cp -f /certificates/*.crt /tls/ \ + && \ + cp -f /certificates/*.key /tls/ + +[ -d "/certificate-authority" ] && \ + cp -f /certificate-authority/*.crt /tls/ \ + && \ + cp -f /certificate-authority/*.key /tls/ + +ln -sf "/tls/${HOST}.crt" /tls/server.crt +ln -sf "/tls/${HOST}.key" /tls/server.key + +if [ "$1" = "nginx" ] || [ "$1" = "nginx-debug" ]; then + if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then + entrypoint_log "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration" + + entrypoint_log "$0: Looking for shell scripts in /docker-entrypoint.d/" + find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do + case "$f" in + *.envsh) + if [ -x "$f" ]; then + entrypoint_log "$0: Sourcing $f"; + . "$f" + else + # warn on shell scripts without exec bit + entrypoint_log "$0: Ignoring $f, not executable"; + fi + ;; + *.sh) + if [ -x "$f" ]; then + entrypoint_log "$0: Launching $f"; + "$f" + else + # warn on shell scripts without exec bit + entrypoint_log "$0: Ignoring $f, not executable"; + fi + ;; + *) entrypoint_log "$0: Ignoring $f";; + esac + done + + # @MahdiBaghbani: I have to do some shenanigans here! sorry nginx. + entrypoint_log "@MahdiBaghbani: overriding some stuff :D keep calm!" + rm /etc/nginx/nginx.conf + mv /etc/nginx/conf.d/server.conf /etc/nginx/nginx.conf + /docker-entrypoint.d/30-tune-worker-processes.sh + + entrypoint_log "$0: Configuration complete; ready for start up" + else + entrypoint_log "$0: No files found in /docker-entrypoint.d/, skipping configuration" + fi +fi + +# @MahdiBaghbani: we need this to check if a port is open in container. and I don't want to create another docker image for nginx -_- +entrypoint_log "@MahdiBaghbani: installing ss command!" +apk add --no-cache iproute2-ss + +exec "$@" diff --git a/docker/scripts/entrypoint/owncloud.sh b/docker/scripts/entrypoint/owncloud.sh new file mode 100755 index 00000000..cdcc386b --- /dev/null +++ b/docker/scripts/entrypoint/owncloud.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# @michielbdejong halt on error in docker init scripts. +set -e + +# create html directory if it doesn't exist. +if [ ! -d /var/www/html ]; then + mkdir -p /var/www/html +fi + +# if /var/www/html has any files in it, do not copy owncloud into it. +if [ -n "$(find /var/www/html -prune -empty -type d 2>/dev/null)" ]; then + echo "/var/www/html is an empty directory, populating it with source codes." + # populate /var/www/html with source codes. + cp -arn /var/www/source/* /var/www/html +else + ls -lsa /var/www/html + echo "/var/www/html contains files, doing noting." +fi + +# fix permissions. +chown -R www-data:root /var/www && chmod -R g=u /var/www + +# update OS certificate store. +mkdir -p /tls + +[ -d "/certificates" ] && \ + cp -f /certificates/*.crt /tls/ \ + && \ + cp -f /certificates/*.key /tls/ + +[ -d "/certificate-authority" ] && \ + cp -f /certificate-authority/*.crt /tls/ \ + && \ + cp -f /certificate-authority/*.key /tls/ + +cp -f /tls/*.crt /usr/local/share/ca-certificates/ || true +update-ca-certificates + +# This will exec the CMD from your Dockerfile, i.e. "npm start" +exec "$@" From e63d6e7a882d1f95443ffdf5dbf73420dcbc0a96 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Fri, 19 Apr 2024 06:40:52 +0000 Subject: [PATCH 4/8] add: owncloud and nextcloud base php images --- docker/dockerfiles/nextcloud-base.Dockerfile | 6 + docker/dockerfiles/owncloud-base.Dockerfile | 126 +++++++++++++++++++ docker/dockerfiles/php-base.Dockerfile | 109 ---------------- 3 files changed, 132 insertions(+), 109 deletions(-) create mode 100644 docker/dockerfiles/owncloud-base.Dockerfile delete mode 100644 docker/dockerfiles/php-base.Dockerfile diff --git a/docker/dockerfiles/nextcloud-base.Dockerfile b/docker/dockerfiles/nextcloud-base.Dockerfile index b3730cee..894159d2 100644 --- a/docker/dockerfiles/nextcloud-base.Dockerfile +++ b/docker/dockerfiles/nextcloud-base.Dockerfile @@ -10,6 +10,7 @@ LABEL org.opencontainers.image.authors="Mohammad Mahdi Baghbani Pourvahid" # entrypoint.sh and cron.sh dependencies. RUN set -ex; apk add --no-cache \ git \ + bash \ imagemagick \ rsync \ ; \ @@ -126,4 +127,9 @@ COPY ./tls/certificate-authority/* /tls/ RUN ln -sf /tls/*.crt /usr/local/share/ca-certificates RUN update-ca-certificates +COPY ./scripts/entrypoint/nextcloud.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] + CMD ["php-fpm"] diff --git a/docker/dockerfiles/owncloud-base.Dockerfile b/docker/dockerfiles/owncloud-base.Dockerfile new file mode 100644 index 00000000..3f8aff3d --- /dev/null +++ b/docker/dockerfiles/owncloud-base.Dockerfile @@ -0,0 +1,126 @@ +FROM php:7.4-fpm-alpine3.16 + +# keys for oci taken from: +# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys +LABEL org.opencontainers.image.licenses=MIT +LABEL org.opencontainers.image.title="PonderSource Base ownCloud PHP 7.4 FPM Image" +LABEL org.opencontainers.image.source="https://github.com/pondersource/dev-stock" +LABEL org.opencontainers.image.authors="Mohammad Mahdi Baghbani Pourvahid" + +RUN set -ex; apk add --no-cache \ + bash \ + git + +# install the PHP extensions we need. +RUN set -ex; apk add --no-cache --virtual .build-deps \ + $PHPIZE_DEPS \ + autoconf \ + curl \ + ca-certificates \ + freetype-dev \ + gmp-dev \ + icu-dev \ + imagemagick-dev \ + libevent-dev \ + libjpeg-turbo-dev \ + libmcrypt-dev \ + libmemcached-dev \ + libpng-dev \ + libwebp-dev \ + libxml2-dev \ + libzip-dev \ + openldap-dev \ + pcre-dev \ + postgresql-dev \ + tzdata \ + ; \ + \ + docker-php-ext-configure ftp --with-openssl-dir=/usr; \ + docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp; \ + docker-php-ext-configure ldap; \ + docker-php-ext-install -j "$(nproc)" \ + bcmath \ + exif \ + ftp \ + gd \ + gmp \ + intl \ + ldap \ + opcache \ + pcntl \ + pdo_mysql \ + pdo_pgsql \ + sysvsem \ + zip \ + ; \ + \ + # pecl will claim success even if one install fails, so we need to perform each install separately + pecl install APCu-5.1.23; \ + pecl install imagick-3.7.0; \ + pecl install memcached-3.2.0; \ + pecl install redis-6.0.2; \ + \ + docker-php-ext-enable \ + apcu \ + imagick \ + memcached \ + redis \ + ; \ + rm -r /tmp/pear; \ + \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .nextcloud-phpext-rundeps $runDeps; \ + apk del --no-network .build-deps + +# set recommended PHP.ini settings. +ENV PHP_MEMORY_LIMIT 512M +ENV PHP_UPLOAD_LIMIT 512M +RUN { \ + echo 'opcache.enable=1'; \ + echo 'opcache.interned_strings_buffer=32'; \ + echo 'opcache.max_accelerated_files=10000'; \ + echo 'opcache.memory_consumption=128'; \ + echo 'opcache.save_comments=1'; \ + echo 'opcache.revalidate_freq=60'; \ + echo 'opcache.jit=1255'; \ + echo 'opcache.jit_buffer_size=128M'; \ + } > "${PHP_INI_DIR}/conf.d/opcache-recommended.ini"; \ + \ + echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ + \ + { \ + echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ + echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ + echo 'post_max_size=${PHP_UPLOAD_LIMIT}'; \ + } > "${PHP_INI_DIR}/conf.d/nextcloud.ini"; \ + \ + mkdir /var/www/data; \ + mkdir -p /docker-entrypoint-hooks.d/pre-installation \ + /docker-entrypoint-hooks.d/post-installation \ + /docker-entrypoint-hooks.d/pre-upgrade \ + /docker-entrypoint-hooks.d/post-upgrade \ + /docker-entrypoint-hooks.d/before-starting; \ + chown -R www-data:root /var/www; \ + chmod -R g=u /var/www + +ENV TZ=Etc/UTC + +VOLUME /var/www/html + +# trust all the certificates: +COPY ./tls/certificates/* /tls/ +COPY ./tls/certificate-authority/* /tls/ +RUN ln -sf /tls/*.crt /usr/local/share/ca-certificates +RUN update-ca-certificates + +COPY ./scripts/entrypoint/owncloud.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] + +CMD ["php-fpm"] diff --git a/docker/dockerfiles/php-base.Dockerfile b/docker/dockerfiles/php-base.Dockerfile deleted file mode 100644 index 8ab62eeb..00000000 --- a/docker/dockerfiles/php-base.Dockerfile +++ /dev/null @@ -1,109 +0,0 @@ -FROM ubuntu:22.04 - -# keys for oci taken from: -# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys -LABEL org.opencontainers.image.licenses=MIT -LABEL org.opencontainers.image.title="PonderSource Base PHP Image" -LABEL org.opencontainers.image.source="https://github.com/pondersource/dev-stock" -LABEL org.opencontainers.image.authors="Mohammad Mahdi Baghbani Pourvahid" - -# set timezone. -ENV TZ=UTC -RUN ln --symbolic --no-dereference --force /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone - -ENV DEBIAN_FRONTEND noninteractive - -RUN apt-get update --yes - -# install dependencies. -RUN apt-get install --yes \ - git \ - vim \ - curl \ - wget \ - sudo \ - unzip \ - libxml2 \ - iproute2 \ - apt-utils \ - libxml2-dev \ - lsb-release \ - mysql-client \ - build-essential \ - ca-certificates \ - apt-transport-https \ - software-properties-common - -# add the Ondrej PPA, which contains all versions of PHP packages for Ubuntu systems. -RUN LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php -RUN LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/apache2 - -RUN apt-get update --yes - -RUN apt-get install --yes apache2 - -# install php versions -RUN apt-get install --yes \ - php8.2 \ - php8.2-gd \ - php8.2-xml \ - php8.2-zip \ - php8.2-curl \ - php8.2-intl \ - php8.2-redis \ - php8.2-mysql \ - php8.2-xdebug \ - php8.2-opcache \ - php8.2-sqlite3 \ - php8.2-mbstring - -RUN apt-get install --yes \ - php7.4 \ - php7.4-gd \ - php7.4-xml \ - php7.4-zip \ - php7.4-apcu \ - php7.4-curl \ - php7.4-intl \ - php7.4-json \ - php7.4-redis \ - php7.4-mysql \ - php7.4-xdebug \ - php7.4-imagick \ - php7.4-opcache \ - php7.4-sqlite3 \ - php7.4-mbstring \ - php7.4-memcached - - -# PHP switcher script. -COPY ./scripts/switch-php.sh /usr/bin/switch-php.sh -RUN chmod +x /usr/bin/switch-php.sh - -# copy xdebug configuration and create its link in each PHP version conf directory. -COPY ./configs/20-xdebug.ini /configs-pondersource/20-xdebug.ini -RUN ln --symbolic --force /configs-pondersource/20-xdebug.ini /etc/php/7.4/cli/conf.d/20-xdebug.ini -RUN ln --symbolic --force /configs-pondersource/20-xdebug.ini /etc/php/8.2/cli/conf.d/20-xdebug.ini - -# apache config. -COPY ./configs/site.conf /configs-pondersource/site.conf -RUN ln --symbolic --force /configs-pondersource/site.conf /etc/apache2/sites-enabled/000-default.conf - -# trust all the certificates: -COPY ./tls/certificates/* /tls/ -COPY ./tls/certificate-authority/* /tls/ -RUN ln --symbolic --force /tls/*.crt /usr/local/share/ca-certificates -RUN update-ca-certificates -RUN a2enmod ssl - -# app directory. -WORKDIR /var/www -RUN chown www-data:www-data . - -EXPOSE 443 - -COPY ./scripts/entrypoint.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh - -ENTRYPOINT ["/entrypoint.sh"] -CMD /usr/sbin/apache2ctl -DFOREGROUND From dd79b5feeb43063bb0eae44fc0d0377ac09eae68 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Fri, 19 Apr 2024 06:41:19 +0000 Subject: [PATCH 5/8] add: owncloud and nextcloud images --- docker/dockerfiles/nextcloud.Dockerfile | 8 +++- docker/dockerfiles/owncloud.Dockerfile | 53 +++++++++++-------------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/docker/dockerfiles/nextcloud.Dockerfile b/docker/dockerfiles/nextcloud.Dockerfile index cfa7b247..6beb6fc8 100644 --- a/docker/dockerfiles/nextcloud.Dockerfile +++ b/docker/dockerfiles/nextcloud.Dockerfile @@ -1,4 +1,4 @@ -FROM pondersource/dev-stock-nextcloud-base +FROM pondersource/dev-stock-nextcloud-base:latest # keys for oci taken from: # https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys @@ -16,6 +16,8 @@ ARG BRANCH_NEXTCLOUD=v27.1.7 # example: docker build -t your-image --build-arg CACHEBUST="default" . # $RANDOM returns random number each time. ARG CACHEBUST="default" + +WORKDIR /var/www/source RUN git clone \ --depth 1 \ --recursive \ @@ -24,6 +26,8 @@ RUN git clone \ ${REPO_NEXTCLOUD} \ . +RUN find . -type d | grep -i "\.git" | xargs rm -rf + WORKDIR /var/www/html -RUN find . -type d | grep -i "\.git" | xargs rm -rf +RUN chown -R www-data:root /var/www && chmod -R g=u /var/www diff --git a/docker/dockerfiles/owncloud.Dockerfile b/docker/dockerfiles/owncloud.Dockerfile index 9d411167..8c2f7c3e 100644 --- a/docker/dockerfiles/owncloud.Dockerfile +++ b/docker/dockerfiles/owncloud.Dockerfile @@ -1,4 +1,4 @@ -FROM pondersource/dev-stock-php-base +FROM pondersource/dev-stock-owncloud-base:latest # keys for oci taken from: # https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys @@ -7,8 +7,8 @@ LABEL org.opencontainers.image.title="PonderSource ownCloud Image" LABEL org.opencontainers.image.source="https://github.com/pondersource/dev-stock" LABEL org.opencontainers.image.authors="Mohammad Mahdi Baghbani Pourvahid" -RUN rm --recursive --force /var/www/html -USER www-data +RUN curl --silent --show-error https://getcomposer.org/installer -o /root/composer-setup.php +RUN php /root/composer-setup.php --install-dir=/usr/local/bin --filename=composer && rm /root/composer-setup.php ARG REPO_OWNCLOUD=https://github.com/owncloud/core ARG BRANCH_OWNCLOUD=v10.14.0 @@ -16,39 +16,32 @@ ARG BRANCH_OWNCLOUD=v10.14.0 # example: docker build -t your-image --build-arg CACHEBUST="default" . # $RANDOM returns random number each time. ARG CACHEBUST="default" + +WORKDIR /var/www/source RUN git clone \ --depth 1 \ --recursive \ --shallow-submodules \ --branch ${BRANCH_OWNCLOUD} \ ${REPO_OWNCLOUD} \ - html + . + +RUN find . -type d | grep -i "\.git" | xargs rm -rf +RUN cat /etc/ssl/certs/ca-certificates.crt >> /var/www/source/resources/config/ca-bundle.crt + +RUN set -ex; \ + apk add --no-cache --update-cache --virtual .fetch-deps \ + --allow-untrusted --repository http://dl-cdn.alpinelinux.org/alpine/v3.16/main \ + bash \ + make \ + nodejs \ + ; \ + \ + composer install --no-dev && npm install -g yarn && make install-nodejs-deps \ + ; \ + \ + apk del --no-network .fetch-deps -USER root WORKDIR /var/www/html -# switch php version for ownCloud. -RUN switch-php.sh 7.4 - -ENV PHP_MEMORY_LIMIT="512M" - -RUN curl --silent --show-error https://getcomposer.org/installer -o /root/composer-setup.php -RUN php /root/composer-setup.php --install-dir=/usr/local/bin --filename=composer - -# install nodejs and yarn. -RUN curl --silent --location https://deb.nodesource.com/setup_18.x | bash - -RUN apt install nodejs -RUN npm install --global yarn - -USER www-data -# this file can be overrided in docker run or docker compose.yaml. -# example: docker run --volume new-init.sh:/init.sh:ro -COPY ./scripts/init-owncloud.sh /oc-init.sh -RUN mkdir -p data; touch data/owncloud.log - -RUN composer install --no-dev -RUN make install-nodejs-deps - -USER root -RUN cat /etc/ssl/certs/ca-certificates.crt >> /var/www/html/resources/config/ca-bundle.crt -CMD /usr/sbin/apache2ctl -DFOREGROUND & tail --follow /var/log/apache2/access.log & tail --follow /var/log/apache2/error.log & tail --follow data/owncloud.log +RUN chown -R www-data:root /var/www && chmod -R g=u /var/www From db85e32eb260a1154f063a340530340ac78e5f29 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Fri, 19 Apr 2024 06:41:48 +0000 Subject: [PATCH 6/8] add: curly braces to variables --- docker/scripts/init-nextcloud.sh | 4 ++-- docker/scripts/init-owncloud.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker/scripts/init-nextcloud.sh b/docker/scripts/init-nextcloud.sh index d4e4905c..c51b2b59 100755 --- a/docker/scripts/init-nextcloud.sh +++ b/docker/scripts/init-nextcloud.sh @@ -3,8 +3,8 @@ # @michielbdejong halt on error in docker init scripts set -e -php console.php maintenance:install --admin-user "$USER" --admin-pass "$PASS" --database "mysql" \ - --database-name "efss" --database-user "root" --database-host "$DBHOST" \ +php console.php maintenance:install --admin-user "${USER}" --admin-pass "${PASS}" --database "mysql" \ + --database-name "efss" --database-user "root" --database-host "${DBHOST}" \ --database-pass "eilohtho9oTahsuongeeTh7reedahPo1Ohwi3aek" php console.php app:disable firstrunwizard diff --git a/docker/scripts/init-owncloud.sh b/docker/scripts/init-owncloud.sh index 2ee5ba1e..22c6e83c 100755 --- a/docker/scripts/init-owncloud.sh +++ b/docker/scripts/init-owncloud.sh @@ -3,8 +3,8 @@ # @michielbdejong halt on error in docker init scripts set -e -php console.php maintenance:install --admin-user "${USER}" --admin-pass "${PASS}" --database "mysql" \ - --database-name "efss" --database-user "root" --database-host "$DBHOST" \ +php console.php maintenance:install --admin-user "${USER}" --admin-pass "${PASS}" --database "mysql" \ + --database-name "efss" --database-user "root" --database-host "${DBHOST}" \ --database-pass "eilohtho9oTahsuongeeTh7reedahPo1Ohwi3aek" php console.php app:disable firstrunwizard From b423706d51cc0c91731a2cd7ec4103988bb919ae Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Fri, 19 Apr 2024 06:42:31 +0000 Subject: [PATCH 7/8] add: select tags when pulling images from docker --- dev/efss.sh | 89 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/dev/efss.sh b/dev/efss.sh index 5f094e4f..1f9c09ef 100755 --- a/dev/efss.sh +++ b/dev/efss.sh @@ -17,6 +17,8 @@ cd "${DIR}/.." || exit ENV_ROOT=$(pwd) export ENV_ROOT=${ENV_ROOT} +export NGINX_IMAGE="nginx:1.25.4-alpine3.18-slim" +export MARIADB_IMAGE="mariadb:11.3.2" function waitForPort () { echo waitForPort "${1} ${2}" @@ -37,6 +39,7 @@ function createEfss() { local user="${3}" local password="${4}" local image="${5}" + local tag="${6-latest}" if [[ -z "${image}" ]]; then local image="pondersource/dev-stock-${platform}" @@ -46,51 +49,75 @@ function createEfss() { echo "creating efss ${platform} ${number}" - docker run --detach --network=testnet \ - --name="maria${platform}${number}.docker" \ - -e MARIADB_ROOT_PASSWORD=eilohtho9oTahsuongeeTh7reedahPo1Ohwi3aek \ - mariadb \ - --transaction-isolation=READ-COMMITTED \ - --binlog-format=ROW \ - --innodb-file-per-table=1 \ + docker run --detach --network=testnet \ + --name="maria${platform}${number}.docker" \ + -e MARIADB_ROOT_PASSWORD=eilohtho9oTahsuongeeTh7reedahPo1Ohwi3aek \ + "${MARIADB_IMAGE}" \ + --transaction-isolation=READ-COMMITTED \ + --binlog-format=ROW \ + --innodb-file-per-table=1 \ --skip-innodb-read-only-compressed - docker run --detach --network=testnet \ - --name="${platform}${number}.docker" \ - --add-host "host.docker.internal:host-gateway" \ - -e HOST="${platform}${number}" \ - -e DBHOST="maria${platform}${number}.docker" \ - -e USER="${user}" \ - -e PASS="${password}" \ - -v "${ENV_ROOT}/docker/tls/certificates:/certificates" \ - -v "${ENV_ROOT}/docker/tls/certificate-authority:/certificate-authority" \ - -v "${ENV_ROOT}/temp/${platform}.sh:/${platform}-init.sh" \ - -v "${ENV_ROOT}/docker/scripts/entrypoint.sh:/entrypoint.sh" \ - "${image}" - - # wait for hostname port to be open. + docker run --detach --network=testnet \ + --name="php${platform}${number}.docker" \ + --add-host "host.docker.internal:host-gateway" \ + -e HOST="${platform}${number}" \ + -e DBHOST="maria${platform}${number}.docker" \ + -e USER="${user}" \ + -e PASS="${password}" \ + -v "${ENV_ROOT}/docker/tls/certificates:/certificates" \ + -v "${ENV_ROOT}/docker/tls/certificate-authority:/certificate-authority" \ + -v "${ENV_ROOT}/temp/${platform}.sh:/${platform}-init.sh" \ + -v "${ENV_ROOT}/temp/entrypoint/${platform}.sh:/entrypoint.sh" \ + -v "${ENV_ROOT}/temp/mounted-${platform}${number}:/var/www/html:z" \ + "${image}:${tag}" + + # wait for database port to be open. waitForPort "maria${platform}${number}.docker" 3306 - waitForPort "${platform}${number}.docker" 443 # add self-signed certificates to os and trust them. (use >/dev/null 2>&1 to shut these up) - docker exec "${platform}${number}.docker" bash -c "cp -f /certificates/*.crt /usr/local/share/ca-certificates/ || true" >/dev/null 2>&1 - docker exec "${platform}${number}.docker" bash -c "cp -f /certificate-authority/*.crt /usr/local/share/ca-certificates/ || true" >/dev/null 2>&1 - docker exec "${platform}${number}.docker" bash -c "cp -f /tls/*.crt /usr/local/share/ca-certificates/ || true" >/dev/null 2>&1 - docker exec "${platform}${number}.docker" update-ca-certificates >/dev/null 2>&1 - docker exec "${platform}${number}.docker" bash -c "cat /etc/ssl/certs/ca-certificates.crt >> /var/www/html/resources/config/ca-bundle.crt" >/dev/null 2>&1 + docker exec "php${platform}${number}.docker" bash -c "cp -f /certificates/*.crt /usr/local/share/ca-certificates/ || true" >/dev/null 2>&1 + docker exec "php${platform}${number}.docker" bash -c "cp -f /certificate-authority/*.crt /usr/local/share/ca-certificates/ || true" >/dev/null 2>&1 + docker exec "php${platform}${number}.docker" bash -c "cp -f /tls/*.crt /usr/local/share/ca-certificates/ || true" >/dev/null 2>&1 + docker exec "php${platform}${number}.docker" update-ca-certificates >/dev/null 2>&1 + docker exec "php${platform}${number}.docker" bash -c "cat /etc/ssl/certs/ca-certificates.crt >> /var/www/html/resources/config/ca-bundle.crt" >/dev/null 2>&1 # run init script inside efss. - docker exec -u www-data "${platform}${number}.docker" bash "/${platform}-init.sh" + docker exec -u www-data "php${platform}${number}.docker" bash "/${platform}-init.sh" + + docker run --detach --network=testnet \ + --name="${platform}${number}.docker" \ + -e HOST="${platform}${number}" \ + -e SERVER_NAME="php${platform}${number}.docker" \ + -e PROXY_HOST="php${platform}${number}.docker" \ + -e PROXY_PORT="9000" \ + -v "${ENV_ROOT}/docker/tls/certificates:/certificates" \ + -v "${ENV_ROOT}/docker/tls/certificate-authority:/certificate-authority" \ + -v "${ENV_ROOT}/temp/entrypoint/nginx.sh:/docker-entrypoint.sh" \ + -v "${ENV_ROOT}/temp/nginx/${platform}.conf:/etc/nginx/templates/server.conf.template:ro" \ + -v "${ENV_ROOT}/temp/mounted-${platform}${number}:/var/www/html:z,ro" \ + "${NGINX_IMAGE}" + + # wait for nginx port to be open. + waitForPort "${platform}${number}.docker" 443 echo "" } # delete and create temp directory. -rm -rf "${ENV_ROOT}/temp" && mkdir --parents "${ENV_ROOT}/temp" +rm -rf "${ENV_ROOT}/temp" +mkdir -p "${ENV_ROOT}/temp" +mkdir -p "${ENV_ROOT}/temp/nginx" +mkdir -p "${ENV_ROOT}/temp/entrypoint" # copy init files. -cp -f "${ENV_ROOT}/docker/scripts/init-owncloud.sh" "${ENV_ROOT}/temp/owncloud.sh" -cp -f "${ENV_ROOT}/docker/scripts/init-nextcloud.sh" "${ENV_ROOT}/temp/nextcloud.sh" +cp -f "${ENV_ROOT}/docker/scripts/entrypoint/nginx.sh" "${ENV_ROOT}/temp/entrypoint/nginx.sh" +cp -f "${ENV_ROOT}/docker/scripts/entrypoint/owncloud.sh" "${ENV_ROOT}/temp/entrypoint/owncloud.sh" +cp -f "${ENV_ROOT}/docker/scripts/entrypoint/nextcloud.sh" "${ENV_ROOT}/temp/entrypoint/nextcloud.sh" +cp -f "${ENV_ROOT}/docker/scripts/init-owncloud.sh" "${ENV_ROOT}/temp/owncloud.sh" +cp -f "${ENV_ROOT}/docker/scripts/init-nextcloud.sh" "${ENV_ROOT}/temp/nextcloud.sh" +cp -f "${ENV_ROOT}/docker/configs/nginx/owncloud.conf" "${ENV_ROOT}/temp/nginx/owncloud.conf" +cp -f "${ENV_ROOT}/docker/configs/nginx/nextcloud.conf" "${ENV_ROOT}/temp/nginx/nextcloud.conf" # make sure network exists. docker network inspect testnet >/dev/null 2>&1 || docker network create testnet >/dev/null 2>&1 From 3323b55aee76d685311dbaec8d7a214914096dcd Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Fri, 19 Apr 2024 06:42:50 +0000 Subject: [PATCH 8/8] add: nginx config files --- docker/configs/nginx/nextcloud.conf | 228 ++++++++++++++++++++++++++++ docker/configs/nginx/owncloud.conf | 209 +++++++++++++++++++++++++ 2 files changed, 437 insertions(+) create mode 100644 docker/configs/nginx/nextcloud.conf create mode 100644 docker/configs/nginx/owncloud.conf diff --git a/docker/configs/nginx/nextcloud.conf b/docker/configs/nginx/nextcloud.conf new file mode 100644 index 00000000..882d84f2 --- /dev/null +++ b/docker/configs/nginx/nextcloud.conf @@ -0,0 +1,228 @@ +worker_processes auto; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + error_log /var/log/nginx/error.log; + access_log /var/log/nginx/access.log main; + + sendfile on; + + # Prevent nginx HTTP Server Detection + server_tokens off; + + keepalive_timeout 65; + + # Set the `immutable` cache control options only for assets with a cache busting `v` argument + map $arg_v $asset_immutable { + "" ""; + default "immutable"; + } + + upstream php-handler { + server $PROXY_HOST:$PROXY_PORT; + } + + server { + listen 80; + server_name $SERVER_NAME; + + # For SSL certificate verification, this needs to be served via HTTP + location /.well-known/(acme-challenge|pki-validation)/ { + # Specify here where the challenge file is placed + root /var/www/html; + } + + # enforce https + location / { + return 301 https://$server_name:443$request_uri; # Change 443 if using a custom HTTPS port + } + } + + server { + listen 443 default_server ssl; + server_name $SERVER_NAME; + + # specify the certificate files to use + ssl_certificate /tls/server.crt; + ssl_certificate_key /tls/server.key; + ssl_protocols TLSv1.3 TLSv1.2; + ssl_prefer_server_ciphers off; + + # set max upload size and increase upload timeout: + client_max_body_size 512M; + client_body_timeout 300s; + fastcgi_buffers 64 4K; + + # The settings allows you to optimize the HTTP2 bandwidth. + # See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/ + # for tuning hints + client_body_buffer_size 512k; + + # Enable gzip but do not remove ETag headers + gzip on; + gzip_vary on; + gzip_comp_level 4; + gzip_min_length 256; + gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; + gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; + + # Pagespeed is not supported by Nextcloud, so if your server is built + # with the `ngx_pagespeed` module, uncomment this line to disable it. + #pagespeed off; + + # HSTS settings + # WARNING: Only add the preload option once you read about + # the consequences in https://hstspreload.org/. This option + # will add the domain to a hardcoded list that is shipped + # in all major browsers and getting removed from this list + # could take several months. + add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always; + + # Add headers to serve security related headers + # The always parameter ensures that the header is set for all responses, including internally generated error responses. + # Before enabling Strict-Transport-Security headers please read into this topic first. + # https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/ + # HTTP response headers borrowed from Nextcloud `.htaccess` + add_header Referrer-Policy "no-referrer" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header X-Robots-Tag "noindex, nofollow" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Download-Options "noopen" always; + + # Remove X-Powered-By, which is an information leak + fastcgi_hide_header X-Powered-By; + + # Path to the root of your installation + root /var/www/html; + + # Specify how to handle directories -- specifying `/index.php$request_uri` + # here as the fallback means that Nginx always exhibits the desired behaviour + # when a client requests a path that corresponds to a directory that exists + # on the server. In particular, if that directory contains an index.php file, + # that file is correctly served; if it doesn't, then the request is passed to + # the front-end controller. This consistent behaviour means that we don't need + # to specify custom rules for certain paths (e.g. images and other assets, + # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus + # `try_files $uri $uri/ /index.php$request_uri` + # always provides the desired behaviour. + index index.php index.html /index.php$request_uri; + + # Rule borrowed from `.htaccess` to handle Microsoft DAV clients + location = / { + if ( $http_user_agent ~ ^DavClnt ) { + return 302 /remote.php/webdav/$is_args$args; + } + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + # Make a regex exception for `/.well-known` so that clients can still + # access it despite the existence of the regex rule + # `location ~ /(\.|autotest|...)` which would otherwise handle requests + # for `/.well-known`. + location ^~ /.well-known { + # The rules in this block are an adaptation of the rules + # in `.htaccess` that concern `/.well-known`. + + location = /.well-known/carddav { return 301 /remote.php/dav/; } + location = /.well-known/caldav { return 301 /remote.php/dav/; } + + location /.well-known/acme-challenge { try_files $uri $uri/ =404; } + location /.well-known/pki-validation { try_files $uri $uri/ =404; } + + # Let Nextcloud's API for `/.well-known` URIs handle all other + # requests by passing them to the front-end controller. + return 301 /index.php$request_uri; + } + + # Rules borrowed from `.htaccess` to hide certain paths from clients + location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; } + location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; } + + # Ensure this block, which passes PHP files to the PHP process, is above the blocks + # which handle static assets (as seen below). If this block is not declared first, + # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php` + # to the URI, resulting in a HTTP 500 error response. + location ~ \.php(?:$|/) { + # Required for legacy support + rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri; + + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + set $path_info $fastcgi_path_info; + + try_files $fastcgi_script_name =404; + + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $path_info; + fastcgi_param HTTPS on; + + fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice + fastcgi_param front_controller_active true; # Enable pretty urls + fastcgi_pass php-handler; + + fastcgi_intercept_errors on; + fastcgi_request_buffering off; + + fastcgi_max_temp_file_size 0; + } + + # Javascript mimetype fixes for nginx + # Note: The block below should be removed, and the js|mjs section should be + # added to the block below this one. This is a temporary fix until Nginx + # upstream fixes the js mime-type + location ~* \.(?:js|mjs)$ { + types { + text/javascript js mjs; + } + try_files $uri /index.php$request_uri; + add_header Cache-Control "public, max-age=15778463, $asset_immutable"; + access_log off; + } + + # Serve static files + location ~ \.(?:css|svg|gif|png|jpg|ico|wasm|tflite|map|ogg|flac)$ { + try_files $uri /index.php$request_uri; + add_header Cache-Control "public, max-age=15778463, $asset_immutable"; + access_log off; # Optional: Don't log access to assets + + location ~ \.wasm$ { + default_type application/wasm; + } + } + + location ~ \.woff2?$ { + try_files $uri /index.php$request_uri; + expires 7d; # Cache-Control policy borrowed from `.htaccess` + access_log off; # Optional: Don't log access to assets + } + + # Rule borrowed from `.htaccess` + location /remote { + return 301 /remote.php$request_uri; + } + + location / { + try_files $uri $uri/ /index.php$request_uri; + } + } +} diff --git a/docker/configs/nginx/owncloud.conf b/docker/configs/nginx/owncloud.conf new file mode 100644 index 00000000..62e4a0b3 --- /dev/null +++ b/docker/configs/nginx/owncloud.conf @@ -0,0 +1,209 @@ +worker_processes auto; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + error_log /var/log/nginx/error.log; + access_log /var/log/nginx/access.log main; + + sendfile on; + + # Prevent nginx HTTP Server Detection + server_tokens off; + + keepalive_timeout 65; + + # Set the `immutable` cache control options only for assets with a cache busting `v` argument + map $arg_v $asset_immutable { + "" ""; + default "immutable"; + } + + upstream php-handler { + server $PROXY_HOST:$PROXY_PORT; + } + + server { + listen 80; + server_name $SERVER_NAME; + + # For SSL certificate verification, this needs to be served via HTTP + location /.well-known/(acme-challenge|pki-validation)/ { + # Specify here where the challenge file is placed + root /var/www/html; + } + + # enforce https + location / { + return 301 https://$server_name:443$request_uri; # Change 443 if using a custom HTTPS port + } + } + + server { + listen 443 default_server ssl; + server_name $SERVER_NAME; + + # specify the certificate files to use + ssl_certificate /tls/server.crt; + ssl_certificate_key /tls/server.key; + ssl_protocols TLSv1.3 TLSv1.2; + ssl_prefer_server_ciphers off; + + # set max upload size and increase upload timeout: + client_max_body_size 512M; + client_body_timeout 300s; + fastcgi_buffers 8 4K; # Please see note 1 + fastcgi_ignore_headers X-Accel-Buffering; # Please see note 2 + + # The settings allows you to optimize the HTTP2 bandwidth. + # See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/ + # for tuning hints + client_body_buffer_size 512k; + + # Disable gzip to avoid the removal of the ETag header + # Enabling gzip would also make your server vulnerable to BREACH + # if no additional measures are done. See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=773332 + gzip off; + + # Pagespeed is not supported by Nextcloud, so if your server is built + # with the `ngx_pagespeed` module, uncomment this line to disable it. + #pagespeed off; + + # HSTS settings + # WARNING: Only add the preload option once you read about + # the consequences in https://hstspreload.org/. This option + # will add the domain to a hardcoded list that is shipped + # in all major browsers and getting removed from this list + # could take several months. + add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always; + + # Add headers to serve security related headers + # The always parameter ensures that the header is set for all responses, including internally generated error responses. + # Before enabling Strict-Transport-Security headers please read into this topic first. + # https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/ + # HTTP response headers borrowed from Nextcloud `.htaccess` + add_header Referrer-Policy "no-referrer" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header X-Robots-Tag "noindex, nofollow" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Download-Options "noopen" always; + + # Remove X-Powered-By, which is an information leak + fastcgi_hide_header X-Powered-By; + + # Path to the root of your installation + root /var/www/html; + + # Specify how to handle directories -- specifying `/index.php$request_uri` + # here as the fallback means that Nginx always exhibits the desired behaviour + # when a client requests a path that corresponds to a directory that exists + # on the server. In particular, if that directory contains an index.php file, + # that file is correctly served; if it doesn't, then the request is passed to + # the front-end controller. This consistent behaviour means that we don't need + # to specify custom rules for certain paths (e.g. images and other assets, + # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus + # `try_files $uri $uri/ /index.php$request_uri` + # always provides the desired behaviour. + index index.php index.html /index.php$request_uri; + + # Rule borrowed from `.htaccess` to handle Microsoft DAV clients + location = / { + if ( $http_user_agent ~ ^DavClnt ) { + return 302 /remote.php/webdav/$is_args$args; + } + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + location = /.well-known/carddav { + return 301 $scheme://$host:$server_port/remote.php/dav; + } + location = /.well-known/caldav { + return 301 $scheme://$host:$server_port/remote.php/dav; + } + + error_page 403 /core/templates/403.php; + error_page 404 /core/templates/404.php; + + location / { + rewrite ^ /index.php$uri; + } + + location ~ ^/(?:build|tests|config|lib|3rdparty|templates|changelog|data)/ { + return 404; + } + location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console|core/skeleton/) { + return 404; + } + location ~ ^/core/signature\.json { + return 404; + } + + location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|oc[sm]-provider/.+|core/templates/40[34])\.php(?:$|/) { + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param SCRIPT_NAME $fastcgi_script_name; # necessary for ownCloud to detect the contextroot https://github.com/owncloud/core/blob/v10.0.0/lib/private/AppFramework/Http/Request.php#L603 + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param HTTPS on; + fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice + fastcgi_param front_controller_active true; + fastcgi_read_timeout 180; # increase default timeout e.g. for long running carddav/caldav syncs with 1000+ entries + fastcgi_pass php-handler; + fastcgi_intercept_errors on; + fastcgi_request_buffering off; #Available since Nginx 1.7.11 + } + + location ~ ^/(?:updater|oc[sm]-provider)(?:$|/) { + try_files $uri $uri/ =404; + index index.php; + } + + # Adding the cache control header for js and css files + # Make sure it is BELOW the PHP block + location ~ \.(?:css|js)$ { + try_files $uri /index.php$uri$is_args$args; + add_header Cache-Control "max-age=15778463" always; + + # Add headers to serve security related headers (It is intended to have those duplicated to the ones above) + # The always parameter ensures that the header is set for all responses, including internally generated error responses. + # Before enabling Strict-Transport-Security headers please read into this topic first. + # https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/ + + #add_header Strict-Transport-Security "max-age=15552000; includeSubDomains; preload" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Robots-Tag "none" always; + add_header X-Download-Options "noopen" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + # Optional: Don't log access to assets + access_log off; + } + + location ~ \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg|map|json)$ { + add_header Cache-Control "public, max-age=7200" always; + try_files $uri /index.php$uri$is_args$args; + # Optional: Don't log access to other assets + access_log off; + } + } +}