Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .docker/app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ FROM nextcloud:${NEXTCLOUD_VERSION}
RUN apt-get update \
&& apt-get install -y \
locales \
postgresql-client \
poppler-utils \
&& sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \
&& locale-gen \
Expand Down
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ LETSENCRYPT_EMAIL=
TZ=

POSTGRES_PASSWORD=
NEXTCLOUD_BACKUP_DIR=/backups
NEXTCLOUD_UPGRADE_MIN_FREE_MB=2048
Comment on lines +11 to +12

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pass upgrade hook settings into the container

These new values are only added to .env.example, but the app service environment lists in the compose files never pass NEXTCLOUD_BACKUP_DIR or NEXTCLOUD_UPGRADE_MIN_FREE_MB through to the container. In deployments that edit .env to change the backup path or free-space threshold as documented, the pre-upgrade hook still falls back to /backups and 2048, so the safety check and backup location cannot actually be configured from the sample env file. Add these variables to the app environment in both compose files.

Useful? React with 👍 / 👎.


NEXTCLOUD_ADMIN_USER=
NEXTCLOUD_ADMIN_PASSWORD=
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/volumes
/backups
.env
docker-compose.override.yml
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Languages avaliable: [pt-BR](docs/README_ptBR.md)
- [After setup](#after-setup)
- [Custom setup](#custom-setup)
- [Customize docker-compose content](#customize-docker-compose-content)
- [Nextcloud upgrade hooks](#nextcloud-upgrade-hooks)
- [PHP](#php)
- [Run Nextcloud](#run-nextcloud)
- [Use a specific version of Nextcloud](#use-a-specific-version-of-nextcloud)
Expand Down Expand Up @@ -106,6 +107,46 @@ docker compose exec -u www-data app ./occ db:convert-filecache-bigint

You can do this using environments and creating a file called `docker-compose.override.yml` to add new services.

### Redis

The main compose files now include a `redis` service by default. This keeps the stack self-contained for Nextcloud installations that already use Redis in `config.php` and avoids depending on a host-specific external network.

### Nextcloud upgrade hooks

This repository mounts the official Nextcloud Docker hook directories so you can extend install and upgrade flows without touching the image entrypoint.

The `app` service uses these mounts:

```yaml
services:
app:
volumes:
- ./volumes/nextcloud:/var/www/html
- ./backups:/backups
- ./app-hooks/pre-installation:/docker-entrypoint-hooks.d/pre-installation
- ./app-hooks/post-installation:/docker-entrypoint-hooks.d/post-installation
- ./app-hooks/pre-upgrade:/docker-entrypoint-hooks.d/pre-upgrade
- ./app-hooks/post-upgrade:/docker-entrypoint-hooks.d/post-upgrade
- ./app-hooks/before-starting:/docker-entrypoint-hooks.d/before-starting
```

The upgrade hooks behave like this:

- `pre-upgrade`: turns maintenance mode on
- `pre-upgrade`: saves the active app list to `/backups/app_list.old`
- `pre-upgrade`: checks free disk space on the Nextcloud volume and the backup volume
- `pre-upgrade`: creates a compressed PostgreSQL dump at `/backups`
- `post-upgrade`: saves the new app list to `/backups/app_list.new` and prints a diff when possible
- `post-upgrade`: runs the extra `occ` commands needed after a major upgrade
- `post-upgrade`: turns maintenance mode off at the end

The following variables control the safety check and backup location:

- `NEXTCLOUD_BACKUP_DIR`, defaulting to `/backups`
- `NEXTCLOUD_UPGRADE_MIN_FREE_MB`, defaulting to `2048`

The `./backups` directory on the host must be writable by `www-data` inside the container. The recommended host-side ownership is `www-data:www-data` with mode `0755`.

### Garage S3 primary storage

Use `docker-compose-garages3.yml` when you want Nextcloud to store files in a Garage S3 bucket instead of the local `data/` directory.
Expand Down
1 change: 1 addition & 0 deletions app-hooks/before-starting/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

23 changes: 23 additions & 0 deletions app-hooks/post-upgrade/01-run-post-upgrade-commands.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

set -euo pipefail

run_occ() {
echo "Running: php occ $*"
php occ "$@"
}

echo "Running post-upgrade Nextcloud commands"
php occ app:list > /backups/app_list.new

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor the configured backup directory after upgrade

When NEXTCLOUD_BACKUP_DIR is customized for the pre-upgrade hook, this post-upgrade hook still writes and reads /backups directly. On setups that mount only the configured backup path, the redirect here fails after occ upgrade but before maintenance:mode --off, leaving the upgraded instance stuck in maintenance; even when /backups exists, the app-list diff compares the wrong files. Use the same backup directory variable here as the pre-upgrade script.

Useful? React with 👍 / 👎.

if [ -f /backups/app_list.old ]; then
echo "Comparing app lists"
diff -u /backups/app_list.old /backups/app_list.new || true
fi
run_occ db:add-missing-columns
run_occ db:add-missing-indices
run_occ db:add-missing-primary-keys
run_occ maintenance:repair --include-expensive
run_occ config:system:set maintenance_window_start --type=integer --value=1
run_occ app:update --all
run_occ maintenance:mode --off
echo "Post-upgrade commands completed successfully"
1 change: 1 addition & 0 deletions app-hooks/pre-installation/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

58 changes: 58 additions & 0 deletions app-hooks/pre-upgrade/01-check-disk-and-dump-db.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash

set -euo pipefail

nextcloud_dir=${NEXTCLOUD_DIR:-/var/www/html}
backup_dir=${NEXTCLOUD_BACKUP_DIR:-/backups}
min_free_mb=${NEXTCLOUD_UPGRADE_MIN_FREE_MB:-2048}
db_host=${POSTGRES_HOST:-postgres}
db_name=${POSTGRES_DB:-nextcloud}
db_user=${POSTGRES_USER:-nextcloud}
db_password=${POSTGRES_PASSWORD:-}
timestamp=$(date +%Y%m%d-%H%M%S)
backup_file="${backup_dir}/nextcloud-db-${timestamp}.sql.gz"
app_list_file="${backup_dir}/app_list.old"

run_occ() {
echo "Running: php occ $*"
php occ "$@"
}

check_free_space() {
local path=$1
local label=$2
local available_mb

available_mb=$(df -Pm "$path" | awk 'NR==2 { print $4 }')

if [ "$available_mb" -lt "$min_free_mb" ]; then
echo "Not enough disk space on ${label}: ${available_mb} MB available, ${min_free_mb} MB required"
exit 1
fi

echo "${label} has ${available_mb} MB free"
}

echo "Running pre-upgrade safety checks"
mkdir -p "$backup_dir"

run_occ maintenance:mode --on
php occ app:list > "$app_list_file"
echo "Saved active apps list to ${app_list_file}"

check_free_space "$nextcloud_dir" "Nextcloud volume"
check_free_space "$backup_dir" "Backup volume"

if ! command -v pg_dump >/dev/null 2>&1; then
echo "pg_dump is not available in the container image"
exit 1
fi

if [ -z "$db_password" ]; then
echo "POSTGRES_PASSWORD is empty, refusing to create a database dump"
exit 1
fi

echo "Creating PostgreSQL dump at ${backup_file}"
PGPASSWORD="$db_password" pg_dump -h "$db_host" -U "$db_user" "$db_name" | gzip -9 > "$backup_file"
echo "Database dump completed successfully"
13 changes: 13 additions & 0 deletions docker-compose-garages3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ services:
networks:
- internal

redis:
image: redis:7-alpine
restart: unless-stopped
networks:
- internal

garage:
image: dxflrs/garage:v1.0.0
restart: unless-stopped
Expand All @@ -35,7 +41,12 @@ services:
restart: unless-stopped
volumes:
- ./volumes/nextcloud:/var/www/html
- ./backups:/backups
- ./app-hooks/pre-installation:/docker-entrypoint-hooks.d/pre-installation
- ./app-hooks/post-installation:/docker-entrypoint-hooks.d/post-installation
- ./app-hooks/pre-upgrade:/docker-entrypoint-hooks.d/pre-upgrade
- ./app-hooks/post-upgrade:/docker-entrypoint-hooks.d/post-upgrade
- ./app-hooks/before-starting:/docker-entrypoint-hooks.d/before-starting
- ./.docker/garages3.config.php:/var/www/html/config/garages3.config.php:ro
environment:
- POSTGRES_DB=${POSTGRES_DB:-nextcloud}
Expand Down Expand Up @@ -69,6 +80,7 @@ services:
- host.docker.internal:host-gateway
depends_on:
- db
- redis
- garage
networks:
- internal
Expand Down Expand Up @@ -115,6 +127,7 @@ services:
- host.docker.internal:host-gateway
depends_on:
- db
- redis
- garage
networks:
- internal
Expand Down
15 changes: 15 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,25 @@ networks:
driver: bridge

services:
redis:
image: redis:7-alpine
restart: unless-stopped
networks:
- internal

app:
build:
context: .docker/app
args:
NEXTCLOUD_VERSION: ${NEXTCLOUD_VERSION:-stable-fpm}
volumes:
- ./volumes/nextcloud:/var/www/html
- ./backups:/backups

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Create a writable backup mount before running hooks

On a fresh checkout where ./backups does not already exist, this bind mount is created by Docker as a root-owned host directory, but the official Nextcloud entrypoint executes hook scripts as www-data. The first upgrade then fails at the pre-upgrade redirect to /backups/app_list.old (or the dump output) before the database backup is made, so the container cannot complete an image upgrade unless the operator manually pre-creates and chowns the directory. Please make this mount writable by default, for example by committing a managed directory/setup step or using a named volume with suitable ownership.

Useful? React with 👍 / 👎.

- ./app-hooks/pre-installation:/docker-entrypoint-hooks.d/pre-installation
- ./app-hooks/post-installation:/docker-entrypoint-hooks.d/post-installation
- ./app-hooks/pre-upgrade:/docker-entrypoint-hooks.d/pre-upgrade
- ./app-hooks/post-upgrade:/docker-entrypoint-hooks.d/post-upgrade
- ./app-hooks/before-starting:/docker-entrypoint-hooks.d/before-starting
restart: unless-stopped
environment:
- POSTGRES_DB=${POSTGRES_DB:-nextcloud}
Expand All @@ -33,6 +44,8 @@ services:
- MAIL_FROM_ADDRESS
- MAIL_DOMAIN
- TZ
depends_on:
- redis
networks:
- internal

Expand Down Expand Up @@ -63,6 +76,8 @@ services:
- TZ
volumes:
- ./volumes/nextcloud:/var/www/html
depends_on:
- redis
networks:
- internal
entrypoint: /cron.sh
41 changes: 41 additions & 0 deletions docs/README_ptBR.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- [Após a configuração](#após-a-configuração)
- [Configuração personalizada](#configuração-personalizada)
- [Personalize o conteúdo do docker-compose](#personalize-o-conteúdo-do-docker-compose)
- [Hooks de upgrade do Nextcloud](#hooks-de-upgrade-do-nextcloud)
- [PHP](#php)
- [Execute o Nextcloud](#execute-o-nextcloud)
- [Use uma versão específica do Nextcloud](#use-uma-versão-específica-do-nextcloud)
Expand Down Expand Up @@ -78,6 +79,46 @@ docker compose exec -u www-data app ./occ db:convert-filecache-bigint

Você pode fazer isso usando variáveis de ambiente e criando um arquivo chamado `docker-compose.override.yml` para adicionar novos serviços.

### Redis

Os arquivos principais de compose agora incluem o serviço `redis` por padrão. Isso deixa o stack autocontido para instalações do Nextcloud que já usam Redis no `config.php` e evita depender de uma rede externa específica do host.

### Hooks de upgrade do Nextcloud

Este repositório monta os diretórios oficiais de hooks do Nextcloud Docker para permitir extensões do fluxo de instalação e upgrade sem alterar o entrypoint da imagem.

O serviço `app` usa estes mounts:

```yaml
services:
app:
volumes:
- ./volumes/nextcloud:/var/www/html
- ./backups:/backups
- ./app-hooks/pre-installation:/docker-entrypoint-hooks.d/pre-installation
- ./app-hooks/post-installation:/docker-entrypoint-hooks.d/post-installation
- ./app-hooks/pre-upgrade:/docker-entrypoint-hooks.d/pre-upgrade
- ./app-hooks/post-upgrade:/docker-entrypoint-hooks.d/post-upgrade
- ./app-hooks/before-starting:/docker-entrypoint-hooks.d/before-starting
```

Os hooks de upgrade funcionam assim:

- `pre-upgrade`: ativa o modo de manutenção
- `pre-upgrade`: salva a lista de apps ativos em `/backups/app_list.old`
- `pre-upgrade`: verifica o espaço livre no volume do Nextcloud e no volume de backup
- `pre-upgrade`: cria um dump compactado do PostgreSQL em `/backups`
- `post-upgrade`: salva a nova lista de apps em `/backups/app_list.new` e mostra o diff quando possível
- `post-upgrade`: executa os comandos `occ` extras necessários após um upgrade maior
- `post-upgrade`: desativa o modo de manutenção ao final

As variáveis abaixo controlam a checagem e o diretório de backup:

- `NEXTCLOUD_BACKUP_DIR`, com padrão `/backups`
- `NEXTCLOUD_UPGRADE_MIN_FREE_MB`, com padrão `2048`

O diretório `./backups` no host precisa ser gravável pelo `www-data` dentro do container. O recomendado é usar `www-data:www-data` com permissão `0755`.

### Storage primário Garage S3

Use `docker-compose-garages3.yml` quando quiser que o Nextcloud grave os arquivos em um bucket Garage S3 em vez do diretório local `data/`.
Expand Down
Loading