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
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
NEXTCLOUD_VERSION=35-fpm
# GHCR app image tag shared by app and cron. stable-fpm follows the latest approved major.
# For production, pin a supported major such as <major>-fpm before deployment.
NEXTCLOUD_VERSION=stable-fpm

VIRTUAL_HOST=
LETSENCRYPT_HOST=
Expand Down
17 changes: 10 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
COMPOSE ?= docker compose
GARAGES3_COMPOSE_FILE ?= docker-compose-garages3.yml
APP_TEST_IMAGE ?= nextcloud-app:acceptance
# Maintainer builds use the latest reviewed upstream base, not the deployment image channel.
APP_BASE_IMAGE ?= $(shell jq -er '.versions[-1].image' .github/nextcloud-supported.json)

.PHONY: up-garages3 down-garages3 bootstrap-garages3 garage-status-garages3 start-garages3 wait-nextcloud-garages3 setup-garages3 test-scan-images test-ci-scripts test-development-image-scripts test-ncdd test-app-image test-current-app-image scan-images

Expand Down Expand Up @@ -32,6 +34,7 @@ test-scan-images:

test-ci-scripts:
bats tests/check-action-pins.bats \
tests/compose-images.bats \
tests/nextcloud-versions.bats \
tests/publish-images.bats

Expand All @@ -47,20 +50,20 @@ test-app-image:

test-current-app-image:
@set -e; \
version="$$(sed -n 's/^NEXTCLOUD_VERSION=//p' .env.example | head -n 1)"; \
test -n "$$version" || { echo 'NEXTCLOUD_VERSION is missing from .env.example' >&2; exit 1; }; \
base_image='$(APP_BASE_IMAGE)'; \
test -n "$$base_image" || { echo 'No approved Nextcloud image in .github/nextcloud-supported.json' >&2; exit 1; }; \
docker buildx build --platform linux/amd64 --load --tag "$(APP_TEST_IMAGE)" \
--build-arg "NEXTCLOUD_BASE_IMAGE=nextcloud:$version" --file .docker/app/Dockerfile .docker/app; \
--build-arg "NEXTCLOUD_BASE_IMAGE=$$base_image" --file .docker/app/Dockerfile .docker/app; \
$(MAKE) test-app-image APP_IMAGE="$(APP_TEST_IMAGE)"

