Compare commits

...
Author SHA1 Message Date
Linus Gasser 71b98922af Adding EuroOffice as a compose file 2026-08-11 07:13:00 +02:00
Linus Gasser a6bf651b5c Updating to nextcloud 34.0.2 2026-08-11 07:12:08 +02:00
Linus Gasser 6a39984ed6 Releasing rolling version of nextcloud 2026-08-11 07:06:54 +02:00
Linus Gasser cf0b65feb5 Upgrading postgresql to 17 2026-08-11 07:06:36 +02:00
Linus Gasser 0998a98df5 Updating to nextcloud 33.0.7 2026-08-11 06:46:34 +02:00
dannygroenewegen 2fb279d96a feat: add check_major_upgrade abra.sh function to check readiness for the next major
Checks version skip, pending DB upgrade, occ update:check status, and
non-shipped app compatibility (with an apps.nextcloud.com fallback
lookup) to verify if it looks safe to upgrade to the next Nextcloud major
version.
2026-08-10 15:29:02 +02:00
dannygroenewegen 5d923d343f chore: publish 13.2.0+32-fpm release
continuous-integration/drone/tag Build is passing
2026-08-09 20:52:28 +02:00
dannygroenewegen 14ec244f97 fix: use pgautoupgrade's default healthcheck 2026-08-09 20:48:18 +02:00
dannygroenewegen abd102e3a8 fix: align nginx_conf config name with its compose key
continuous-integration/drone/tag Build is passing
Name dropped the _conf suffix, so abra's live-vs-desired lookup
(keyed by compose config name) never matched and always showed
nginx_conf as (new) on deploy, even when unchanged.
2026-08-09 13:00:35 +00:00
ineiti c7152cc390 Merge pull request 'pr-13.2.0 - Last release for nextcloud-32' (#97) from pr-13.2.0+32-fpm into main
Reviewed-on: #97
2026-08-09 12:48:15 +00:00
Linus Gasser f9e57d1ec1 Last release for nextcloud-32 2026-08-08 11:09:55 +02:00
dannygroenewegen 3be4c3aa4a chore: publish 13.1.5+32.0.13-fpm release
continuous-integration/drone/tag Build is passing
2026-08-02 17:13:45 +02:00
dannygroenewegen e1c9ebd047 Merge pull request 'fix: remove -c max_connections flag from postgres command to fix pgautoupgrade' (#95) from fix-pgautoupgrade-max-connections into main
Reviewed-on: #95
2026-08-02 15:11:45 +00:00
dannygroenewegen 1d9c844cad fix: remove -c max_connections flag from postgres command to fix pgautoupgrade
The pgautoupgrade switch from 13.1.0+32.0.11-fpm was released untested and had a bug: the db service's `-c max_connections=...` command breaks pgautoupgrade, failing with `initdb: invalid option -- 'c'`. See pgautoupgrade/docker-pgautoupgrade#148
2026-08-02 17:02:40 +02:00
Linus Gasser 8e57236f0d Releasing updates
continuous-integration/drone/tag Build is passing
2026-07-25 21:59:52 +02:00
renovate-bot 4c41c21799 chore(deps): update mariadb docker tag to v12 2026-07-25 21:55:11 +02:00
renovate-bot f60f10c6dd chore(deps): update mariadb docker tag to v11.8
continuous-integration/drone/tag Build is passing
2026-07-25 19:40:39 +00:00
renovate-bot d8f5c23897 chore(deps): update nginx docker tag to v1.31.3 2026-07-25 19:35:35 +00:00
renovate-bot 7e4cbce41e chore(deps): update docker.elastic.co/elasticsearch/elasticsearch docker tag to v8.19.19 2026-07-25 19:33:35 +00:00
renovate-bot 6619501f5c chore(deps): update redis docker tag to v8.8.1 2026-07-24 19:17:43 +00:00
renovate-bot 53d7f765ae chore(deps): update nextcloud docker tag to v32.0.13
continuous-integration/drone/tag Build is passing
2026-07-24 02:28:12 +00:00
stevensting fcf1ca56d3 chore: publish 13.1.1+32.0.12-fpm release
continuous-integration/drone/tag Build is passing
2026-07-22 13:27:50 +02:00
renovate-bot 15a795affd chore(deps): update nextcloud docker tag to v32.0.12 (#89)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| nextcloud | patch | `32.0.11-fpm` -> `32.0.12-fpm` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS4xNzMuMSIsInVwZGF0ZWRJblZlciI6IjQxLjE3My4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: #89
Co-authored-by: Renovate Bot <renovate@coopcloud.tech>
Co-committed-by: Renovate Bot <renovate@coopcloud.tech>
2026-07-22 11:19:36 +00:00
Linus Gasser 38c426178a Removing last TBDs 2026-07-21 08:08:52 +02:00
Linus Gasser 38920ae3de README improvements 2026-07-21 07:59:34 +02:00
Linus Gasser 6e6c235acd Adding maintainers to README.md 2026-07-21 07:59:34 +02:00
Linus Gasser 10fdbc92b4 Adding suggestions from @dannygroenewegen 2026-07-21 07:59:34 +02:00
Linus Gasser 8ce1b9cf30 Proposing a MAINTENANCE file
Cobbled together a file with the help of Claude.
I did re-read all of it, manually edited some parts,
and asked for modifications.
2026-07-21 07:59:34 +02:00
ineiti 29431d2a14 Merge pull request 'Remove test-swarm deployment' (#90) from ineiti/nextcloud:remove_test-swarm into main
Reviewed-on: #90
Reviewed-by: ammaratef45 <ammaratef45@proton.me>
2026-07-21 05:54:04 +00:00
Linus Gasser 66fdde358e Remove test-swarm deployment
According to @kawaiipunk from autonomic.zone, this server has been shut
down.
While waiting if they want to spin up a new server, remove this part,
so we get clean CI/CD.
2026-07-20 17:31:21 +02:00
carla 19e7fbb648 chore: publish 13.1.0+32.0.11-fpm release
continuous-integration/drone/push Build is failing
continuous-integration/drone/tag Build is passing
2026-06-10 11:51:22 +02:00
carla 6113ccedde chore: switch from postgres to pgautoupgrade 14 2026-06-08 20:59:29 +02:00
carla 0d0c3b3266 chore: update image tags 2026-06-08 20:21:10 +02:00
18 changed files with 650 additions and 57 deletions
-35
View File
@@ -1,40 +1,5 @@
---
kind: pipeline
name: deploy to swarm-test.autonomic.zone
steps:
- name: deployment
image: git.coopcloud.tech/coop-cloud/stack-ssh-deploy:latest
settings:
host: swarm-test.autonomic.zone
stack: nextcloud
generate_secrets: true
purge: true
deploy_key:
from_secret: drone_ssh_swarm_test
networks:
- proxy
environment:
DOMAIN: nextcloud.swarm-test.autonomic.zone
STACK_NAME: nextcloud
LETS_ENCRYPT_ENV: production
ADMIN_USER: foobar
FPM_TUNE_VERSION: v1
NGINX_CONF_VERSION: v1
MY_CNF_VERSION: v1
ENTRYPOINT_VERSION: v1
CRONTAB_VERSION: v1
PG_BACKUP_VERSION: v2
SECRET_DB_PASSWORD_VERSION: v1
SECRET_DB_ROOT_PASSWORD_VERSION: v1
SECRET_ADMIN_PASSWORD_VERSION: v1
SECRET_ONLYOFFICE_JWT_VERSION: v1
SECRET_BBB_SECRET_VERSION: v1
EXTRA_VOLUME: "/dev/null:/tmp/.dummy"
trigger:
branch:
- main
---
kind: pipeline
name: generate recipe catalogue
steps:
- name: release a new version
+7
View File
@@ -69,6 +69,13 @@ DEFAULT_QUOTA="10 GB"
# APPS="$APPS onlyoffice"
# SECRET_ONLYOFFICE_JWT_VERSION=v1
# Euro-Office runs its own document server in this stack; EUROOFFICE_DOMAIN
# needs its own DNS record pointing at this host.
# COMPOSE_FILE="$COMPOSE_FILE:compose.eurooffice.yml"
# EUROOFFICE_DOMAIN=eurooffice.example.com
# APPS="$APPS eurooffice"
# SECRET_EUROOFFICE_JWT_VERSION=v1
# COMPOSE_FILE="$COMPOSE_FILE:compose.bbb.yml"
# BBB_URL=https://talk.example.org/bigbluebutton/ # trailing slash!
# SECRET_BBB_SECRET_VERSION=v1
+91
View File
@@ -0,0 +1,91 @@
# Nextcloud Recipe Maintenance
This document describes how the Nextcloud recipe is maintained. It builds on
the floor set by [Federation Resolution
025](https://docs.coopcloud.tech/federation/resolutions/passed/025/) and
follows the [`MAINTENANCE.md`
template](https://docs.coopcloud.tech/maintainers/maintain/#maintenancemd-template)
described in the Co-op Cloud maintainers' docs.
All contributions should be made via a pull request so that quality and
consistency stay something others can rely on.
## Maintainers
Everyone can apply to be a recipe maintainer.
Simply add yourself to the list in the README.md and open a new pull request
with the change.
## Maintainer Responsibilities
This recipe commits to the following, which is tighter than the floor set by
Resolution 025 (stable-recipe category). However, these timelines are
best-effort, so we aim for them as good as possible:
- Respond to PRs / issues within 3 working days
- Apply security patches within 1 week of disclosure
- Ship patch / minor image updates within 2 weeks of upstream release
- Adopt major Nextcloud version updates within 1 release cycle of upstream
EOL of the previous major (see below)
- Keep documentation current
In order to meet these responsibilities each maintainer:
- Watches the repository so notifications arrive
- Keeps an eye on [Renovate](./renovate.json) updates and helps shepherd them through
- Has a working contact (Matrix handle or email) reachable by the others
## Release cadence
The intent is to **track Nextcloud's own release schedule** rather than invent
our own. In practice this means:
- **Patch releases (e.g. `32.0.x`)**: published to this recipe shortly after
upstream, ideally within 1 week. `chore(deps)` opens the PRs; a maintainer
reviews the release notes and Nextcloud's issue tracker, and merges the PR
if it is OK.
- **Minor releases**: same flow as patch releases, but one of the maintainer
tests it on their own instance before merging.
- **Major releases (e.g. `32 → 33`)**: not adopted on day one. We wait for the
first one or two upstream patch releases of the new major to land
(typically 12 months) before promoting it here, to avoid passing the
early-adopter cost to operators. Major bumps get their own PR with release
notes and an upgrade-path check.
Before adding a major release, the following needs to be done:
- at least two maintainers update one of their production instances to the
new version
- the previous release gets a last update pointing to the docker image
versions nextcloud:xx-fpm, so that users can auto-update if they wish so
- the new release is added to this repo
- If people have the time it would be nice to create specially tagged versions
for major releases, which reflect that this is 'bleeding edge' and has not
been thoroughly tested.
- **Co-installed components** (Talk HPB, OnlyOffice, Whiteboard, etc.) are
bumped alongside or shortly after the matching Nextcloud release.
## Pull Requests
A pull request can be merged once it is approved by at least one maintainer.
PRs opened by a maintainer need approval from another maintainer. With three
maintainers this is workable; if the group shrinks, the rule should be
revisited.
Approvals should ideally include a smoke test on a real instance for anything
beyond a patch bump — Nextcloud upgrades have a long history of surprising us
(see the [upgrade notes in `README.md`](./README.md#upgrading-nextcloud)),
and silent CI is not enough.
## Becoming a maintainer
Everyone is welcome to apply:
1. Watch the repository so you get notifications.
2. Open a pull request adding yourself to the `Maintainer` line in
[`README.md`](./README.md) and to the list above.
3. Once an existing maintainer merges the PR, you'll be added to the
[nextcloud maintainers
team](https://git.coopcloud.tech/org/coop-cloud/teams/nextcloud-maintainers).
Stepping down is symmetrical: open a PR removing yourself, and flag it in
the federation channels so the group can plan replacement before falling
below the Res. 025 floor of one named maintainer.
+79 -4
View File
@@ -5,6 +5,7 @@
Fully automated luxury Nextcloud via docker-swarm.
<!-- metadata -->
* **Maintainer**: [@dannygroenewegen](https://git.coopcloud.tech/dannygroenewegen), [@ineiti](https://git.coopcloud.tech/ineiti)
* **Category**: Apps
* **Status**: 5
* **Image**: [`nextcloud`](https://hub.docker.com/_/nextcloud), 4, upstream
@@ -25,9 +26,9 @@ Fully automated luxury Nextcloud via docker-swarm.
### Onlyoffice Integration
First install onlyoffice following the instructions in the
First, install onlyoffice following the instructions in the
[OnlyOffice Recipe](https://recipes.coopcloud.tech/onlyoffice), and enable
the JWT secret.
the JWT secret. Then configure your nextcloud instance with:
`abra app config <app-name>`
@@ -43,6 +44,40 @@ Then set the onlyoffice JWT secret from the onlyoffice installation:
* `abra app secret insert <app-name> onlyoffice_jwt v1 <jwt_secret>`
* `abra app cmd <app-name> app install_onlyoffice`
### Euro-Office Integration
Euro-Office is the AGPL fork of OnlyOffice that powers "Nextcloud Office" from
Nextcloud 34 onwards. Like OnlyOffice it uses a client-side document-server
architecture, so a separate document server is required — but this overlay runs
that document server **inside the same stack**, so there is no external host to
manage. The browser talks to it directly, so it needs its own public HTTPS
domain (`EUROOFFICE_DOMAIN`) with a DNS record pointing at this host.
`abra app config <app-name>`
Enable the overlay and set the document server's domain:
```
COMPOSE_FILE="$COMPOSE_FILE:compose.eurooffice.yml"
EUROOFFICE_DOMAIN=eurooffice.example.com
APPS="$APPS eurooffice"
SECRET_EUROOFFICE_JWT_VERSION=v1
```
The overlay runs the document server with its own Postgres and RabbitMQ services
(the image's bundled Postgres is unreliable). The document server schema is
seeded into that Postgres automatically on first init (see
`eurooffice-createdb.sql`). The Postgres is internal-only and uses trust auth, so
the only secret to manage is the JWT; generate it, deploy, then wire up the
Nextcloud app:
* `abra app secret generate -a <app-name>`
* `abra app deploy <app-name>`
* `abra app cmd <app-name> app install_eurooffice`
> Note: the document server needs ~4 GB RAM (8 GB for multi-user) and pulls the
> `ghcr.io/euro-office/documentserver` image, which currently only publishes a
> `latest` tag (no semver / Renovate pinning yet).
### BBB Integration
`abra app config <app-name>`
@@ -129,9 +164,49 @@ To disable dashboard app (since it is so corporate):
- Configure a `defaultapp` in your `config.php` or use [apporder](https://apps.nextcloud.com/apps/apporder)
## Upgrading Nextcloud
Upgrading Nextcloud can be a hair raising experiance. They [don't support downgrading](https://docs.nextcloud.com/server/latest/admin_manual/maintenance/upgrade.html) even for minor versions.
Many of us have found that jumping major versions when upgrading is also a bad idea. We have however found that it's ok to skip minor version upgrades and go to the last minor version before a major version (e.g. 24.0.0 to 24.9.9 before going to 25.0.0). To extra cautious just upgrade one release at a time. Read the release notes and check your logs.
Upgrading Nextcloud can be a hair raising experiance. They
[don't support downgrading](https://docs.nextcloud.com/server/latest/admin_manual/maintenance/upgrade.html)
even for minor versions.
### Upgrade path
Many of us have found that jumping major versions when upgrading is a bad idea.
We have however found that it's ok to skip minor version upgrades and go to the
last minor version before a major version (e.g. 24.0.0 to 24.9.9 before going to
25.0.0). To be extra cautious just upgrade one release at a time. Read the
release notes and check your logs.
### Checking upgrade readiness
Before upgrading to a new major, check whether the instance (and its enabled
apps) look ready:
`abra app cmd <app-name> app check_major_upgrade`
This checks that you're not skipping a major version, that there's no pending DB
upgrade left over from a previous update, and that every enabled non-shipped app
declares support for the target major (falling back to an apps.nextcloud.com
lookup to see if an app update would fix it). Shipped apps (`files`, `settings`,
etc.) are skipped since they come bundled and are upgraded within the Docker
image. Pass an explicit target major as the first argument (e.g.
`check_major_upgrade 33`) to check readiness for a specific major, or it
defaults to current major + 1. This is a sanity check, not a guarantee. Still
read Nextcloud's release notes for any
[critical changes between major versions](https://docs.nextcloud.com/server/stable/admin_manual/release_notes/index.html#critical-changes).
### Staying on an old major version
If you're not able to move to a new major version yet (e.g. because of app
incompatibility), note that (starting from v32) before we release a recipe
container a new major Nextcloud version, we also publish one more release of the
previous major that points its image at the floating `nextcloud:XX-fpm` tag
(e.g. `nextcloud:32-fpm`) instead of a pinned patch version. Deploying that
release is less predictable: every redeploy pulls whatever the latest `32-fpm`
build happens to be at that moment, rather than a fixed, reproducible version.
But it means you keep getting security patches for the old major if you can't
move to the next major. See [MAINTENANCE.md](./MAINTENANCE.md#release-cadence)
for how this fits into our release process.
## Upgrading Nextcloud apps (plug-ins)
+167 -1
View File
@@ -6,11 +6,14 @@ export MY_CNF_VERSION=v6
export ENTRYPOINT_VERSION=v3
export ENTRYPOINT_WHITEBOARD_VERSION=v1
export ENTRYPOINT_TALK_VERSION=v1
export ENTRYPOINT_EUROOFFICE_VERSION=v3
export EUROOFFICE_CREATEDB_VERSION=v1
export CRONTAB_VERSION=v1
export PG_BACKUP_VERSION=v2
run_occ() {
su -p www-data -s /bin/sh -c "/var/www/html/occ $@"
# NOTE: uses $* (not $@) so this still works when called with multiple args as seperate words.
su -p www-data -s /bin/sh -c "/var/www/html/occ $*"
}
install_apps() {
@@ -83,6 +86,13 @@ install_onlyoffice() {
set_app_config onlyoffice customizationForcesave true
}
install_eurooffice() {
install_apps eurooffice
set_app_config eurooffice DocumentServerUrl "https://${EUROOFFICE_DOMAIN}"
set_app_config eurooffice jwt_secret "$(cat /run/secrets/eurooffice_jwt)"
set_app_config eurooffice customizationForcesave true
}
install_collabora() {
install_apps richdocuments
set_app_config richdocuments wopi_url "$COLLABORA_URL"
@@ -193,3 +203,159 @@ set_windowsfriendly_filenames() {
upgrade_mariadb() {
mariadb-upgrade -p`cat /run/secrets/db_root_password`
}
# Checks whether this instance looks ready to update to the next Nextcloud
# major version.
#
# Usage:
# abra app cmd <app-name> app check_major_upgrade
# abra app cmd <app-name> app check_major_upgrade 33 # check readiness for a specific target
#
# What it checks:
# - current version is exactly one major behind the target
# - no pending DB upgrade from a previous, unfinished update
# - whether a newer release is available on the current major
# (recommended before upgradeing to the next major)
# - every enabled, non-shipped app's compatibility with the target major
# - for apps that don't, whether apps.nextcloud.com already has a newer
# release that does
#
# It does NOT check every precondition, always read the release notes
# from Nextcloud too.
check_major_upgrade() {
target_major=$1
echo "=== Nextcloud major upgrade readiness check ==="
status_json=$(run_occ status --output=json 2>/dev/null)
if [ -z "$status_json" ]; then
echo "[FAIL] Could not read 'occ status' - is Nextcloud installed and reachable?"
return 1
fi
current_version=$(echo "$status_json" | php -r '$d=json_decode(stream_get_contents(STDIN),true); echo $d["versionstring"] ?? "";')
current_major=${current_version%%.*}
needs_db_upgrade=$(echo "$status_json" | php -r '$d=json_decode(stream_get_contents(STDIN),true); echo ($d["needsDbUpgrade"] ?? false) ? "true" : "false";')
if [ -z "$current_major" ]; then
echo "[FAIL] Could not determine the current Nextcloud version from 'occ status'."
return 1
fi
if [ -z "$target_major" ]; then
target_major=$((current_major + 1))
fi
echo "Current version: $current_version"
echo "Target major version: $target_major"
ok=true
if [ "$target_major" -le "$current_major" ]; then
echo "[FAIL] Target major ($target_major) is not newer than the current major ($current_major)."
ok=false
elif [ "$target_major" -gt "$((current_major + 1))" ]; then
echo "[FAIL] Cannot skip major versions. Upgrade to $((current_major + 1)) first."
ok=false
fi
if [ "$needs_db_upgrade" = "true" ]; then
echo "[FAIL] A pending database upgrade was detected. Run 'occ upgrade' for the current version first."
ok=false
fi
echo
echo "--- occ update:check ---"
update_check_output=$(run_occ "update:check" 2>&1)
if [ -z "$update_check_output" ]; then
echo "[WARN] 'occ update:check' produced no output, could not verify."
elif echo "$update_check_output" | grep -q "Everything up to date"; then
echo "[OK] Everything up to date."
else
available_version=$(echo "$update_check_output" | grep -oE 'Nextcloud [0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1 | awk '{print $2}')
available_major=${available_version%%.*}
if [ -z "$available_major" ]; then
echo "[WARN] Could not parse 'occ update:check' output to determine the available version."
elif [ "$available_major" = "$current_major" ]; then
echo "[WARN] $available_version is available on the current major. Recommended to update to that before upgrading to $target_major."
else
echo "[OK] Already on the latest release of major $current_major (next available update is $available_version)."
fi
fi
echo
echo "--- Non-shipped app compatibility with Nextcloud $target_major ---"
echo "(shipped apps are skipped, they come bundled with the docker image)"
apps_json=$(run_occ "app:list --shipped=false --enabled --output=json" 2>/dev/null)
if [ -z "$apps_json" ]; then
echo "[WARN] 'occ app:list' returned no output, could not check non-shipped app compatibility."
enabled_apps=""
else
apps_json_valid=$(echo "$apps_json" | php -r '$d=json_decode(stream_get_contents(STDIN),true); echo (json_last_error() === JSON_ERROR_NONE && is_array($d)) ? "1" : "0";')
if [ "$apps_json_valid" != "1" ]; then
echo "[WARN] Could not parse 'occ app:list' output, could not check non-shipped app compatibility."
enabled_apps=""
else
enabled_apps=$(echo "$apps_json" | php -r '$d=json_decode(stream_get_contents(STDIN),true); foreach(array_keys($d["enabled"] ?? []) as $a) echo $a."\n";')
if [ -z "$enabled_apps" ]; then
echo "No non-shipped apps are enabled - nothing to check here."
fi
fi
fi
compatible_apps=""
compatible_apps_fetched=0
for app in $enabled_apps; do
info_file=$(find /var/www/html/apps /var/www/html/custom_apps -maxdepth 3 -type f -ipath "*/$app/appinfo/info.xml" 2>/dev/null | head -n1)
if [ -z "$info_file" ]; then
echo "[WARN] $app: could not locate appinfo/info.xml, skipping"
continue
fi
max_version=$(php -r '
$x = @simplexml_load_file($argv[1]);
$dep = $x ? ($x->dependencies->nextcloud ?? null) : null;
echo $dep !== null ? (string)$dep["max-version"] : "";
' "$info_file")
if [ -z "$max_version" ]; then
echo "[WARN] $app: no max-version declared in info.xml, assume compatible but verify manually"
continue
fi
if [ "${max_version%%.*}" -ge "$target_major" ] 2>/dev/null; then
echo "[OK] $app: installed version supports up to Nextcloud $max_version"
continue
fi
echo "[INFO] $app: installed version only supports up to Nextcloud $max_version"
if [ "$compatible_apps_fetched" != "1" ]; then
compatible_apps_fetched=1
compatible_apps=$(curl -fsSL --max-time 30 "https://apps.nextcloud.com/api/v1/platform/${target_major}.0.0/apps.json" 2>/dev/null \
| php -r '$d=json_decode(stream_get_contents(STDIN),true); if(is_array($d)) foreach($d as $a) echo $a["id"]."\n";')
fi
if [ -z "$compatible_apps" ]; then
echo "[FAIL] $app: could not reach apps.nextcloud.com to check for a newer compatible release, verify manually"
ok=false
elif echo "$compatible_apps" | grep -qxF "$app"; then
echo "[WARN] $app: apps.nextcloud.com has a release that supports $target_major. It may not update until Nextcloud is upgraded, occ upgrade will try to update it automatically"
else
echo "[FAIL] $app: no apps.nextcloud.com release supports $target_major yet, it will be disabled during the upgrade"
ok=false
fi
done
echo
if [ "$ok" = true ]; then
echo "=== READY: no blocking issues found for upgrade to major $target_major ==="
return 0
else
echo "=== NOT READY: resolve the [FAIL] items above before running the upgrade ==="
return 1
fi
}
+118
View File
@@ -0,0 +1,118 @@
version: "3.8"
services:
app:
secrets:
- eurooffice_jwt
environment:
- EUROOFFICE_DOMAIN
eurooffice:
image: ghcr.io/euro-office/documentserver:v9.3.2
stdin_open: true
depends_on:
- eurooffice-db
- eurooffice-rabbitmq
networks:
- proxy
- internal
environment:
- JWT_ENABLED=true
- JWT_SECRET_FILE=/run/secrets/eurooffice_jwt
# Use external Postgres + RabbitMQ instead of the flaky bundled ones.
# (The all-in-one image ships an uncleanly-shut-down Postgres data dir
# whose crash recovery exceeds pg_ctl's start timeout -> restart loop.)
- DB_TYPE=postgres
- DB_HOST=eurooffice-db
- DB_PORT=5432
- DB_NAME=eurooffice
- DB_USER=eurooffice
- AMQP_URI=amqp://guest:guest@eurooffice-rabbitmq
volumes:
- eurooffice_data:/var/lib/euro-office
- eurooffice_config:/etc/euro-office
- eurooffice_logs:/var/log/euro-office
- eurooffice_fonts:/usr/share/fonts/custom
secrets:
- eurooffice_jwt
configs:
- source: entrypoint_eurooffice
target: /custom-entrypoint.sh
mode: 555
entrypoint: /custom-entrypoint.sh
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/healthcheck"]
interval: 30s
timeout: 10s
retries: 10
start_period: 3m
deploy:
update_config:
failure_action: rollback
order: start-first
labels:
- "traefik.enable=true"
- "traefik.swarm.network=proxy"
- "traefik.http.services.${STACK_NAME}_eurooffice.loadbalancer.server.port=80"
- "traefik.http.routers.${STACK_NAME}_eurooffice.rule=Host(`${EUROOFFICE_DOMAIN}`)"
- "traefik.http.routers.${STACK_NAME}_eurooffice.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}_eurooffice.tls.certresolver=${LETS_ENCRYPT_ENV}"
- "traefik.http.routers.${STACK_NAME}_eurooffice.middlewares=${STACK_NAME}_eurooffice-fwdproto"
- "traefik.http.middlewares.${STACK_NAME}_eurooffice-fwdproto.headers.customRequestHeaders.X-Forwarded-Proto=https"
eurooffice-db:
image: postgres:16-alpine
networks:
- internal
environment:
- POSTGRES_DB=eurooffice
- POSTGRES_USER=eurooffice
# Internal-only DB holding transient editing state; trust auth on the
# private overlay network avoids managing a Swarm secret for it.
- POSTGRES_HOST_AUTH_METHOD=trust
volumes:
- eurooffice_db:/var/lib/postgresql/data
configs:
# Seed the document server schema on first init. The all-in-one image only
# creates its schema in the *bundled* Postgres; with an external DB the
# docservice starts against an empty DB, errors on missing task_result /
# doc_changes, never binds its port, and gets healthcheck-killed in a loop.
- source: eurooffice_createdb
target: /docker-entrypoint-initdb.d/createdb.sql
healthcheck:
test: ["CMD", "pg_isready", "-U", "eurooffice"]
interval: 30s
timeout: 10s
retries: 10
start_period: 1m
eurooffice-rabbitmq:
image: rabbitmq:4.3.2
networks:
- internal
healthcheck:
test: rabbitmq-diagnostics -q ping
interval: 30s
timeout: 10s
retries: 10
start_period: 1m
secrets:
eurooffice_jwt:
external: true
name: ${STACK_NAME}_eurooffice_jwt_${SECRET_EUROOFFICE_JWT_VERSION}
volumes:
eurooffice_data:
eurooffice_config:
eurooffice_logs:
eurooffice_fonts:
eurooffice_db:
configs:
entrypoint_eurooffice:
name: ${STACK_NAME}_entrypoint_eurooffice_${ENTRYPOINT_EUROOFFICE_VERSION}
file: entrypoint.eurooffice.sh.tmpl
template_driver: golang
eurooffice_createdb:
name: ${STACK_NAME}_eurooffice_createdb_${EUROOFFICE_CREATEDB_VERSION}
file: eurooffice-createdb.sql
+2 -2
View File
@@ -2,7 +2,7 @@ version: "3.8"
services:
elasticsearch:
image: "docker.elastic.co/elasticsearch/elasticsearch:8.17.2"
image: "docker.elastic.co/elasticsearch/elasticsearch:8.19.19"
environment:
- cluster.name=docker-cluster
- bootstrap.memory_lock=true
@@ -29,7 +29,7 @@ services:
mode: 0600
searchindexer:
image: nextcloud:32.0.3-fpm
image: nextcloud:34.0.2-fpm
volumes:
- nextcloud:/var/www/html/
- nextapps:/var/www/html/custom_apps:cached
+1 -1
View File
@@ -9,7 +9,7 @@ services:
- MYSQL_PASSWORD_FILE=/run/secrets/db_password
db:
image: "mariadb:11.4"
image: "mariadb:12.3"
environment:
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
+8 -7
View File
@@ -10,8 +10,9 @@ services:
- NEXTCLOUD_UPDATE=1
db:
image: "postgres:13"
command: -c "max_connections=${MAX_DB_CONNECTIONS:-100}"
image: "pgautoupgrade/pgautoupgrade:17-debian"
#setting max_connections with -c breaks pgautoupgrade
#command: -c "max_connections=${MAX_DB_CONNECTIONS:-100}"
volumes:
- "postgres:/var/lib/postgresql/data"
networks:
@@ -22,11 +23,11 @@ services:
POSTGRES_DB: nextcloud
secrets:
- db_password
healthcheck:
test: ["CMD-SHELL", "pg_isready", "-U", "nextcloud"]
interval: 10s
timeout: 5s
retries: 5
# The pgautoupgrade image already ships its own HEALTHCHECK.
# This runs pg_isready but also takes into accounts if pg_upgrade is being run.
# No need to override it here.
# healthcheck:
# test: ["CMD", "/usr/local/bin/pgautoupgrade-healthcheck.sh"]
deploy:
labels:
backupbot.backup.pre-hook: "/pg_backup.sh backup"
+1 -1
View File
@@ -6,7 +6,7 @@ services:
- whiteboard_jwt
whiteboard:
image: ghcr.io/nextcloud-releases/whiteboard:v1.5.0
image: ghcr.io/nextcloud-releases/whiteboard:v1.5.9
deploy:
labels:
- traefik.enable=true
+6 -6
View File
@@ -1,7 +1,7 @@
version: "3.8"
services:
web:
image: nginx:1.29.4
image: nginx:1.31.3
depends_on:
- app
configs:
@@ -48,7 +48,7 @@ services:
start_period: 5m
app:
image: nextcloud:32.0.3-fpm
image: nextcloud:34.0.2-fpm
depends_on:
- db
configs:
@@ -95,7 +95,7 @@ services:
failure_action: rollback
order: start-first
labels:
- "coop-cloud.${STACK_NAME}.version=13.0.1+32.0.3-fpm"
- "coop-cloud.${STACK_NAME}.version=15.1.0+34.0.2-fpm"
- "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT}"
- "backupbot.backup=${ENABLE_BACKUPS:-true}"
- "backupbot.backup.volumes.redis=false"
@@ -109,7 +109,7 @@ services:
start_period: 15m
cron:
image: nextcloud:32.0.3-fpm
image: nextcloud:34.0.2-fpm
volumes:
- nextcloud:/var/www/html/
- nextapps:/var/www/html/custom_apps:cached
@@ -125,7 +125,7 @@ services:
cache:
image: redis:8.4.0-alpine
image: redis:8.8.1-alpine
networks:
- internal
volumes:
@@ -154,7 +154,7 @@ volumes:
configs:
nginx_conf:
name: ${STACK_NAME}_nginx_${NGINX_CONF_VERSION}
name: ${STACK_NAME}_nginx_conf_${NGINX_CONF_VERSION}
file: nginx.conf.tmpl
template_driver: golang
fpm_tune:
+30
View File
@@ -0,0 +1,30 @@
#!/bin/bash
set -eu
# Read a Swarm secret file (<VAR>_FILE) into the plain env var the
# Euro-Office document server expects, then hand off to its own entrypoint.
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
local val="$def"
if [ "${!var:-}" ]; then
val="${!var}"
elif [ "${!fileVar:-}" ]; then
val="$(< "${!fileVar}")"
fi
export "$var"="$val"
unset "$fileVar"
}
file_env "JWT_SECRET"
exec /entrypoint.sh
+73
View File
@@ -0,0 +1,73 @@
--
-- Create schema onlyoffice
--
-- CREATE DATABASE onlyoffice ENCODING = 'UTF8' CONNECTION LIMIT = -1;
-- ----------------------------
-- Table structure for doc_changes
-- ----------------------------
CREATE TABLE IF NOT EXISTS "doc_changes" (
"tenant" varchar(255) COLLATE "default" NOT NULL,
"id" varchar(255) COLLATE "default" NOT NULL,
"change_id" int4 NOT NULL,
"user_id" varchar(255) COLLATE "default" NOT NULL,
"user_id_original" varchar(255) COLLATE "default" NOT NULL,
"user_name" varchar(255) COLLATE "default" NOT NULL,
"change_data" text COLLATE "default" NOT NULL,
"change_date" timestamp without time zone NOT NULL,
PRIMARY KEY ("tenant", "id", "change_id")
)
WITH (OIDS=FALSE);
-- ----------------------------
-- Table structure for task_result
-- ----------------------------
CREATE TABLE IF NOT EXISTS "task_result" (
"tenant" varchar(255) COLLATE "default" NOT NULL,
"id" varchar(255) COLLATE "default" NOT NULL,
"status" int2 NOT NULL,
"status_info" int4 NOT NULL,
"created_at" timestamp without time zone DEFAULT NOW(),
"last_open_date" timestamp without time zone NOT NULL,
"user_index" int4 NOT NULL DEFAULT 1,
"change_id" int4 NOT NULL DEFAULT 0,
"callback" text COLLATE "default" NOT NULL,
"baseurl" text COLLATE "default" NOT NULL,
"password" text COLLATE "default" NULL,
"additional" text COLLATE "default" NULL,
PRIMARY KEY ("tenant", "id")
)
WITH (OIDS=FALSE);
CREATE OR REPLACE FUNCTION merge_db(_tenant varchar(255), _id varchar(255), _status int2, _status_info int4, _last_open_date timestamp without time zone, _user_index int4, _change_id int4, _callback text, _baseurl text, OUT isupdate char(5), OUT userindex int4) AS
$$
DECLARE
t_var "task_result"."user_index"%TYPE;
BEGIN
LOOP
-- first try to update the key
-- note that "a" must be unique
IF ((_callback <> '') IS TRUE) AND ((_baseurl <> '') IS TRUE) THEN
UPDATE "task_result" SET last_open_date=_last_open_date, user_index=user_index+1,callback=_callback,baseurl=_baseurl WHERE tenant = _tenant AND id = _id RETURNING user_index into userindex;
ELSE
UPDATE "task_result" SET last_open_date=_last_open_date, user_index=user_index+1 WHERE tenant = _tenant AND id = _id RETURNING user_index into userindex;
END IF;
IF found THEN
isupdate := 'true';
RETURN;
END IF;
-- not there, so try to insert the key
-- if someone else inserts the same key concurrently,
-- we could get a unique-key failure
BEGIN
INSERT INTO "task_result"(tenant, id, status, status_info, last_open_date, user_index, change_id, callback, baseurl) VALUES(_tenant, _id, _status, _status_info, _last_open_date, _user_index, _change_id, _callback, _baseurl) RETURNING user_index into userindex;
isupdate := 'false';
RETURN;
EXCEPTION WHEN unique_violation THEN
-- do nothing, and loop to try the UPDATE again
END;
END LOOP;
END;
$$
LANGUAGE plpgsql;
+3
View File
@@ -0,0 +1,3 @@
Important:
Posgres: Due to end of support for postgres 13 we upgraded to pgautoupgrade-14-debian but we could not test it, so please take backups before the upgrade!
Elastic Search: We chose the latest minor update for elasticsearch but we were also not able to test it.
+4
View File
@@ -0,0 +1,4 @@
chore(deps): update mariadb docker tag to v12
chore(deps): update mariadb docker tag to v11.8
chore(deps): update nginx docker tag to v1.31.3
chore(deps): update docker.elastic.co/elasticsearch/elasticsearch docker tag to v8.19.19
+2
View File
@@ -0,0 +1,2 @@
Important:
The pgautoupgrade switch from 13.1.0+32.0.11-fpm was released untested and had a bug: the db service's `-c max_connections=...` command breaks pgautoupgrade, failing with `initdb: invalid option -- 'c'`. If your db got stuck mid-upgrade on 13.1.0-13.1.4 with that error: restore the old data dir and remove the upgrade lock file. Then redeploy this version.
+1
View File
@@ -0,0 +1 @@
Last release for nextcloud-32, pointing to the latest version of nextcloud-32.
+57
View File
@@ -0,0 +1,57 @@
Upgrades Nextcloud from 32.0.13 to 33 (major version upgrade).
IMPORTANT:
- Nextcloud does NOT support downgrades. Take a backup before deploying.
- Do not skip major versions: your instance must be on the latest 32.x before
upgrading to 33. If you are on an older 32.x, deploy 32.0.13 first.
- After deploying, check the logs and run any pending repair/upgrade steps:
`abra app cmd <app> app run_occ '"app:update --all"'`
- Review app (plug-in) compatibility with Nextcloud 33 before upgrading; some
apps may need to be updated or temporarily disabled.
- Added `check_major_upgrade` (`abra app cmd <app-name> app check_major_upgrade`)
to check whether an instance is ready to upgrade to the next Nextcloud
major version.
Upgrades postgresql with pgautoupgrade:17.
Please only update coming from 14.0.0+33.0.7-fpm.
Last release of the nextcloud recipe for versio 33 with a rolling version.
Upgrades Nextcloud from 33 to 34.0.2 (major version upgrade).
IMPORTANT:
- Check your current version is up-to-date with
`abra app cmd <app-name> app check_major_upgrade` before updating to this version
- Nextcloud does NOT support downgrades. Take a backup before deploying.
- Do not skip major versions: your instance must be on the latest 33.x before
upgrading to 34.0.2. If you are on an older 33.x, deploy 33.0.7 first.
- After deploying, check the logs and run any pending repair/upgrade steps:
`abra app cmd <app> app run_occ '"app:update --all"'`
- Review app (plug-in) compatibility with Nextcloud 34.0.2 before upgrading; some
apps may need to be updated or temporarily disabled.
Adds an optional Euro-Office integration (compose.eurooffice.yml).
Euro-Office is the AGPL fork of OnlyOffice that powers "Nextcloud Office" from
Nextcloud 34 onwards. This overlay runs the Euro-Office document server inside
the stack, so there is no external document server to manage.
This change is additive: existing installs are unaffected unless you opt in.
To enable it (`abra app config <app>`):
- COMPOSE_FILE="$COMPOSE_FILE:compose.eurooffice.yml"
- EUROOFFICE_DOMAIN=eurooffice.example.com
- APPS="$APPS eurooffice"
- SECRET_EUROOFFICE_JWT_VERSION=v1
Then:
- Create a DNS record for EUROOFFICE_DOMAIN pointing at this host (the browser
talks to the document server directly over HTTPS).
- `abra app secret generate -a <app>`
- `abra app deploy <app>`
- `abra app cmd <app> app install_eurooffice`
Notes:
- The document server needs ~4 GB RAM (8 GB recommended for multi-user).
- The `ghcr.io/euro-office/documentserver` image currently only publishes a
`latest` tag (no semver pinning yet), so it is not tracked by Renovate.