Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/volumes
/backups/*
!/backups/
!/backups/.gitkeep
.env
docker-compose.override.yml
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
COMPOSE ?= docker compose
GARAGES3_COMPOSE_FILE ?= docker-compose-garages3.yml

.PHONY: up-garages3 down-garages3 bootstrap-garages3 garage-status-garages3 start-garages3 wait-nextcloud-garages3 setup-garages3
.PHONY: up-garages3 down-garages3 bootstrap-garages3 garage-status-garages3 start-garages3 wait-nextcloud-garages3 setup-garages3 test-hooks

up-garages3:
$(COMPOSE) -f $(GARAGES3_COMPOSE_FILE) up -d garage
Expand All @@ -25,3 +25,6 @@ setup-garages3:
$(MAKE) bootstrap-garages3
$(MAKE) start-garages3
$(MAKE) wait-nextcloud-garages3

test-hooks:
bash tests/test-hooks.sh
43 changes: 43 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,48 @@ 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/nextcloud-db.sql.gz`, replacing the previous dump
- `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`

Both upgrade hooks use `NEXTCLOUD_BACKUP_DIR` for the app list files and the database dump.

This repository includes the `./backups` directory so Docker does not create it as a root-owned host path on a fresh checkout. It must still 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 @@

30 changes: 30 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,30 @@
#!/bin/bash

set -euo pipefail

backup_dir=${NEXTCLOUD_BACKUP_DIR:-/backups}

cleanup() {
php occ maintenance:mode --off >/dev/null 2>&1 || true
}

trap cleanup EXIT

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

echo "Running post-upgrade Nextcloud commands"
php occ app:list > "$backup_dir/app_list.new"
if [ -f "$backup_dir/app_list.old" ]; then
echo "Comparing app lists"
diff -u "$backup_dir/app_list.old" "$backup_dir/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
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 @@

72 changes: 72 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,72 @@
#!/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:-}
backup_file="${backup_dir}/nextcloud-db.sql.gz"
backup_tmp_file="${backup_file}.tmp"
app_list_file="${backup_dir}/app_list.old"
maintenance_enabled=0

cleanup() {
if [ "$maintenance_enabled" -eq 1 ]; then
php occ maintenance:mode --off >/dev/null 2>&1 || true
fi

rm -f "$backup_tmp_file"
}

trap cleanup EXIT

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 Keep maintenance mode on until post-upgrade

When the pre-upgrade dump succeeds, this EXIT trap still runs cleanup; because maintenance_enabled was set after maintenance:mode --on, the hook immediately turns maintenance mode back off before the Docker entrypoint proceeds to occ upgrade and the post-upgrade hook. In production upgrades with live traffic, requests can then hit the instance while files/schema are being upgraded, so the trap should only disable maintenance on failure or be cleared before a successful exit.

Useful? React with 👍 / 👎.


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
maintenance_enabled=1
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_tmp_file"
mv "$backup_tmp_file" "$backup_file"
rm -f "$backup_tmp_file"
echo "Database dump completed successfully"
1 change: 1 addition & 0 deletions backups/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

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
- ./volumes/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
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
43 changes: 43 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,48 @@ 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/nextcloud-db.sql.gz`, substituindo o dump anterior
- `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`

Os dois hooks de upgrade usam `NEXTCLOUD_BACKUP_DIR` para os arquivos da lista de apps e para o dump do banco.

Este repositório já inclui o diretório `./backups`, então o Docker não cria um caminho root-owned em um checkout novo. Ele ainda 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
Loading