scan-images:
@set -e; \
version="$$(sed -n 's/^NEXTCLOUD_VERSION=//p' .env.example | head -n 1)"; \
test -n "$$version" || { echo 'NEXTCLOUD_VERSION is missing from .env.example' >&2; exit 1; }; \
base_image='$(APP_BASE_IMAGE)'; \
test -n "$$base_image" || { echo 'No approved Nextcloud image in .github/nextcloud-supported.json' >&2; exit 1; }; \
docker buildx build --platform linux/amd64 --load --tag nextcloud-app:scan-amd64 \
--build-arg "NEXTCLOUD_BASE_IMAGE=nextcloud:$version" --file .docker/app/Dockerfile .docker/app; \
--build-arg "NEXTCLOUD_BASE_IMAGE=$$base_image" --file .docker/app/Dockerfile .docker/app; \
docker buildx build --platform linux/arm64 --load --tag nextcloud-app:scan-arm64 \
--build-arg "NEXTCLOUD_BASE_IMAGE=nextcloud:$version" --file .docker/app/Dockerfile .docker/app; \
--build-arg "NEXTCLOUD_BASE_IMAGE=$$base_image" --file .docker/app/Dockerfile .docker/app; \
docker buildx build --platform linux/amd64 --load --tag nextcloud-web:scan-amd64 \
--file .docker/web/Dockerfile .docker/web; \
docker buildx build --platform linux/arm64 --load --tag nextcloud-web:scan-arm64 \
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ cp .env.example .env
# Edit .env: domain, credentials, administrator account, and your Nextcloud version.
docker network create reverse-proxy
docker network create postgres
docker compose -f docker-compose.yml -f docker-compose-postgres.yml up -d --build
docker compose -f docker-compose.yml -f docker-compose-postgres.yml pull
docker compose -f docker-compose.yml -f docker-compose-postgres.yml up -d
```

The external `reverse-proxy` network must have a configured proxy attached. Set up the proxy and DNS before expecting HTTPS to work. For production, review the PostgreSQL version in the Compose example, your backup strategy, and volume migrations.
Expand All @@ -31,7 +32,9 @@ For environment variables, existing deployments, storage options, and troublesho

## Nextcloud versions and image updates

Set `NEXTCLOUD_VERSION` in `.env` to select the **official Nextcloud base image** for this repository's local Docker Compose build. This is separate from publishing the LibreCode images to GHCR.
Set `NEXTCLOUD_VERSION` in `.env` to select the **published LibreCode application image tag** for both `app` and `cron`. The `web` service uses the independent `nextcloud-docker-web:main` image. The default Compose deployment does not build images locally.

The sample `.env.example` uses the moving `stable-fpm` channel. Set `NEXTCLOUD_VERSION` to a maintained major-specific tag (for example, `35-fpm`) before production deployment so a future image pull does not switch Nextcloud majors unexpectedly.

Prebuilt LibreCode application images use versioned tags, such as:

Expand Down
12 changes: 3 additions & 9 deletions docker-compose-garages3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ services:
- ./garage/data:/var/lib/garage/data

app:
build:
context: .docker/app
args:
NEXTCLOUD_BASE_IMAGE: nextcloud:${NEXTCLOUD_VERSION:-stable-fpm}
image: ghcr.io/librecodecoop/nextcloud-docker-app:${NEXTCLOUD_VERSION:-stable-fpm}
restart: unless-stopped
volumes:
- ./volumes/nextcloud:/var/www/html
Expand Down Expand Up @@ -83,7 +80,7 @@ services:
- internal

web:
build: .docker/web
image: ghcr.io/librecodecoop/nextcloud-docker-web:main
restart: unless-stopped
volumes:
- ./volumes/nextcloud:/var/www/html:ro
Expand All @@ -100,10 +97,7 @@ services:
- reverse-proxy

cron:
build:
context: .docker/app
args:
NEXTCLOUD_BASE_IMAGE: nextcloud:${NEXTCLOUD_VERSION:-stable-fpm}
image: ghcr.io/librecodecoop/nextcloud-docker-app:${NEXTCLOUD_VERSION:-stable-fpm}
restart: unless-stopped
environment:
- TZ
Expand Down
12 changes: 3 additions & 9 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ services:
- internal

app:
build:
context: .docker/app
args:
NEXTCLOUD_BASE_IMAGE: nextcloud:${NEXTCLOUD_VERSION:-stable-fpm}
image: ghcr.io/librecodecoop/nextcloud-docker-app:${NEXTCLOUD_VERSION:-stable-fpm}
volumes:
- ./volumes/nextcloud:/var/www/html
- ./app-hooks/pre-installation:/docker-entrypoint-hooks.d/pre-installation
Expand Down Expand Up @@ -47,7 +44,7 @@ services:
- internal

web:
build: .docker/web
image: ghcr.io/librecodecoop/nextcloud-docker-web:main
restart: unless-stopped
volumes:
- ./volumes/nextcloud:/var/www/html:ro
Expand All @@ -64,10 +61,7 @@ services:
- reverse-proxy

cron:
build:
context: .docker/app
args:
NEXTCLOUD_BASE_IMAGE: nextcloud:${NEXTCLOUD_VERSION:-stable-fpm}
image: ghcr.io/librecodecoop/nextcloud-docker-app:${NEXTCLOUD_VERSION:-stable-fpm}
restart: unless-stopped
environment:
- TZ
Expand Down
7 changes: 5 additions & 2 deletions docs/README_ptBR.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ cp .env.example .env
# Edite .env: domínio, credenciais, administrador e versão do Nextcloud.
docker network create reverse-proxy
docker network create postgres
docker compose -f docker-compose.yml -f docker-compose-postgres.yml up -d --build
docker compose -f docker-compose.yml -f docker-compose-postgres.yml pull
docker compose -f docker-compose.yml -f docker-compose-postgres.yml up -d
```

O proxy reverso deve estar configurado e conectado à rede externa `reverse-proxy`. Configure também o DNS antes de esperar que o HTTPS funcione. Em produção, revise a versão do PostgreSQL usada no exemplo, os backups e as migrações dos volumes.
Expand All @@ -31,7 +32,9 @@ Para variáveis de ambiente, instalações existentes, armazenamento e solução

## Versões e atualizações do Nextcloud

