Showing preview only (502K chars total). Download the full file or copy to clipboard to get everything.
Repository: nextcloud/docker
Branch: master
Commit: 803d941dcbb5
Files: 195
Total size: 455.5 KB
Directory structure:
gitextract_83p45qnn/
├── .config/
│ ├── apache-pretty-urls.config.php
│ ├── apcu.config.php
│ ├── apps.config.php
│ ├── autoconfig.php
│ ├── redis.config.php
│ ├── reverse-proxy.config.php
│ ├── s3.config.php
│ ├── smtp.config.php
│ ├── swift.config.php
│ └── upgrade-disable-web.config.php
├── .examples/
│ ├── README.md
│ ├── docker-compose/
│ │ ├── insecure/
│ │ │ ├── mariadb/
│ │ │ │ ├── apache/
│ │ │ │ │ ├── compose.yaml
│ │ │ │ │ └── db.env
│ │ │ │ └── fpm/
│ │ │ │ ├── compose.yaml
│ │ │ │ ├── db.env
│ │ │ │ └── web/
│ │ │ │ └── nginx.conf
│ │ │ └── postgres/
│ │ │ ├── apache/
│ │ │ │ ├── compose.yaml
│ │ │ │ └── db.env
│ │ │ └── fpm/
│ │ │ ├── compose.yaml
│ │ │ ├── db.env
│ │ │ └── web/
│ │ │ └── nginx.conf
│ │ └── with-nginx-proxy/
│ │ ├── mariadb/
│ │ │ ├── apache/
│ │ │ │ ├── compose.yaml
│ │ │ │ ├── db.env
│ │ │ │ └── proxy/
│ │ │ │ ├── Dockerfile
│ │ │ │ └── uploadsize.conf
│ │ │ └── fpm/
│ │ │ ├── compose.yaml
│ │ │ ├── db.env
│ │ │ ├── proxy/
│ │ │ │ ├── Dockerfile
│ │ │ │ └── uploadsize.conf
│ │ │ └── web/
│ │ │ └── nginx.conf
│ │ └── postgres/
│ │ ├── apache/
│ │ │ ├── compose.yaml
│ │ │ ├── db.env
│ │ │ └── proxy/
│ │ │ ├── Dockerfile
│ │ │ └── uploadsize.conf
│ │ └── fpm/
│ │ ├── compose.yaml
│ │ ├── db.env
│ │ ├── proxy/
│ │ │ ├── Dockerfile
│ │ │ └── uploadsize.conf
│ │ └── web/
│ │ └── nginx.conf
│ └── dockerfiles/
│ ├── cron/
│ │ ├── apache/
│ │ │ ├── Dockerfile
│ │ │ └── supervisord.conf
│ │ ├── fpm/
│ │ │ ├── Dockerfile
│ │ │ └── supervisord.conf
│ │ └── fpm-alpine/
│ │ ├── Dockerfile
│ │ └── supervisord.conf
│ ├── full/
│ │ ├── apache/
│ │ │ ├── Dockerfile
│ │ │ └── supervisord.conf
│ │ ├── fpm/
│ │ │ ├── Dockerfile
│ │ │ └── supervisord.conf
│ │ └── fpm-alpine/
│ │ ├── Dockerfile
│ │ └── supervisord.conf
│ ├── imap/
│ │ ├── apache/
│ │ │ └── Dockerfile
│ │ ├── fpm/
│ │ │ └── Dockerfile
│ │ └── fpm-alpine/
│ │ └── Dockerfile
│ └── smb/
│ ├── apache/
│ │ └── Dockerfile
│ ├── fpm/
│ │ └── Dockerfile
│ └── fpm-alpine/
│ └── Dockerfile
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── 01-Image_issue.md
│ │ ├── 02-Image_enhancement
│ │ └── config.yml
│ └── workflows/
│ ├── images.yml
│ └── update-sh.yml
├── 31/
│ ├── apache/
│ │ ├── Dockerfile
│ │ ├── config/
│ │ │ ├── apache-pretty-urls.config.php
│ │ │ ├── apcu.config.php
│ │ │ ├── apps.config.php
│ │ │ ├── autoconfig.php
│ │ │ ├── redis.config.php
│ │ │ ├── reverse-proxy.config.php
│ │ │ ├── s3.config.php
│ │ │ ├── smtp.config.php
│ │ │ ├── swift.config.php
│ │ │ └── upgrade-disable-web.config.php
│ │ ├── cron.sh
│ │ ├── entrypoint.sh
│ │ └── upgrade.exclude
│ ├── fpm/
│ │ ├── Dockerfile
│ │ ├── config/
│ │ │ ├── apcu.config.php
│ │ │ ├── apps.config.php
│ │ │ ├── autoconfig.php
│ │ │ ├── redis.config.php
│ │ │ ├── reverse-proxy.config.php
│ │ │ ├── s3.config.php
│ │ │ ├── smtp.config.php
│ │ │ ├── swift.config.php
│ │ │ └── upgrade-disable-web.config.php
│ │ ├── cron.sh
│ │ ├── entrypoint.sh
│ │ └── upgrade.exclude
│ └── fpm-alpine/
│ ├── Dockerfile
│ ├── config/
│ │ ├── apcu.config.php
│ │ ├── apps.config.php
│ │ ├── autoconfig.php
│ │ ├── redis.config.php
│ │ ├── reverse-proxy.config.php
│ │ ├── s3.config.php
│ │ ├── smtp.config.php
│ │ ├── swift.config.php
│ │ └── upgrade-disable-web.config.php
│ ├── cron.sh
│ ├── entrypoint.sh
│ └── upgrade.exclude
├── 32/
│ ├── apache/
│ │ ├── Dockerfile
│ │ ├── config/
│ │ │ ├── apache-pretty-urls.config.php
│ │ │ ├── apcu.config.php
│ │ │ ├── apps.config.php
│ │ │ ├── autoconfig.php
│ │ │ ├── redis.config.php
│ │ │ ├── reverse-proxy.config.php
│ │ │ ├── s3.config.php
│ │ │ ├── smtp.config.php
│ │ │ ├── swift.config.php
│ │ │ └── upgrade-disable-web.config.php
│ │ ├── cron.sh
│ │ ├── entrypoint.sh
│ │ └── upgrade.exclude
│ ├── fpm/
│ │ ├── Dockerfile
│ │ ├── config/
│ │ │ ├── apcu.config.php
│ │ │ ├── apps.config.php
│ │ │ ├── autoconfig.php
│ │ │ ├── redis.config.php
│ │ │ ├── reverse-proxy.config.php
│ │ │ ├── s3.config.php
│ │ │ ├── smtp.config.php
│ │ │ ├── swift.config.php
│ │ │ └── upgrade-disable-web.config.php
│ │ ├── cron.sh
│ │ ├── entrypoint.sh
│ │ └── upgrade.exclude
│ └── fpm-alpine/
│ ├── Dockerfile
│ ├── config/
│ │ ├── apcu.config.php
│ │ ├── apps.config.php
│ │ ├── autoconfig.php
│ │ ├── redis.config.php
│ │ ├── reverse-proxy.config.php
│ │ ├── s3.config.php
│ │ ├── smtp.config.php
│ │ ├── swift.config.php
│ │ └── upgrade-disable-web.config.php
│ ├── cron.sh
│ ├── entrypoint.sh
│ └── upgrade.exclude
├── 33/
│ ├── apache/
│ │ ├── Dockerfile
│ │ ├── config/
│ │ │ ├── apache-pretty-urls.config.php
│ │ │ ├── apcu.config.php
│ │ │ ├── apps.config.php
│ │ │ ├── autoconfig.php
│ │ │ ├── redis.config.php
│ │ │ ├── reverse-proxy.config.php
│ │ │ ├── s3.config.php
│ │ │ ├── smtp.config.php
│ │ │ ├── swift.config.php
│ │ │ └── upgrade-disable-web.config.php
│ │ ├── cron.sh
│ │ ├── entrypoint.sh
│ │ └── upgrade.exclude
│ ├── fpm/
│ │ ├── Dockerfile
│ │ ├── config/
│ │ │ ├── apcu.config.php
│ │ │ ├── apps.config.php
│ │ │ ├── autoconfig.php
│ │ │ ├── redis.config.php
│ │ │ ├── reverse-proxy.config.php
│ │ │ ├── s3.config.php
│ │ │ ├── smtp.config.php
│ │ │ ├── swift.config.php
│ │ │ └── upgrade-disable-web.config.php
│ │ ├── cron.sh
│ │ ├── entrypoint.sh
│ │ └── upgrade.exclude
│ └── fpm-alpine/
│ ├── Dockerfile
│ ├── config/
│ │ ├── apcu.config.php
│ │ ├── apps.config.php
│ │ ├── autoconfig.php
│ │ ├── redis.config.php
│ │ ├── reverse-proxy.config.php
│ │ ├── s3.config.php
│ │ ├── smtp.config.php
│ │ ├── swift.config.php
│ │ └── upgrade-disable-web.config.php
│ ├── cron.sh
│ ├── entrypoint.sh
│ └── upgrade.exclude
├── CODE_OF_CONDUCT.md
├── Dockerfile-alpine.template
├── Dockerfile-debian.template
├── LICENSE.md
├── README.md
├── docker-cron.sh
├── docker-entrypoint.sh
├── generate-stackbrew-library.sh
├── latest.txt
├── stack.yml
├── update.sh
├── upgrade.exclude
└── versions.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .config/apache-pretty-urls.config.php
================================================
<?php
$CONFIG = array (
'htaccess.RewriteBase' => '/',
);
================================================
FILE: .config/apcu.config.php
================================================
<?php
$CONFIG = array (
'memcache.local' => '\OC\Memcache\APCu',
);
================================================
FILE: .config/apps.config.php
================================================
<?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,
),
),
);
================================================
FILE: .config/autoconfig.php
================================================
<?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';
}
================================================
FILE: .config/redis.config.php
================================================
<?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');
}
}
================================================
FILE: .config/reverse-proxy.config.php
================================================
<?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)));
}
================================================
FILE: .config/s3.config.php
================================================
<?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');
}
}
================================================
FILE: .config/smtp.config.php
================================================
<?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'] = '';
}
}
================================================
FILE: .config/swift.config.php
================================================
<?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'),
]
]
);
}
================================================
FILE: .config/upgrade-disable-web.config.php
================================================
<?php
$CONFIG = array (
'upgrade.disable-web' => true,
);
================================================
FILE: .examples/README.md
================================================
# Examples section
In this subfolders are some examples how to use the docker image. There are two sections:
* [`dockerfiles`](https://github.com/nextcloud/docker/tree/master/.examples/dockerfiles)
* [`docker-compose`](https://github.com/nextcloud/docker/tree/master/.examples/docker-compose)
The `dockerfiles` are derived images, that add or alter certain functionalities of the default docker images. In the `docker-compose` subfolder are examples for deployment of the application, including database, redis, collabora and other services.
## Dockerfiles
The Dockerfiles use the default images as base image and build on top of it.
Example | Description
------- | -------
[cron](https://github.com/nextcloud/docker/tree/master/.examples/dockerfiles/cron) | uses supervisor to run the cron job inside the container (so no extra container is needed). This image runs `supervisord` to start nextcloud and cron as two seperate processes inside the container.
[imap](https://github.com/nextcloud/docker/tree/master/.examples/dockerfiles/imap) | adds dependencies required to authenticate users via imap
[smb](https://github.com/nextcloud/docker/tree/master/.examples/dockerfiles/smb) | adds dependencies required to use smb shares
[full](https://github.com/nextcloud/docker/tree/master/.examples/dockerfiles/full) | adds dependencies for ALL optional packages and cron functionality via supervisor (as in the `cron` example Dockerfile).
### cron
NOTE: [this container must run as root or `cron.php` will not run](https://github.com/nextcloud/docker/issues/1899).
### full
The `full` Dockerfile example adds dependencies for all optional packages suggested by nextcloud that may be needed for some features (e.g. Video Preview Generation), as stated in the [Administration Manual](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html).
NOTE: The Dockerfile does not install the LibreOffice package (line is commented), because it would increase the generated Image size by approximately 500 MB. In order to install it, simply uncomment the appropriate line in the Dockerfile.
NOTE: Per default, only previews for BMP, GIF, JPEG, MarkDown, MP3, PNG, TXT, and XBitmap Files are generated. The configuration of the preview generation can be done in config.php, as explained in the [Administration Manual](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/config_sample_php_parameters.html#previews)
NOTE: Nextcloud recommends [disabling preview generation](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#disable-preview-image-generation) for high security deployments, as preview generation opens your nextcloud instance to new possible attack vectors.
The required steps for each optional/recommended package that is not already in the Nextcloud image are listed here, so that the Dockerfile can easily be modified to only install the needed extra packages. Simply remove the steps for the unwanted packages from the Dockerfile.
#### PHP Module bz2
`docker-php-ext-install bz2`
#### PHP Module imap
`apt install libc-client-dev libkrb5-dev`
`docker-php-ext-configure imap --with-kerberos --with-imap-ssl`
`docker-php-ext-install imap`
#### PHP Module gmp
`apt install libgmp3-dev`
`docker-php-ext-install gmp`
#### PHP Module smbclient
`apt install smbclient libsmbclient-dev`
`pecl install smbclient`
`docker-php-ext-enable smbclient`
#### ffmpeg
`apt install ffmpeg`
#### LibreOffice
`apt install libreoffice`
#### CRON via supervisor
`apt install supervisor`
`mkdir /var/log/supervisord /var/run/supervisord`
The following Dockerfile commands are also necessary for a sucessfull cron installation:
`COPY supervisord.conf /etc/supervisor/supervisord.conf`
`CMD ["/usr/bin/supervisord"]`
## docker-compose
In `docker-compose` additional services are bundled to create a complete nextcloud installation. The examples are designed to run out-of-the-box.
Before running the examples you have to modify the `db.env` and `compose.yaml` file and fill in your custom information.
The docker compose examples make heavily use of derived Dockerfiles to add configuration files into the containers. This way they should also work on remote docker systems as _Docker for Windows_. When running docker compose on the same host as the docker daemon, another possibility would be to simply mount the files in the volumes section in the `compose.yaml` file.
### insecure
This example should only be used for testing on the local network because it uses a unencrypted http connection.
When you want to have your server reachable from the internet adding HTTPS-encryption is mandatory!
For this use one of the [with-nginx-proxy](#with-nginx-proxy) examples.
To use this example complete the following steps:
1. if you use mariadb or mysql choose a root password for the database in `compose.yaml` behind `MYSQL_ROOT_PASSWORD=`
2. choose a password for the database user nextcloud in `db.env` behind `MYSQL_PASSWORD=` (for mariadb/mysql) or `POSTGRES_PASSWORD=` (for postgres)
3. run `docker compose build --pull` to pull the most recent base images and build the custom dockerfiles
4. start nextcloud with `docker compose up -d`
If you want to update your installation to a newer version of nextcloud, repeat the steps 3 and 4.
### with-nginx-proxy
The nginx proxy adds a proxy layer between nextcloud and the internet. The proxy is designed to serve multiple sites on the same host machine.
The advantage in adding this layer is the ability to add a container for [Let's Encrypt](https://letsencrypt.org/) certificate handling.
This combination of the [nginxproxy/nginx-proxy](https://github.com/nginx-proxy/nginx-proxy) and [nginxproxy/acme-companion](https://github.com/nginx-proxy/acme-companion) containers creates a fully automated https encryption of the nextcloud installation without worrying about certificate generation, validation or renewal.
**This setup only works with a valid domain name on a server that is reachable from the internet.**
To use this example complete the following steps:
1. open `compose.yaml`
1. insert your nextcloud domain behind `VIRTUAL_HOST=`and `LETSENCRYPT_HOST=`
2. enter a valid email behind `LETSENCRYPT_EMAIL=`
3. if you use mariadb or mysql choose a root password for the database behind `MYSQL_ROOT_PASSWORD=`
2. choose a password for the database user nextcloud in `db.env` behind `MYSQL_PASSWORD=` (for mariadb/mysql) or `POSTGRES_PASSWORD=` (for postgres)
3. run `docker compose build --pull` to pull the most recent base images and build the custom dockerfiles
4. start nextcloud with `docker compose up -d`
If you want to update your installation to a newer version of nextcloud, repeat the steps 3 and 4.
================================================
FILE: .examples/docker-compose/insecure/mariadb/apache/compose.yaml
================================================
---
services:
# Note: MariaDB is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/mariadb
db:
# Note: Check the recommend version here: https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server
image: mariadb:lts
command: --transaction-isolation=READ-COMMITTED
restart: always
volumes:
- db:/var/lib/mysql:Z
environment:
- MYSQL_ROOT_PASSWORD=
- MARIADB_AUTO_UPGRADE=1
- MARIADB_DISABLE_UPGRADE_BACKUP=1
env_file:
- db.env
# Note: Redis is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/redis
redis:
image: redis:alpine
restart: always
app:
image: nextcloud:apache
restart: always
ports:
- 127.0.0.1:8080:80
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
environment:
- MYSQL_HOST=db
- REDIS_HOST=redis
env_file:
- db.env
depends_on:
- db
- redis
cron:
image: nextcloud:apache
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
entrypoint: /cron.sh
depends_on:
- db
- redis
volumes:
db:
nextcloud:
================================================
FILE: .examples/docker-compose/insecure/mariadb/apache/db.env
================================================
MYSQL_PASSWORD=
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
================================================
FILE: .examples/docker-compose/insecure/mariadb/fpm/compose.yaml
================================================
---
services:
# Note: MariaDB is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/mariadb
db:
# Note: Check the recommend version here: https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server
image: mariadb:lts
command: --transaction-isolation=READ-COMMITTED
restart: always
volumes:
- db:/var/lib/mysql:Z
environment:
- MYSQL_ROOT_PASSWORD=
- MARIADB_AUTO_UPGRADE=1
- MARIADB_DISABLE_UPGRADE_BACKUP=1
env_file:
- db.env
# Note: Redis is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/redis
redis:
image: redis:alpine
restart: always
app:
image: nextcloud:fpm-alpine
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
environment:
- MYSQL_HOST=db
- REDIS_HOST=redis
env_file:
- db.env
depends_on:
- db
- redis
# Note: Nginx is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/nginx/
web:
image: nginx:alpine-slim
restart: always
ports:
- 127.0.0.1:8080:80
volumes:
# https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html
- ./web/nginx.conf:/etc/nginx/nginx.conf:ro
# NOTE: The `volumes` included below should match those of the `app` container (unless you know what you're doing)
- nextcloud:/var/www/html:z,ro
depends_on:
- app
cron:
image: nextcloud:fpm-alpine
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
entrypoint: /cron.sh
depends_on:
- db
- redis
volumes:
db:
nextcloud:
================================================
FILE: .examples/docker-compose/insecure/mariadb/fpm/db.env
================================================
MYSQL_PASSWORD=
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
================================================
FILE: .examples/docker-compose/insecure/mariadb/fpm/web/nginx.conf
================================================
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
types {
text/javascript mjs;
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
# Prevent nginx HTTP Server Detection
server_tokens off;
keepalive_timeout 65;
# Set the `immutable` cache control options only for assets with a cache busting `v` argument
map $arg_v $asset_immutable {
"" "";
default ", immutable";
}
#gzip on;
resolver 127.0.0.11 valid=2s;
upstream php-handler {
zone backends 64k;
server app:9000 resolve;
}
server {
listen 80;
# HSTS settings
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
# set max upload size and increase upload timeout:
client_max_body_size 512M;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
# The settings allows you to optimize the HTTP2 bandwidth.
# See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
# for tuning hints
client_body_buffer_size 512k;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Pagespeed is not supported by Nextcloud, so if your server is built
# with the `ngx_pagespeed` module, uncomment this line to disable it.
#pagespeed off;
# HTTP response headers borrowed from Nextcloud `.htaccess`
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
# Path to the root of your installation
root /var/www/html;
# Specify how to handle directories -- specifying `/index.php$request_uri`
# here as the fallback means that Nginx always exhibits the desired behaviour
# when a client requests a path that corresponds to a directory that exists
# on the server. In particular, if that directory contains an index.php file,
# that file is correctly served; if it doesn't, then the request is passed to
# the front-end controller. This consistent behaviour means that we don't need
# to specify custom rules for certain paths (e.g. images and other assets,
# `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
# `try_files $uri $uri/ /index.php$request_uri`
# always provides the desired behaviour.
index index.php index.html /index.php$request_uri;
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Make a regex exception for `/.well-known` so that clients can still
# access it despite the existence of the regex rule
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
# for `/.well-known`.
location ^~ /.well-known {
# The rules in this block are an adaptation of the rules
# in `.htaccess` that concern `/.well-known`.
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
# Let Nextcloud's API for `/.well-known` URIs handle all other
# requests by passing them to the front-end controller.
return 301 /index.php$request_uri;
}
# Rules borrowed from `.htaccess` to hide certain paths from clients
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
# which handle static assets (as seen below). If this block is not declared first,
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
# to the URI, resulting in a HTTP 500 error response.
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
#fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering on; # Required as PHP-FPM does not support chunked transfer encoding and requires a valid ContentLength header.
fastcgi_max_temp_file_size 0;
}
# Serve static files
location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac|mp4|webm)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463$asset_immutable";
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
access_log off; # Optional: Don't log access to assets
}
location ~ \.(otf|woff2?)$ {
try_files $uri /index.php$request_uri;
expires 7d; # Cache-Control policy borrowed from `.htaccess`
access_log off; # Optional: Don't log access to assets
}
# Rule borrowed from `.htaccess`
location /remote {
return 301 /remote.php$request_uri;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}
}
================================================
FILE: .examples/docker-compose/insecure/postgres/apache/compose.yaml
================================================
---
services:
# Note: PostgreSQL is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/postgres
db:
# Note: Check the recommend version here: https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server
image: postgres:alpine
restart: always
volumes:
- db:/var/lib/postgresql/data:Z
env_file:
- db.env
# Note: Redis is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/redis
redis:
image: redis:alpine
restart: always
app:
image: nextcloud:apache
restart: always
ports:
- 127.0.0.1:8080:80
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
environment:
- POSTGRES_HOST=db
- REDIS_HOST=redis
env_file:
- db.env
depends_on:
- db
- redis
cron:
image: nextcloud:apache
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
entrypoint: /cron.sh
depends_on:
- db
- redis
volumes:
db:
nextcloud:
================================================
FILE: .examples/docker-compose/insecure/postgres/apache/db.env
================================================
POSTGRES_PASSWORD=
POSTGRES_DB=nextcloud
POSTGRES_USER=nextcloud
================================================
FILE: .examples/docker-compose/insecure/postgres/fpm/compose.yaml
================================================
---
services:
# Note: PostgreSQL is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/postgres
db:
# Note: Check the recommend version here: https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server
image: postgres:alpine
restart: always
volumes:
- db:/var/lib/postgresql/data:Z
env_file:
- db.env
# Note: Redis is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/redis
redis:
image: redis:alpine
restart: always
app:
image: nextcloud:fpm-alpine
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
environment:
- POSTGRES_HOST=db
- REDIS_HOST=redis
env_file:
- db.env
depends_on:
- db
- redis
# Note: Nginx is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/nginx/
web:
image: nginx:alpine-slim
restart: always
ports:
- 127.0.0.1:8080:80
volumes:
# https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html
- ./web/nginx.conf:/etc/nginx/nginx.conf:ro
# NOTE: The `volumes` included below should match those of the `app` container (unless you know what you're doing)
- nextcloud:/var/www/html:z,ro
depends_on:
- app
cron:
image: nextcloud:fpm-alpine
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
entrypoint: /cron.sh
depends_on:
- db
- redis
volumes:
db:
nextcloud:
================================================
FILE: .examples/docker-compose/insecure/postgres/fpm/db.env
================================================
POSTGRES_PASSWORD=
POSTGRES_DB=nextcloud
POSTGRES_USER=nextcloud
================================================
FILE: .examples/docker-compose/insecure/postgres/fpm/web/nginx.conf
================================================
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
types {
text/javascript mjs;
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
# Prevent nginx HTTP Server Detection
server_tokens off;
keepalive_timeout 65;
# Set the `immutable` cache control options only for assets with a cache busting `v` argument
map $arg_v $asset_immutable {
"" "";
default ", immutable";
}
#gzip on;
resolver 127.0.0.11 valid=2s;
upstream php-handler {
zone backends 64k;
server app:9000 resolve;
}
server {
listen 80;
# HSTS settings
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
# set max upload size and increase upload timeout:
client_max_body_size 512M;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
# The settings allows you to optimize the HTTP2 bandwidth.
# See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
# for tuning hints
client_body_buffer_size 512k;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Pagespeed is not supported by Nextcloud, so if your server is built
# with the `ngx_pagespeed` module, uncomment this line to disable it.
#pagespeed off;
# HTTP response headers borrowed from Nextcloud `.htaccess`
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
# Path to the root of your installation
root /var/www/html;
# Specify how to handle directories -- specifying `/index.php$request_uri`
# here as the fallback means that Nginx always exhibits the desired behaviour
# when a client requests a path that corresponds to a directory that exists
# on the server. In particular, if that directory contains an index.php file,
# that file is correctly served; if it doesn't, then the request is passed to
# the front-end controller. This consistent behaviour means that we don't need
# to specify custom rules for certain paths (e.g. images and other assets,
# `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
# `try_files $uri $uri/ /index.php$request_uri`
# always provides the desired behaviour.
index index.php index.html /index.php$request_uri;
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Make a regex exception for `/.well-known` so that clients can still
# access it despite the existence of the regex rule
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
# for `/.well-known`.
location ^~ /.well-known {
# The rules in this block are an adaptation of the rules
# in `.htaccess` that concern `/.well-known`.
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
# Let Nextcloud's API for `/.well-known` URIs handle all other
# requests by passing them to the front-end controller.
return 301 /index.php$request_uri;
}
# Rules borrowed from `.htaccess` to hide certain paths from clients
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
# which handle static assets (as seen below). If this block is not declared first,
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
# to the URI, resulting in a HTTP 500 error response.
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
#fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering on; # Required as PHP-FPM does not support chunked transfer encoding and requires a valid ContentLength header.
fastcgi_max_temp_file_size 0;
}
# Serve static files
location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac|mp4|webm)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463$asset_immutable";
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
access_log off; # Optional: Don't log access to assets
}
location ~ \.(otf|woff2?)$ {
try_files $uri /index.php$request_uri;
expires 7d; # Cache-Control policy borrowed from `.htaccess`
access_log off; # Optional: Don't log access to assets
}
# Rule borrowed from `.htaccess`
location /remote {
return 301 /remote.php$request_uri;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}
}
================================================
FILE: .examples/docker-compose/with-nginx-proxy/mariadb/apache/compose.yaml
================================================
---
services:
# Note: MariaDB is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/mariadb
db:
# Note: Check the recommend version here: https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server
image: mariadb:lts
command: --transaction-isolation=READ-COMMITTED
restart: always
volumes:
- db:/var/lib/mysql:Z
environment:
- MYSQL_ROOT_PASSWORD=
- MARIADB_AUTO_UPGRADE=1
- MARIADB_DISABLE_UPGRADE_BACKUP=1
env_file:
- db.env
# Note: Redis is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/redis
redis:
image: redis:alpine
restart: always
app:
image: nextcloud:apache
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
environment:
- VIRTUAL_HOST=
- LETSENCRYPT_HOST=
- LETSENCRYPT_EMAIL=
- MYSQL_HOST=db
- REDIS_HOST=redis
env_file:
- db.env
depends_on:
- db
- redis
- proxy
networks:
- proxy-tier
- default
cron:
image: nextcloud:apache
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
entrypoint: /cron.sh
depends_on:
- db
- redis
# Note: Nginx-proxy is an external service. You can find more information about the configuration here:
# Warning: Do not use :latest tags of nginx-proxy unless absolutely sure about the consequences.
# https://hub.docker.com/r/nginxproxy/nginx-proxy
proxy:
build: ./proxy
restart: always
ports:
- 80:80
- 443:443
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
volumes:
- certs:/etc/nginx/certs:ro,z
- vhost.d:/etc/nginx/vhost.d:z
- html:/usr/share/nginx/html:z
- dhparam:/etc/nginx/dhparam:z
- /var/run/docker.sock:/tmp/docker.sock:z,ro
networks:
- proxy-tier
# Note: Letsencrypt companion is an external service. You can find more information about the configuration here:
# https://hub.docker.com/r/nginxproxy/acme-companion
letsencrypt-companion:
image: nginxproxy/acme-companion
restart: always
environment:
- DEFAULT_EMAIL=
volumes:
- certs:/etc/nginx/certs:z
- acme:/etc/acme.sh:z
- vhost.d:/etc/nginx/vhost.d:z
- html:/usr/share/nginx/html:z
- /var/run/docker.sock:/var/run/docker.sock:z,ro
networks:
- proxy-tier
depends_on:
- proxy
# self signed,outdated
# omgwtfssl:
# image: paulczar/omgwtfssl
# restart: "no"
# volumes:
# - certs:/certs
# environment:
# - SSL_SUBJECT=servhostname.local
# - CA_SUBJECT=my@example.com
# - SSL_KEY=/certs/servhostname.local.key
# - SSL_CSR=/certs/servhostname.local.csr
# - SSL_CERT=/certs/servhostname.local.crt
# networks:
# - proxy-tier
volumes:
db:
nextcloud:
certs:
acme:
vhost.d:
html:
dhparam:
networks:
proxy-tier:
================================================
FILE: .examples/docker-compose/with-nginx-proxy/mariadb/apache/db.env
================================================
MYSQL_PASSWORD=
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
================================================
FILE: .examples/docker-compose/with-nginx-proxy/mariadb/apache/proxy/Dockerfile
================================================
FROM nginxproxy/nginx-proxy:1.7-alpine
COPY uploadsize.conf /etc/nginx/conf.d/uploadsize.conf
================================================
FILE: .examples/docker-compose/with-nginx-proxy/mariadb/apache/proxy/uploadsize.conf
================================================
client_max_body_size 10G;
proxy_request_buffering off;
================================================
FILE: .examples/docker-compose/with-nginx-proxy/mariadb/fpm/compose.yaml
================================================
---
services:
# Note: MariaDB is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/mariadb
db:
# Note: Check the recommend version here: https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server
image: mariadb:lts
command: --transaction-isolation=READ-COMMITTED
restart: always
volumes:
- db:/var/lib/mysql:Z
environment:
- MYSQL_ROOT_PASSWORD=
- MARIADB_AUTO_UPGRADE=1
- MARIADB_DISABLE_UPGRADE_BACKUP=1
env_file:
- db.env
# Note: Redis is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/redis
redis:
image: redis:alpine
restart: always
app:
image: nextcloud:fpm-alpine
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
environment:
- MYSQL_HOST=db
- REDIS_HOST=redis
env_file:
- db.env
depends_on:
- db
- redis
- proxy
# Note: Nginx is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/nginx/
web:
image: nginx:alpine-slim
restart: always
volumes:
# https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html
- ./web/nginx.conf:/etc/nginx/nginx.conf:ro
# NOTE: The `volumes` included below should match those of the `app` container (unless you know what you're doing)
- nextcloud:/var/www/html:z,ro
environment:
- VIRTUAL_HOST=
- LETSENCRYPT_HOST=
- LETSENCRYPT_EMAIL=
depends_on:
- app
networks:
- proxy-tier
- default
cron:
image: nextcloud:fpm-alpine
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
entrypoint: /cron.sh
depends_on:
- db
- redis
# Note: Nginx-proxy is an external service. You can find more information about the configuration here:
# Warning: Do not use :latest tags of nginx-proxy unless absolutely sure about the consequences.
# https://hub.docker.com/r/nginxproxy/nginx-proxy
proxy:
build: ./proxy
restart: always
ports:
- 80:80
- 443:443
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
volumes:
- certs:/etc/nginx/certs:z,ro
- vhost.d:/etc/nginx/vhost.d:z
- html:/usr/share/nginx/html:z
- /var/run/docker.sock:/tmp/docker.sock:z,ro
networks:
- proxy-tier
# Note: Letsencrypt companion is an external service. You can find more information about the configuration here:
# https://hub.docker.com/r/nginxproxy/acme-companion
letsencrypt-companion:
image: nginxproxy/acme-companion
restart: always
environment:
- DEFAULT_EMAIL=
volumes:
- certs:/etc/nginx/certs:z
- acme:/etc/acme.sh:z
- vhost.d:/etc/nginx/vhost.d:z
- html:/usr/share/nginx/html:z
- /var/run/docker.sock:/var/run/docker.sock:z,ro
networks:
- proxy-tier
depends_on:
- proxy
# self signed, outdated.
# omgwtfssl:
# image: paulczar/omgwtfssl
# restart: "no"
# volumes:
# - certs:/certs
# environment:
# - SSL_SUBJECT=servhostname.local
# - CA_SUBJECT=my@example.com
# - SSL_KEY=/certs/servhostname.local.key
# - SSL_CSR=/certs/servhostname.local.csr
# - SSL_CERT=/certs/servhostname.local.crt
# networks:
# - proxy-tier
volumes:
db:
nextcloud:
certs:
acme:
vhost.d:
html:
networks:
proxy-tier:
================================================
FILE: .examples/docker-compose/with-nginx-proxy/mariadb/fpm/db.env
================================================
MYSQL_PASSWORD=
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
================================================
FILE: .examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/Dockerfile
================================================
FROM nginxproxy/nginx-proxy:1.7-alpine
COPY uploadsize.conf /etc/nginx/conf.d/uploadsize.conf
================================================
FILE: .examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/uploadsize.conf
================================================
client_max_body_size 10G;
proxy_request_buffering off;
================================================
FILE: .examples/docker-compose/with-nginx-proxy/mariadb/fpm/web/nginx.conf
================================================
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
types {
text/javascript mjs;
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
# Prevent nginx HTTP Server Detection
server_tokens off;
keepalive_timeout 65;
# Set the `immutable` cache control options only for assets with a cache busting `v` argument
map $arg_v $asset_immutable {
"" "";
default ", immutable";
}
#gzip on;
resolver 127.0.0.11 valid=2s;
upstream php-handler {
zone backends 64k;
server app:9000 resolve;
}
server {
listen 80;
# HSTS settings
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
# set max upload size and increase upload timeout:
client_max_body_size 512M;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
# The settings allows you to optimize the HTTP2 bandwidth.
# See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
# for tuning hints
client_body_buffer_size 512k;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Pagespeed is not supported by Nextcloud, so if your server is built
# with the `ngx_pagespeed` module, uncomment this line to disable it.
#pagespeed off;
# HTTP response headers borrowed from Nextcloud `.htaccess`
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
# Path to the root of your installation
root /var/www/html;
# Specify how to handle directories -- specifying `/index.php$request_uri`
# here as the fallback means that Nginx always exhibits the desired behaviour
# when a client requests a path that corresponds to a directory that exists
# on the server. In particular, if that directory contains an index.php file,
# that file is correctly served; if it doesn't, then the request is passed to
# the front-end controller. This consistent behaviour means that we don't need
# to specify custom rules for certain paths (e.g. images and other assets,
# `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
# `try_files $uri $uri/ /index.php$request_uri`
# always provides the desired behaviour.
index index.php index.html /index.php$request_uri;
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Make a regex exception for `/.well-known` so that clients can still
# access it despite the existence of the regex rule
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
# for `/.well-known`.
location ^~ /.well-known {
# The rules in this block are an adaptation of the rules
# in `.htaccess` that concern `/.well-known`.
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
# Let Nextcloud's API for `/.well-known` URIs handle all other
# requests by passing them to the front-end controller.
return 301 /index.php$request_uri;
}
# Rules borrowed from `.htaccess` to hide certain paths from clients
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
# which handle static assets (as seen below). If this block is not declared first,
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
# to the URI, resulting in a HTTP 500 error response.
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering on; # Required as PHP-FPM does not support chunked transfer encoding and requires a valid ContentLength header.
fastcgi_max_temp_file_size 0;
}
# Serve static files
location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac|mp4|webm)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463$asset_immutable";
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
access_log off; # Optional: Don't log access to assets
}
location ~ \.(otf|woff2?)$ {
try_files $uri /index.php$request_uri;
expires 7d; # Cache-Control policy borrowed from `.htaccess`
access_log off; # Optional: Don't log access to assets
}
# Rule borrowed from `.htaccess`
location /remote {
return 301 /remote.php$request_uri;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}
}
================================================
FILE: .examples/docker-compose/with-nginx-proxy/postgres/apache/compose.yaml
================================================
---
services:
# Note: PostgreSQL is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/postgres
db:
# Note: Check the recommend version here: https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server
image: postgres:alpine
restart: always
volumes:
- db:/var/lib/postgresql/data:Z
env_file:
- db.env
# Note: Redis is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/redis
redis:
image: redis:alpine
restart: always
app:
image: nextcloud:apache
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
environment:
- VIRTUAL_HOST=
- LETSENCRYPT_HOST=
- LETSENCRYPT_EMAIL=
- POSTGRES_HOST=db
- REDIS_HOST=redis
env_file:
- db.env
depends_on:
- db
- redis
- proxy
networks:
- proxy-tier
- default
cron:
image: nextcloud:apache
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
entrypoint: /cron.sh
depends_on:
- db
- redis
# Note: Nginx-proxy is an external service. You can find more information about the configuration here:
# Warning: Do not use :latest tags of nginx-proxy unless absolutely sure about the consequences.
# https://hub.docker.com/r/nginxproxy/nginx-proxy
proxy:
build: ./proxy
restart: always
ports:
- 80:80
- 443:443
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
volumes:
- certs:/etc/nginx/certs:ro,z
- vhost.d:/etc/nginx/vhost.d:z
- html:/usr/share/nginx/html:z
- /var/run/docker.sock:/tmp/docker.sock:z,ro
networks:
- proxy-tier
# Note: Letsencrypt companion is an external service. You can find more information about the configuration here:
# https://hub.docker.com/r/nginxproxy/acme-companion
letsencrypt-companion:
image: nginxproxy/acme-companion
restart: always
volumes:
- certs:/etc/nginx/certs:z
- acme:/etc/acme.sh:z
- vhost.d:/etc/nginx/vhost.d:z
- html:/usr/share/nginx/html:z
- /var/run/docker.sock:/var/run/docker.sock:z,ro
networks:
- proxy-tier
depends_on:
- proxy
# self signed, outdated
# omgwtfssl:
# image: paulczar/omgwtfssl
# restart: "no"
# volumes:
# - certs:/certs
# environment:
# - SSL_SUBJECT=servhostname.local
# - CA_SUBJECT=my@example.com
# - SSL_KEY=/certs/servhostname.local.key
# - SSL_CSR=/certs/servhostname.local.csr
# - SSL_CERT=/certs/servhostname.local.crt
# networks:
# - proxy-tier
volumes:
db:
nextcloud:
certs:
acme:
vhost.d:
html:
networks:
proxy-tier:
================================================
FILE: .examples/docker-compose/with-nginx-proxy/postgres/apache/db.env
================================================
POSTGRES_PASSWORD=
POSTGRES_DB=nextcloud
POSTGRES_USER=nextcloud
================================================
FILE: .examples/docker-compose/with-nginx-proxy/postgres/apache/proxy/Dockerfile
================================================
FROM nginxproxy/nginx-proxy:1.7-alpine
COPY uploadsize.conf /etc/nginx/conf.d/uploadsize.conf
================================================
FILE: .examples/docker-compose/with-nginx-proxy/postgres/apache/proxy/uploadsize.conf
================================================
client_max_body_size 10G;
proxy_request_buffering off;
================================================
FILE: .examples/docker-compose/with-nginx-proxy/postgres/fpm/compose.yaml
================================================
---
services:
# Note: PostgreSQL is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/postgres
db:
# Note: Check the recommend version here: https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server
image: postgres:alpine
restart: always
volumes:
- db:/var/lib/postgresql/data:Z
env_file:
- db.env
# Note: Redis is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/redis
redis:
image: redis:alpine
restart: always
app:
image: nextcloud:fpm-alpine
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
environment:
- POSTGRES_HOST=db
- REDIS_HOST=redis
env_file:
- db.env
depends_on:
- db
- redis
- proxy
# Note: Nginx is an external service. You can find more information about the configuration here:
# https://hub.docker.com/_/nginx/
web:
image: nginx:alpine-slim
restart: always
volumes:
# https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html
- ./web/nginx.conf:/etc/nginx/nginx.conf:ro
# NOTE: The `volumes` included below should match those of the `app` container (unless you know what you're doing)
- nextcloud:/var/www/html:z,ro
environment:
- VIRTUAL_HOST=
- LETSENCRYPT_HOST=
- LETSENCRYPT_EMAIL=
depends_on:
- app
networks:
- proxy-tier
- default
cron:
image: nextcloud:fpm-alpine
restart: always
volumes:
- nextcloud:/var/www/html:z
# NOTE: The `volumes` config of the `cron` and `app` containers must match
entrypoint: /cron.sh
depends_on:
- db
- redis
# Note: Nginx-proxy is an external service. You can find more information about the configuration here:
# Warning: Do not use :latest tags of nginx-proxy unless absolutely sure about the consequences.
# https://hub.docker.com/r/nginxproxy/nginx-proxy
proxy:
build: ./proxy
restart: always
ports:
- 80:80
- 443:443
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
volumes:
- certs:/etc/nginx/certs:z,ro
- vhost.d:/etc/nginx/vhost.d:z
- html:/usr/share/nginx/html:z
- /var/run/docker.sock:/tmp/docker.sock:z,ro
networks:
- proxy-tier
# Note: Letsencrypt companion is an external service. You can find more information about the configuration here:
# https://hub.docker.com/r/nginxproxy/acme-companion
letsencrypt-companion:
image: nginxproxy/acme-companion
restart: always
volumes:
- certs:/etc/nginx/certs:z
- acme:/etc/acme.sh:z
- vhost.d:/etc/nginx/vhost.d:z
- html:/usr/share/nginx/html:z
- /var/run/docker.sock:/var/run/docker.sock:z,ro
environment:
- DEFAULT_EMAIL=
networks:
- proxy-tier
depends_on:
- proxy
# self signed, outdated
# omgwtfssl:
# image: paulczar/omgwtfssl
# restart: "no"
# volumes:
# - certs:/certs
# environment:
# - SSL_SUBJECT=servhostname.local
# - CA_SUBJECT=my@example.com
# - SSL_KEY=/certs/servhostname.local.key
# - SSL_CSR=/certs/servhostname.local.csr
# - SSL_CERT=/certs/servhostname.local.crt
# networks:
# - proxy-tier
volumes:
db:
nextcloud:
certs:
acme:
vhost.d:
html:
networks:
proxy-tier:
================================================
FILE: .examples/docker-compose/with-nginx-proxy/postgres/fpm/db.env
================================================
POSTGRES_PASSWORD=
POSTGRES_DB=nextcloud
POSTGRES_USER=nextcloud
================================================
FILE: .examples/docker-compose/with-nginx-proxy/postgres/fpm/proxy/Dockerfile
================================================
FROM nginxproxy/nginx-proxy:1.7-alpine
COPY uploadsize.conf /etc/nginx/conf.d/uploadsize.conf
================================================
FILE: .examples/docker-compose/with-nginx-proxy/postgres/fpm/proxy/uploadsize.conf
================================================
client_max_body_size 10G;
proxy_request_buffering off;
================================================
FILE: .examples/docker-compose/with-nginx-proxy/postgres/fpm/web/nginx.conf
================================================
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
types {
text/javascript mjs;
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
# Prevent nginx HTTP Server Detection
server_tokens off;
keepalive_timeout 65;
# Set the `immutable` cache control options only for assets with a cache busting `v` argument
map $arg_v $asset_immutable {
"" "";
default ", immutable";
}
#gzip on;
resolver 127.0.0.11 valid=2s;
upstream php-handler {
zone backends 64k;
server app:9000 resolve;
}
server {
listen 80;
# HSTS settings
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
# set max upload size and increase upload timeout:
client_max_body_size 512M;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
# The settings allows you to optimize the HTTP2 bandwidth.
# See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
# for tuning hints
client_body_buffer_size 512k;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Pagespeed is not supported by Nextcloud, so if your server is built
# with the `ngx_pagespeed` module, uncomment this line to disable it.
#pagespeed off;
# HTTP response headers borrowed from Nextcloud `.htaccess`
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
# Path to the root of your installation
root /var/www/html;
# Specify how to handle directories -- specifying `/index.php$request_uri`
# here as the fallback means that Nginx always exhibits the desired behaviour
# when a client requests a path that corresponds to a directory that exists
# on the server. In particular, if that directory contains an index.php file,
# that file is correctly served; if it doesn't, then the request is passed to
# the front-end controller. This consistent behaviour means that we don't need
# to specify custom rules for certain paths (e.g. images and other assets,
# `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
# `try_files $uri $uri/ /index.php$request_uri`
# always provides the desired behaviour.
index index.php index.html /index.php$request_uri;
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Make a regex exception for `/.well-known` so that clients can still
# access it despite the existence of the regex rule
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
# for `/.well-known`.
location ^~ /.well-known {
# The rules in this block are an adaptation of the rules
# in `.htaccess` that concern `/.well-known`.
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
# Let Nextcloud's API for `/.well-known` URIs handle all other
# requests by passing them to the front-end controller.
return 301 /index.php$request_uri;
}
# Rules borrowed from `.htaccess` to hide certain paths from clients
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
# which handle static assets (as seen below). If this block is not declared first,
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
# to the URI, resulting in a HTTP 500 error response.
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering on; # Required as PHP-FPM does not support chunked transfer encoding and requires a valid ContentLength header.
fastcgi_max_temp_file_size 0;
}
# Serve static files
location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac|mp4|webm)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463$asset_immutable";
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
access_log off; # Optional: Don't log access to assets
}
location ~ \.(otf|woff2?)$ {
try_files $uri /index.php$request_uri;
expires 7d; # Cache-Control policy borrowed from `.htaccess`
access_log off; # Optional: Don't log access to assets
}
# Rule borrowed from `.htaccess`
location /remote {
return 301 /remote.php$request_uri;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}
}
================================================
FILE: .examples/dockerfiles/cron/apache/Dockerfile
================================================
FROM nextcloud:apache
RUN apt-get update && apt-get install -y \
supervisor \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir /var/log/supervisord /var/run/supervisord
COPY supervisord.conf /
ENV NEXTCLOUD_UPDATE=1
CMD ["/usr/bin/supervisord", "-c", "/supervisord.conf"]
================================================
FILE: .examples/dockerfiles/cron/apache/supervisord.conf
================================================
[supervisord]
nodaemon=true
logfile=/var/log/supervisord/supervisord.log
pidfile=/var/run/supervisord/supervisord.pid
childlogdir=/var/log/supervisord/
logfile_maxbytes=50MB ; maximum size of logfile before rotation
logfile_backups=10 ; number of backed up logfiles
loglevel=error
[program:apache2]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=apache2-foreground
[program:cron]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=/cron.sh
================================================
FILE: .examples/dockerfiles/cron/fpm/Dockerfile
================================================
FROM nextcloud:fpm
RUN apt-get update && apt-get install -y \
supervisor \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir /var/log/supervisord /var/run/supervisord
COPY supervisord.conf /
ENV NEXTCLOUD_UPDATE=1
CMD ["/usr/bin/supervisord", "-c", "/supervisord.conf"]
================================================
FILE: .examples/dockerfiles/cron/fpm/supervisord.conf
================================================
[supervisord]
nodaemon=true
logfile=/var/log/supervisord/supervisord.log
pidfile=/var/run/supervisord/supervisord.pid
childlogdir=/var/log/supervisord/
logfile_maxbytes=50MB ; maximum size of logfile before rotation
logfile_backups=10 ; number of backed up logfiles
loglevel=error
[program:php-fpm]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=php-fpm
[program:cron]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=/cron.sh
================================================
FILE: .examples/dockerfiles/cron/fpm-alpine/Dockerfile
================================================
FROM nextcloud:fpm-alpine
RUN apk add --no-cache supervisor \
&& mkdir /var/log/supervisord /var/run/supervisord
COPY supervisord.conf /
ENV NEXTCLOUD_UPDATE=1
CMD ["/usr/bin/supervisord", "-c", "/supervisord.conf"]
================================================
FILE: .examples/dockerfiles/cron/fpm-alpine/supervisord.conf
================================================
[supervisord]
nodaemon=true
logfile=/var/log/supervisord/supervisord.log
pidfile=/var/run/supervisord/supervisord.pid
childlogdir=/var/log/supervisord/
logfile_maxbytes=50MB ; maximum size of logfile before rotation
logfile_backups=10 ; number of backed up logfiles
loglevel=error
[program:php-fpm]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=php-fpm
[program:cron]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=/cron.sh
================================================
FILE: .examples/dockerfiles/full/apache/Dockerfile
================================================
FROM nextcloud:apache
RUN set -ex; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
ffmpeg \
ghostscript \
libmagickcore-6.q16-6-extra \
procps \
smbclient \
supervisor \
# libreoffice \
; \
rm -rf /var/lib/apt/lists/*
RUN set -ex; \
\
savedAptMark="$(apt-mark showmanual)"; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
libbz2-dev \
libc-client-dev \
libkrb5-dev \
libsmbclient-dev \
; \
\
docker-php-ext-configure imap --with-kerberos --with-imap-ssl; \
docker-php-ext-install \
bz2 \
imap \
; \
pecl install smbclient; \
docker-php-ext-enable smbclient; \
\
# 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/*
RUN mkdir -p \
/var/log/supervisord \
/var/run/supervisord \
;
COPY supervisord.conf /
ENV NEXTCLOUD_UPDATE=1
CMD ["/usr/bin/supervisord", "-c", "/supervisord.conf"]
================================================
FILE: .examples/dockerfiles/full/apache/supervisord.conf
================================================
[supervisord]
nodaemon=true
logfile=/var/log/supervisord/supervisord.log
pidfile=/var/run/supervisord/supervisord.pid
childlogdir=/var/log/supervisord/
logfile_maxbytes=50MB ; maximum size of logfile before rotation
logfile_backups=10 ; number of backed up logfiles
loglevel=error
[program:apache2]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=apache2-foreground
[program:cron]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=/cron.sh
================================================
FILE: .examples/dockerfiles/full/fpm/Dockerfile
================================================
FROM nextcloud:fpm
RUN set -ex; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
ffmpeg \
ghostscript \
libmagickcore-6.q16-6-extra \
procps \
smbclient \
supervisor \
# libreoffice \
; \
rm -rf /var/lib/apt/lists/*
RUN set -ex; \
\
savedAptMark="$(apt-mark showmanual)"; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
libbz2-dev \
libc-client-dev \
libkrb5-dev \
libsmbclient-dev \
; \
\
docker-php-ext-configure imap --with-kerberos --with-imap-ssl; \
docker-php-ext-install \
bz2 \
imap \
; \
pecl install smbclient; \
docker-php-ext-enable smbclient; \
\
# 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/*
RUN mkdir -p \
/var/log/supervisord \
/var/run/supervisord \
;
COPY supervisord.conf /
ENV NEXTCLOUD_UPDATE=1
CMD ["/usr/bin/supervisord", "-c", "/supervisord.conf"]
================================================
FILE: .examples/dockerfiles/full/fpm/supervisord.conf
================================================
[supervisord]
nodaemon=true
logfile=/var/log/supervisord/supervisord.log
pidfile=/var/run/supervisord/supervisord.pid
childlogdir=/var/log/supervisord/
logfile_maxbytes=50MB ; maximum size of logfile before rotation
logfile_backups=10 ; number of backed up logfiles
loglevel=error
[program:php-fpm]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=php-fpm
[program:cron]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=/cron.sh
================================================
FILE: .examples/dockerfiles/full/fpm-alpine/Dockerfile
================================================
FROM nextcloud:fpm-alpine
RUN set -ex; \
\
apk add --no-cache \
ffmpeg \
imagemagick \
procps \
samba-client \
supervisor \
# libreoffice \
;
RUN set -ex; \
\
apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
imap-dev \
krb5-dev \
openssl-dev \
samba-dev \
bzip2-dev \
; \
\
docker-php-ext-configure imap --with-kerberos --with-imap-ssl; \
docker-php-ext-install \
bz2 \
imap \
; \
pecl install smbclient; \
docker-php-ext-enable smbclient; \
\
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 --virtual .nextcloud-phpext-rundeps $runDeps; \
apk del .build-deps
RUN mkdir -p \
/var/log/supervisord \
/var/run/supervisord \
;
COPY supervisord.conf /
ENV NEXTCLOUD_UPDATE=1
CMD ["/usr/bin/supervisord", "-c", "/supervisord.conf"]
================================================
FILE: .examples/dockerfiles/full/fpm-alpine/supervisord.conf
================================================
[supervisord]
nodaemon=true
logfile=/var/log/supervisord/supervisord.log
pidfile=/var/run/supervisord/supervisord.pid
childlogdir=/var/log/supervisord/
logfile_maxbytes=50MB ; maximum size of logfile before rotation
logfile_backups=10 ; number of backed up logfiles
loglevel=error
[program:php-fpm]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=php-fpm
[program:cron]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=/cron.sh
================================================
FILE: .examples/dockerfiles/imap/apache/Dockerfile
================================================
FROM nextcloud:apache
RUN set -ex; \
\
savedAptMark="$(apt-mark showmanual)"; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
libc-client-dev \
libkrb5-dev \
; \
\
docker-php-ext-configure imap --with-kerberos --with-imap-ssl; \
docker-php-ext-install imap; \
\
# 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/*
================================================
FILE: .examples/dockerfiles/imap/fpm/Dockerfile
================================================
FROM nextcloud:fpm
RUN set -ex; \
\
savedAptMark="$(apt-mark showmanual)"; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
libc-client-dev \
libkrb5-dev \
; \
\
docker-php-ext-configure imap --with-kerberos --with-imap-ssl; \
docker-php-ext-install imap; \
\
# 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/*
================================================
FILE: .examples/dockerfiles/imap/fpm-alpine/Dockerfile
================================================
FROM nextcloud:fpm-alpine
RUN set -ex; \
\
apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
imap-dev \
krb5-dev \
openssl-dev \
; \
\
docker-php-ext-configure imap --with-kerberos --with-imap-ssl; \
docker-php-ext-install imap; \
\
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 --virtual .nextcloud-phpext-rundeps $runDeps; \
apk del .build-deps
================================================
FILE: .examples/dockerfiles/smb/apache/Dockerfile
================================================
FROM nextcloud:apache
RUN apt-get update && apt-get install -y procps smbclient && rm -rf /var/lib/apt/lists/*
================================================
FILE: .examples/dockerfiles/smb/fpm/Dockerfile
================================================
FROM nextcloud:fpm
RUN apt-get update && apt-get install -y procps smbclient && rm -rf /var/lib/apt/lists/*
================================================
FILE: .examples/dockerfiles/smb/fpm-alpine/Dockerfile
================================================
FROM nextcloud:fpm-alpine
RUN apk add --no-cache procps samba-client
================================================
FILE: .github/ISSUE_TEMPLATE/01-Image_issue.md
================================================
---
name: 🐛 Report a bug in the image
about: Create a report to help us improve the image
labels: "bug, 0. Needs triage"
---
<!--
Thanks for reporting issues back to Nextcloud!
When reporting problems, please include your *complete* Docker Compose file (or run commands) and your Nextcloud Server config (e.g. `occ config:list system`). Incomplete reports cause extra work for all parties involved and delay resolution.
Note: This is the issue tracker of the official Nextcloud **Docker image**, please do NOT use this to report issues with Docker or Nextcloud Server itself. You can find help debugging your system on our forums: https://help.nextcloud.com/ or https://forums.docker.com/.
To learn more about official images, see https://github.com/docker-library/faq
-->
================================================
FILE: .github/ISSUE_TEMPLATE/02-Image_enhancement
================================================
---
name: 🚀 Suggest an enhancement
about: Suggest an idea for improving the image
labels: "enhancement, 0. Needs triage"
---
<!--
Thanks for suggesting an idea to improve the Nextcloud Docker image!
This image is maintained by volunteers so if you're able to assist with implementing your idea, please mention that (and consider submitting a PR as well).
Note: This is the issue tracker of the official Nextcloud **Docker image**, please do NOT use this to suggestion enhancements in Nextcloud Server itself.
To learn more about official images, see https://github.com/docker-library/faq
-->
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
contact_links:
- name: ❓ Ask a question
url: https://help.nextcloud.com/
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
================================================
FILE: .github/workflows/images.yml
================================================
---
name: Images
on:
pull_request:
workflow_run:
workflows: ["update.sh"]
branches: [master]
types:
- completed
defaults:
run:
shell: 'bash -Eeuo pipefail -x {0}'
jobs:
init:
name: Generate Jobs
runs-on: ubuntu-latest
outputs:
strategy: ${{ steps.generate-jobs.outputs.strategy }}
steps:
- uses: actions/checkout@v4
- uses: docker-library/bashbrew@HEAD
- id: generate-jobs
name: Generate Jobs
run: |
strategy="$(GITHUB_REPOSITORY=nextcloud "$BASHBREW_SCRIPTS/github-actions/generate.sh")"
strategy="$("$BASHBREW_SCRIPTS/github-actions/munge-i386.sh" -c <<<"$strategy")"
echo "strategy=$strategy" >> "$GITHUB_OUTPUT"
jq . <<<"$strategy" # sanity check / debugging aid
test:
needs: init
strategy: ${{ fromJson(needs.init.outputs.strategy) }}
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Prepare Environment
run: ${{ matrix.runs.prepare }}
- name: Run update.sh script
run: ./update.sh
- name: Pull Dependencies
run: ${{ matrix.runs.pull }}
- name: Build ${{ matrix.name }}
run: ${{ matrix.runs.build }}
- name: History ${{ matrix.name }}
run: ${{ matrix.runs.history }}
- name: Test ${{ matrix.name }}
run: ${{ matrix.runs.test }}
- name: '"docker images"'
run: ${{ matrix.runs.images }}
summary:
runs-on: ubuntu-latest
needs: test
if: always()
name: images-test-summary
steps:
- name: Summary status
run: if ${{ needs.test.result != 'success' && needs.test.result != 'skipped' }}; then exit 1; fi
================================================
FILE: .github/workflows/update-sh.yml
================================================
---
name: update.sh
on:
push:
branches:
- master
schedule:
- cron: '15 18 * * *'
workflow_dispatch:
jobs:
run_update_sh:
name: Run update.sh script
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run update.sh script
run: ./update.sh
- name: Commit files
run: |
git config --local user.email "workflow@github.com"
git config --local user.name "GitHub Workflow"
git add -A
git commit -m "Runs update.sh" || echo "Nothing to update"
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
force: true
================================================
FILE: 31/apache/Dockerfile
================================================
# DO NOT EDIT: created by update.sh from Dockerfile-debian.template
FROM php:8.3-apache-trixie
# 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-7.q16-10-extra \
rsync \
; \
apt-get dist-clean; \
\
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 \
liblz4-dev \
libmagickwand-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 \
pcntl \
pdo_mysql \
pdo_pgsql \
sysvsem \
zip \
; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.28; \
pecl install igbinary-3.2.16; \
pecl install imagick-3.8.1; \
pecl install --configureoptions 'enable-memcached-igbinary="yes"' \
memcached-3.4.0; \
pecl install --configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"' \
redis-6.3.0; \
\
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 -rt dpkg-query --search \
# https://manpages.debian.org/trixie/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file)
| awk 'sub(":$", "", $1) { print $1 }' \
| sort -u \
| xargs -rt apt-mark manual; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
apt-get dist-clean
# 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.14
RUN set -ex; \
fetchDeps=" \
gnupg \
dirmngr \
"; \
apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \
\
curl -fsSL -o nextcloud.tar.bz2 "https://github.com/nextcloud-releases/server/releases/download/v31.0.14/nextcloud-31.0.14.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://github.com/nextcloud-releases/server/releases/download/v31.0.14/nextcloud-31.0.14.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; \
apt-get dist-clean
COPY *.sh upgrade.exclude /
COPY config/* /usr/src/nextcloud/config/
ENTRYPOINT ["/entrypoint.sh"]
CMD ["apache2-foreground"]
================================================
FILE: 31/apache/config/apache-pretty-urls.config.php
================================================
<?php
$CONFIG = array (
'htaccess.RewriteBase' => '/',
);
================================================
FILE: 31/apache/config/apcu.config.php
================================================
<?php
$CONFIG = array (
'memcache.local' => '\OC\Memcache\APCu',
);
================================================
FILE: 31/apache/config/apps.config.php
================================================
<?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,
),
),
);
================================================
FILE: 31/apache/config/autoconfig.php
================================================
<?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';
}
================================================
FILE: 31/apache/config/redis.config.php
================================================
<?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');
}
}
================================================
FILE: 31/apache/config/reverse-proxy.config.php
================================================
<?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)));
}
================================================
FILE: 31/apache/config/s3.config.php
================================================
<?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');
}
}
================================================
FILE: 31/apache/config/smtp.config.php
================================================
<?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'] = '';
}
}
================================================
FILE: 31/apache/config/swift.config.php
================================================
<?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'),
]
]
);
}
================================================
FILE: 31/apache/config/upgrade-disable-web.config.php
================================================
<?php
$CONFIG = array (
'upgrade.disable-web' => true,
);
================================================
FILE: 31/apache/cron.sh
================================================
#!/bin/sh
set -eu
exec busybox crond -f -L /dev/stdout
================================================
FILE: 31/apache/entrypoint.sh
================================================
#!/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
local found=0
echo "=> Searching for hook scripts (*.sh) to run, located in the folder \"${hook_folder_path}\""
if ! [ -d "${hook_folder_path}" ] || directory_empty "${hook_folder_path}"; then
echo "==> Skipped: the \"$1\" folder is empty (or does not exist)"
return 0
fi
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 lacks the executable flag"
found=$((found-1))
continue
fi
echo "==> Running the script (cwd: $(pwd)): \"${script_file_path}\""
found=$((found+1))
run_as "${script_file_path}" || return_code="$?"
if [ "${return_code}" -ne "0" ]; then
echo "==> Failed at executing script \"${script_file_path}\". Exit code: ${return_code}"
exit 1
fi
echo "==> Finished executing the script: \"${script_file_path}\""
done
if [ "$found" -lt "1" ]; then
echo "==> Skipped: the \"$1\" folder does not contain any valid scripts"
else
echo "=> Completed executing scripts in the \"$1\" folder"
fi
)
}
# 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
if [ -n "${REDIS_HOST_USER+x}" ]; then
echo "session.save_path = \"unix://${REDIS_HOST}?auth[]=${REDIS_HOST_USER}&auth[]=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"unix://${REDIS_HOST}?auth=${REDIS_HOST_PASSWORD}\""
fi
else
echo "session.save_path = \"unix://${REDIS_HOST}\""
fi
# check if redis password has been set
elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
if [ -n "${REDIS_HOST_USER+x}" ]; then
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth[]=${REDIS_HOST_USER}&auth[]=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth=${REDIS_HOST_PASSWORD}\""
fi
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…"
set -f # turn off glob
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
set +f # turn glob back on
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 "$@"
================================================
FILE: 31/apache/upgrade.exclude
================================================
/config/
/data/
/custom_apps/
/themes/
/version.php
/nextcloud-init-sync.lock
================================================
FILE: 31/fpm/Dockerfile
================================================
# DO NOT EDIT: created by update.sh from Dockerfile-debian.template
FROM php:8.3-fpm-trixie
# 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-7.q16-10-extra \
rsync \
; \
apt-get dist-clean; \
\
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 \
liblz4-dev \
libmagickwand-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 \
pcntl \
pdo_mysql \
pdo_pgsql \
sysvsem \
zip \
; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.28; \
pecl install igbinary-3.2.16; \
pecl install imagick-3.8.1; \
pecl install --configureoptions 'enable-memcached-igbinary="yes"' \
memcached-3.4.0; \
pecl install --configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"' \
redis-6.3.0; \
\
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 -rt dpkg-query --search \
# https://manpages.debian.org/trixie/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file)
| awk 'sub(":$", "", $1) { print $1 }' \
| sort -u \
| xargs -rt apt-mark manual; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
apt-get dist-clean
# 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.14
RUN set -ex; \
fetchDeps=" \
gnupg \
dirmngr \
"; \
apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \
\
curl -fsSL -o nextcloud.tar.bz2 "https://github.com/nextcloud-releases/server/releases/download/v31.0.14/nextcloud-31.0.14.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://github.com/nextcloud-releases/server/releases/download/v31.0.14/nextcloud-31.0.14.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; \
apt-get dist-clean
COPY *.sh upgrade.exclude /
COPY config/* /usr/src/nextcloud/config/
ENTRYPOINT ["/entrypoint.sh"]
CMD ["php-fpm"]
================================================
FILE: 31/fpm/config/apcu.config.php
================================================
<?php
$CONFIG = array (
'memcache.local' => '\OC\Memcache\APCu',
);
================================================
FILE: 31/fpm/config/apps.config.php
================================================
<?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,
),
),
);
================================================
FILE: 31/fpm/config/autoconfig.php
================================================
<?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';
}
================================================
FILE: 31/fpm/config/redis.config.php
================================================
<?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');
}
}
================================================
FILE: 31/fpm/config/reverse-proxy.config.php
================================================
<?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)));
}
================================================
FILE: 31/fpm/config/s3.config.php
================================================
<?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');
}
}
================================================
FILE: 31/fpm/config/smtp.config.php
================================================
<?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'] = '';
}
}
================================================
FILE: 31/fpm/config/swift.config.php
================================================
<?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'),
]
]
);
}
================================================
FILE: 31/fpm/config/upgrade-disable-web.config.php
================================================
<?php
$CONFIG = array (
'upgrade.disable-web' => true,
);
================================================
FILE: 31/fpm/cron.sh
================================================
#!/bin/sh
set -eu
exec busybox crond -f -L /dev/stdout
================================================
FILE: 31/fpm/entrypoint.sh
================================================
#!/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
local found=0
echo "=> Searching for hook scripts (*.sh) to run, located in the folder \"${hook_folder_path}\""
if ! [ -d "${hook_folder_path}" ] || directory_empty "${hook_folder_path}"; then
echo "==> Skipped: the \"$1\" folder is empty (or does not exist)"
return 0
fi
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 lacks the executable flag"
found=$((found-1))
continue
fi
echo "==> Running the script (cwd: $(pwd)): \"${script_file_path}\""
found=$((found+1))
run_as "${script_file_path}" || return_code="$?"
if [ "${return_code}" -ne "0" ]; then
echo "==> Failed at executing script \"${script_file_path}\". Exit code: ${return_code}"
exit 1
fi
echo "==> Finished executing the script: \"${script_file_path}\""
done
if [ "$found" -lt "1" ]; then
echo "==> Skipped: the \"$1\" folder does not contain any valid scripts"
else
echo "=> Completed executing scripts in the \"$1\" folder"
fi
)
}
# 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
if [ -n "${REDIS_HOST_USER+x}" ]; then
echo "session.save_path = \"unix://${REDIS_HOST}?auth[]=${REDIS_HOST_USER}&auth[]=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"unix://${REDIS_HOST}?auth=${REDIS_HOST_PASSWORD}\""
fi
else
echo "session.save_path = \"unix://${REDIS_HOST}\""
fi
# check if redis password has been set
elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
if [ -n "${REDIS_HOST_USER+x}" ]; then
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth[]=${REDIS_HOST_USER}&auth[]=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth=${REDIS_HOST_PASSWORD}\""
fi
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…"
set -f # turn off glob
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
set +f # turn glob back on
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 "$@"
================================================
FILE: 31/fpm/upgrade.exclude
================================================
/config/
/data/
/custom_apps/
/themes/
/version.php
/nextcloud-init-sync.lock
================================================
FILE: 31/fpm-alpine/Dockerfile
================================================
# DO NOT EDIT: created by update.sh from Dockerfile-alpine.template
FROM php:8.3-fpm-alpine3.23
# 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 \
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 \
pcntl \
pdo_mysql \
pdo_pgsql \
sysvsem \
zip \
; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.28; \
pecl install igbinary-3.2.16; \
pecl install imagick-3.8.1; \
pecl install --configureoptions 'enable-memcached-igbinary="yes"' \
memcached-3.4.0; \
pecl install --configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"' \
redis-6.3.0; \
\
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.14
RUN set -ex; \
apk add --no-cache --virtual .fetch-deps \
bzip2 \
gnupg \
; \
\
curl -fsSL -o nextcloud.tar.bz2 "https://github.com/nextcloud-releases/server/releases/download/v31.0.14/nextcloud-31.0.14.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://github.com/nextcloud-releases/server/releases/download/v31.0.14/nextcloud-31.0.14.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"]
================================================
FILE: 31/fpm-alpine/config/apcu.config.php
================================================
<?php
$CONFIG = array (
'memcache.local' => '\OC\Memcache\APCu',
);
================================================
FILE: 31/fpm-alpine/config/apps.config.php
================================================
<?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,
),
),
);
================================================
FILE: 31/fpm-alpine/config/autoconfig.php
================================================
<?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';
}
================================================
FILE: 31/fpm-alpine/config/redis.config.php
================================================
<?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');
}
}
================================================
FILE: 31/fpm-alpine/config/reverse-proxy.config.php
================================================
<?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)));
}
================================================
FILE: 31/fpm-alpine/config/s3.config.php
================================================
<?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');
}
}
================================================
FILE: 31/fpm-alpine/config/smtp.config.php
================================================
<?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'] = '';
}
}
================================================
FILE: 31/fpm-alpine/config/swift.config.php
================================================
<?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'),
]
]
);
}
================================================
FILE: 31/fpm-alpine/config/upgrade-disable-web.config.php
================================================
<?php
$CONFIG = array (
'upgrade.disable-web' => true,
);
================================================
FILE: 31/fpm-alpine/cron.sh
================================================
#!/bin/sh
set -eu
exec busybox crond -f -L /dev/stdout
================================================
FILE: 31/fpm-alpine/entrypoint.sh
================================================
#!/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
local found=0
echo "=> Searching for hook scripts (*.sh) to run, located in the folder \"${hook_folder_path}\""
if ! [ -d "${hook_folder_path}" ] || directory_empty "${hook_folder_path}"; then
echo "==> Skipped: the \"$1\" folder is empty (or does not exist)"
return 0
fi
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 lacks the executable flag"
found=$((found-1))
continue
fi
echo "==> Running the script (cwd: $(pwd)): \"${script_file_path}\""
found=$((found+1))
run_as "${script_file_path}" || return_code="$?"
if [ "${return_code}" -ne "0" ]; then
echo "==> Failed at executing script \"${script_file_path}\". Exit code: ${return_code}"
exit 1
fi
echo "==> Finished executing the script: \"${script_file_path}\""
done
if [ "$found" -lt "1" ]; then
echo "==> Skipped: the \"$1\" folder does not contain any valid scripts"
else
echo "=> Completed executing scripts in the \"$1\" folder"
fi
)
}
# 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
if [ -n "${REDIS_HOST_USER+x}" ]; then
echo "session.save_path = \"unix://${REDIS_HOST}?auth[]=${REDIS_HOST_USER}&auth[]=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"unix://${REDIS_HOST}?auth=${REDIS_HOST_PASSWORD}\""
fi
else
echo "session.save_path = \"unix://${REDIS_HOST}\""
fi
# check if redis password has been set
elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
if [ -n "${REDIS_HOST_USER+x}" ]; then
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth[]=${REDIS_HOST_USER}&auth[]=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth=${REDIS_HOST_PASSWORD}\""
fi
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…"
set -f # turn off glob
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
set +f # turn glob back on
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 "$@"
================================================
FILE: 31/fpm-alpine/upgrade.exclude
================================================
/config/
/data/
/custom_apps/
/themes/
/version.php
/nextcloud-init-sync.lock
================================================
FILE: 32/apache/Dockerfile
================================================
# DO NOT EDIT: created by update.sh from Dockerfile-debian.template
FROM php:8.3-apache-trixie
# 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-7.q16-10-extra \
rsync \
; \
apt-get dist-clean; \
\
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 \
liblz4-dev \
libmagickwand-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 \
pcntl \
pdo_mysql \
pdo_pgsql \
sysvsem \
zip \
; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.28; \
pecl install igbinary-3.2.16; \
pecl install imagick-3.8.1; \
pecl install --configureoptions 'enable-memcached-igbinary="yes"' \
memcached-3.4.0; \
pecl install --configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"' \
redis-6.3.0; \
\
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 -rt dpkg-query --search \
# https://manpages.debian.org/trixie/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file)
| awk 'sub(":$", "", $1) { print $1 }' \
| sort -u \
| xargs -rt apt-mark manual; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
apt-get dist-clean
# 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 32.0.6
RUN set -ex; \
fetchDeps=" \
gnupg \
dirmngr \
"; \
apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \
\
curl -fsSL -o nextcloud.tar.bz2 "https://github.com/nextcloud-releases/server/releases/download/v32.0.6/nextcloud-32.0.6.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc "https://github.com/nextcloud-releases/server/releases/download/v32.0.6/nextcloud-32.0.6.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; \
apt-get dist-clean
COPY *.sh upgrade.exclude /
COPY config/* /usr/src/nextcloud/config/
ENTRYPOINT ["/entrypoint.sh"]
CMD ["apache2-foreground"]
================================================
FILE: 32/apache/config/apache-pretty-urls.config.php
================================================
<?php
$CONFIG = array (
'htaccess.RewriteBase' => '/',
);
================================================
FILE: 32/apache/config/apcu.config.php
================================================
<?php
$CONFIG = array (
'memcache.local' => '\OC\Memcache\APCu',
);
================================================
FILE: 32/apache/config/apps.config.php
================================================
<?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,
),
),
);
================================================
FILE: 32/apache/config/autoconfig.php
================================================
<?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';
}
================================================
FILE: 32/apache/config/redis.config.php
================================================
<?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');
}
}
================================================
FILE: 32/apache/config/reverse-proxy.config.php
================================================
<?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)));
}
================================================
FILE: 32/apache/config/s3.config.php
================================================
<?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
gitextract_83p45qnn/ ├── .config/ │ ├── apache-pretty-urls.config.php │ ├── apcu.config.php │ ├── apps.config.php │ ├── autoconfig.php │ ├── redis.config.php │ ├── reverse-proxy.config.php │ ├── s3.config.php │ ├── smtp.config.php │ ├── swift.config.php │ └── upgrade-disable-web.config.php ├── .examples/ │ ├── README.md │ ├── docker-compose/ │ │ ├── insecure/ │ │ │ ├── mariadb/ │ │ │ │ ├── apache/ │ │ │ │ │ ├── compose.yaml │ │ │ │ │ └── db.env │ │ │ │ └── fpm/ │ │ │ │ ├── compose.yaml │ │ │ │ ├── db.env │ │ │ │ └── web/ │ │ │ │ └── nginx.conf │ │ │ └── postgres/ │ │ │ ├── apache/ │ │ │ │ ├── compose.yaml │ │ │ │ └── db.env │ │ │ └── fpm/ │ │ │ ├── compose.yaml │ │ │ ├── db.env │ │ │ └── web/ │ │ │ └── nginx.conf │ │ └── with-nginx-proxy/ │ │ ├── mariadb/ │ │ │ ├── apache/ │ │ │ │ ├── compose.yaml │ │ │ │ ├── db.env │ │ │ │ └── proxy/ │ │ │ │ ├── Dockerfile │ │ │ │ └── uploadsize.conf │ │ │ └── fpm/ │ │ │ ├── compose.yaml │ │ │ ├── db.env │ │ │ ├── proxy/ │ │ │ │ ├── Dockerfile │ │ │ │ └── uploadsize.conf │ │ │ └── web/ │ │ │ └── nginx.conf │ │ └── postgres/ │ │ ├── apache/ │ │ │ ├── compose.yaml │ │ │ ├── db.env │ │ │ └── proxy/ │ │ │ ├── Dockerfile │ │ │ └── uploadsize.conf │ │ └── fpm/ │ │ ├── compose.yaml │ │ ├── db.env │ │ ├── proxy/ │ │ │ ├── Dockerfile │ │ │ └── uploadsize.conf │ │ └── web/ │ │ └── nginx.conf │ └── dockerfiles/ │ ├── cron/ │ │ ├── apache/ │ │ │ ├── Dockerfile │ │ │ └── supervisord.conf │ │ ├── fpm/ │ │ │ ├── Dockerfile │ │ │ └── supervisord.conf │ │ └── fpm-alpine/ │ │ ├── Dockerfile │ │ └── supervisord.conf │ ├── full/ │ │ ├── apache/ │ │ │ ├── Dockerfile │ │ │ └── supervisord.conf │ │ ├── fpm/ │ │ │ ├── Dockerfile │ │ │ └── supervisord.conf │ │ └── fpm-alpine/ │ │ ├── Dockerfile │ │ └── supervisord.conf │ ├── imap/ │ │ ├── apache/ │ │ │ └── Dockerfile │ │ ├── fpm/ │ │ │ └── Dockerfile │ │ └── fpm-alpine/ │ │ └── Dockerfile │ └── smb/ │ ├── apache/ │ │ └── Dockerfile │ ├── fpm/ │ │ └── Dockerfile │ └── fpm-alpine/ │ └── Dockerfile ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── 01-Image_issue.md │ │ ├── 02-Image_enhancement │ │ └── config.yml │ └── workflows/ │ ├── images.yml │ └── update-sh.yml ├── 31/ │ ├── apache/ │ │ ├── Dockerfile │ │ ├── config/ │ │ │ ├── apache-pretty-urls.config.php │ │ │ ├── apcu.config.php │ │ │ ├── apps.config.php │ │ │ ├── autoconfig.php │ │ │ ├── redis.config.php │ │ │ ├── reverse-proxy.config.php │ │ │ ├── s3.config.php │ │ │ ├── smtp.config.php │ │ │ ├── swift.config.php │ │ │ └── upgrade-disable-web.config.php │ │ ├── cron.sh │ │ ├── entrypoint.sh │ │ └── upgrade.exclude │ ├── fpm/ │ │ ├── Dockerfile │ │ ├── config/ │ │ │ ├── apcu.config.php │ │ │ ├── apps.config.php │ │ │ ├── autoconfig.php │ │ │ ├── redis.config.php │ │ │ ├── reverse-proxy.config.php │ │ │ ├── s3.config.php │ │ │ ├── smtp.config.php │ │ │ ├── swift.config.php │ │ │ └── upgrade-disable-web.config.php │ │ ├── cron.sh │ │ ├── entrypoint.sh │ │ └── upgrade.exclude │ └── fpm-alpine/ │ ├── Dockerfile │ ├── config/ │ │ ├── apcu.config.php │ │ ├── apps.config.php │ │ ├── autoconfig.php │ │ ├── redis.config.php │ │ ├── reverse-proxy.config.php │ │ ├── s3.config.php │ │ ├── smtp.config.php │ │ ├── swift.config.php │ │ └── upgrade-disable-web.config.php │ ├── cron.sh │ ├── entrypoint.sh │ └── upgrade.exclude ├── 32/ │ ├── apache/ │ │ ├── Dockerfile │ │ ├── config/ │ │ │ ├── apache-pretty-urls.config.php │ │ │ ├── apcu.config.php │ │ │ ├── apps.config.php │ │ │ ├── autoconfig.php │ │ │ ├── redis.config.php │ │ │ ├── reverse-proxy.config.php │ │ │ ├── s3.config.php │ │ │ ├── smtp.config.php │ │ │ ├── swift.config.php │ │ │ └── upgrade-disable-web.config.php │ │ ├── cron.sh │ │ ├── entrypoint.sh │ │ └── upgrade.exclude │ ├── fpm/ │ │ ├── Dockerfile │ │ ├── config/ │ │ │ ├── apcu.config.php │ │ │ ├── apps.config.php │ │ │ ├── autoconfig.php │ │ │ ├── redis.config.php │ │ │ ├── reverse-proxy.config.php │ │ │ ├── s3.config.php │ │ │ ├── smtp.config.php │ │ │ ├── swift.config.php │ │ │ └── upgrade-disable-web.config.php │ │ ├── cron.sh │ │ ├── entrypoint.sh │ │ └── upgrade.exclude │ └── fpm-alpine/ │ ├── Dockerfile │ ├── config/ │ │ ├── apcu.config.php │ │ ├── apps.config.php │ │ ├── autoconfig.php │ │ ├── redis.config.php │ │ ├── reverse-proxy.config.php │ │ ├── s3.config.php │ │ ├── smtp.config.php │ │ ├── swift.config.php │ │ └── upgrade-disable-web.config.php │ ├── cron.sh │ ├── entrypoint.sh │ └── upgrade.exclude ├── 33/ │ ├── apache/ │ │ ├── Dockerfile │ │ ├── config/ │ │ │ ├── apache-pretty-urls.config.php │ │ │ ├── apcu.config.php │ │ │ ├── apps.config.php │ │ │ ├── autoconfig.php │ │ │ ├── redis.config.php │ │ │ ├── reverse-proxy.config.php │ │ │ ├── s3.config.php │ │ │ ├── smtp.config.php │ │ │ ├── swift.config.php │ │ │ └── upgrade-disable-web.config.php │ │ ├── cron.sh │ │ ├── entrypoint.sh │ │ └── upgrade.exclude │ ├── fpm/ │ │ ├── Dockerfile │ │ ├── config/ │ │ │ ├── apcu.config.php │ │ │ ├── apps.config.php │ │ │ ├── autoconfig.php │ │ │ ├── redis.config.php │ │ │ ├── reverse-proxy.config.php │ │ │ ├── s3.config.php │ │ │ ├── smtp.config.php │ │ │ ├── swift.config.php │ │ │ └── upgrade-disable-web.config.php │ │ ├── cron.sh │ │ ├── entrypoint.sh │ │ └── upgrade.exclude │ └── fpm-alpine/ │ ├── Dockerfile │ ├── config/ │ │ ├── apcu.config.php │ │ ├── apps.config.php │ │ ├── autoconfig.php │ │ ├── redis.config.php │ │ ├── reverse-proxy.config.php │ │ ├── s3.config.php │ │ ├── smtp.config.php │ │ ├── swift.config.php │ │ └── upgrade-disable-web.config.php │ ├── cron.sh │ ├── entrypoint.sh │ └── upgrade.exclude ├── CODE_OF_CONDUCT.md ├── Dockerfile-alpine.template ├── Dockerfile-debian.template ├── LICENSE.md ├── README.md ├── docker-cron.sh ├── docker-entrypoint.sh ├── generate-stackbrew-library.sh ├── latest.txt ├── stack.yml ├── update.sh ├── upgrade.exclude └── versions.json
Condensed preview — 195 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (499K chars).
[
{
"path": ".config/apache-pretty-urls.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'htaccess.RewriteBase' => '/',\n);\n"
},
{
"path": ".config/apcu.config.php",
"chars": 70,
"preview": "<?php\n$CONFIG = array (\n 'memcache.local' => '\\OC\\Memcache\\APCu',\n);\n"
},
{
"path": ".config/apps.config.php",
"chars": 377,
"preview": "<?php\n$CONFIG = array (\n 'apps_paths' => array (\n 0 => array (\n 'path' => OC::$SERVERROOT.'/apps'"
},
{
"path": ".config/autoconfig.php",
"chars": 2110,
"preview": "<?php\n\n$autoconfig_enabled = false;\n\nif (getenv('SQLITE_DATABASE')) {\n $AUTOCONFIG['dbtype'] = 'sqlite';\n $AUTOCON"
},
{
"path": ".config/redis.config.php",
"chars": 700,
"preview": "<?php\nif (getenv('REDIS_HOST')) {\n $CONFIG = array(\n 'memcache.distributed' => '\\OC\\Memcache\\Redis',\n 'memcache.l"
},
{
"path": ".config/reverse-proxy.config.php",
"chars": 991,
"preview": "<?php\n$overwriteHost = getenv('OVERWRITEHOST');\nif ($overwriteHost) {\n $CONFIG['overwritehost'] = $overwriteHost;\n}\n\n$o"
},
{
"path": ".config/s3.config.php",
"chars": 2235,
"preview": "<?php\nif (getenv('OBJECTSTORE_S3_BUCKET')) {\n $use_ssl = getenv('OBJECTSTORE_S3_SSL');\n $use_path = getenv('OBJECTSTOR"
},
{
"path": ".config/smtp.config.php",
"chars": 933,
"preview": "<?php\nif (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {\n $CONFIG = array (\n 'mail_s"
},
{
"path": ".config/swift.config.php",
"chars": 1103,
"preview": "<?php\nif (getenv('OBJECTSTORE_SWIFT_URL')) {\n $autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');\n $CONFIG = array"
},
{
"path": ".config/upgrade-disable-web.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'upgrade.disable-web' => true,\n);\n"
},
{
"path": ".examples/README.md",
"chars": 6788,
"preview": "# Examples section\n\nIn this subfolders are some examples how to use the docker image. There are two sections:\n\n * [`dock"
},
{
"path": ".examples/docker-compose/insecure/mariadb/apache/compose.yaml",
"chars": 1411,
"preview": "---\nservices:\n # Note: MariaDB is an external service. You can find more information about the configuration here:\n # "
},
{
"path": ".examples/docker-compose/insecure/mariadb/apache/db.env",
"chars": 62,
"preview": "MYSQL_PASSWORD=\nMYSQL_DATABASE=nextcloud\nMYSQL_USER=nextcloud\n"
},
{
"path": ".examples/docker-compose/insecure/mariadb/fpm/compose.yaml",
"chars": 1947,
"preview": "---\nservices:\n # Note: MariaDB is an external service. You can find more information about the configuration here:\n # "
},
{
"path": ".examples/docker-compose/insecure/mariadb/fpm/db.env",
"chars": 62,
"preview": "MYSQL_PASSWORD=\nMYSQL_DATABASE=nextcloud\nMYSQL_USER=nextcloud\n"
},
{
"path": ".examples/docker-compose/insecure/mariadb/fpm/web/nginx.conf",
"chars": 8502,
"preview": "worker_processes auto;\n\nerror_log /var/log/nginx/error.log warn;\npid /var/run/nginx.pid;\n\n\nevents {\n worker_c"
},
{
"path": ".examples/docker-compose/insecure/postgres/apache/compose.yaml",
"chars": 1262,
"preview": "---\nservices:\n # Note: PostgreSQL is an external service. You can find more information about the configuration here:\n "
},
{
"path": ".examples/docker-compose/insecure/postgres/apache/db.env",
"chars": 65,
"preview": "POSTGRES_PASSWORD=\nPOSTGRES_DB=nextcloud\nPOSTGRES_USER=nextcloud\n"
},
{
"path": ".examples/docker-compose/insecure/postgres/fpm/compose.yaml",
"chars": 1798,
"preview": "---\nservices:\n # Note: PostgreSQL is an external service. You can find more information about the configuration here:\n "
},
{
"path": ".examples/docker-compose/insecure/postgres/fpm/db.env",
"chars": 65,
"preview": "POSTGRES_PASSWORD=\nPOSTGRES_DB=nextcloud\nPOSTGRES_USER=nextcloud\n"
},
{
"path": ".examples/docker-compose/insecure/postgres/fpm/web/nginx.conf",
"chars": 8502,
"preview": "worker_processes auto;\n\nerror_log /var/log/nginx/error.log warn;\npid /var/run/nginx.pid;\n\n\nevents {\n worker_c"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/mariadb/apache/compose.yaml",
"chars": 3213,
"preview": "---\nservices:\n # Note: MariaDB is an external service. You can find more information about the configuration here:\n # "
},
{
"path": ".examples/docker-compose/with-nginx-proxy/mariadb/apache/db.env",
"chars": 62,
"preview": "MYSQL_PASSWORD=\nMYSQL_DATABASE=nextcloud\nMYSQL_USER=nextcloud\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/mariadb/apache/proxy/Dockerfile",
"chars": 95,
"preview": "FROM nginxproxy/nginx-proxy:1.7-alpine\n\nCOPY uploadsize.conf /etc/nginx/conf.d/uploadsize.conf\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/mariadb/apache/proxy/uploadsize.conf",
"chars": 55,
"preview": "client_max_body_size 10G;\nproxy_request_buffering off;\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/mariadb/fpm/compose.yaml",
"chars": 3720,
"preview": "---\nservices:\n # Note: MariaDB is an external service. You can find more information about the configuration here:\n # "
},
{
"path": ".examples/docker-compose/with-nginx-proxy/mariadb/fpm/db.env",
"chars": 62,
"preview": "MYSQL_PASSWORD=\nMYSQL_DATABASE=nextcloud\nMYSQL_USER=nextcloud\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/Dockerfile",
"chars": 95,
"preview": "FROM nginxproxy/nginx-proxy:1.7-alpine\n\nCOPY uploadsize.conf /etc/nginx/conf.d/uploadsize.conf\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/mariadb/fpm/proxy/uploadsize.conf",
"chars": 55,
"preview": "client_max_body_size 10G;\nproxy_request_buffering off;\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/mariadb/fpm/web/nginx.conf",
"chars": 8501,
"preview": "worker_processes auto;\n\nerror_log /var/log/nginx/error.log warn;\npid /var/run/nginx.pid;\n\n\nevents {\n worker_c"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/postgres/apache/compose.yaml",
"chars": 2977,
"preview": "---\nservices:\n # Note: PostgreSQL is an external service. You can find more information about the configuration here:\n "
},
{
"path": ".examples/docker-compose/with-nginx-proxy/postgres/apache/db.env",
"chars": 65,
"preview": "POSTGRES_PASSWORD=\nPOSTGRES_DB=nextcloud\nPOSTGRES_USER=nextcloud\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/postgres/apache/proxy/Dockerfile",
"chars": 95,
"preview": "FROM nginxproxy/nginx-proxy:1.7-alpine\n\nCOPY uploadsize.conf /etc/nginx/conf.d/uploadsize.conf\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/postgres/apache/proxy/uploadsize.conf",
"chars": 55,
"preview": "client_max_body_size 10G;\nproxy_request_buffering off;\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/postgres/fpm/compose.yaml",
"chars": 3570,
"preview": "---\nservices:\n # Note: PostgreSQL is an external service. You can find more information about the configuration here:\n "
},
{
"path": ".examples/docker-compose/with-nginx-proxy/postgres/fpm/db.env",
"chars": 65,
"preview": "POSTGRES_PASSWORD=\nPOSTGRES_DB=nextcloud\nPOSTGRES_USER=nextcloud\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/postgres/fpm/proxy/Dockerfile",
"chars": 95,
"preview": "FROM nginxproxy/nginx-proxy:1.7-alpine\n\nCOPY uploadsize.conf /etc/nginx/conf.d/uploadsize.conf\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/postgres/fpm/proxy/uploadsize.conf",
"chars": 55,
"preview": "client_max_body_size 10G;\nproxy_request_buffering off;\n"
},
{
"path": ".examples/docker-compose/with-nginx-proxy/postgres/fpm/web/nginx.conf",
"chars": 8501,
"preview": "worker_processes auto;\n\nerror_log /var/log/nginx/error.log warn;\npid /var/run/nginx.pid;\n\n\nevents {\n worker_c"
},
{
"path": ".examples/dockerfiles/cron/apache/Dockerfile",
"chars": 277,
"preview": "FROM nextcloud:apache\n\nRUN apt-get update && apt-get install -y \\\n supervisor \\\n && rm -rf /var/lib/apt/lists/* \\\n "
},
{
"path": ".examples/dockerfiles/cron/apache/supervisord.conf",
"chars": 627,
"preview": "[supervisord]\nnodaemon=true\nlogfile=/var/log/supervisord/supervisord.log\npidfile=/var/run/supervisord/supervisord.pid\nch"
},
{
"path": ".examples/dockerfiles/cron/fpm/Dockerfile",
"chars": 274,
"preview": "FROM nextcloud:fpm\n\nRUN apt-get update && apt-get install -y \\\n supervisor \\\n && rm -rf /var/lib/apt/lists/* \\\n && "
},
{
"path": ".examples/dockerfiles/cron/fpm/supervisord.conf",
"chars": 616,
"preview": "[supervisord]\nnodaemon=true\nlogfile=/var/log/supervisord/supervisord.log\npidfile=/var/run/supervisord/supervisord.pid\nch"
},
{
"path": ".examples/dockerfiles/cron/fpm-alpine/Dockerfile",
"chars": 222,
"preview": "FROM nextcloud:fpm-alpine\n\nRUN apk add --no-cache supervisor \\\n && mkdir /var/log/supervisord /var/run/supervisord\n\nCOP"
},
{
"path": ".examples/dockerfiles/cron/fpm-alpine/supervisord.conf",
"chars": 616,
"preview": "[supervisord]\nnodaemon=true\nlogfile=/var/log/supervisord/supervisord.log\npidfile=/var/run/supervisord/supervisord.pid\nch"
},
{
"path": ".examples/dockerfiles/full/apache/Dockerfile",
"chars": 1575,
"preview": "FROM nextcloud:apache\n\nRUN set -ex; \\\n \\\n apt-get update; \\\n apt-get install -y --no-install-recommends \\\n "
},
{
"path": ".examples/dockerfiles/full/apache/supervisord.conf",
"chars": 627,
"preview": "[supervisord]\nnodaemon=true\nlogfile=/var/log/supervisord/supervisord.log\npidfile=/var/run/supervisord/supervisord.pid\nch"
},
{
"path": ".examples/dockerfiles/full/fpm/Dockerfile",
"chars": 1572,
"preview": "FROM nextcloud:fpm\n\nRUN set -ex; \\\n \\\n apt-get update; \\\n apt-get install -y --no-install-recommends \\\n "
},
{
"path": ".examples/dockerfiles/full/fpm/supervisord.conf",
"chars": 616,
"preview": "[supervisord]\nnodaemon=true\nlogfile=/var/log/supervisord/supervisord.log\npidfile=/var/run/supervisord/supervisord.pid\nch"
},
{
"path": ".examples/dockerfiles/full/fpm-alpine/Dockerfile",
"chars": 1149,
"preview": "FROM nextcloud:fpm-alpine\n\nRUN set -ex; \\\n \\\n apk add --no-cache \\\n ffmpeg \\\n imagemagick \\\n "
},
{
"path": ".examples/dockerfiles/full/fpm-alpine/supervisord.conf",
"chars": 616,
"preview": "[supervisord]\nnodaemon=true\nlogfile=/var/log/supervisord/supervisord.log\npidfile=/var/run/supervisord/supervisord.pid\nch"
},
{
"path": ".examples/dockerfiles/imap/apache/Dockerfile",
"chars": 959,
"preview": "FROM nextcloud:apache\n\nRUN set -ex; \\\n \\\n savedAptMark=\"$(apt-mark showmanual)\"; \\\n \\\n apt-get update; \\\n "
},
{
"path": ".examples/dockerfiles/imap/fpm/Dockerfile",
"chars": 956,
"preview": "FROM nextcloud:fpm\n\nRUN set -ex; \\\n \\\n savedAptMark=\"$(apt-mark showmanual)\"; \\\n \\\n apt-get update; \\\n ap"
},
{
"path": ".examples/dockerfiles/imap/fpm-alpine/Dockerfile",
"chars": 656,
"preview": "FROM nextcloud:fpm-alpine\n\nRUN set -ex; \\\n \\\n apk add --no-cache --virtual .build-deps \\\n $PHPIZE_DEPS \\\n "
},
{
"path": ".examples/dockerfiles/smb/apache/Dockerfile",
"chars": 112,
"preview": "FROM nextcloud:apache\n\nRUN apt-get update && apt-get install -y procps smbclient && rm -rf /var/lib/apt/lists/*\n"
},
{
"path": ".examples/dockerfiles/smb/fpm/Dockerfile",
"chars": 109,
"preview": "FROM nextcloud:fpm\n\nRUN apt-get update && apt-get install -y procps smbclient && rm -rf /var/lib/apt/lists/*\n"
},
{
"path": ".examples/dockerfiles/smb/fpm-alpine/Dockerfile",
"chars": 70,
"preview": "FROM nextcloud:fpm-alpine\n\nRUN apk add --no-cache procps samba-client\n"
},
{
"path": ".github/ISSUE_TEMPLATE/01-Image_issue.md",
"chars": 777,
"preview": "---\nname: 🐛 Report a bug in the image\nabout: Create a report to help us improve the image\nlabels: \"bug, 0. Needs triage\""
},
{
"path": ".github/ISSUE_TEMPLATE/02-Image_enhancement",
"chars": 597,
"preview": "---\nname: 🚀 Suggest an enhancement\nabout: Suggest an idea for improving the image\nlabels: \"enhancement, 0. Needs triage\""
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 1142,
"preview": "contact_links:\n - name: ❓ Ask a question\n url: https://help.nextcloud.com/\n about: Ask a question, get assi"
},
{
"path": ".github/workflows/images.yml",
"chars": 1742,
"preview": "---\nname: Images\n\non:\n pull_request:\n workflow_run:\n workflows: [\"update.sh\"]\n branches: [master]\n types:\n "
},
{
"path": ".github/workflows/update-sh.yml",
"chars": 719,
"preview": "---\nname: update.sh\n\non:\n push:\n branches:\n - master\n schedule:\n - cron: '15 18 * * *'\n workflow_dispatch:"
},
{
"path": "31/apache/Dockerfile",
"chars": 6514,
"preview": "# DO NOT EDIT: created by update.sh from Dockerfile-debian.template\nFROM php:8.3-apache-trixie\n\n# entrypoint.sh and cron"
},
{
"path": "31/apache/config/apache-pretty-urls.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'htaccess.RewriteBase' => '/',\n);\n"
},
{
"path": "31/apache/config/apcu.config.php",
"chars": 70,
"preview": "<?php\n$CONFIG = array (\n 'memcache.local' => '\\OC\\Memcache\\APCu',\n);\n"
},
{
"path": "31/apache/config/apps.config.php",
"chars": 377,
"preview": "<?php\n$CONFIG = array (\n 'apps_paths' => array (\n 0 => array (\n 'path' => OC::$SERVERROOT.'/apps'"
},
{
"path": "31/apache/config/autoconfig.php",
"chars": 2110,
"preview": "<?php\n\n$autoconfig_enabled = false;\n\nif (getenv('SQLITE_DATABASE')) {\n $AUTOCONFIG['dbtype'] = 'sqlite';\n $AUTOCON"
},
{
"path": "31/apache/config/redis.config.php",
"chars": 700,
"preview": "<?php\nif (getenv('REDIS_HOST')) {\n $CONFIG = array(\n 'memcache.distributed' => '\\OC\\Memcache\\Redis',\n 'memcache.l"
},
{
"path": "31/apache/config/reverse-proxy.config.php",
"chars": 991,
"preview": "<?php\n$overwriteHost = getenv('OVERWRITEHOST');\nif ($overwriteHost) {\n $CONFIG['overwritehost'] = $overwriteHost;\n}\n\n$o"
},
{
"path": "31/apache/config/s3.config.php",
"chars": 2235,
"preview": "<?php\nif (getenv('OBJECTSTORE_S3_BUCKET')) {\n $use_ssl = getenv('OBJECTSTORE_S3_SSL');\n $use_path = getenv('OBJECTSTOR"
},
{
"path": "31/apache/config/smtp.config.php",
"chars": 933,
"preview": "<?php\nif (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {\n $CONFIG = array (\n 'mail_s"
},
{
"path": "31/apache/config/swift.config.php",
"chars": 1103,
"preview": "<?php\nif (getenv('OBJECTSTORE_SWIFT_URL')) {\n $autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');\n $CONFIG = array"
},
{
"path": "31/apache/config/upgrade-disable-web.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'upgrade.disable-web' => true,\n);\n"
},
{
"path": "31/apache/cron.sh",
"chars": 56,
"preview": "#!/bin/sh\nset -eu\n\nexec busybox crond -f -L /dev/stdout\n"
},
{
"path": "31/apache/entrypoint.sh",
"chars": 13806,
"preview": "#!/bin/sh\nset -eu\n\n# version_greater A B returns whether A > B\nversion_greater() {\n [ \"$(printf '%s\\n' \"$@\" | sort -t"
},
{
"path": "31/apache/upgrade.exclude",
"chars": 78,
"preview": "/config/\n/data/\n/custom_apps/\n/themes/\n/version.php\n/nextcloud-init-sync.lock\n"
},
{
"path": "31/fpm/Dockerfile",
"chars": 5968,
"preview": "# DO NOT EDIT: created by update.sh from Dockerfile-debian.template\nFROM php:8.3-fpm-trixie\n\n# entrypoint.sh and cron.sh"
},
{
"path": "31/fpm/config/apcu.config.php",
"chars": 70,
"preview": "<?php\n$CONFIG = array (\n 'memcache.local' => '\\OC\\Memcache\\APCu',\n);\n"
},
{
"path": "31/fpm/config/apps.config.php",
"chars": 377,
"preview": "<?php\n$CONFIG = array (\n 'apps_paths' => array (\n 0 => array (\n 'path' => OC::$SERVERROOT.'/apps'"
},
{
"path": "31/fpm/config/autoconfig.php",
"chars": 2110,
"preview": "<?php\n\n$autoconfig_enabled = false;\n\nif (getenv('SQLITE_DATABASE')) {\n $AUTOCONFIG['dbtype'] = 'sqlite';\n $AUTOCON"
},
{
"path": "31/fpm/config/redis.config.php",
"chars": 700,
"preview": "<?php\nif (getenv('REDIS_HOST')) {\n $CONFIG = array(\n 'memcache.distributed' => '\\OC\\Memcache\\Redis',\n 'memcache.l"
},
{
"path": "31/fpm/config/reverse-proxy.config.php",
"chars": 991,
"preview": "<?php\n$overwriteHost = getenv('OVERWRITEHOST');\nif ($overwriteHost) {\n $CONFIG['overwritehost'] = $overwriteHost;\n}\n\n$o"
},
{
"path": "31/fpm/config/s3.config.php",
"chars": 2235,
"preview": "<?php\nif (getenv('OBJECTSTORE_S3_BUCKET')) {\n $use_ssl = getenv('OBJECTSTORE_S3_SSL');\n $use_path = getenv('OBJECTSTOR"
},
{
"path": "31/fpm/config/smtp.config.php",
"chars": 933,
"preview": "<?php\nif (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {\n $CONFIG = array (\n 'mail_s"
},
{
"path": "31/fpm/config/swift.config.php",
"chars": 1103,
"preview": "<?php\nif (getenv('OBJECTSTORE_SWIFT_URL')) {\n $autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');\n $CONFIG = array"
},
{
"path": "31/fpm/config/upgrade-disable-web.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'upgrade.disable-web' => true,\n);\n"
},
{
"path": "31/fpm/cron.sh",
"chars": 56,
"preview": "#!/bin/sh\nset -eu\n\nexec busybox crond -f -L /dev/stdout\n"
},
{
"path": "31/fpm/entrypoint.sh",
"chars": 13806,
"preview": "#!/bin/sh\nset -eu\n\n# version_greater A B returns whether A > B\nversion_greater() {\n [ \"$(printf '%s\\n' \"$@\" | sort -t"
},
{
"path": "31/fpm/upgrade.exclude",
"chars": 78,
"preview": "/config/\n/data/\n/custom_apps/\n/themes/\n/version.php\n/nextcloud-init-sync.lock\n"
},
{
"path": "31/fpm-alpine/Dockerfile",
"chars": 5257,
"preview": "# DO NOT EDIT: created by update.sh from Dockerfile-alpine.template\nFROM php:8.3-fpm-alpine3.23\n\n# entrypoint.sh and cro"
},
{
"path": "31/fpm-alpine/config/apcu.config.php",
"chars": 70,
"preview": "<?php\n$CONFIG = array (\n 'memcache.local' => '\\OC\\Memcache\\APCu',\n);\n"
},
{
"path": "31/fpm-alpine/config/apps.config.php",
"chars": 377,
"preview": "<?php\n$CONFIG = array (\n 'apps_paths' => array (\n 0 => array (\n 'path' => OC::$SERVERROOT.'/apps'"
},
{
"path": "31/fpm-alpine/config/autoconfig.php",
"chars": 2110,
"preview": "<?php\n\n$autoconfig_enabled = false;\n\nif (getenv('SQLITE_DATABASE')) {\n $AUTOCONFIG['dbtype'] = 'sqlite';\n $AUTOCON"
},
{
"path": "31/fpm-alpine/config/redis.config.php",
"chars": 700,
"preview": "<?php\nif (getenv('REDIS_HOST')) {\n $CONFIG = array(\n 'memcache.distributed' => '\\OC\\Memcache\\Redis',\n 'memcache.l"
},
{
"path": "31/fpm-alpine/config/reverse-proxy.config.php",
"chars": 991,
"preview": "<?php\n$overwriteHost = getenv('OVERWRITEHOST');\nif ($overwriteHost) {\n $CONFIG['overwritehost'] = $overwriteHost;\n}\n\n$o"
},
{
"path": "31/fpm-alpine/config/s3.config.php",
"chars": 2235,
"preview": "<?php\nif (getenv('OBJECTSTORE_S3_BUCKET')) {\n $use_ssl = getenv('OBJECTSTORE_S3_SSL');\n $use_path = getenv('OBJECTSTOR"
},
{
"path": "31/fpm-alpine/config/smtp.config.php",
"chars": 933,
"preview": "<?php\nif (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {\n $CONFIG = array (\n 'mail_s"
},
{
"path": "31/fpm-alpine/config/swift.config.php",
"chars": 1103,
"preview": "<?php\nif (getenv('OBJECTSTORE_SWIFT_URL')) {\n $autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');\n $CONFIG = array"
},
{
"path": "31/fpm-alpine/config/upgrade-disable-web.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'upgrade.disable-web' => true,\n);\n"
},
{
"path": "31/fpm-alpine/cron.sh",
"chars": 56,
"preview": "#!/bin/sh\nset -eu\n\nexec busybox crond -f -L /dev/stdout\n"
},
{
"path": "31/fpm-alpine/entrypoint.sh",
"chars": 13806,
"preview": "#!/bin/sh\nset -eu\n\n# version_greater A B returns whether A > B\nversion_greater() {\n [ \"$(printf '%s\\n' \"$@\" | sort -t"
},
{
"path": "31/fpm-alpine/upgrade.exclude",
"chars": 78,
"preview": "/config/\n/data/\n/custom_apps/\n/themes/\n/version.php\n/nextcloud-init-sync.lock\n"
},
{
"path": "32/apache/Dockerfile",
"chars": 6509,
"preview": "# DO NOT EDIT: created by update.sh from Dockerfile-debian.template\nFROM php:8.3-apache-trixie\n\n# entrypoint.sh and cron"
},
{
"path": "32/apache/config/apache-pretty-urls.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'htaccess.RewriteBase' => '/',\n);\n"
},
{
"path": "32/apache/config/apcu.config.php",
"chars": 70,
"preview": "<?php\n$CONFIG = array (\n 'memcache.local' => '\\OC\\Memcache\\APCu',\n);\n"
},
{
"path": "32/apache/config/apps.config.php",
"chars": 377,
"preview": "<?php\n$CONFIG = array (\n 'apps_paths' => array (\n 0 => array (\n 'path' => OC::$SERVERROOT.'/apps'"
},
{
"path": "32/apache/config/autoconfig.php",
"chars": 2110,
"preview": "<?php\n\n$autoconfig_enabled = false;\n\nif (getenv('SQLITE_DATABASE')) {\n $AUTOCONFIG['dbtype'] = 'sqlite';\n $AUTOCON"
},
{
"path": "32/apache/config/redis.config.php",
"chars": 700,
"preview": "<?php\nif (getenv('REDIS_HOST')) {\n $CONFIG = array(\n 'memcache.distributed' => '\\OC\\Memcache\\Redis',\n 'memcache.l"
},
{
"path": "32/apache/config/reverse-proxy.config.php",
"chars": 991,
"preview": "<?php\n$overwriteHost = getenv('OVERWRITEHOST');\nif ($overwriteHost) {\n $CONFIG['overwritehost'] = $overwriteHost;\n}\n\n$o"
},
{
"path": "32/apache/config/s3.config.php",
"chars": 2235,
"preview": "<?php\nif (getenv('OBJECTSTORE_S3_BUCKET')) {\n $use_ssl = getenv('OBJECTSTORE_S3_SSL');\n $use_path = getenv('OBJECTSTOR"
},
{
"path": "32/apache/config/smtp.config.php",
"chars": 933,
"preview": "<?php\nif (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {\n $CONFIG = array (\n 'mail_s"
},
{
"path": "32/apache/config/swift.config.php",
"chars": 1103,
"preview": "<?php\nif (getenv('OBJECTSTORE_SWIFT_URL')) {\n $autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');\n $CONFIG = array"
},
{
"path": "32/apache/config/upgrade-disable-web.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'upgrade.disable-web' => true,\n);\n"
},
{
"path": "32/apache/cron.sh",
"chars": 56,
"preview": "#!/bin/sh\nset -eu\n\nexec busybox crond -f -L /dev/stdout\n"
},
{
"path": "32/apache/entrypoint.sh",
"chars": 13806,
"preview": "#!/bin/sh\nset -eu\n\n# version_greater A B returns whether A > B\nversion_greater() {\n [ \"$(printf '%s\\n' \"$@\" | sort -t"
},
{
"path": "32/apache/upgrade.exclude",
"chars": 78,
"preview": "/config/\n/data/\n/custom_apps/\n/themes/\n/version.php\n/nextcloud-init-sync.lock\n"
},
{
"path": "32/fpm/Dockerfile",
"chars": 5963,
"preview": "# DO NOT EDIT: created by update.sh from Dockerfile-debian.template\nFROM php:8.3-fpm-trixie\n\n# entrypoint.sh and cron.sh"
},
{
"path": "32/fpm/config/apcu.config.php",
"chars": 70,
"preview": "<?php\n$CONFIG = array (\n 'memcache.local' => '\\OC\\Memcache\\APCu',\n);\n"
},
{
"path": "32/fpm/config/apps.config.php",
"chars": 377,
"preview": "<?php\n$CONFIG = array (\n 'apps_paths' => array (\n 0 => array (\n 'path' => OC::$SERVERROOT.'/apps'"
},
{
"path": "32/fpm/config/autoconfig.php",
"chars": 2110,
"preview": "<?php\n\n$autoconfig_enabled = false;\n\nif (getenv('SQLITE_DATABASE')) {\n $AUTOCONFIG['dbtype'] = 'sqlite';\n $AUTOCON"
},
{
"path": "32/fpm/config/redis.config.php",
"chars": 700,
"preview": "<?php\nif (getenv('REDIS_HOST')) {\n $CONFIG = array(\n 'memcache.distributed' => '\\OC\\Memcache\\Redis',\n 'memcache.l"
},
{
"path": "32/fpm/config/reverse-proxy.config.php",
"chars": 991,
"preview": "<?php\n$overwriteHost = getenv('OVERWRITEHOST');\nif ($overwriteHost) {\n $CONFIG['overwritehost'] = $overwriteHost;\n}\n\n$o"
},
{
"path": "32/fpm/config/s3.config.php",
"chars": 2235,
"preview": "<?php\nif (getenv('OBJECTSTORE_S3_BUCKET')) {\n $use_ssl = getenv('OBJECTSTORE_S3_SSL');\n $use_path = getenv('OBJECTSTOR"
},
{
"path": "32/fpm/config/smtp.config.php",
"chars": 933,
"preview": "<?php\nif (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {\n $CONFIG = array (\n 'mail_s"
},
{
"path": "32/fpm/config/swift.config.php",
"chars": 1103,
"preview": "<?php\nif (getenv('OBJECTSTORE_SWIFT_URL')) {\n $autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');\n $CONFIG = array"
},
{
"path": "32/fpm/config/upgrade-disable-web.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'upgrade.disable-web' => true,\n);\n"
},
{
"path": "32/fpm/cron.sh",
"chars": 56,
"preview": "#!/bin/sh\nset -eu\n\nexec busybox crond -f -L /dev/stdout\n"
},
{
"path": "32/fpm/entrypoint.sh",
"chars": 13806,
"preview": "#!/bin/sh\nset -eu\n\n# version_greater A B returns whether A > B\nversion_greater() {\n [ \"$(printf '%s\\n' \"$@\" | sort -t"
},
{
"path": "32/fpm/upgrade.exclude",
"chars": 78,
"preview": "/config/\n/data/\n/custom_apps/\n/themes/\n/version.php\n/nextcloud-init-sync.lock\n"
},
{
"path": "32/fpm-alpine/Dockerfile",
"chars": 5252,
"preview": "# DO NOT EDIT: created by update.sh from Dockerfile-alpine.template\nFROM php:8.3-fpm-alpine3.23\n\n# entrypoint.sh and cro"
},
{
"path": "32/fpm-alpine/config/apcu.config.php",
"chars": 70,
"preview": "<?php\n$CONFIG = array (\n 'memcache.local' => '\\OC\\Memcache\\APCu',\n);\n"
},
{
"path": "32/fpm-alpine/config/apps.config.php",
"chars": 377,
"preview": "<?php\n$CONFIG = array (\n 'apps_paths' => array (\n 0 => array (\n 'path' => OC::$SERVERROOT.'/apps'"
},
{
"path": "32/fpm-alpine/config/autoconfig.php",
"chars": 2110,
"preview": "<?php\n\n$autoconfig_enabled = false;\n\nif (getenv('SQLITE_DATABASE')) {\n $AUTOCONFIG['dbtype'] = 'sqlite';\n $AUTOCON"
},
{
"path": "32/fpm-alpine/config/redis.config.php",
"chars": 700,
"preview": "<?php\nif (getenv('REDIS_HOST')) {\n $CONFIG = array(\n 'memcache.distributed' => '\\OC\\Memcache\\Redis',\n 'memcache.l"
},
{
"path": "32/fpm-alpine/config/reverse-proxy.config.php",
"chars": 991,
"preview": "<?php\n$overwriteHost = getenv('OVERWRITEHOST');\nif ($overwriteHost) {\n $CONFIG['overwritehost'] = $overwriteHost;\n}\n\n$o"
},
{
"path": "32/fpm-alpine/config/s3.config.php",
"chars": 2235,
"preview": "<?php\nif (getenv('OBJECTSTORE_S3_BUCKET')) {\n $use_ssl = getenv('OBJECTSTORE_S3_SSL');\n $use_path = getenv('OBJECTSTOR"
},
{
"path": "32/fpm-alpine/config/smtp.config.php",
"chars": 933,
"preview": "<?php\nif (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {\n $CONFIG = array (\n 'mail_s"
},
{
"path": "32/fpm-alpine/config/swift.config.php",
"chars": 1103,
"preview": "<?php\nif (getenv('OBJECTSTORE_SWIFT_URL')) {\n $autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');\n $CONFIG = array"
},
{
"path": "32/fpm-alpine/config/upgrade-disable-web.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'upgrade.disable-web' => true,\n);\n"
},
{
"path": "32/fpm-alpine/cron.sh",
"chars": 56,
"preview": "#!/bin/sh\nset -eu\n\nexec busybox crond -f -L /dev/stdout\n"
},
{
"path": "32/fpm-alpine/entrypoint.sh",
"chars": 13806,
"preview": "#!/bin/sh\nset -eu\n\n# version_greater A B returns whether A > B\nversion_greater() {\n [ \"$(printf '%s\\n' \"$@\" | sort -t"
},
{
"path": "32/fpm-alpine/upgrade.exclude",
"chars": 78,
"preview": "/config/\n/data/\n/custom_apps/\n/themes/\n/version.php\n/nextcloud-init-sync.lock\n"
},
{
"path": "33/apache/Dockerfile",
"chars": 6500,
"preview": "# DO NOT EDIT: created by update.sh from Dockerfile-debian.template\nFROM php:8.4-apache-trixie\n\n# entrypoint.sh and cron"
},
{
"path": "33/apache/config/apache-pretty-urls.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'htaccess.RewriteBase' => '/',\n);\n"
},
{
"path": "33/apache/config/apcu.config.php",
"chars": 70,
"preview": "<?php\n$CONFIG = array (\n 'memcache.local' => '\\OC\\Memcache\\APCu',\n);\n"
},
{
"path": "33/apache/config/apps.config.php",
"chars": 377,
"preview": "<?php\n$CONFIG = array (\n 'apps_paths' => array (\n 0 => array (\n 'path' => OC::$SERVERROOT.'/apps'"
},
{
"path": "33/apache/config/autoconfig.php",
"chars": 2110,
"preview": "<?php\n\n$autoconfig_enabled = false;\n\nif (getenv('SQLITE_DATABASE')) {\n $AUTOCONFIG['dbtype'] = 'sqlite';\n $AUTOCON"
},
{
"path": "33/apache/config/redis.config.php",
"chars": 700,
"preview": "<?php\nif (getenv('REDIS_HOST')) {\n $CONFIG = array(\n 'memcache.distributed' => '\\OC\\Memcache\\Redis',\n 'memcache.l"
},
{
"path": "33/apache/config/reverse-proxy.config.php",
"chars": 991,
"preview": "<?php\n$overwriteHost = getenv('OVERWRITEHOST');\nif ($overwriteHost) {\n $CONFIG['overwritehost'] = $overwriteHost;\n}\n\n$o"
},
{
"path": "33/apache/config/s3.config.php",
"chars": 2235,
"preview": "<?php\nif (getenv('OBJECTSTORE_S3_BUCKET')) {\n $use_ssl = getenv('OBJECTSTORE_S3_SSL');\n $use_path = getenv('OBJECTSTOR"
},
{
"path": "33/apache/config/smtp.config.php",
"chars": 933,
"preview": "<?php\nif (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {\n $CONFIG = array (\n 'mail_s"
},
{
"path": "33/apache/config/swift.config.php",
"chars": 1103,
"preview": "<?php\nif (getenv('OBJECTSTORE_SWIFT_URL')) {\n $autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');\n $CONFIG = array"
},
{
"path": "33/apache/config/upgrade-disable-web.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'upgrade.disable-web' => true,\n);\n"
},
{
"path": "33/apache/cron.sh",
"chars": 56,
"preview": "#!/bin/sh\nset -eu\n\nexec busybox crond -f -L /dev/stdout\n"
},
{
"path": "33/apache/entrypoint.sh",
"chars": 13806,
"preview": "#!/bin/sh\nset -eu\n\n# version_greater A B returns whether A > B\nversion_greater() {\n [ \"$(printf '%s\\n' \"$@\" | sort -t"
},
{
"path": "33/apache/upgrade.exclude",
"chars": 78,
"preview": "/config/\n/data/\n/custom_apps/\n/themes/\n/version.php\n/nextcloud-init-sync.lock\n"
},
{
"path": "33/fpm/Dockerfile",
"chars": 5954,
"preview": "# DO NOT EDIT: created by update.sh from Dockerfile-debian.template\nFROM php:8.4-fpm-trixie\n\n# entrypoint.sh and cron.sh"
},
{
"path": "33/fpm/config/apcu.config.php",
"chars": 70,
"preview": "<?php\n$CONFIG = array (\n 'memcache.local' => '\\OC\\Memcache\\APCu',\n);\n"
},
{
"path": "33/fpm/config/apps.config.php",
"chars": 377,
"preview": "<?php\n$CONFIG = array (\n 'apps_paths' => array (\n 0 => array (\n 'path' => OC::$SERVERROOT.'/apps'"
},
{
"path": "33/fpm/config/autoconfig.php",
"chars": 2110,
"preview": "<?php\n\n$autoconfig_enabled = false;\n\nif (getenv('SQLITE_DATABASE')) {\n $AUTOCONFIG['dbtype'] = 'sqlite';\n $AUTOCON"
},
{
"path": "33/fpm/config/redis.config.php",
"chars": 700,
"preview": "<?php\nif (getenv('REDIS_HOST')) {\n $CONFIG = array(\n 'memcache.distributed' => '\\OC\\Memcache\\Redis',\n 'memcache.l"
},
{
"path": "33/fpm/config/reverse-proxy.config.php",
"chars": 991,
"preview": "<?php\n$overwriteHost = getenv('OVERWRITEHOST');\nif ($overwriteHost) {\n $CONFIG['overwritehost'] = $overwriteHost;\n}\n\n$o"
},
{
"path": "33/fpm/config/s3.config.php",
"chars": 2235,
"preview": "<?php\nif (getenv('OBJECTSTORE_S3_BUCKET')) {\n $use_ssl = getenv('OBJECTSTORE_S3_SSL');\n $use_path = getenv('OBJECTSTOR"
},
{
"path": "33/fpm/config/smtp.config.php",
"chars": 933,
"preview": "<?php\nif (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {\n $CONFIG = array (\n 'mail_s"
},
{
"path": "33/fpm/config/swift.config.php",
"chars": 1103,
"preview": "<?php\nif (getenv('OBJECTSTORE_SWIFT_URL')) {\n $autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');\n $CONFIG = array"
},
{
"path": "33/fpm/config/upgrade-disable-web.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'upgrade.disable-web' => true,\n);\n"
},
{
"path": "33/fpm/cron.sh",
"chars": 56,
"preview": "#!/bin/sh\nset -eu\n\nexec busybox crond -f -L /dev/stdout\n"
},
{
"path": "33/fpm/entrypoint.sh",
"chars": 13806,
"preview": "#!/bin/sh\nset -eu\n\n# version_greater A B returns whether A > B\nversion_greater() {\n [ \"$(printf '%s\\n' \"$@\" | sort -t"
},
{
"path": "33/fpm/upgrade.exclude",
"chars": 78,
"preview": "/config/\n/data/\n/custom_apps/\n/themes/\n/version.php\n/nextcloud-init-sync.lock\n"
},
{
"path": "33/fpm-alpine/Dockerfile",
"chars": 5243,
"preview": "# DO NOT EDIT: created by update.sh from Dockerfile-alpine.template\nFROM php:8.4-fpm-alpine3.23\n\n# entrypoint.sh and cro"
},
{
"path": "33/fpm-alpine/config/apcu.config.php",
"chars": 70,
"preview": "<?php\n$CONFIG = array (\n 'memcache.local' => '\\OC\\Memcache\\APCu',\n);\n"
},
{
"path": "33/fpm-alpine/config/apps.config.php",
"chars": 377,
"preview": "<?php\n$CONFIG = array (\n 'apps_paths' => array (\n 0 => array (\n 'path' => OC::$SERVERROOT.'/apps'"
},
{
"path": "33/fpm-alpine/config/autoconfig.php",
"chars": 2110,
"preview": "<?php\n\n$autoconfig_enabled = false;\n\nif (getenv('SQLITE_DATABASE')) {\n $AUTOCONFIG['dbtype'] = 'sqlite';\n $AUTOCON"
},
{
"path": "33/fpm-alpine/config/redis.config.php",
"chars": 700,
"preview": "<?php\nif (getenv('REDIS_HOST')) {\n $CONFIG = array(\n 'memcache.distributed' => '\\OC\\Memcache\\Redis',\n 'memcache.l"
},
{
"path": "33/fpm-alpine/config/reverse-proxy.config.php",
"chars": 991,
"preview": "<?php\n$overwriteHost = getenv('OVERWRITEHOST');\nif ($overwriteHost) {\n $CONFIG['overwritehost'] = $overwriteHost;\n}\n\n$o"
},
{
"path": "33/fpm-alpine/config/s3.config.php",
"chars": 2235,
"preview": "<?php\nif (getenv('OBJECTSTORE_S3_BUCKET')) {\n $use_ssl = getenv('OBJECTSTORE_S3_SSL');\n $use_path = getenv('OBJECTSTOR"
},
{
"path": "33/fpm-alpine/config/smtp.config.php",
"chars": 933,
"preview": "<?php\nif (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {\n $CONFIG = array (\n 'mail_s"
},
{
"path": "33/fpm-alpine/config/swift.config.php",
"chars": 1103,
"preview": "<?php\nif (getenv('OBJECTSTORE_SWIFT_URL')) {\n $autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');\n $CONFIG = array"
},
{
"path": "33/fpm-alpine/config/upgrade-disable-web.config.php",
"chars": 60,
"preview": "<?php\n$CONFIG = array (\n 'upgrade.disable-web' => true,\n);\n"
},
{
"path": "33/fpm-alpine/cron.sh",
"chars": 56,
"preview": "#!/bin/sh\nset -eu\n\nexec busybox crond -f -L /dev/stdout\n"
},
{
"path": "33/fpm-alpine/entrypoint.sh",
"chars": 13806,
"preview": "#!/bin/sh\nset -eu\n\n# version_greater A B returns whether A > B\nversion_greater() {\n [ \"$(printf '%s\\n' \"$@\" | sort -t"
},
{
"path": "33/fpm-alpine/upgrade.exclude",
"chars": 78,
"preview": "/config/\n/data/\n/custom_apps/\n/themes/\n/version.php\n/nextcloud-init-sync.lock\n"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 934,
"preview": "In the Nextcloud community, participants from all over the world come together to create Free Software for a free intern"
},
{
"path": "Dockerfile-alpine.template",
"chars": 5148,
"preview": "FROM php:%%PHP_VERSION%%-%%VARIANT%%%%ALPINE_VERSION%%\n\n# entrypoint.sh and cron.sh dependencies\nRUN set -ex; \\\n \\\n "
},
{
"path": "Dockerfile-debian.template",
"chars": 5864,
"preview": "FROM php:%%PHP_VERSION%%-%%VARIANT%%-%%DEBIAN_VERSION%%\n\n# entrypoint.sh and cron.sh dependencies\nRUN set -ex; \\\n \\\n "
},
{
"path": "LICENSE.md",
"chars": 34520,
"preview": " GNU AFFERO GENERAL PUBLIC LICENSE\n Version 3, 19 November 2007\n\n Copyright (C)"
},
{
"path": "README.md",
"chars": 50261,
"preview": "\n[ {\n [ \"$(printf '%s\\n' \"$@\" | sort -t"
},
{
"path": "generate-stackbrew-library.sh",
"chars": 3381,
"preview": "#!/usr/bin/env bash\nset -Eeuo pipefail\n\nstable_channel='32.0.6'\n\nself=\"$(basename \"$BASH_SOURCE\")\"\ncd \"$(dirname \"$(read"
},
{
"path": "latest.txt",
"chars": 7,
"preview": "33.0.0\n"
},
{
"path": "stack.yml",
"chars": 700,
"preview": "version: '3.2'\n\nservices:\n db:\n image: postgres\n restart: always\n volumes:\n - db:/var/lib/postgresql/data"
},
{
"path": "update.sh",
"chars": 6371,
"preview": "#!/usr/bin/env bash\nset -eo pipefail\n\ndeclare -A alpine_version=(\n\t[default]='3.23'\n)\n\ndeclare -A debian_version=(\n\t[def"
},
{
"path": "upgrade.exclude",
"chars": 78,
"preview": "/config/\n/data/\n/custom_apps/\n/themes/\n/version.php\n/nextcloud-init-sync.lock\n"
},
{
"path": "versions.json",
"chars": 2225,
"preview": "{\n \"33\": {\n \"branch\": \"33\",\n \"version\": \"33.0.0\",\n \"url\": \"https://github.com/nextcloud-releases/server/releas"
}
]
About this extraction
This page contains the full source code of the nextcloud/docker GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 195 files (455.5 KB), approximately 125.4k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.