0
0
Fork 0
mirror of https://github.com/nextcloud/docker.git synced 2025-04-20 18:56:09 +02:00

Compare commits

...

19 commits

Author SHA1 Message Date
Tilo Spannagel
161f00d3f8
Merge 174a45cc5c into 3adaf30839 2025-03-31 01:48:59 +00:00
GitHub Workflow
3adaf30839 Runs update.sh 2025-03-25 00:35:32 +00:00
J0WI
c76fb1dc57
Bump stable to 30.0.8
Signed-off-by: J0WI <J0WI@users.noreply.github.com>
2025-03-19 22:49:00 +00:00
GitHub Workflow
e56b9a4e2e Runs update.sh 2025-03-19 22:47:36 +00:00
J0WI
16727bbbde
Bump stable to 30.0.7
Signed-off-by: J0WI <J0WI@users.noreply.github.com>
2025-03-14 00:41:51 +00:00
GitHub Workflow
df3b447621 Runs update.sh 2025-03-14 00:34:18 +00:00
Josh
c351ce76ab
docs(README): Fix missing -it in non-Compose docker exec command
Signed-off-by: Josh <josh.t.richards@gmail.com>
2025-03-09 10:31:16 -04:00
Josh
73949fe23a
fix(templates): Fix bug in issue template config
Fix bug introduced by #2400