Defina `NEXTCLOUD_VERSION` no arquivo `.env` para selecionar a **imagem-base oficial do Nextcloud** utilizada no build local do Docker Compose. Isso é diferente da publicação das imagens da LibreCode no GHCR.
Defina `NEXTCLOUD_VERSION` no arquivo `.env` para selecionar a **tag da imagem de aplicação publicada pela LibreCode** para os serviços `app` e `cron`. O serviço `web` utiliza a imagem independente `nextcloud-docker-web:main`. O Compose padrão não constrói imagens localmente.

O arquivo `.env.example` utiliza o canal móvel `stable-fpm`. Antes de implantar em produção, configure `NEXTCLOUD_VERSION` com uma tag de versão principal ainda suportada (por exemplo, `35-fpm`), para evitar a troca inesperada de versão principal em futuras atualizações das imagens.

As imagens de aplicação da LibreCode disponibilizam tags por versão, por exemplo:

Expand Down
15 changes: 8 additions & 7 deletions docs/deployment.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Deployment and customization

This guide covers the example Docker Compose stack shipped with this repository. The Compose configuration **builds application and web images locally**. It does not pull the prebuilt LibreCode GHCR images by default.
This guide covers the example Docker Compose stack shipped with this repository. The default stack **uses the prebuilt LibreCode GHCR images**: `app` and `cron` share a versioned application image, while `web` uses the published Nginx image. Image maintainers can still use the repository's explicit build commands.

Return to the [project overview](../README.md) or see the [published image tags](images.md).

Expand All @@ -23,11 +23,11 @@ Create these networks **once** if they do not exist. Configure the proxy service
cp .env.example .env
```

Edit `.env` before running the services. At a minimum, provide administrator credentials, the database password, and your public domain.
Edit `.env` before running the services. At a minimum, provide administrator credentials, the database password, and your public domain. The sample selects `stable-fpm`, which moves to the newest approved major; pin a maintained major-specific tag before production deployment to avoid unintended major upgrades.

| Variable | Purpose |
| --- | --- |
| `NEXTCLOUD_VERSION` | Nextcloud version/tag used for the **official Docker base image** during a local build, e.g. `35-fpm` |
| `NEXTCLOUD_VERSION` | Tag of the **published LibreCode GHCR application image** used by `app` and `cron`; default `stable-fpm` (moving); use a supported major tag for production |
| `VIRTUAL_HOST`, `LETSENCRYPT_HOST` | Public domain passed to the external proxy |
| `LETSENCRYPT_EMAIL` | Contact email for certificate management |
| `NEXTCLOUD_TRUSTED_DOMAINS` | Trusted hostnames, including the public domain and the internal `web` host where applicable |
Expand All @@ -46,7 +46,8 @@ See `docker-compose.yml` and `.env.example` for the values consumed by the stack
The standard setup uses the base Compose file plus the PostgreSQL extension:

```bash
docker compose -f docker-compose.yml -f docker-compose-postgres.yml up -d --build
docker compose -f docker-compose.yml -f docker-compose-postgres.yml pull
docker compose -f docker-compose.yml -f docker-compose-postgres.yml up -d
```

The main Compose file provides Nextcloud FPM, an Nginx web container, Redis, and cron. The additional Compose file supplies PostgreSQL and connects the app and cron services to its network.
Expand All @@ -64,16 +65,16 @@ docker compose -f docker-compose.yml -f docker-compose-postgres.yml \

## Choosing and upgrading Nextcloud

Change `NEXTCLOUD_VERSION` in `.env` to select the official upstream image used by local Compose builds. It **does not control** which GHCR versions are published by LibreCode.
Change `NEXTCLOUD_VERSION` in `.env` to select a published LibreCode application image tag for both `app` and `cron`. This setting **does not control** which GHCR images LibreCode builds and publishes.

```bash
docker compose -f docker-compose.yml -f docker-compose-postgres.yml build --pull
docker compose -f docker-compose.yml -f docker-compose-postgres.yml pull app cron web
docker compose -f docker-compose.yml -f docker-compose-postgres.yml up -d
```

Back up the database, application configuration, and persistent files before an upgrade. Check Nextcloud's upgrade requirements and compatibility first: downgrades and skipping unsupported upgrade paths can leave stored data unusable. Use a controlled major-version upgrade process instead of unattended `:latest` changes.

For users deploying the prebuilt GHCR images, see the [image selection and upgrade policy](images.md).
See the [image selection and upgrade policy](images.md) before changing major versions or using immutable OCI digests.

## Optional Garage S3 primary storage

Expand Down
15 changes: 8 additions & 7 deletions docs/deployment_ptBR.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Implantação e personalização

Este guia explica o ambiente Docker Compose fornecido pelo repositório. O Compose **constrói as imagens da aplicação e do servidor web localmente**. Por padrão, ele não utiliza as imagens pré-compiladas da LibreCode no GHCR.
Este guia explica o ambiente Docker Compose fornecido pelo repositório. A configuração padrão **utiliza as imagens publicadas pela LibreCode no GHCR**: `app` e `cron` compartilham uma imagem de aplicação versionada, enquanto `web` utiliza a imagem publicada do Nginx. Os mantenedores ainda podem utilizar os comandos específicos para builds locais.

Volte para a [apresentação do projeto](README_ptBR.md) ou consulte as [tags das imagens publicadas](images.md).

Expand All @@ -23,11 +23,11 @@ Crie essas redes **uma única vez**, caso ainda não existam. Configure separada
cp .env.example .env
```

Edite o `.env` antes de iniciar os serviços. Informe, no mínimo, as credenciais do administrador, a senha do banco e o domínio público.
Edite o `.env` antes de iniciar os serviços. Informe, no mínimo, as credenciais do administrador, a senha do banco e o domínio público. O exemplo seleciona `stable-fpm`, que acompanha a versão principal aprovada mais recente; fixe uma tag de versão principal suportada antes da implantação em produção para evitar atualizações inesperadas.

| Variável | Finalidade |
| --- | --- |
| `NEXTCLOUD_VERSION` | Versão/tag da **imagem-base oficial do Nextcloud** utilizada no build local, por exemplo `35-fpm` |
| `NEXTCLOUD_VERSION` | Tag da **imagem de aplicação publicada pela LibreCode no GHCR** para `app` e `cron`; padrão `stable-fpm` (móvel); utilize uma tag de versão principal em produção |
| `VIRTUAL_HOST`, `LETSENCRYPT_HOST` | Domínio público utilizado pelo proxy |
| `LETSENCRYPT_EMAIL` | E-mail de contato para os certificados |
| `NEXTCLOUD_TRUSTED_DOMAINS` | Domínios confiáveis, incluindo o domínio público e o host interno `web`, quando aplicável |
Expand All @@ -46,7 +46,8 @@ Consulte `docker-compose.yml` e `.env.example` para verificar as variáveis usad
A configuração padrão combina o Compose principal com a extensão do PostgreSQL:

```bash
docker compose -f docker-compose.yml -f docker-compose-postgres.yml up -d --build
docker compose -f docker-compose.yml -f docker-compose-postgres.yml pull
docker compose -f docker-compose.yml -f docker-compose-postgres.yml up -d
```

O Compose principal contém Nextcloud FPM, Nginx, Redis e cron. A extensão adiciona o PostgreSQL e conecta os serviços da aplicação e do cron à rede do banco.
Expand All @@ -64,16 +65,16 @@ docker compose -f docker-compose.yml -f docker-compose-postgres.yml \

## Escolher e atualizar a versão do Nextcloud

Altere `NEXTCLOUD_VERSION` no arquivo `.env` para escolher a imagem oficial utilizada nos builds locais. Essa variável **não define** quais versões são publicadas pela LibreCode no GHCR.
Altere `NEXTCLOUD_VERSION` no arquivo `.env` para escolher uma tag publicada da imagem de aplicação da LibreCode, utilizada por `app` e `cron`. Essa variável **não define** quais versões são construídas e publicadas pela LibreCode no GHCR.

```bash
docker compose -f docker-compose.yml -f docker-compose-postgres.yml build --pull
docker compose -f docker-compose.yml -f docker-compose-postgres.yml pull app cron web
docker compose -f docker-compose.yml -f docker-compose-postgres.yml up -d
```

Faça backup do banco de dados, da configuração e dos arquivos persistidos antes de atualizar. Confira as exigências de compatibilidade do Nextcloud: downgrade ou saltos não suportados entre versões podem impedir o uso dos dados. Prefira atualizações de versões principais planejadas.

Para quem utiliza as imagens do GHCR, consulte a [política de tags e atualizações](images.md).
Consulte a [política de tags e atualizações](images.md) antes de mudar de versão principal ou utilizar digests OCI imutáveis.

## Armazenamento primário opcional com Garage S3