Signed-off-by: Josh <josh.t.richards@gmail.com>
2025-03-06 16:08:37 -05:00
Josh
86ab9d769c
meta(templates): Re-order "Create new issue" links (#2400)
Re-order and add additional links to highlight:

- where to ask a question (forum) 
- documentation resources
- upstream (server) bug reporting and enhancement ideas

Some rewording as well.

Signed-off-by: Josh <josh.t.richards@gmail.com>
2025-03-01 19:48:36 +00:00
Josh
5be2a020e0
docs(readme): Document running as an arbitrary user (#2398)
Signed-off-by: Josh <josh.t.richards@gmail.com>
2025-03-01 19:47:33 +00:00
J0WI
af00599148
Build imagick for PHP 8.3 (#2394)
Signed-off-by: J0WI <J0WI@users.noreply.github.com>
2025-02-25 22:37:43 +00:00
GitHub Workflow
71235584cd Runs update.sh 2025-02-25 19:50:02 +00:00
J0WI
4daafc8d20
Bump stable to 30.0.6
Signed-off-by: J0WI <J0WI@users.noreply.github.com>
2025-02-13 20:34:07 +00:00
GitHub Workflow
4f691770ae Runs update.sh 2025-02-13 19:43:06 +00:00
J0WI
a5656577ef
Compile with igbinary (#2368)
Signed-off-by: J0WI <J0WI@users.noreply.github.com>
2025-02-11 18:01:24 +01:00
Josh
174a45cc5c
Update linter.yml
Signed-off-by: Josh <josh.t.richards@gmail.com>
2024-07-02 15:33:02 -04:00
Josh
a540bef384
Update linter.yml
Signed-off-by: Josh <josh.t.richards@gmail.com>
2024-07-02 15:32:02 -04:00
Josh
4aa61c067c
Update linter.yml
Signed-off-by: Josh <josh.t.richards@gmail.com>
2024-07-02 15:23:32 -04:00
Tilo Spannagel
9cbb4604ab Add Super-Linter
Signed-off-by: Tilo Spannagel <development@tilosp.de>
2020-08-28 17:39:29 +02:00
55 changed files with 2506 additions and 70 deletions

View file

@ -1,10 +1,22 @@
contact_links: contact_links:
- name: 🐛 Nextcloud issue - name: ❓ Ask a question
url: https://github.com/nextcloud/server/issues/new/choose
about: Bug reports and feature requests for Nextcloud
- name: 🐳 Docker Support and Help
url: https://forums.docker.com/
about: Configuration, installation, networking and other questions
- name: ❓ Nextcloud Support and Help
url: https://help.nextcloud.com/ url: https://help.nextcloud.com/
about: Configuration, webserver/proxy or performance issues and other questions about: Ask a question, get assistance or start a discussion regarding Nextcloud and/or this image
- name: Documentation - Nextcloud Server
url: https://docs.nextcloud.com/
about: Official documentation for Nextcloud Server
- name: Documentation - Nextcloud Docker Image
url: https://github.com/nextcloud/docker/blob/master/README.md
about: Official documentation for this image
- name: 🐳 Documentation - Docker
url: https://docs.docker.com/
about: Official documentation for Docker (installing, configuring, troubleshooting)
- name: 🐳 Docker Forum
url: https://forums.docker.com/
about: Ask a question, get assistance or start a discussion regarding Docker
- name: 🐛 Bug Report - Nextcloud Server
url: https://github.com/nextcloud/server/issues/new/choose
about: Report a bug in Nextcloud Server
- name: Enhancement Idea - Nextcloud Server
url: https://github.com/nextcloud/server/issues/new/choose
about: Suggest an enhancement idea for Nextcloud Server

38
.github/workflows/linter.yml vendored Normal file
View file

@ -0,0 +1,38 @@
---
name: Lint Code Base
on:
pull_request:
push:
permissions: { }
jobs:
build:
name: Lint Code Base
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
statuses: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Super-Linter
uses: super-linter/super-linter@v6.6.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VALIDATE_BASH: true
VALIDATE_DOCKERFILE_HADOLINT: true
VALIDATE_ENV: true
VALIDATE_GITHUB_ACTIONS: true
VALIDATE_MARKDOWN: true
VALIDATE_PHP_BUILTIN: true
VALIDATE_PHP_PHPCS: true
VALIDATE_PHP_PHPSTAN: true
VALIDATE_PHP_PSALM: true
VALIDATE_YAML: true

View file

@ -1,6 +1,9 @@
# DO NOT EDIT: created by update.sh from Dockerfile-debian.template # DO NOT EDIT: created by update.sh from Dockerfile-debian.template
FROM php:8.2-apache-bookworm FROM php:8.2-apache-bookworm
# Define the commit hash for imagick as a variable
ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b
# entrypoint.sh and cron.sh dependencies # entrypoint.sh and cron.sh dependencies
RUN set -ex; \ RUN set -ex; \
\ \
@ -65,14 +68,31 @@ RUN set -ex; \
zip \ zip \
; \ ; \
\ \
# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet.
# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround.
curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \
tar -xzf imagick.tar.gz -C /tmp; \
rm imagick.tar.gz; \
cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \
phpize; \
./configure; \
make; \
make install; \
cd; \
rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately # pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.24; \ pecl install APCu-5.1.24; \
pecl install imagick-3.7.0; \ pecl install igbinary-3.2.16; \
pecl install memcached-3.3.0; \ pecl install memcached-3.3.0 \
pecl install redis-6.1.0; \ --configureoptions 'enable-memcached-igbinary="yes"'; \
pecl install redis-6.2.0 \
--configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \
\ \
docker-php-ext-enable \ docker-php-ext-enable \
apcu \ apcu \
igbinary \
imagick \ imagick \
memcached \ memcached \
redis \ redis \
@ -108,6 +128,11 @@ RUN { \
\ \
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\ \
{ \
echo 'apc.serializer=igbinary'; \
echo 'session.serialize_handler=igbinary'; \
} >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.ini"; \
\
{ \ { \
echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \
echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \
@ -141,7 +166,7 @@ RUN { \
} > /etc/apache2/conf-available/apache-limits.conf; \ } > /etc/apache2/conf-available/apache-limits.conf; \
a2enconf apache-limits a2enconf apache-limits
ENV NEXTCLOUD_VERSION 29.0.11 ENV NEXTCLOUD_VERSION 29.0.14
RUN set -ex; \ RUN set -ex; \
fetchDeps=" \ fetchDeps=" \
@ -151,8 +176,8 @@ RUN set -ex; \
apt-get update; \ apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \ apt-get install -y --no-install-recommends $fetchDeps; \
\ \
curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-29.0.11.tar.bz2"; \ curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-29.0.14.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-29.0.11.tar.bz2.asc"; \ curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-29.0.14.tar.bz2.asc"; \
export GNUPGHOME="$(mktemp -d)"; \ export GNUPGHOME="$(mktemp -d)"; \
# gpg key from https://nextcloud.com/nextcloud.asc # gpg key from https://nextcloud.com/nextcloud.asc
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \ gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \

View file

@ -1,6 +1,9 @@
# DO NOT EDIT: created by update.sh from Dockerfile-alpine.template # DO NOT EDIT: created by update.sh from Dockerfile-alpine.template
FROM php:8.2-fpm-alpine3.21 FROM php:8.2-fpm-alpine3.21
# Define the commit hash for imagick as a variable
ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b
# entrypoint.sh and cron.sh dependencies # entrypoint.sh and cron.sh dependencies
RUN set -ex; \ RUN set -ex; \
\ \
@ -62,14 +65,31 @@ RUN set -ex; \
zip \ zip \
; \ ; \
\ \
# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet.
# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround.
curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \
tar -xzf imagick.tar.gz -C /tmp; \
rm imagick.tar.gz; \
cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \
phpize; \
./configure; \
make; \
make install; \
cd; \
rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately # pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.24; \ pecl install APCu-5.1.24; \
pecl install imagick-3.7.0; \ pecl install igbinary-3.2.16; \
pecl install memcached-3.3.0; \ pecl install memcached-3.3.0 \
pecl install redis-6.1.0; \ --configureoptions 'enable-memcached-igbinary="yes"'; \
pecl install redis-6.2.0 \
--configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \
\ \
docker-php-ext-enable \ docker-php-ext-enable \
apcu \ apcu \
igbinary \
imagick \ imagick \
memcached \ memcached \
redis \ redis \
@ -103,6 +123,11 @@ RUN { \
\ \
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\ \
{ \
echo 'apc.serializer=igbinary'; \
echo 'session.serialize_handler=igbinary'; \
} >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.ini"; \
\
{ \ { \
echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \
echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \
@ -121,7 +146,7 @@ RUN { \
VOLUME /var/www/html VOLUME /var/www/html
ENV NEXTCLOUD_VERSION 29.0.11 ENV NEXTCLOUD_VERSION 29.0.14
RUN set -ex; \ RUN set -ex; \
apk add --no-cache --virtual .fetch-deps \ apk add --no-cache --virtual .fetch-deps \
@ -129,8 +154,8 @@ RUN set -ex; \
gnupg \ gnupg \
; \ ; \
\ \
curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-29.0.11.tar.bz2"; \ curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-29.0.14.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-29.0.11.tar.bz2.asc"; \ curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-29.0.14.tar.bz2.asc"; \
export GNUPGHOME="$(mktemp -d)"; \ export GNUPGHOME="$(mktemp -d)"; \
# gpg key from https://nextcloud.com/nextcloud.asc # gpg key from https://nextcloud.com/nextcloud.asc
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \ gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \

View file

@ -1,6 +1,9 @@
# DO NOT EDIT: created by update.sh from Dockerfile-debian.template # DO NOT EDIT: created by update.sh from Dockerfile-debian.template
FROM php:8.2-fpm-bookworm FROM php:8.2-fpm-bookworm
# Define the commit hash for imagick as a variable
ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b
# entrypoint.sh and cron.sh dependencies # entrypoint.sh and cron.sh dependencies
RUN set -ex; \ RUN set -ex; \
\ \
@ -65,14 +68,31 @@ RUN set -ex; \
zip \ zip \
; \ ; \
\ \
# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet.
# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround.
curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \
tar -xzf imagick.tar.gz -C /tmp; \
rm imagick.tar.gz; \
cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \
phpize; \
./configure; \
make; \
make install; \
cd; \
rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately # pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.24; \ pecl install APCu-5.1.24; \
pecl install imagick-3.7.0; \ pecl install igbinary-3.2.16; \
pecl install memcached-3.3.0; \ pecl install memcached-3.3.0 \
pecl install redis-6.1.0; \ --configureoptions 'enable-memcached-igbinary="yes"'; \
pecl install redis-6.2.0 \
--configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \
\ \
docker-php-ext-enable \ docker-php-ext-enable \
apcu \ apcu \
igbinary \
imagick \ imagick \
memcached \ memcached \
redis \ redis \
@ -108,6 +128,11 @@ RUN { \
\ \
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\ \
{ \
echo 'apc.serializer=igbinary'; \
echo 'session.serialize_handler=igbinary'; \
} >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.ini"; \
\
{ \ { \
echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \
echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \
@ -126,7 +151,7 @@ RUN { \
VOLUME /var/www/html VOLUME /var/www/html
ENV NEXTCLOUD_VERSION 29.0.11 ENV NEXTCLOUD_VERSION 29.0.14
RUN set -ex; \ RUN set -ex; \
fetchDeps=" \ fetchDeps=" \
@ -136,8 +161,8 @@ RUN set -ex; \
apt-get update; \ apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \ apt-get install -y --no-install-recommends $fetchDeps; \
\ \
curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-29.0.11.tar.bz2"; \ curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-29.0.14.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-29.0.11.tar.bz2.asc"; \ curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-29.0.14.tar.bz2.asc"; \
export GNUPGHOME="$(mktemp -d)"; \ export GNUPGHOME="$(mktemp -d)"; \
# gpg key from https://nextcloud.com/nextcloud.asc # gpg key from https://nextcloud.com/nextcloud.asc
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \ gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \

View file

@ -1,6 +1,9 @@
# DO NOT EDIT: created by update.sh from Dockerfile-debian.template # DO NOT EDIT: created by update.sh from Dockerfile-debian.template
FROM php:8.2-apache-bookworm FROM php:8.2-apache-bookworm
# Define the commit hash for imagick as a variable
ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b
# entrypoint.sh and cron.sh dependencies # entrypoint.sh and cron.sh dependencies
RUN set -ex; \ RUN set -ex; \
\ \
@ -65,14 +68,31 @@ RUN set -ex; \
zip \ zip \
; \ ; \
\ \
# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet.
# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround.
curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \
tar -xzf imagick.tar.gz -C /tmp; \
rm imagick.tar.gz; \
cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \
phpize; \
./configure; \
make; \
make install; \
cd; \
rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately # pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.24; \ pecl install APCu-5.1.24; \
pecl install imagick-3.7.0; \ pecl install igbinary-3.2.16; \
pecl install memcached-3.3.0; \ pecl install memcached-3.3.0 \
pecl install redis-6.1.0; \ --configureoptions 'enable-memcached-igbinary="yes"'; \
pecl install redis-6.2.0 \
--configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \
\ \
docker-php-ext-enable \ docker-php-ext-enable \
apcu \ apcu \
igbinary \
imagick \ imagick \
memcached \ memcached \
redis \ redis \
@ -108,6 +128,11 @@ RUN { \
\ \
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\ \
{ \
echo 'apc.serializer=igbinary'; \
echo 'session.serialize_handler=igbinary'; \
} >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.ini"; \
\
{ \ { \
echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \
echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \
@ -141,7 +166,7 @@ RUN { \
} > /etc/apache2/conf-available/apache-limits.conf; \ } > /etc/apache2/conf-available/apache-limits.conf; \
a2enconf apache-limits a2enconf apache-limits
ENV NEXTCLOUD_VERSION 30.0.5 ENV NEXTCLOUD_VERSION 30.0.8
RUN set -ex; \ RUN set -ex; \
fetchDeps=" \ fetchDeps=" \
@ -151,8 +176,8 @@ RUN set -ex; \
apt-get update; \ apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \ apt-get install -y --no-install-recommends $fetchDeps; \
\ \
curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-30.0.5.tar.bz2"; \ curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-30.0.8.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-30.0.5.tar.bz2.asc"; \ curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-30.0.8.tar.bz2.asc"; \
export GNUPGHOME="$(mktemp -d)"; \ export GNUPGHOME="$(mktemp -d)"; \
# gpg key from https://nextcloud.com/nextcloud.asc # gpg key from https://nextcloud.com/nextcloud.asc
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \ gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \

View file

@ -1,6 +1,9 @@
# DO NOT EDIT: created by update.sh from Dockerfile-alpine.template # DO NOT EDIT: created by update.sh from Dockerfile-alpine.template
FROM php:8.2-fpm-alpine3.21 FROM php:8.2-fpm-alpine3.21
# Define the commit hash for imagick as a variable
ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b
# entrypoint.sh and cron.sh dependencies # entrypoint.sh and cron.sh dependencies
RUN set -ex; \ RUN set -ex; \
\ \
@ -62,14 +65,31 @@ RUN set -ex; \
zip \ zip \
; \ ; \
\ \
# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet.
# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround.
curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \
tar -xzf imagick.tar.gz -C /tmp; \
rm imagick.tar.gz; \
cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \
phpize; \
./configure; \
make; \
make install; \
cd; \
rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately # pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.24; \ pecl install APCu-5.1.24; \
pecl install imagick-3.7.0; \ pecl install igbinary-3.2.16; \
pecl install memcached-3.3.0; \ pecl install memcached-3.3.0 \
pecl install redis-6.1.0; \ --configureoptions 'enable-memcached-igbinary="yes"'; \
pecl install redis-6.2.0 \
--configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \
\ \
docker-php-ext-enable \ docker-php-ext-enable \
apcu \ apcu \
igbinary \
imagick \ imagick \
memcached \ memcached \
redis \ redis \
@ -103,6 +123,11 @@ RUN { \
\ \
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\ \
{ \
echo 'apc.serializer=igbinary'; \
echo 'session.serialize_handler=igbinary'; \
} >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.ini"; \
\
{ \ { \
echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \
echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \
@ -121,7 +146,7 @@ RUN { \
VOLUME /var/www/html VOLUME /var/www/html
ENV NEXTCLOUD_VERSION 30.0.5 ENV NEXTCLOUD_VERSION 30.0.8
RUN set -ex; \ RUN set -ex; \
apk add --no-cache --virtual .fetch-deps \ apk add --no-cache --virtual .fetch-deps \
@ -129,8 +154,8 @@ RUN set -ex; \
gnupg \ gnupg \
; \ ; \
\ \
curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-30.0.5.tar.bz2"; \ curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-30.0.8.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-30.0.5.tar.bz2.asc"; \ curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-30.0.8.tar.bz2.asc"; \
export GNUPGHOME="$(mktemp -d)"; \ export GNUPGHOME="$(mktemp -d)"; \
# gpg key from https://nextcloud.com/nextcloud.asc # gpg key from https://nextcloud.com/nextcloud.asc
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \ gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \

View file

@ -1,6 +1,9 @@
# DO NOT EDIT: created by update.sh from Dockerfile-debian.template # DO NOT EDIT: created by update.sh from Dockerfile-debian.template
FROM php:8.2-fpm-bookworm FROM php:8.2-fpm-bookworm
# Define the commit hash for imagick as a variable
ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b
# entrypoint.sh and cron.sh dependencies # entrypoint.sh and cron.sh dependencies
RUN set -ex; \ RUN set -ex; \
\ \
@ -65,14 +68,31 @@ RUN set -ex; \
zip \ zip \
; \ ; \
\ \
# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet.
# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround.
curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \
tar -xzf imagick.tar.gz -C /tmp; \
rm imagick.tar.gz; \
cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \
phpize; \
./configure; \
make; \
make install; \
cd; \
rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately # pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.24; \ pecl install APCu-5.1.24; \
pecl install imagick-3.7.0; \ pecl install igbinary-3.2.16; \
pecl install memcached-3.3.0; \ pecl install memcached-3.3.0 \
pecl install redis-6.1.0; \ --configureoptions 'enable-memcached-igbinary="yes"'; \
pecl install redis-6.2.0 \
--configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \
\ \
docker-php-ext-enable \ docker-php-ext-enable \
apcu \ apcu \
igbinary \
imagick \ imagick \
memcached \ memcached \
redis \ redis \
@ -108,6 +128,11 @@ RUN { \
\ \
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\ \
{ \
echo 'apc.serializer=igbinary'; \
echo 'session.serialize_handler=igbinary'; \
} >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.ini"; \
\
{ \ { \
echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \
echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \
@ -126,7 +151,7 @@ RUN { \
VOLUME /var/www/html VOLUME /var/www/html
ENV NEXTCLOUD_VERSION 30.0.5 ENV NEXTCLOUD_VERSION 30.0.8
RUN set -ex; \ RUN set -ex; \
fetchDeps=" \ fetchDeps=" \
@ -136,8 +161,8 @@ RUN set -ex; \
apt-get update; \ apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \ apt-get install -y --no-install-recommends $fetchDeps; \
\ \
curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-30.0.5.tar.bz2"; \ curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-30.0.8.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-30.0.5.tar.bz2.asc"; \ curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-30.0.8.tar.bz2.asc"; \
export GNUPGHOME="$(mktemp -d)"; \ export GNUPGHOME="$(mktemp -d)"; \
# gpg key from https://nextcloud.com/nextcloud.asc # gpg key from https://nextcloud.com/nextcloud.asc
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \ gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \

200
31/apache/Dockerfile Normal file
View file

@ -0,0 +1,200 @@
# DO NOT EDIT: created by update.sh from Dockerfile-debian.template
FROM php:8.3-apache-bookworm
# Define the commit hash for imagick as a variable
ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b
# entrypoint.sh and cron.sh dependencies
RUN set -ex; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
busybox-static \
bzip2 \
libldap-common \
libmagickcore-6.q16-6-extra \
rsync \
; \
rm -rf /var/lib/apt/lists/*; \
\
mkdir -p /var/spool/cron/crontabs; \
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
ENV PHP_MEMORY_LIMIT 512M
ENV PHP_UPLOAD_LIMIT 512M
ENV PHP_OPCACHE_MEMORY_CONSUMPTION 128
RUN set -ex; \
\
savedAptMark="$(apt-mark showmanual)"; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
libcurl4-openssl-dev \
libevent-dev \
libfreetype6-dev \
libgmp-dev \
libicu-dev \
libjpeg-dev \
libldap2-dev \
libmagickwand-dev \
libmcrypt-dev \
libmemcached-dev \
libpng-dev \
libpq-dev \
libwebp-dev \
libxml2-dev \
libzip-dev \
; \
\
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
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 --with-libdir="lib/$debMultiarch"; \
docker-php-ext-install -j "$(nproc)" \
bcmath \
exif \
ftp \
gd \
gmp \
intl \
ldap \
opcache \
pcntl \
pdo_mysql \
pdo_pgsql \
sysvsem \
zip \
; \
\
# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet.
# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround.
curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \
tar -xzf imagick.tar.gz -C /tmp; \
rm imagick.tar.gz; \
cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \
phpize; \
./configure; \
make; \
make install; \
cd; \
rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.24; \
pecl install igbinary-3.2.16; \
pecl install memcached-3.3.0 \
--configureoptions 'enable-memcached-igbinary="yes"'; \
pecl install redis-6.2.0 \
--configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \
\
docker-php-ext-enable \
apcu \
igbinary \
imagick \
memcached \
redis \
; \
rm -r /tmp/pear; \
\
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
apt-mark auto '.*' > /dev/null; \
apt-mark manual $savedAptMark; \
ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \
| awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); print so }' \
| sort -u \
| xargs -r dpkg-query --search \
| cut -d: -f1 \
| sort -u \
| xargs -rt apt-mark manual; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*
# set recommended PHP.ini settings
# see https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#enable-php-opcache
RUN { \
echo 'opcache.enable=1'; \
echo 'opcache.interned_strings_buffer=32'; \
echo 'opcache.max_accelerated_files=10000'; \
echo 'opcache.memory_consumption=${PHP_OPCACHE_MEMORY_CONSUMPTION}'; \
echo 'opcache.save_comments=1'; \
echo 'opcache.revalidate_freq=60'; \
echo 'opcache.jit=1255'; \
echo 'opcache.jit_buffer_size=8M'; \
} > "${PHP_INI_DIR}/conf.d/opcache-recommended.ini"; \
\
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\
{ \
echo 'apc.serializer=igbinary'; \
echo 'session.serialize_handler=igbinary'; \
} >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.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
VOLUME /var/www/html
RUN a2enmod headers rewrite remoteip ; \
{ \
echo 'RemoteIPHeader X-Real-IP'; \
echo 'RemoteIPInternalProxy 10.0.0.0/8'; \
echo 'RemoteIPInternalProxy 172.16.0.0/12'; \
echo 'RemoteIPInternalProxy 192.168.0.0/16'; \
} > /etc/apache2/conf-available/remoteip.conf; \
a2enconf remoteip
# set apache config LimitRequestBody
ENV APACHE_BODY_LIMIT 1073741824
RUN { \
echo 'LimitRequestBody ${APACHE_BODY_LIMIT}'; \
} > /etc/apache2/conf-available/apache-limits.conf; \
a2enconf apache-limits
ENV NEXTCLOUD_VERSION 31.0.2
RUN set -ex; \
fetchDeps=" \
gnupg \
dirmngr \
"; \
apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \
\
curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-31.0.2.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-31.0.2.tar.bz2.asc"; \
export GNUPGHOME="$(mktemp -d)"; \
# gpg key from https://nextcloud.com/nextcloud.asc
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \
gpg --batch --verify nextcloud.tar.bz2.asc nextcloud.tar.bz2; \
tar -xjf nextcloud.tar.bz2 -C /usr/src/; \
gpgconf --kill all; \
rm nextcloud.tar.bz2.asc nextcloud.tar.bz2; \
rm -rf "$GNUPGHOME" /usr/src/nextcloud/updater; \
mkdir -p /usr/src/nextcloud/data; \
mkdir -p /usr/src/nextcloud/custom_apps; \
chmod +x /usr/src/nextcloud/occ; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps; \
rm -rf /var/lib/apt/lists/*
COPY *.sh upgrade.exclude /
COPY config/* /usr/src/nextcloud/config/
ENTRYPOINT ["/entrypoint.sh"]
CMD ["apache2-foreground"]

View file

@ -0,0 +1,4 @@
<?php
$CONFIG = array (
'htaccess.RewriteBase' => '/',
);

View file

@ -0,0 +1,4 @@
<?php
$CONFIG = array (
'memcache.local' => '\OC\Memcache\APCu',
);

View file

@ -0,0 +1,15 @@
<?php
$CONFIG = array (
'apps_paths' => array (
0 => array (
'path' => OC::$SERVERROOT.'/apps',
'url' => '/apps',
'writable' => false,
),
1 => array (
'path' => OC::$SERVERROOT.'/custom_apps',
'url' => '/custom_apps',
'writable' => true,
),
),
);

View file

@ -0,0 +1,41 @@
<?php
$autoconfig_enabled = false;
if (getenv('SQLITE_DATABASE')) {
$AUTOCONFIG['dbtype'] = 'sqlite';
$AUTOCONFIG['dbname'] = getenv('SQLITE_DATABASE');
$autoconfig_enabled = true;
} elseif (getenv('MYSQL_DATABASE_FILE') && getenv('MYSQL_USER_FILE') && getenv('MYSQL_PASSWORD_FILE') && getenv('MYSQL_HOST')) {
$AUTOCONFIG['dbtype'] = 'mysql';
$AUTOCONFIG['dbname'] = trim(file_get_contents(getenv('MYSQL_DATABASE_FILE')));
$AUTOCONFIG['dbuser'] = trim(file_get_contents(getenv('MYSQL_USER_FILE')));
$AUTOCONFIG['dbpass'] = trim(file_get_contents(getenv('MYSQL_PASSWORD_FILE')));
$AUTOCONFIG['dbhost'] = getenv('MYSQL_HOST');
$autoconfig_enabled = true;
} elseif (getenv('MYSQL_DATABASE') && getenv('MYSQL_USER') && getenv('MYSQL_PASSWORD') && getenv('MYSQL_HOST')) {
$AUTOCONFIG['dbtype'] = 'mysql';
$AUTOCONFIG['dbname'] = getenv('MYSQL_DATABASE');
$AUTOCONFIG['dbuser'] = getenv('MYSQL_USER');
$AUTOCONFIG['dbpass'] = getenv('MYSQL_PASSWORD');
$AUTOCONFIG['dbhost'] = getenv('MYSQL_HOST');
$autoconfig_enabled = true;
} elseif (getenv('POSTGRES_DB_FILE') && getenv('POSTGRES_USER_FILE') && getenv('POSTGRES_PASSWORD_FILE') && getenv('POSTGRES_HOST')) {
$AUTOCONFIG['dbtype'] = 'pgsql';
$AUTOCONFIG['dbname'] = trim(file_get_contents(getenv('POSTGRES_DB_FILE')));
$AUTOCONFIG['dbuser'] = trim(file_get_contents(getenv('POSTGRES_USER_FILE')));
$AUTOCONFIG['dbpass'] = trim(file_get_contents(getenv('POSTGRES_PASSWORD_FILE')));
$AUTOCONFIG['dbhost'] = getenv('POSTGRES_HOST');
$autoconfig_enabled = true;
} elseif (getenv('POSTGRES_DB') && getenv('POSTGRES_USER') && getenv('POSTGRES_PASSWORD') && getenv('POSTGRES_HOST')) {
$AUTOCONFIG['dbtype'] = 'pgsql';
$AUTOCONFIG['dbname'] = getenv('POSTGRES_DB');
$AUTOCONFIG['dbuser'] = getenv('POSTGRES_USER');
$AUTOCONFIG['dbpass'] = getenv('POSTGRES_PASSWORD');
$AUTOCONFIG['dbhost'] = getenv('POSTGRES_HOST');
$autoconfig_enabled = true;
}
if ($autoconfig_enabled) {
$AUTOCONFIG['directory'] = getenv('NEXTCLOUD_DATA_DIR') ?: '/var/www/html/data';
}

View file

@ -0,0 +1,21 @@
<?php
if (getenv('REDIS_HOST')) {
$CONFIG = array(
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => array(
'host' => getenv('REDIS_HOST'),
'password' => getenv('REDIS_HOST_PASSWORD_FILE') ? trim(file_get_contents(getenv('REDIS_HOST_PASSWORD_FILE'))) : (string) getenv('REDIS_HOST_PASSWORD'),
),
);
if (getenv('REDIS_HOST_PORT') !== false) {
$CONFIG['redis']['port'] = (int) getenv('REDIS_HOST_PORT');
} elseif (getenv('REDIS_HOST')[0] != '/') {
$CONFIG['redis']['port'] = 6379;
}
if (getenv('REDIS_HOST_USER') !== false) {
$CONFIG['redis']['user'] = (string) getenv('REDIS_HOST_USER');
}
}

View file

@ -0,0 +1,35 @@
<?php
$overwriteHost = getenv('OVERWRITEHOST');
if ($overwriteHost) {
$CONFIG['overwritehost'] = $overwriteHost;
}
$overwriteProtocol = getenv('OVERWRITEPROTOCOL');
if ($overwriteProtocol) {
$CONFIG['overwriteprotocol'] = $overwriteProtocol;
}
$overwriteCliUrl = getenv('OVERWRITECLIURL');
if ($overwriteCliUrl) {
$CONFIG['overwrite.cli.url'] = $overwriteCliUrl;
}
$overwriteWebRoot = getenv('OVERWRITEWEBROOT');
if ($overwriteWebRoot) {
$CONFIG['overwritewebroot'] = $overwriteWebRoot;
}
$overwriteCondAddr = getenv('OVERWRITECONDADDR');
if ($overwriteCondAddr) {
$CONFIG['overwritecondaddr'] = $overwriteCondAddr;
}
$trustedProxies = getenv('TRUSTED_PROXIES');
if ($trustedProxies) {
$CONFIG['trusted_proxies'] = array_filter(array_map('trim', explode(' ', $trustedProxies)));
}
$forwardedForHeaders = getenv('FORWARDED_FOR_HEADERS');
if ($forwardedForHeaders) {
$CONFIG['forwarded_for_headers'] = array_filter(array_map('trim', explode(' ', $forwardedForHeaders)));
}

View file

@ -0,0 +1,48 @@
<?php
if (getenv('OBJECTSTORE_S3_BUCKET')) {
$use_ssl = getenv('OBJECTSTORE_S3_SSL');
$use_path = getenv('OBJECTSTORE_S3_USEPATH_STYLE');
$use_legacyauth = getenv('OBJECTSTORE_S3_LEGACYAUTH');
$autocreate = getenv('OBJECTSTORE_S3_AUTOCREATE');
$CONFIG = array(
'objectstore' => array(
'class' => '\OC\Files\ObjectStore\S3',
'arguments' => array(
'bucket' => getenv('OBJECTSTORE_S3_BUCKET'),
'region' => getenv('OBJECTSTORE_S3_REGION') ?: '',
'hostname' => getenv('OBJECTSTORE_S3_HOST') ?: '',
'port' => getenv('OBJECTSTORE_S3_PORT') ?: '',
'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '',
'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:",
'autocreate' => strtolower($autocreate) !== 'false',
'use_ssl' => strtolower($use_ssl) !== 'false',
// required for some non Amazon S3 implementations
'use_path_style' => $use_path == true && strtolower($use_path) !== 'false',
// required for older protocol versions
'legacy_auth' => $use_legacyauth == true && strtolower($use_legacyauth) !== 'false'
)
)
);
if (getenv('OBJECTSTORE_S3_KEY_FILE')) {
$CONFIG['objectstore']['arguments']['key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_KEY_FILE')));
} elseif (getenv('OBJECTSTORE_S3_KEY')) {
$CONFIG['objectstore']['arguments']['key'] = getenv('OBJECTSTORE_S3_KEY');
} else {
$CONFIG['objectstore']['arguments']['key'] = '';
}
if (getenv('OBJECTSTORE_S3_SECRET_FILE')) {
$CONFIG['objectstore']['arguments']['secret'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SECRET_FILE')));
} elseif (getenv('OBJECTSTORE_S3_SECRET')) {
$CONFIG['objectstore']['arguments']['secret'] = getenv('OBJECTSTORE_S3_SECRET');
} else {
$CONFIG['objectstore']['arguments']['secret'] = '';
}
if (getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE')) {
$CONFIG['objectstore']['arguments']['sse_c_key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE')));
} elseif (getenv('OBJECTSTORE_S3_SSE_C_KEY')) {
$CONFIG['objectstore']['arguments']['sse_c_key'] = getenv('OBJECTSTORE_S3_SSE_C_KEY');
}
}

View file

@ -0,0 +1,22 @@
<?php
if (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {
$CONFIG = array (
'mail_smtpmode' => 'smtp',
'mail_smtphost' => getenv('SMTP_HOST'),
'mail_smtpport' => getenv('SMTP_PORT') ?: (getenv('SMTP_SECURE') ? 465 : 25),
'mail_smtpsecure' => getenv('SMTP_SECURE') ?: '',
'mail_smtpauth' => getenv('SMTP_NAME') && (getenv('SMTP_PASSWORD') || getenv('SMTP_PASSWORD_FILE')),
'mail_smtpauthtype' => getenv('SMTP_AUTHTYPE') ?: 'LOGIN',
'mail_smtpname' => getenv('SMTP_NAME') ?: '',
'mail_from_address' => getenv('MAIL_FROM_ADDRESS'),
'mail_domain' => getenv('MAIL_DOMAIN'),
);
if (getenv('SMTP_PASSWORD_FILE')) {
$CONFIG['mail_smtppassword'] = trim(file_get_contents(getenv('SMTP_PASSWORD_FILE')));
} elseif (getenv('SMTP_PASSWORD')) {
$CONFIG['mail_smtppassword'] = getenv('SMTP_PASSWORD');
} else {
$CONFIG['mail_smtppassword'] = '';
}
}

View file

@ -0,0 +1,31 @@
<?php
if (getenv('OBJECTSTORE_SWIFT_URL')) {
$autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');
$CONFIG = array(
'objectstore' => [
'class' => 'OC\\Files\\ObjectStore\\Swift',
'arguments' => [
'autocreate' => $autocreate == true && strtolower($autocreate) !== 'false',
'user' => [
'name' => getenv('OBJECTSTORE_SWIFT_USER_NAME'),
'password' => getenv('OBJECTSTORE_SWIFT_USER_PASSWORD'),
'domain' => [
'name' => (getenv('OBJECTSTORE_SWIFT_USER_DOMAIN')) ?: 'Default',
],
],
'scope' => [
'project' => [
'name' => getenv('OBJECTSTORE_SWIFT_PROJECT_NAME'),
'domain' => [
'name' => (getenv('OBJECTSTORE_SWIFT_PROJECT_DOMAIN')) ?: 'Default',
],
],
],
'serviceName' => (getenv('OBJECTSTORE_SWIFT_SERVICE_NAME')) ?: 'swift',
'region' => getenv('OBJECTSTORE_SWIFT_REGION'),
'url' => getenv('OBJECTSTORE_SWIFT_URL'),
'bucket' => getenv('OBJECTSTORE_SWIFT_CONTAINER_NAME'),
]
]
);
}

View file

@ -0,0 +1,4 @@
<?php
$CONFIG = array (
'upgrade.disable-web' => true,
);

4
31/apache/cron.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/sh
set -eu
exec busybox crond -f -L /dev/stdout

293
31/apache/entrypoint.sh Executable file
View file

@ -0,0 +1,293 @@
#!/bin/sh
set -eu
# version_greater A B returns whether A > B
version_greater() {
[ "$(printf '%s\n' "$@" | sort -t '.' -n -k1,1 -k2,2 -k3,3 -k4,4 | head -n 1)" != "$1" ]
}
# return true if specified directory is empty
directory_empty() {
[ -z "$(ls -A "$1/")" ]
}
run_as() {
if [ "$(id -u)" = 0 ]; then
su -p "$user" -s /bin/sh -c "$1"
else
sh -c "$1"
fi
}
# Execute all executable files in a given directory in alphanumeric order
run_path() {
local hook_folder_path="/docker-entrypoint-hooks.d/$1"
local return_code=0
if ! [ -d "${hook_folder_path}" ]; then
echo "=> Skipping the folder \"${hook_folder_path}\", because it doesn't exist"
return 0
fi
echo "=> Searching for scripts (*.sh) to run, located in the folder: ${hook_folder_path}"
(
find "${hook_folder_path}" -maxdepth 1 -iname '*.sh' '(' -type f -o -type l ')' -print | sort | while read -r script_file_path; do
if ! [ -x "${script_file_path}" ]; then
echo "==> The script \"${script_file_path}\" was skipped, because it didn't have the executable flag"
continue
fi
echo "==> Running the script (cwd: $(pwd)): \"${script_file_path}\""
run_as "${script_file_path}" || return_code="$?"
if [ "${return_code}" -ne "0" ]; then
echo "==> Failed at executing \"${script_file_path}\". Exit code: ${return_code}"
exit 1
fi
echo "==> Finished the script: \"${script_file_path}\""
done
)
}
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//")
local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//")
if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
if [ -n "${varValue}" ]; then
export "$var"="${varValue}"
elif [ -n "${fileVarValue}" ]; then
export "$var"="$(cat "${fileVarValue}")"
elif [ -n "${def}" ]; then
export "$var"="$def"
fi
unset "$fileVar"
}
if expr "$1" : "apache" 1>/dev/null; then
if [ -n "${APACHE_DISABLE_REWRITE_IP+x}" ]; then
a2disconf remoteip
fi
fi
if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UPDATE:-0}" -eq 1 ]; then
uid="$(id -u)"
gid="$(id -g)"
if [ "$uid" = '0' ]; then
case "$1" in
apache2*)
user="${APACHE_RUN_USER:-www-data}"
group="${APACHE_RUN_GROUP:-www-data}"
# strip off any '#' symbol ('#1000' is valid syntax for Apache)
user="${user#'#'}"
group="${group#'#'}"
;;
*) # php-fpm
user='www-data'
group='www-data'
;;
esac
else
user="$uid"
group="$gid"
fi
if [ -n "${REDIS_HOST+x}" ]; then
echo "Configuring Redis as session handler"
{
file_env REDIS_HOST_PASSWORD
echo 'session.save_handler = redis'
# check if redis host is an unix socket path
if [ "$(echo "$REDIS_HOST" | cut -c1-1)" = "/" ]; then
if [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
echo "session.save_path = \"unix://${REDIS_HOST}?auth=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"unix://${REDIS_HOST}\""
fi
# check if redis password has been set
elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}\""
fi
echo "redis.session.locking_enabled = 1"
echo "redis.session.lock_retries = -1"
# redis.session.lock_wait_time is specified in microseconds.
# Wait 10ms before retrying the lock rather than the default 2ms.
echo "redis.session.lock_wait_time = 10000"
} > /usr/local/etc/php/conf.d/redis-session.ini
fi
# If another process is syncing the html folder, wait for
# it to be done, then escape initalization.
(
if ! flock -n 9; then
# If we couldn't get it immediately, show a message, then wait for real
echo "Another process is initializing Nextcloud. Waiting..."
flock 9
fi
installed_version="0.0.0.0"
if [ -f /var/www/html/version.php ]; then
# shellcheck disable=SC2016
installed_version="$(php -r 'require "/var/www/html/version.php"; echo implode(".", $OC_Version);')"
fi
# shellcheck disable=SC2016
image_version="$(php -r 'require "/usr/src/nextcloud/version.php"; echo implode(".", $OC_Version);')"
if version_greater "$installed_version" "$image_version"; then
echo "Can't start Nextcloud because the version of the data ($installed_version) is higher than the docker image version ($image_version) and downgrading is not supported. Are you sure you have pulled the newest image version?"
exit 1
fi
if version_greater "$image_version" "$installed_version"; then
echo "Initializing nextcloud $image_version ..."
if [ "$installed_version" != "0.0.0.0" ]; then
if [ "${image_version%%.*}" -gt "$((${installed_version%%.*} + 1))" ]; then
echo "Can't start Nextcloud because upgrading from $installed_version to $image_version is not supported."
echo "It is only possible to upgrade one major version at a time. For example, if you want to upgrade from version 14 to 16, you will have to upgrade from version 14 to 15, then from 15 to 16."
exit 1
fi
echo "Upgrading nextcloud from $installed_version ..."
run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_before
fi
if [ "$(id -u)" = 0 ]; then
rsync_options="-rlDog --chown $user:$group"
else
rsync_options="-rlD"
fi
rsync $rsync_options --delete --exclude-from=/upgrade.exclude /usr/src/nextcloud/ /var/www/html/
for dir in config data custom_apps themes; do
if [ ! -d "/var/www/html/$dir" ] || directory_empty "/var/www/html/$dir"; then
rsync $rsync_options --include "/$dir/" --exclude '/*' /usr/src/nextcloud/ /var/www/html/
fi
done
rsync $rsync_options --include '/version.php' --exclude '/*' /usr/src/nextcloud/ /var/www/html/
# Install
if [ "$installed_version" = "0.0.0.0" ]; then
echo "New nextcloud instance"
file_env NEXTCLOUD_ADMIN_PASSWORD
file_env NEXTCLOUD_ADMIN_USER
install=false
if [ -n "${NEXTCLOUD_ADMIN_USER+x}" ] && [ -n "${NEXTCLOUD_ADMIN_PASSWORD+x}" ]; then
# shellcheck disable=SC2016
install_options='-n --admin-user "$NEXTCLOUD_ADMIN_USER" --admin-pass "$NEXTCLOUD_ADMIN_PASSWORD"'
if [ -n "${NEXTCLOUD_DATA_DIR+x}" ]; then
# shellcheck disable=SC2016
install_options=$install_options' --data-dir "$NEXTCLOUD_DATA_DIR"'
fi
file_env MYSQL_DATABASE
file_env MYSQL_PASSWORD
file_env MYSQL_USER
file_env POSTGRES_DB
file_env POSTGRES_PASSWORD
file_env POSTGRES_USER
if [ -n "${SQLITE_DATABASE+x}" ]; then
echo "Installing with SQLite database"
# shellcheck disable=SC2016
install_options=$install_options' --database-name "$SQLITE_DATABASE"'
install=true
elif [ -n "${MYSQL_DATABASE+x}" ] && [ -n "${MYSQL_USER+x}" ] && [ -n "${MYSQL_PASSWORD+x}" ] && [ -n "${MYSQL_HOST+x}" ]; then
echo "Installing with MySQL database"
# shellcheck disable=SC2016
install_options=$install_options' --database mysql --database-name "$MYSQL_DATABASE" --database-user "$MYSQL_USER" --database-pass "$MYSQL_PASSWORD" --database-host "$MYSQL_HOST"'
install=true
elif [ -n "${POSTGRES_DB+x}" ] && [ -n "${POSTGRES_USER+x}" ] && [ -n "${POSTGRES_PASSWORD+x}" ] && [ -n "${POSTGRES_HOST+x}" ]; then
echo "Installing with PostgreSQL database"
# shellcheck disable=SC2016
install_options=$install_options' --database pgsql --database-name "$POSTGRES_DB" --database-user "$POSTGRES_USER" --database-pass "$POSTGRES_PASSWORD" --database-host "$POSTGRES_HOST"'
install=true
fi
if [ "$install" = true ]; then
run_path pre-installation
echo "Starting nextcloud installation"
max_retries=10
try=0
until [ "$try" -gt "$max_retries" ] || run_as "php /var/www/html/occ maintenance:install $install_options"
do
echo "Retrying install..."
try=$((try+1))
sleep 10s
done
if [ "$try" -gt "$max_retries" ]; then
echo "Installing of nextcloud failed!"
exit 1
fi
if [ -n "${NEXTCLOUD_TRUSTED_DOMAINS+x}" ]; then
echo "Setting trusted domains…"
NC_TRUSTED_DOMAIN_IDX=1
for DOMAIN in $NEXTCLOUD_TRUSTED_DOMAINS ; do
DOMAIN=$(echo "$DOMAIN" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
run_as "php /var/www/html/occ config:system:set trusted_domains $NC_TRUSTED_DOMAIN_IDX --value=$DOMAIN"
NC_TRUSTED_DOMAIN_IDX=$((NC_TRUSTED_DOMAIN_IDX+1))
done
fi
run_path post-installation
fi
fi
# not enough specified to do a fully automated installation
if [ "$install" = false ]; then
echo "Next step: Access your instance to finish the web-based installation!"
echo "Hint: You can specify NEXTCLOUD_ADMIN_USER and NEXTCLOUD_ADMIN_PASSWORD and the database variables _prior to first launch_ to fully automate initial installation."
fi
# Upgrade
else
run_path pre-upgrade
run_as 'php /var/www/html/occ upgrade'
run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_after
echo "The following apps have been disabled:"
diff /tmp/list_before /tmp/list_after | grep '<' | cut -d- -f2 | cut -d: -f1
rm -f /tmp/list_before /tmp/list_after
run_path post-upgrade
fi
echo "Initializing finished"
fi
# Update htaccess after init if requested
if [ -n "${NEXTCLOUD_INIT_HTACCESS+x}" ] && [ "$installed_version" != "0.0.0.0" ]; then
run_as 'php /var/www/html/occ maintenance:update:htaccess'
fi
) 9> /var/www/html/nextcloud-init-sync.lock
# warn if config files on persistent storage differ from the latest version of this image
for cfgPath in /usr/src/nextcloud/config/*.php; do
cfgFile=$(basename "$cfgPath")
if [ "$cfgFile" != "config.sample.php" ] && [ "$cfgFile" != "autoconfig.php" ]; then
if ! cmp -s "/usr/src/nextcloud/config/$cfgFile" "/var/www/html/config/$cfgFile"; then
echo "Warning: /var/www/html/config/$cfgFile differs from the latest version of this image at /usr/src/nextcloud/config/$cfgFile"
fi
fi
done
run_path before-starting
fi
exec "$@"

View file

@ -0,0 +1,6 @@
/config/
/data/
/custom_apps/
/themes/
/version.php
/nextcloud-init-sync.lock

176
31/fpm-alpine/Dockerfile Normal file
View file

@ -0,0 +1,176 @@
# DO NOT EDIT: created by update.sh from Dockerfile-alpine.template
FROM php:8.3-fpm-alpine3.21
# Define the commit hash for imagick as a variable
ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b
# entrypoint.sh and cron.sh dependencies
RUN set -ex; \
\
apk add --no-cache \
imagemagick \
imagemagick-pdf \
imagemagick-jpeg \
imagemagick-raw \
imagemagick-tiff \
imagemagick-heic \
imagemagick-webp \
imagemagick-svg \
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 \
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 \
; \
\
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 \
; \
\
# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet.
# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround.
curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \
tar -xzf imagick.tar.gz -C /tmp; \
rm imagick.tar.gz; \
cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \
phpize; \
./configure; \
make; \
make install; \
cd; \
rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.24; \
pecl install igbinary-3.2.16; \
pecl install memcached-3.3.0 \
--configureoptions 'enable-memcached-igbinary="yes"'; \
pecl install redis-6.2.0 \
--configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \
\
docker-php-ext-enable \
apcu \
igbinary \
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
ENV PHP_OPCACHE_MEMORY_CONSUMPTION 128
RUN { \
echo 'opcache.enable=1'; \
echo 'opcache.interned_strings_buffer=32'; \
echo 'opcache.max_accelerated_files=10000'; \
echo 'opcache.memory_consumption=${PHP_OPCACHE_MEMORY_CONSUMPTION}'; \
echo 'opcache.save_comments=1'; \
echo 'opcache.revalidate_freq=60'; \
echo 'opcache.jit=1255'; \
echo 'opcache.jit_buffer_size=8M'; \
} > "${PHP_INI_DIR}/conf.d/opcache-recommended.ini"; \
\
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\
{ \
echo 'apc.serializer=igbinary'; \
echo 'session.serialize_handler=igbinary'; \
} >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.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
VOLUME /var/www/html
ENV NEXTCLOUD_VERSION 31.0.2
RUN set -ex; \
apk add --no-cache --virtual .fetch-deps \
bzip2 \
gnupg \
; \
\
curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-31.0.2.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-31.0.2.tar.bz2.asc"; \
export GNUPGHOME="$(mktemp -d)"; \
# gpg key from https://nextcloud.com/nextcloud.asc
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \
gpg --batch --verify nextcloud.tar.bz2.asc nextcloud.tar.bz2; \
tar -xjf nextcloud.tar.bz2 -C /usr/src/; \
gpgconf --kill all; \
rm nextcloud.tar.bz2.asc nextcloud.tar.bz2; \
rm -rf "$GNUPGHOME" /usr/src/nextcloud/updater; \
mkdir -p /usr/src/nextcloud/data; \
mkdir -p /usr/src/nextcloud/custom_apps; \
chmod +x /usr/src/nextcloud/occ; \
apk del --no-network .fetch-deps
COPY *.sh upgrade.exclude /
COPY config/* /usr/src/nextcloud/config/
ENTRYPOINT ["/entrypoint.sh"]
CMD ["php-fpm"]

View file

@ -0,0 +1,4 @@
<?php
$CONFIG = array (
'memcache.local' => '\OC\Memcache\APCu',
);

View file

@ -0,0 +1,15 @@
<?php
$CONFIG = array (
'apps_paths' => array (
0 => array (
'path' => OC::$SERVERROOT.'/apps',
'url' => '/apps',
'writable' => false,
),
1 => array (
'path' => OC::$SERVERROOT.'/custom_apps',
'url' => '/custom_apps',
'writable' => true,
),
),
);

View file

@ -0,0 +1,41 @@
<?php
$autoconfig_enabled = false;
if (getenv('SQLITE_DATABASE')) {
$AUTOCONFIG['dbtype'] = 'sqlite';
$AUTOCONFIG['dbname'] = getenv('SQLITE_DATABASE');
$autoconfig_enabled = true;
} elseif (getenv('MYSQL_DATABASE_FILE') && getenv('MYSQL_USER_FILE') && getenv('MYSQL_PASSWORD_FILE') && getenv('MYSQL_HOST')) {
$AUTOCONFIG['dbtype'] = 'mysql';
$AUTOCONFIG['dbname'] = trim(file_get_contents(getenv('MYSQL_DATABASE_FILE')));
$AUTOCONFIG['dbuser'] = trim(file_get_contents(getenv('MYSQL_USER_FILE')));
$AUTOCONFIG['dbpass'] = trim(file_get_contents(getenv('MYSQL_PASSWORD_FILE')));
$AUTOCONFIG['dbhost'] = getenv('MYSQL_HOST');
$autoconfig_enabled = true;
} elseif (getenv('MYSQL_DATABASE') && getenv('MYSQL_USER') && getenv('MYSQL_PASSWORD') && getenv('MYSQL_HOST')) {
$AUTOCONFIG['dbtype'] = 'mysql';
$AUTOCONFIG['dbname'] = getenv('MYSQL_DATABASE');
$AUTOCONFIG['dbuser'] = getenv('MYSQL_USER');
$AUTOCONFIG['dbpass'] = getenv('MYSQL_PASSWORD');
$AUTOCONFIG['dbhost'] = getenv('MYSQL_HOST');
$autoconfig_enabled = true;
} elseif (getenv('POSTGRES_DB_FILE') && getenv('POSTGRES_USER_FILE') && getenv('POSTGRES_PASSWORD_FILE') && getenv('POSTGRES_HOST')) {
$AUTOCONFIG['dbtype'] = 'pgsql';
$AUTOCONFIG['dbname'] = trim(file_get_contents(getenv('POSTGRES_DB_FILE')));
$AUTOCONFIG['dbuser'] = trim(file_get_contents(getenv('POSTGRES_USER_FILE')));
$AUTOCONFIG['dbpass'] = trim(file_get_contents(getenv('POSTGRES_PASSWORD_FILE')));
$AUTOCONFIG['dbhost'] = getenv('POSTGRES_HOST');
$autoconfig_enabled = true;
} elseif (getenv('POSTGRES_DB') && getenv('POSTGRES_USER') && getenv('POSTGRES_PASSWORD') && getenv('POSTGRES_HOST')) {
$AUTOCONFIG['dbtype'] = 'pgsql';
$AUTOCONFIG['dbname'] = getenv('POSTGRES_DB');
$AUTOCONFIG['dbuser'] = getenv('POSTGRES_USER');
$AUTOCONFIG['dbpass'] = getenv('POSTGRES_PASSWORD');
$AUTOCONFIG['dbhost'] = getenv('POSTGRES_HOST');
$autoconfig_enabled = true;
}
if ($autoconfig_enabled) {
$AUTOCONFIG['directory'] = getenv('NEXTCLOUD_DATA_DIR') ?: '/var/www/html/data';
}

View file

@ -0,0 +1,21 @@
<?php
if (getenv('REDIS_HOST')) {
$CONFIG = array(
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => array(
'host' => getenv('REDIS_HOST'),
'password' => getenv('REDIS_HOST_PASSWORD_FILE') ? trim(file_get_contents(getenv('REDIS_HOST_PASSWORD_FILE'))) : (string) getenv('REDIS_HOST_PASSWORD'),
),
);
if (getenv('REDIS_HOST_PORT') !== false) {
$CONFIG['redis']['port'] = (int) getenv('REDIS_HOST_PORT');
} elseif (getenv('REDIS_HOST')[0] != '/') {
$CONFIG['redis']['port'] = 6379;
}
if (getenv('REDIS_HOST_USER') !== false) {
$CONFIG['redis']['user'] = (string) getenv('REDIS_HOST_USER');
}
}

View file

@ -0,0 +1,35 @@
<?php
$overwriteHost = getenv('OVERWRITEHOST');
if ($overwriteHost) {
$CONFIG['overwritehost'] = $overwriteHost;
}
$overwriteProtocol = getenv('OVERWRITEPROTOCOL');
if ($overwriteProtocol) {
$CONFIG['overwriteprotocol'] = $overwriteProtocol;
}
$overwriteCliUrl = getenv('OVERWRITECLIURL');
if ($overwriteCliUrl) {
$CONFIG['overwrite.cli.url'] = $overwriteCliUrl;
}
$overwriteWebRoot = getenv('OVERWRITEWEBROOT');
if ($overwriteWebRoot) {
$CONFIG['overwritewebroot'] = $overwriteWebRoot;
}
$overwriteCondAddr = getenv('OVERWRITECONDADDR');
if ($overwriteCondAddr) {
$CONFIG['overwritecondaddr'] = $overwriteCondAddr;
}
$trustedProxies = getenv('TRUSTED_PROXIES');
if ($trustedProxies) {
$CONFIG['trusted_proxies'] = array_filter(array_map('trim', explode(' ', $trustedProxies)));
}
$forwardedForHeaders = getenv('FORWARDED_FOR_HEADERS');
if ($forwardedForHeaders) {
$CONFIG['forwarded_for_headers'] = array_filter(array_map('trim', explode(' ', $forwardedForHeaders)));
}

View file

@ -0,0 +1,48 @@
<?php
if (getenv('OBJECTSTORE_S3_BUCKET')) {
$use_ssl = getenv('OBJECTSTORE_S3_SSL');
$use_path = getenv('OBJECTSTORE_S3_USEPATH_STYLE');
$use_legacyauth = getenv('OBJECTSTORE_S3_LEGACYAUTH');
$autocreate = getenv('OBJECTSTORE_S3_AUTOCREATE');
$CONFIG = array(
'objectstore' => array(
'class' => '\OC\Files\ObjectStore\S3',
'arguments' => array(
'bucket' => getenv('OBJECTSTORE_S3_BUCKET'),
'region' => getenv('OBJECTSTORE_S3_REGION') ?: '',
'hostname' => getenv('OBJECTSTORE_S3_HOST') ?: '',
'port' => getenv('OBJECTSTORE_S3_PORT') ?: '',
'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '',
'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:",
'autocreate' => strtolower($autocreate) !== 'false',
'use_ssl' => strtolower($use_ssl) !== 'false',
// required for some non Amazon S3 implementations
'use_path_style' => $use_path == true && strtolower($use_path) !== 'false',
// required for older protocol versions
'legacy_auth' => $use_legacyauth == true && strtolower($use_legacyauth) !== 'false'
)
)
);
if (getenv('OBJECTSTORE_S3_KEY_FILE')) {
$CONFIG['objectstore']['arguments']['key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_KEY_FILE')));
} elseif (getenv('OBJECTSTORE_S3_KEY')) {
$CONFIG['objectstore']['arguments']['key'] = getenv('OBJECTSTORE_S3_KEY');
} else {
$CONFIG['objectstore']['arguments']['key'] = '';
}
if (getenv('OBJECTSTORE_S3_SECRET_FILE')) {
$CONFIG['objectstore']['arguments']['secret'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SECRET_FILE')));
} elseif (getenv('OBJECTSTORE_S3_SECRET')) {
$CONFIG['objectstore']['arguments']['secret'] = getenv('OBJECTSTORE_S3_SECRET');
} else {
$CONFIG['objectstore']['arguments']['secret'] = '';
}
if (getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE')) {
$CONFIG['objectstore']['arguments']['sse_c_key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE')));
} elseif (getenv('OBJECTSTORE_S3_SSE_C_KEY')) {
$CONFIG['objectstore']['arguments']['sse_c_key'] = getenv('OBJECTSTORE_S3_SSE_C_KEY');
}
}

View file

@ -0,0 +1,22 @@
<?php
if (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {
$CONFIG = array (
'mail_smtpmode' => 'smtp',
'mail_smtphost' => getenv('SMTP_HOST'),
'mail_smtpport' => getenv('SMTP_PORT') ?: (getenv('SMTP_SECURE') ? 465 : 25),
'mail_smtpsecure' => getenv('SMTP_SECURE') ?: '',
'mail_smtpauth' => getenv('SMTP_NAME') && (getenv('SMTP_PASSWORD') || getenv('SMTP_PASSWORD_FILE')),
'mail_smtpauthtype' => getenv('SMTP_AUTHTYPE') ?: 'LOGIN',
'mail_smtpname' => getenv('SMTP_NAME') ?: '',
'mail_from_address' => getenv('MAIL_FROM_ADDRESS'),
'mail_domain' => getenv('MAIL_DOMAIN'),
);
if (getenv('SMTP_PASSWORD_FILE')) {
$CONFIG['mail_smtppassword'] = trim(file_get_contents(getenv('SMTP_PASSWORD_FILE')));
} elseif (getenv('SMTP_PASSWORD')) {
$CONFIG['mail_smtppassword'] = getenv('SMTP_PASSWORD');
} else {
$CONFIG['mail_smtppassword'] = '';
}
}

View file

@ -0,0 +1,31 @@
<?php
if (getenv('OBJECTSTORE_SWIFT_URL')) {
$autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');
$CONFIG = array(
'objectstore' => [
'class' => 'OC\\Files\\ObjectStore\\Swift',
'arguments' => [
'autocreate' => $autocreate == true && strtolower($autocreate) !== 'false',
'user' => [
'name' => getenv('OBJECTSTORE_SWIFT_USER_NAME'),
'password' => getenv('OBJECTSTORE_SWIFT_USER_PASSWORD'),
'domain' => [
'name' => (getenv('OBJECTSTORE_SWIFT_USER_DOMAIN')) ?: 'Default',
],
],
'scope' => [
'project' => [
'name' => getenv('OBJECTSTORE_SWIFT_PROJECT_NAME'),
'domain' => [
'name' => (getenv('OBJECTSTORE_SWIFT_PROJECT_DOMAIN')) ?: 'Default',
],
],
],
'serviceName' => (getenv('OBJECTSTORE_SWIFT_SERVICE_NAME')) ?: 'swift',
'region' => getenv('OBJECTSTORE_SWIFT_REGION'),
'url' => getenv('OBJECTSTORE_SWIFT_URL'),
'bucket' => getenv('OBJECTSTORE_SWIFT_CONTAINER_NAME'),
]
]
);
}

View file

@ -0,0 +1,4 @@
<?php
$CONFIG = array (
'upgrade.disable-web' => true,
);

4
31/fpm-alpine/cron.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/sh
set -eu
exec busybox crond -f -L /dev/stdout

293
31/fpm-alpine/entrypoint.sh Executable file
View file

@ -0,0 +1,293 @@
#!/bin/sh
set -eu
# version_greater A B returns whether A > B
version_greater() {
[ "$(printf '%s\n' "$@" | sort -t '.' -n -k1,1 -k2,2 -k3,3 -k4,4 | head -n 1)" != "$1" ]
}
# return true if specified directory is empty
directory_empty() {
[ -z "$(ls -A "$1/")" ]
}
run_as() {
if [ "$(id -u)" = 0 ]; then
su -p "$user" -s /bin/sh -c "$1"
else
sh -c "$1"
fi
}
# Execute all executable files in a given directory in alphanumeric order
run_path() {
local hook_folder_path="/docker-entrypoint-hooks.d/$1"
local return_code=0
if ! [ -d "${hook_folder_path}" ]; then
echo "=> Skipping the folder \"${hook_folder_path}\", because it doesn't exist"
return 0
fi
echo "=> Searching for scripts (*.sh) to run, located in the folder: ${hook_folder_path}"
(
find "${hook_folder_path}" -maxdepth 1 -iname '*.sh' '(' -type f -o -type l ')' -print | sort | while read -r script_file_path; do
if ! [ -x "${script_file_path}" ]; then
echo "==> The script \"${script_file_path}\" was skipped, because it didn't have the executable flag"
continue
fi
echo "==> Running the script (cwd: $(pwd)): \"${script_file_path}\""
run_as "${script_file_path}" || return_code="$?"
if [ "${return_code}" -ne "0" ]; then
echo "==> Failed at executing \"${script_file_path}\". Exit code: ${return_code}"
exit 1
fi
echo "==> Finished the script: \"${script_file_path}\""
done
)
}
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//")
local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//")
if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
if [ -n "${varValue}" ]; then
export "$var"="${varValue}"
elif [ -n "${fileVarValue}" ]; then
export "$var"="$(cat "${fileVarValue}")"
elif [ -n "${def}" ]; then
export "$var"="$def"
fi
unset "$fileVar"
}
if expr "$1" : "apache" 1>/dev/null; then
if [ -n "${APACHE_DISABLE_REWRITE_IP+x}" ]; then
a2disconf remoteip
fi
fi
if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UPDATE:-0}" -eq 1 ]; then
uid="$(id -u)"
gid="$(id -g)"
if [ "$uid" = '0' ]; then
case "$1" in
apache2*)
user="${APACHE_RUN_USER:-www-data}"
group="${APACHE_RUN_GROUP:-www-data}"
# strip off any '#' symbol ('#1000' is valid syntax for Apache)
user="${user#'#'}"
group="${group#'#'}"
;;
*) # php-fpm
user='www-data'
group='www-data'
;;
esac
else
user="$uid"
group="$gid"
fi
if [ -n "${REDIS_HOST+x}" ]; then
echo "Configuring Redis as session handler"
{
file_env REDIS_HOST_PASSWORD
echo 'session.save_handler = redis'
# check if redis host is an unix socket path
if [ "$(echo "$REDIS_HOST" | cut -c1-1)" = "/" ]; then
if [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
echo "session.save_path = \"unix://${REDIS_HOST}?auth=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"unix://${REDIS_HOST}\""
fi
# check if redis password has been set
elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}\""
fi
echo "redis.session.locking_enabled = 1"
echo "redis.session.lock_retries = -1"
# redis.session.lock_wait_time is specified in microseconds.
# Wait 10ms before retrying the lock rather than the default 2ms.
echo "redis.session.lock_wait_time = 10000"
} > /usr/local/etc/php/conf.d/redis-session.ini
fi
# If another process is syncing the html folder, wait for
# it to be done, then escape initalization.
(
if ! flock -n 9; then
# If we couldn't get it immediately, show a message, then wait for real
echo "Another process is initializing Nextcloud. Waiting..."
flock 9
fi
installed_version="0.0.0.0"
if [ -f /var/www/html/version.php ]; then
# shellcheck disable=SC2016
installed_version="$(php -r 'require "/var/www/html/version.php"; echo implode(".", $OC_Version);')"
fi
# shellcheck disable=SC2016
image_version="$(php -r 'require "/usr/src/nextcloud/version.php"; echo implode(".", $OC_Version);')"
if version_greater "$installed_version" "$image_version"; then
echo "Can't start Nextcloud because the version of the data ($installed_version) is higher than the docker image version ($image_version) and downgrading is not supported. Are you sure you have pulled the newest image version?"
exit 1
fi
if version_greater "$image_version" "$installed_version"; then
echo "Initializing nextcloud $image_version ..."
if [ "$installed_version" != "0.0.0.0" ]; then
if [ "${image_version%%.*}" -gt "$((${installed_version%%.*} + 1))" ]; then
echo "Can't start Nextcloud because upgrading from $installed_version to $image_version is not supported."
echo "It is only possible to upgrade one major version at a time. For example, if you want to upgrade from version 14 to 16, you will have to upgrade from version 14 to 15, then from 15 to 16."
exit 1
fi
echo "Upgrading nextcloud from $installed_version ..."
run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_before
fi
if [ "$(id -u)" = 0 ]; then
rsync_options="-rlDog --chown $user:$group"
else
rsync_options="-rlD"
fi
rsync $rsync_options --delete --exclude-from=/upgrade.exclude /usr/src/nextcloud/ /var/www/html/
for dir in config data custom_apps themes; do
if [ ! -d "/var/www/html/$dir" ] || directory_empty "/var/www/html/$dir"; then
rsync $rsync_options --include "/$dir/" --exclude '/*' /usr/src/nextcloud/ /var/www/html/
fi
done
rsync $rsync_options --include '/version.php' --exclude '/*' /usr/src/nextcloud/ /var/www/html/
# Install
if [ "$installed_version" = "0.0.0.0" ]; then
echo "New nextcloud instance"
file_env NEXTCLOUD_ADMIN_PASSWORD
file_env NEXTCLOUD_ADMIN_USER
install=false
if [ -n "${NEXTCLOUD_ADMIN_USER+x}" ] && [ -n "${NEXTCLOUD_ADMIN_PASSWORD+x}" ]; then
# shellcheck disable=SC2016
install_options='-n --admin-user "$NEXTCLOUD_ADMIN_USER" --admin-pass "$NEXTCLOUD_ADMIN_PASSWORD"'
if [ -n "${NEXTCLOUD_DATA_DIR+x}" ]; then
# shellcheck disable=SC2016
install_options=$install_options' --data-dir "$NEXTCLOUD_DATA_DIR"'
fi
file_env MYSQL_DATABASE
file_env MYSQL_PASSWORD
file_env MYSQL_USER
file_env POSTGRES_DB
file_env POSTGRES_PASSWORD
file_env POSTGRES_USER
if [ -n "${SQLITE_DATABASE+x}" ]; then
echo "Installing with SQLite database"
# shellcheck disable=SC2016
install_options=$install_options' --database-name "$SQLITE_DATABASE"'
install=true
elif [ -n "${MYSQL_DATABASE+x}" ] && [ -n "${MYSQL_USER+x}" ] && [ -n "${MYSQL_PASSWORD+x}" ] && [ -n "${MYSQL_HOST+x}" ]; then
echo "Installing with MySQL database"
# shellcheck disable=SC2016
install_options=$install_options' --database mysql --database-name "$MYSQL_DATABASE" --database-user "$MYSQL_USER" --database-pass "$MYSQL_PASSWORD" --database-host "$MYSQL_HOST"'
install=true
elif [ -n "${POSTGRES_DB+x}" ] && [ -n "${POSTGRES_USER+x}" ] && [ -n "${POSTGRES_PASSWORD+x}" ] && [ -n "${POSTGRES_HOST+x}" ]; then
echo "Installing with PostgreSQL database"
# shellcheck disable=SC2016
install_options=$install_options' --database pgsql --database-name "$POSTGRES_DB" --database-user "$POSTGRES_USER" --database-pass "$POSTGRES_PASSWORD" --database-host "$POSTGRES_HOST"'
install=true
fi
if [ "$install" = true ]; then
run_path pre-installation
echo "Starting nextcloud installation"
max_retries=10
try=0
until [ "$try" -gt "$max_retries" ] || run_as "php /var/www/html/occ maintenance:install $install_options"
do
echo "Retrying install..."
try=$((try+1))
sleep 10s
done
if [ "$try" -gt "$max_retries" ]; then
echo "Installing of nextcloud failed!"
exit 1
fi
if [ -n "${NEXTCLOUD_TRUSTED_DOMAINS+x}" ]; then
echo "Setting trusted domains…"
NC_TRUSTED_DOMAIN_IDX=1
for DOMAIN in $NEXTCLOUD_TRUSTED_DOMAINS ; do
DOMAIN=$(echo "$DOMAIN" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
run_as "php /var/www/html/occ config:system:set trusted_domains $NC_TRUSTED_DOMAIN_IDX --value=$DOMAIN"
NC_TRUSTED_DOMAIN_IDX=$((NC_TRUSTED_DOMAIN_IDX+1))
done
fi
run_path post-installation
fi
fi
# not enough specified to do a fully automated installation
if [ "$install" = false ]; then
echo "Next step: Access your instance to finish the web-based installation!"
echo "Hint: You can specify NEXTCLOUD_ADMIN_USER and NEXTCLOUD_ADMIN_PASSWORD and the database variables _prior to first launch_ to fully automate initial installation."
fi
# Upgrade
else
run_path pre-upgrade
run_as 'php /var/www/html/occ upgrade'
run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_after
echo "The following apps have been disabled:"
diff /tmp/list_before /tmp/list_after | grep '<' | cut -d- -f2 | cut -d: -f1
rm -f /tmp/list_before /tmp/list_after
run_path post-upgrade
fi
echo "Initializing finished"
fi
# Update htaccess after init if requested
if [ -n "${NEXTCLOUD_INIT_HTACCESS+x}" ] && [ "$installed_version" != "0.0.0.0" ]; then
run_as 'php /var/www/html/occ maintenance:update:htaccess'
fi
) 9> /var/www/html/nextcloud-init-sync.lock
# warn if config files on persistent storage differ from the latest version of this image
for cfgPath in /usr/src/nextcloud/config/*.php; do
cfgFile=$(basename "$cfgPath")
if [ "$cfgFile" != "config.sample.php" ] && [ "$cfgFile" != "autoconfig.php" ]; then
if ! cmp -s "/usr/src/nextcloud/config/$cfgFile" "/var/www/html/config/$cfgFile"; then
echo "Warning: /var/www/html/config/$cfgFile differs from the latest version of this image at /usr/src/nextcloud/config/$cfgFile"
fi
fi
done
run_path before-starting
fi
exec "$@"

View file

@ -0,0 +1,6 @@
/config/
/data/
/custom_apps/
/themes/
/version.php
/nextcloud-init-sync.lock

185
31/fpm/Dockerfile Normal file
View file

@ -0,0 +1,185 @@
# DO NOT EDIT: created by update.sh from Dockerfile-debian.template
FROM php:8.3-fpm-bookworm
# Define the commit hash for imagick as a variable
ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b
# entrypoint.sh and cron.sh dependencies
RUN set -ex; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
busybox-static \
bzip2 \
libldap-common \
libmagickcore-6.q16-6-extra \
rsync \
; \
rm -rf /var/lib/apt/lists/*; \
\
mkdir -p /var/spool/cron/crontabs; \
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
ENV PHP_MEMORY_LIMIT 512M
ENV PHP_UPLOAD_LIMIT 512M
ENV PHP_OPCACHE_MEMORY_CONSUMPTION 128
RUN set -ex; \
\
savedAptMark="$(apt-mark showmanual)"; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
libcurl4-openssl-dev \
libevent-dev \
libfreetype6-dev \
libgmp-dev \
libicu-dev \
libjpeg-dev \
libldap2-dev \
libmagickwand-dev \
libmcrypt-dev \
libmemcached-dev \
libpng-dev \
libpq-dev \
libwebp-dev \
libxml2-dev \
libzip-dev \
; \
\
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
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 --with-libdir="lib/$debMultiarch"; \
docker-php-ext-install -j "$(nproc)" \
bcmath \
exif \
ftp \
gd \
gmp \
intl \
ldap \
opcache \
pcntl \
pdo_mysql \
pdo_pgsql \
sysvsem \
zip \
; \
\
# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet.
# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround.
curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \
tar -xzf imagick.tar.gz -C /tmp; \
rm imagick.tar.gz; \
cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \
phpize; \
./configure; \
make; \
make install; \
cd; \
rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.24; \
pecl install igbinary-3.2.16; \
pecl install memcached-3.3.0 \
--configureoptions 'enable-memcached-igbinary="yes"'; \
pecl install redis-6.2.0 \
--configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \
\
docker-php-ext-enable \
apcu \
igbinary \
imagick \
memcached \
redis \
; \
rm -r /tmp/pear; \
\
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
apt-mark auto '.*' > /dev/null; \
apt-mark manual $savedAptMark; \
ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \
| awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); print so }' \
| sort -u \
| xargs -r dpkg-query --search \
| cut -d: -f1 \
| sort -u \
| xargs -rt apt-mark manual; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*
# set recommended PHP.ini settings
# see https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#enable-php-opcache
RUN { \
echo 'opcache.enable=1'; \
echo 'opcache.interned_strings_buffer=32'; \
echo 'opcache.max_accelerated_files=10000'; \
echo 'opcache.memory_consumption=${PHP_OPCACHE_MEMORY_CONSUMPTION}'; \
echo 'opcache.save_comments=1'; \
echo 'opcache.revalidate_freq=60'; \
echo 'opcache.jit=1255'; \
echo 'opcache.jit_buffer_size=8M'; \
} > "${PHP_INI_DIR}/conf.d/opcache-recommended.ini"; \
\
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\
{ \
echo 'apc.serializer=igbinary'; \
echo 'session.serialize_handler=igbinary'; \
} >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.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
VOLUME /var/www/html
ENV NEXTCLOUD_VERSION 31.0.2
RUN set -ex; \
fetchDeps=" \
gnupg \
dirmngr \
"; \
apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \
\
curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-31.0.2.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-31.0.2.tar.bz2.asc"; \
export GNUPGHOME="$(mktemp -d)"; \
# gpg key from https://nextcloud.com/nextcloud.asc
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \
gpg --batch --verify nextcloud.tar.bz2.asc nextcloud.tar.bz2; \
tar -xjf nextcloud.tar.bz2 -C /usr/src/; \
gpgconf --kill all; \
rm nextcloud.tar.bz2.asc nextcloud.tar.bz2; \
rm -rf "$GNUPGHOME" /usr/src/nextcloud/updater; \
mkdir -p /usr/src/nextcloud/data; \
mkdir -p /usr/src/nextcloud/custom_apps; \
chmod +x /usr/src/nextcloud/occ; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps; \
rm -rf /var/lib/apt/lists/*
COPY *.sh upgrade.exclude /
COPY config/* /usr/src/nextcloud/config/
ENTRYPOINT ["/entrypoint.sh"]
CMD ["php-fpm"]

View file

@ -0,0 +1,4 @@
<?php
$CONFIG = array (
'memcache.local' => '\OC\Memcache\APCu',
);

View file

@ -0,0 +1,15 @@
<?php
$CONFIG = array (
'apps_paths' => array (
0 => array (
'path' => OC::$SERVERROOT.'/apps',
'url' => '/apps',
'writable' => false,
),
1 => array (
'path' => OC::$SERVERROOT.'/custom_apps',
'url' => '/custom_apps',
'writable' => true,
),
),
);

View file

@ -0,0 +1,41 @@
<?php
$autoconfig_enabled = false;
if (getenv('SQLITE_DATABASE')) {
$AUTOCONFIG['dbtype'] = 'sqlite';
$AUTOCONFIG['dbname'] = getenv('SQLITE_DATABASE');
$autoconfig_enabled = true;
} elseif (getenv('MYSQL_DATABASE_FILE') && getenv('MYSQL_USER_FILE') && getenv('MYSQL_PASSWORD_FILE') && getenv('MYSQL_HOST')) {
$AUTOCONFIG['dbtype'] = 'mysql';
$AUTOCONFIG['dbname'] = trim(file_get_contents(getenv('MYSQL_DATABASE_FILE')));
$AUTOCONFIG['dbuser'] = trim(file_get_contents(getenv('MYSQL_USER_FILE')));
$AUTOCONFIG['dbpass'] = trim(file_get_contents(getenv('MYSQL_PASSWORD_FILE')));
$AUTOCONFIG['dbhost'] = getenv('MYSQL_HOST');
$autoconfig_enabled = true;
} elseif (getenv('MYSQL_DATABASE') && getenv('MYSQL_USER') && getenv('MYSQL_PASSWORD') && getenv('MYSQL_HOST')) {
$AUTOCONFIG['dbtype'] = 'mysql';
$AUTOCONFIG['dbname'] = getenv('MYSQL_DATABASE');
$AUTOCONFIG['dbuser'] = getenv('MYSQL_USER');
$AUTOCONFIG['dbpass'] = getenv('MYSQL_PASSWORD');
$AUTOCONFIG['dbhost'] = getenv('MYSQL_HOST');
$autoconfig_enabled = true;
} elseif (getenv('POSTGRES_DB_FILE') && getenv('POSTGRES_USER_FILE') && getenv('POSTGRES_PASSWORD_FILE') && getenv('POSTGRES_HOST')) {
$AUTOCONFIG['dbtype'] = 'pgsql';
$AUTOCONFIG['dbname'] = trim(file_get_contents(getenv('POSTGRES_DB_FILE')));
$AUTOCONFIG['dbuser'] = trim(file_get_contents(getenv('POSTGRES_USER_FILE')));
$AUTOCONFIG['dbpass'] = trim(file_get_contents(getenv('POSTGRES_PASSWORD_FILE')));
$AUTOCONFIG['dbhost'] = getenv('POSTGRES_HOST');
$autoconfig_enabled = true;
} elseif (getenv('POSTGRES_DB') && getenv('POSTGRES_USER') && getenv('POSTGRES_PASSWORD') && getenv('POSTGRES_HOST')) {
$AUTOCONFIG['dbtype'] = 'pgsql';
$AUTOCONFIG['dbname'] = getenv('POSTGRES_DB');
$AUTOCONFIG['dbuser'] = getenv('POSTGRES_USER');
$AUTOCONFIG['dbpass'] = getenv('POSTGRES_PASSWORD');
$AUTOCONFIG['dbhost'] = getenv('POSTGRES_HOST');
$autoconfig_enabled = true;
}
if ($autoconfig_enabled) {
$AUTOCONFIG['directory'] = getenv('NEXTCLOUD_DATA_DIR') ?: '/var/www/html/data';
}

View file

@ -0,0 +1,21 @@
<?php
if (getenv('REDIS_HOST')) {
$CONFIG = array(
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => array(
'host' => getenv('REDIS_HOST'),
'password' => getenv('REDIS_HOST_PASSWORD_FILE') ? trim(file_get_contents(getenv('REDIS_HOST_PASSWORD_FILE'))) : (string) getenv('REDIS_HOST_PASSWORD'),
),
);
if (getenv('REDIS_HOST_PORT') !== false) {
$CONFIG['redis']['port'] = (int) getenv('REDIS_HOST_PORT');
} elseif (getenv('REDIS_HOST')[0] != '/') {
$CONFIG['redis']['port'] = 6379;
}
if (getenv('REDIS_HOST_USER') !== false) {
$CONFIG['redis']['user'] = (string) getenv('REDIS_HOST_USER');
}
}

View file

@ -0,0 +1,35 @@
<?php
$overwriteHost = getenv('OVERWRITEHOST');
if ($overwriteHost) {
$CONFIG['overwritehost'] = $overwriteHost;
}
$overwriteProtocol = getenv('OVERWRITEPROTOCOL');
if ($overwriteProtocol) {
$CONFIG['overwriteprotocol'] = $overwriteProtocol;
}
$overwriteCliUrl = getenv('OVERWRITECLIURL');
if ($overwriteCliUrl) {
$CONFIG['overwrite.cli.url'] = $overwriteCliUrl;
}
$overwriteWebRoot = getenv('OVERWRITEWEBROOT');
if ($overwriteWebRoot) {
$CONFIG['overwritewebroot'] = $overwriteWebRoot;
}
$overwriteCondAddr = getenv('OVERWRITECONDADDR');
if ($overwriteCondAddr) {
$CONFIG['overwritecondaddr'] = $overwriteCondAddr;
}
$trustedProxies = getenv('TRUSTED_PROXIES');
if ($trustedProxies) {
$CONFIG['trusted_proxies'] = array_filter(array_map('trim', explode(' ', $trustedProxies)));
}
$forwardedForHeaders = getenv('FORWARDED_FOR_HEADERS');
if ($forwardedForHeaders) {
$CONFIG['forwarded_for_headers'] = array_filter(array_map('trim', explode(' ', $forwardedForHeaders)));
}

View file

@ -0,0 +1,48 @@
<?php
if (getenv('OBJECTSTORE_S3_BUCKET')) {
$use_ssl = getenv('OBJECTSTORE_S3_SSL');
$use_path = getenv('OBJECTSTORE_S3_USEPATH_STYLE');
$use_legacyauth = getenv('OBJECTSTORE_S3_LEGACYAUTH');
$autocreate = getenv('OBJECTSTORE_S3_AUTOCREATE');
$CONFIG = array(
'objectstore' => array(
'class' => '\OC\Files\ObjectStore\S3',
'arguments' => array(
'bucket' => getenv('OBJECTSTORE_S3_BUCKET'),
'region' => getenv('OBJECTSTORE_S3_REGION') ?: '',
'hostname' => getenv('OBJECTSTORE_S3_HOST') ?: '',
'port' => getenv('OBJECTSTORE_S3_PORT') ?: '',
'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '',
'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:",
'autocreate' => strtolower($autocreate) !== 'false',
'use_ssl' => strtolower($use_ssl) !== 'false',
// required for some non Amazon S3 implementations
'use_path_style' => $use_path == true && strtolower($use_path) !== 'false',
// required for older protocol versions
'legacy_auth' => $use_legacyauth == true && strtolower($use_legacyauth) !== 'false'
)
)
);
if (getenv('OBJECTSTORE_S3_KEY_FILE')) {
$CONFIG['objectstore']['arguments']['key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_KEY_FILE')));
} elseif (getenv('OBJECTSTORE_S3_KEY')) {
$CONFIG['objectstore']['arguments']['key'] = getenv('OBJECTSTORE_S3_KEY');
} else {
$CONFIG['objectstore']['arguments']['key'] = '';
}
if (getenv('OBJECTSTORE_S3_SECRET_FILE')) {
$CONFIG['objectstore']['arguments']['secret'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SECRET_FILE')));
} elseif (getenv('OBJECTSTORE_S3_SECRET')) {
$CONFIG['objectstore']['arguments']['secret'] = getenv('OBJECTSTORE_S3_SECRET');
} else {
$CONFIG['objectstore']['arguments']['secret'] = '';
}
if (getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE')) {
$CONFIG['objectstore']['arguments']['sse_c_key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE')));
} elseif (getenv('OBJECTSTORE_S3_SSE_C_KEY')) {
$CONFIG['objectstore']['arguments']['sse_c_key'] = getenv('OBJECTSTORE_S3_SSE_C_KEY');
}
}

View file

@ -0,0 +1,22 @@
<?php
if (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {
$CONFIG = array (
'mail_smtpmode' => 'smtp',
'mail_smtphost' => getenv('SMTP_HOST'),
'mail_smtpport' => getenv('SMTP_PORT') ?: (getenv('SMTP_SECURE') ? 465 : 25),
'mail_smtpsecure' => getenv('SMTP_SECURE') ?: '',
'mail_smtpauth' => getenv('SMTP_NAME') && (getenv('SMTP_PASSWORD') || getenv('SMTP_PASSWORD_FILE')),
'mail_smtpauthtype' => getenv('SMTP_AUTHTYPE') ?: 'LOGIN',
'mail_smtpname' => getenv('SMTP_NAME') ?: '',
'mail_from_address' => getenv('MAIL_FROM_ADDRESS'),
'mail_domain' => getenv('MAIL_DOMAIN'),
);
if (getenv('SMTP_PASSWORD_FILE')) {
$CONFIG['mail_smtppassword'] = trim(file_get_contents(getenv('SMTP_PASSWORD_FILE')));
} elseif (getenv('SMTP_PASSWORD')) {
$CONFIG['mail_smtppassword'] = getenv('SMTP_PASSWORD');
} else {
$CONFIG['mail_smtppassword'] = '';
}
}

View file

@ -0,0 +1,31 @@
<?php
if (getenv('OBJECTSTORE_SWIFT_URL')) {
$autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');
$CONFIG = array(
'objectstore' => [
'class' => 'OC\\Files\\ObjectStore\\Swift',
'arguments' => [
'autocreate' => $autocreate == true && strtolower($autocreate) !== 'false',
'user' => [
'name' => getenv('OBJECTSTORE_SWIFT_USER_NAME'),
'password' => getenv('OBJECTSTORE_SWIFT_USER_PASSWORD'),
'domain' => [
'name' => (getenv('OBJECTSTORE_SWIFT_USER_DOMAIN')) ?: 'Default',
],
],
'scope' => [
'project' => [
'name' => getenv('OBJECTSTORE_SWIFT_PROJECT_NAME'),
'domain' => [
'name' => (getenv('OBJECTSTORE_SWIFT_PROJECT_DOMAIN')) ?: 'Default',
],
],
],
'serviceName' => (getenv('OBJECTSTORE_SWIFT_SERVICE_NAME')) ?: 'swift',
'region' => getenv('OBJECTSTORE_SWIFT_REGION'),
'url' => getenv('OBJECTSTORE_SWIFT_URL'),
'bucket' => getenv('OBJECTSTORE_SWIFT_CONTAINER_NAME'),
]
]
);
}

View file

@ -0,0 +1,4 @@
<?php
$CONFIG = array (
'upgrade.disable-web' => true,
);

4
31/fpm/cron.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/sh
set -eu
exec busybox crond -f -L /dev/stdout

293
31/fpm/entrypoint.sh Executable file
View file

@ -0,0 +1,293 @@
#!/bin/sh
set -eu
# version_greater A B returns whether A > B
version_greater() {
[ "$(printf '%s\n' "$@" | sort -t '.' -n -k1,1 -k2,2 -k3,3 -k4,4 | head -n 1)" != "$1" ]
}
# return true if specified directory is empty
directory_empty() {
[ -z "$(ls -A "$1/")" ]
}
run_as() {
if [ "$(id -u)" = 0 ]; then
su -p "$user" -s /bin/sh -c "$1"
else
sh -c "$1"
fi
}
# Execute all executable files in a given directory in alphanumeric order
run_path() {
local hook_folder_path="/docker-entrypoint-hooks.d/$1"
local return_code=0
if ! [ -d "${hook_folder_path}" ]; then
echo "=> Skipping the folder \"${hook_folder_path}\", because it doesn't exist"
return 0
fi
echo "=> Searching for scripts (*.sh) to run, located in the folder: ${hook_folder_path}"
(
find "${hook_folder_path}" -maxdepth 1 -iname '*.sh' '(' -type f -o -type l ')' -print | sort | while read -r script_file_path; do
if ! [ -x "${script_file_path}" ]; then
echo "==> The script \"${script_file_path}\" was skipped, because it didn't have the executable flag"
continue
fi
echo "==> Running the script (cwd: $(pwd)): \"${script_file_path}\""
run_as "${script_file_path}" || return_code="$?"
if [ "${return_code}" -ne "0" ]; then
echo "==> Failed at executing \"${script_file_path}\". Exit code: ${return_code}"
exit 1
fi
echo "==> Finished the script: \"${script_file_path}\""
done
)
}
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//")
local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//")
if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
if [ -n "${varValue}" ]; then
export "$var"="${varValue}"
elif [ -n "${fileVarValue}" ]; then
export "$var"="$(cat "${fileVarValue}")"
elif [ -n "${def}" ]; then
export "$var"="$def"
fi
unset "$fileVar"
}
if expr "$1" : "apache" 1>/dev/null; then
if [ -n "${APACHE_DISABLE_REWRITE_IP+x}" ]; then
a2disconf remoteip
fi
fi
if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UPDATE:-0}" -eq 1 ]; then
uid="$(id -u)"
gid="$(id -g)"
if [ "$uid" = '0' ]; then
case "$1" in
apache2*)
user="${APACHE_RUN_USER:-www-data}"
group="${APACHE_RUN_GROUP:-www-data}"
# strip off any '#' symbol ('#1000' is valid syntax for Apache)
user="${user#'#'}"
group="${group#'#'}"
;;
*) # php-fpm
user='www-data'
group='www-data'
;;
esac
else
user="$uid"
group="$gid"
fi
if [ -n "${REDIS_HOST+x}" ]; then
echo "Configuring Redis as session handler"
{
file_env REDIS_HOST_PASSWORD
echo 'session.save_handler = redis'
# check if redis host is an unix socket path
if [ "$(echo "$REDIS_HOST" | cut -c1-1)" = "/" ]; then
if [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
echo "session.save_path = \"unix://${REDIS_HOST}?auth=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"unix://${REDIS_HOST}\""
fi
# check if redis password has been set
elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}\""
fi
echo "redis.session.locking_enabled = 1"
echo "redis.session.lock_retries = -1"
# redis.session.lock_wait_time is specified in microseconds.
# Wait 10ms before retrying the lock rather than the default 2ms.
echo "redis.session.lock_wait_time = 10000"
} > /usr/local/etc/php/conf.d/redis-session.ini
fi
# If another process is syncing the html folder, wait for
# it to be done, then escape initalization.
(
if ! flock -n 9; then
# If we couldn't get it immediately, show a message, then wait for real
echo "Another process is initializing Nextcloud. Waiting..."
flock 9
fi
installed_version="0.0.0.0"
if [ -f /var/www/html/version.php ]; then
# shellcheck disable=SC2016
installed_version="$(php -r 'require "/var/www/html/version.php"; echo implode(".", $OC_Version);')"
fi
# shellcheck disable=SC2016
image_version="$(php -r 'require "/usr/src/nextcloud/version.php"; echo implode(".", $OC_Version);')"
if version_greater "$installed_version" "$image_version"; then
echo "Can't start Nextcloud because the version of the data ($installed_version) is higher than the docker image version ($image_version) and downgrading is not supported. Are you sure you have pulled the newest image version?"
exit 1
fi
if version_greater "$image_version" "$installed_version"; then
echo "Initializing nextcloud $image_version ..."
if [ "$installed_version" != "0.0.0.0" ]; then
if [ "${image_version%%.*}" -gt "$((${installed_version%%.*} + 1))" ]; then
echo "Can't start Nextcloud because upgrading from $installed_version to $image_version is not supported."
echo "It is only possible to upgrade one major version at a time. For example, if you want to upgrade from version 14 to 16, you will have to upgrade from version 14 to 15, then from 15 to 16."
exit 1
fi
echo "Upgrading nextcloud from $installed_version ..."
run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_before
fi
if [ "$(id -u)" = 0 ]; then
rsync_options="-rlDog --chown $user:$group"
else
rsync_options="-rlD"
fi
rsync $rsync_options --delete --exclude-from=/upgrade.exclude /usr/src/nextcloud/ /var/www/html/
for dir in config data custom_apps themes; do
if [ ! -d "/var/www/html/$dir" ] || directory_empty "/var/www/html/$dir"; then
rsync $rsync_options --include "/$dir/" --exclude '/*' /usr/src/nextcloud/ /var/www/html/
fi
done
rsync $rsync_options --include '/version.php' --exclude '/*' /usr/src/nextcloud/ /var/www/html/
# Install
if [ "$installed_version" = "0.0.0.0" ]; then
echo "New nextcloud instance"
file_env NEXTCLOUD_ADMIN_PASSWORD
file_env NEXTCLOUD_ADMIN_USER
install=false
if [ -n "${NEXTCLOUD_ADMIN_USER+x}" ] && [ -n "${NEXTCLOUD_ADMIN_PASSWORD+x}" ]; then
# shellcheck disable=SC2016
install_options='-n --admin-user "$NEXTCLOUD_ADMIN_USER" --admin-pass "$NEXTCLOUD_ADMIN_PASSWORD"'
if [ -n "${NEXTCLOUD_DATA_DIR+x}" ]; then
# shellcheck disable=SC2016
install_options=$install_options' --data-dir "$NEXTCLOUD_DATA_DIR"'
fi
file_env MYSQL_DATABASE
file_env MYSQL_PASSWORD
file_env MYSQL_USER
file_env POSTGRES_DB
file_env POSTGRES_PASSWORD
file_env POSTGRES_USER
if [ -n "${SQLITE_DATABASE+x}" ]; then
echo "Installing with SQLite database"
# shellcheck disable=SC2016
install_options=$install_options' --database-name "$SQLITE_DATABASE"'
install=true
elif [ -n "${MYSQL_DATABASE+x}" ] && [ -n "${MYSQL_USER+x}" ] && [ -n "${MYSQL_PASSWORD+x}" ] && [ -n "${MYSQL_HOST+x}" ]; then
echo "Installing with MySQL database"
# shellcheck disable=SC2016
install_options=$install_options' --database mysql --database-name "$MYSQL_DATABASE" --database-user "$MYSQL_USER" --database-pass "$MYSQL_PASSWORD" --database-host "$MYSQL_HOST"'
install=true
elif [ -n "${POSTGRES_DB+x}" ] && [ -n "${POSTGRES_USER+x}" ] && [ -n "${POSTGRES_PASSWORD+x}" ] && [ -n "${POSTGRES_HOST+x}" ]; then
echo "Installing with PostgreSQL database"
# shellcheck disable=SC2016
install_options=$install_options' --database pgsql --database-name "$POSTGRES_DB" --database-user "$POSTGRES_USER" --database-pass "$POSTGRES_PASSWORD" --database-host "$POSTGRES_HOST"'
install=true
fi
if [ "$install" = true ]; then
run_path pre-installation
echo "Starting nextcloud installation"
max_retries=10
try=0
until [ "$try" -gt "$max_retries" ] || run_as "php /var/www/html/occ maintenance:install $install_options"
do
echo "Retrying install..."
try=$((try+1))
sleep 10s
done
if [ "$try" -gt "$max_retries" ]; then
echo "Installing of nextcloud failed!"
exit 1
fi
if [ -n "${NEXTCLOUD_TRUSTED_DOMAINS+x}" ]; then
echo "Setting trusted domains…"
NC_TRUSTED_DOMAIN_IDX=1
for DOMAIN in $NEXTCLOUD_TRUSTED_DOMAINS ; do
DOMAIN=$(echo "$DOMAIN" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
run_as "php /var/www/html/occ config:system:set trusted_domains $NC_TRUSTED_DOMAIN_IDX --value=$DOMAIN"
NC_TRUSTED_DOMAIN_IDX=$((NC_TRUSTED_DOMAIN_IDX+1))
done
fi
run_path post-installation
fi
fi
# not enough specified to do a fully automated installation
if [ "$install" = false ]; then
echo "Next step: Access your instance to finish the web-based installation!"
echo "Hint: You can specify NEXTCLOUD_ADMIN_USER and NEXTCLOUD_ADMIN_PASSWORD and the database variables _prior to first launch_ to fully automate initial installation."
fi
# Upgrade
else
run_path pre-upgrade
run_as 'php /var/www/html/occ upgrade'
run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_after
echo "The following apps have been disabled:"
diff /tmp/list_before /tmp/list_after | grep '<' | cut -d- -f2 | cut -d: -f1
rm -f /tmp/list_before /tmp/list_after
run_path post-upgrade
fi
echo "Initializing finished"
fi
# Update htaccess after init if requested
if [ -n "${NEXTCLOUD_INIT_HTACCESS+x}" ] && [ "$installed_version" != "0.0.0.0" ]; then
run_as 'php /var/www/html/occ maintenance:update:htaccess'
fi
) 9> /var/www/html/nextcloud-init-sync.lock
# warn if config files on persistent storage differ from the latest version of this image
for cfgPath in /usr/src/nextcloud/config/*.php; do
cfgFile=$(basename "$cfgPath")
if [ "$cfgFile" != "config.sample.php" ] && [ "$cfgFile" != "autoconfig.php" ]; then
if ! cmp -s "/usr/src/nextcloud/config/$cfgFile" "/var/www/html/config/$cfgFile"; then
echo "Warning: /var/www/html/config/$cfgFile differs from the latest version of this image at /usr/src/nextcloud/config/$cfgFile"
fi
fi
done
run_path before-starting
fi
exec "$@"

6
31/fpm/upgrade.exclude Normal file
View file

@ -0,0 +1,6 @@
/config/
/data/
/custom_apps/
/themes/
/version.php
/nextcloud-init-sync.lock

View file

@ -1,5 +1,8 @@
FROM php:%%PHP_VERSION%%-%%VARIANT%%%%ALPINE_VERSION%% FROM php:%%PHP_VERSION%%-%%VARIANT%%%%ALPINE_VERSION%%
# Define the commit hash for imagick as a variable
ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b
# entrypoint.sh and cron.sh dependencies # entrypoint.sh and cron.sh dependencies
RUN set -ex; \ RUN set -ex; \
\ \
@ -61,14 +64,31 @@ RUN set -ex; \
zip \ zip \
; \ ; \
\ \
# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet.
# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround.
curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \
tar -xzf imagick.tar.gz -C /tmp; \
rm imagick.tar.gz; \
cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \
phpize; \
./configure; \
make; \
make install; \
cd; \
rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately # pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-%%APCU_VERSION%%; \ pecl install APCu-%%APCU_VERSION%%; \
pecl install imagick-%%IMAGICK_VERSION%%; \ pecl install igbinary-%%IGBINARY_VERSION%%; \
pecl install memcached-%%MEMCACHED_VERSION%%; \ pecl install memcached-%%MEMCACHED_VERSION%% \
pecl install redis-%%REDIS_VERSION%%; \ --configureoptions 'enable-memcached-igbinary="yes"'; \
pecl install redis-%%REDIS_VERSION%% \
--configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \
\ \
docker-php-ext-enable \ docker-php-ext-enable \
apcu \ apcu \
igbinary \
imagick \ imagick \
memcached \ memcached \
redis \ redis \
@ -102,6 +122,11 @@ RUN { \
\ \
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\ \
{ \
echo 'apc.serializer=igbinary'; \
echo 'session.serialize_handler=igbinary'; \
} >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.ini"; \
\
{ \ { \
echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \
echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \

View file

@ -1,5 +1,8 @@
FROM php:%%PHP_VERSION%%-%%VARIANT%%-%%DEBIAN_VERSION%% FROM php:%%PHP_VERSION%%-%%VARIANT%%-%%DEBIAN_VERSION%%
# Define the commit hash for imagick as a variable
ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b
# entrypoint.sh and cron.sh dependencies # entrypoint.sh and cron.sh dependencies
RUN set -ex; \ RUN set -ex; \
\ \
@ -64,14 +67,31 @@ RUN set -ex; \
zip \ zip \
; \ ; \
\ \
# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet.
# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround.
curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \
tar -xzf imagick.tar.gz -C /tmp; \
rm imagick.tar.gz; \
cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \
phpize; \
./configure; \
make; \
make install; \
cd; \
rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately # pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-%%APCU_VERSION%%; \ pecl install APCu-%%APCU_VERSION%%; \
pecl install imagick-%%IMAGICK_VERSION%%; \ pecl install igbinary-%%IGBINARY_VERSION%%; \
pecl install memcached-%%MEMCACHED_VERSION%%; \ pecl install memcached-%%MEMCACHED_VERSION%% \
pecl install redis-%%REDIS_VERSION%%; \ --configureoptions 'enable-memcached-igbinary="yes"'; \
pecl install redis-%%REDIS_VERSION%% \
--configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \
\ \
docker-php-ext-enable \ docker-php-ext-enable \
apcu \ apcu \
igbinary \
imagick \ imagick \
memcached \ memcached \
redis \ redis \
@ -107,6 +127,11 @@ RUN { \
\ \
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\ \
{ \
echo 'apc.serializer=igbinary'; \
echo 'session.serialize_handler=igbinary'; \
} >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.ini"; \
\
{ \ { \
echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \
echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \

View file

@ -141,12 +141,23 @@ If mounting additional volumes under `/var/www/html`, you should consider:
**Data inside the main folder (`/var/www/html`) will be overridden/removed during installation and upgrades, unless listed in [upgrade.exclude](https://github.com/nextcloud/docker/blob/master/upgrade.exclude).** The additional volumes officially supported are already in that list, but custom volumes will need to be added by you. We suggest mounting custom storage volumes outside of `/var/www/html` and if possible read-only so that making this adjustment is unnecessary. If you must do so, however, you may build a custom image with a modified `/upgrade.exclude` file that incorporates your custom volume(s). **Data inside the main folder (`/var/www/html`) will be overridden/removed during installation and upgrades, unless listed in [upgrade.exclude](https://github.com/nextcloud/docker/blob/master/upgrade.exclude).** The additional volumes officially supported are already in that list, but custom volumes will need to be added by you. We suggest mounting custom storage volumes outside of `/var/www/html` and if possible read-only so that making this adjustment is unnecessary. If you must do so, however, you may build a custom image with a modified `/upgrade.exclude` file that incorporates your custom volume(s).
## Running as an arbitrary user / file permissions / changing the default container user
The default user within a container is root (uid = 0). By default, processes inside the container will expect to have root privileges. Network services will drop privileges and use `www-data` to serve requests.
Depending on your volumes configuration, this can lead to permission issues. You can address this by running the container with a different default user. When changing the default user, the image will no longer assume it has root privileges and will run all processes under the specified uid. To accomplish this, use the `--user` / `user` option in your container environment.
See:
- https://docs.docker.com/engine/containers/run/#user
- https://github.com/docker-library/docs/tree/master/php#running-as-an-arbitrary-user
- https://docs.podman.io/en/stable/markdown/podman-run.1.html#user-u-user-group
## Accessing the Nextcloud command-line interface (`occ`) ## Accessing the Nextcloud command-line interface (`occ`)
To use the [Nextcloud command-line interface](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html) (aka. `occ` command): To use the [Nextcloud command-line interface](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html) (aka. `occ` command):
```console ```console
$ docker exec --user www-data CONTAINER_ID php occ $ docker exec -it --user www-data CONTAINER_ID php occ
``` ```
or for docker compose: or for docker compose:
```console ```console

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -Eeuo pipefail set -Eeuo pipefail
stable_channel='30.0.5' stable_channel='30.0.8'
self="$(basename "$BASH_SOURCE")" self="$(basename "$BASH_SOURCE")"
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"

View file

@ -1 +1 @@
30.0.5 31.0.2

View file

@ -11,6 +11,7 @@ declare -A debian_version=(
declare -A php_version=( declare -A php_version=(
[default]='8.2' [default]='8.2'
[31]='8.3'
) )
declare -A cmd=( declare -A cmd=(
@ -44,6 +45,24 @@ apcu_version="$(
| tail -1 | tail -1
)" )"
igbinary_version="$(
git ls-remote --tags https://github.com/igbinary/igbinary.git \
| cut -d/ -f3 \
| grep -viE '[a-z]' \
| tr -d '^{}' \
| sort -V \
| tail -1
)"
imagick_version="$(
git ls-remote --tags https://github.com/mkoppanen/imagick.git \
| cut -d/ -f3 \
| grep -viE '[a-z]' \
| tr -d '^{}' \
| sort -V \
| tail -1
)"
memcached_version="$( memcached_version="$(
git ls-remote --tags https://github.com/php-memcached-dev/php-memcached.git \ git ls-remote --tags https://github.com/php-memcached-dev/php-memcached.git \
| cut -d/ -f3 \ | cut -d/ -f3 \
@ -62,20 +81,12 @@ redis_version="$(
| tail -1 | tail -1
)" )"
imagick_version="$(
git ls-remote --tags https://github.com/mkoppanen/imagick.git \
| cut -d/ -f3 \
| grep -viE '[a-z]' \
| tr -d '^{}' \
| sort -V \
| tail -1
)"
declare -A pecl_versions=( declare -A pecl_versions=(
[APCu]="$apcu_version" [APCu]="$apcu_version"
[igbinary]="$igbinary_version"
[imagick]="$imagick_version"
[memcached]="$memcached_version" [memcached]="$memcached_version"
[redis]="$redis_version" [redis]="$redis_version"
[imagick]="$imagick_version"
) )
variants=( variants=(
@ -121,9 +132,10 @@ function create_variant() {
s/%%CMD%%/'"${cmd[$variant]}"'/g; s/%%CMD%%/'"${cmd[$variant]}"'/g;
s|%%VARIANT_EXTRAS%%|'"${extras[$variant]}"'|g; s|%%VARIANT_EXTRAS%%|'"${extras[$variant]}"'|g;
s/%%APCU_VERSION%%/'"${pecl_versions[APCu]}"'/g; s/%%APCU_VERSION%%/'"${pecl_versions[APCu]}"'/g;
s/%%IGBINARY_VERSION%%/'"${pecl_versions[igbinary]}"'/g;
s/%%IMAGICK_VERSION%%/'"${pecl_versions[imagick]}"'/g;
s/%%MEMCACHED_VERSION%%/'"${pecl_versions[memcached]}"'/g; s/%%MEMCACHED_VERSION%%/'"${pecl_versions[memcached]}"'/g;
s/%%REDIS_VERSION%%/'"${pecl_versions[redis]}"'/g; s/%%REDIS_VERSION%%/'"${pecl_versions[redis]}"'/g;
s/%%IMAGICK_VERSION%%/'"${pecl_versions[imagick]}"'/g;
s/%%CRONTAB_INT%%/'"$crontabInt"'/g; s/%%CRONTAB_INT%%/'"$crontabInt"'/g;
' "$dir/Dockerfile" ' "$dir/Dockerfile"

View file

@ -1,9 +1,35 @@
{ {
"31": {
"branch": "31",
"version": "31.0.2",
"url": "https://download.nextcloud.com/server/releases/nextcloud-31.0.2.tar.bz2",
"ascUrl": "https://download.nextcloud.com/server/releases/nextcloud-31.0.2.tar.bz2.asc",
"variants": {
"apache": {
"variant": "apache",
"base": "debian",
"baseVersion": "bookworm",
"phpVersion": "8.3"
},
"fpm": {
"variant": "fpm",
"base": "debian",
"baseVersion": "bookworm",
"phpVersion": "8.3"
},
"fpm-alpine": {
"variant": "fpm-alpine",
"base": "alpine",
"baseVersion": "3.21",
"phpVersion": "8.3"
}
}
},
"30": { "30": {
"branch": "30", "branch": "30",
"version": "30.0.5", "version": "30.0.8",
"url": "https://download.nextcloud.com/server/releases/nextcloud-30.0.5.tar.bz2", "url": "https://download.nextcloud.com/server/releases/nextcloud-30.0.8.tar.bz2",
"ascUrl": "https://download.nextcloud.com/server/releases/nextcloud-30.0.5.tar.bz2.asc", "ascUrl": "https://download.nextcloud.com/server/releases/nextcloud-30.0.8.tar.bz2.asc",
"variants": { "variants": {
"apache": { "apache": {
"variant": "apache", "variant": "apache",
@ -27,9 +53,9 @@
}, },
"29": { "29": {
"branch": "29", "branch": "29",
"version": "29.0.11", "version": "29.0.14",
"url": "https://download.nextcloud.com/server/releases/nextcloud-29.0.11.tar.bz2", "url": "https://download.nextcloud.com/server/releases/nextcloud-29.0.14.tar.bz2",
"ascUrl": "https://download.nextcloud.com/server/releases/nextcloud-29.0.11.tar.bz2.asc", "ascUrl": "https://download.nextcloud.com/server/releases/nextcloud-29.0.14.tar.bz2.asc",
"variants": { "variants": {
"apache": { "apache": {
"variant": "apache", "variant": "apache",