Expand Down
2 changes: 1 addition & 1 deletion docs/images.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The LibreCode Nextcloud images let you choose a maintained Nextcloud release for
| `ghcr.io/librecodecoop/nextcloud-docker-app` | Nextcloud application runtime with PHP-FPM |
| `ghcr.io/librecodecoop/nextcloud-docker-web` | Nginx web runtime; independent of the Nextcloud major |

The [repository's Docker Compose example](deployment.md) builds its images locally from the official `nextcloud:${NEXTCLOUD_VERSION}` base. It does not automatically pull these GHCR images.
The [repository's Docker Compose example](deployment.md) uses these published GHCR images by default. `NEXTCLOUD_VERSION` selects the application tag shared by `app` and `cron`; `web` uses the independent `:main` tag. The example environment defaults to the moving `:stable-fpm` alias; set a major-specific tag for production before pulling images.

## Application tags

Expand Down
2 changes: 1 addition & 1 deletion docs/maintenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ For daily builds, `NEXTCLOUD_DAILY_URL` identifies the upstream archive. The Doc

The generic image retains required runtime dependencies such as Poppler, UTF-8 locale support, and the PHP bz2 extension. Avoid reinstalling extensions already provided by the official Nextcloud base. Keep LibreSign-specific behavior outside this generic runtime.

The repository Compose example retains `NEXTCLOUD_VERSION` as its user-facing setting for the **locally built official base image**. It does not control the GHCR publication matrix.
The repository Compose example uses `NEXTCLOUD_VERSION` to select the **published LibreCode application image tag** for `app` and `cron`. Builds stay in CI and explicit maintainer commands; this setting does not control the GHCR publication matrix. The `make test-current-app-image` and `make scan-images` maintenance targets use the newest reviewed upstream image reference from `.github/nextcloud-supported.json` (overridable with `APP_BASE_IMAGE`), independently of the deployment image selector.

## Reviewed stable-version inventory

Expand Down
57 changes: 57 additions & 0 deletions tests/compose-images.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bats

setup() {
REPO_ROOT=$(cd "$BATS_TEST_DIRNAME/.." && pwd)
}

assert_published_images() {
local file="$1" selected_tag="$2" expected_tag="$3" config

# Compose config validates interpolation without pulling any registry image.
# Empty selected_tag exercises the fallback even if a local .env exists.
config=$(NEXTCLOUD_VERSION="$selected_tag" docker compose \
--env-file /dev/null \
--project-directory "$REPO_ROOT" \
-f "$REPO_ROOT/$file" config --format json) || return 1

jq -e --arg app_image "ghcr.io/librecodecoop/nextcloud-docker-app:$expected_tag" '
.services.app.image == $app_image and
.services.cron.image == $app_image and
.services.web.image == "ghcr.io/librecodecoop/nextcloud-docker-web:main" and
(.services.cron.entrypoint == ["/cron.sh"]) and
([.services.app, .services.cron, .services.web] | all(has("build") | not))
' <<< "$config" >/dev/null
}

@test "standard Compose defaults to the stable-fpm channel" {
assert_published_images docker-compose.yml "" stable-fpm
}

@test "Garage S3 Compose defaults to the stable-fpm channel" {
assert_published_images docker-compose-garages3.yml "" stable-fpm
}

@test "standard Compose applies an arbitrary image tag to both app and cron" {
assert_published_images docker-compose.yml "test-version-fpm" "test-version-fpm"
}

@test "Garage S3 Compose applies an arbitrary image tag to both app and cron" {
assert_published_images docker-compose-garages3.yml "test-version-fpm" "test-version-fpm"
}

@test "sample environment selects the moving stable-fpm channel" {
run grep -Fx "NEXTCLOUD_VERSION=stable-fpm" "$REPO_ROOT/.env.example"
[ "$status" -eq 0 ]
}

@test "maintainer builds use the reviewed upstream base independent of the Compose channel" {
local approved_base target
approved_base=$(jq -er '.versions[-1].image' "$REPO_ROOT/.github/nextcloud-supported.json")

for target in test-current-app-image scan-images; do
run make --no-print-directory -n -C "$REPO_ROOT" "$target"
[ "$status" -eq 0 ]
[[ "$output" == *"base_image='$approved_base'"* ]]
[[ "$output" == *'NEXTCLOUD_BASE_IMAGE=$base_image'* ]]
done
}
Loading