forked from coop-cloud/nextcloud
Compare commits
50
Commits
main
...
update_33.0.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd01844b8f | ||
|
|
72562871ea | ||
|
|
bac93fd4a5 | ||
|
|
c0683807bb | ||
|
|
2b23d5f654 | ||
|
|
533f4bf66c | ||
|
|
2e0a4cf928 | ||
|
|
080fedc4b6 | ||
|
|
0998a98df5 | ||
|
|
2fb279d96a
|
||
|
|
5d923d343f | ||
|
|
14ec244f97
|
||
|
|
abd102e3a8 | ||
|
|
c7152cc390 | ||
|
|
f9e57d1ec1 | ||
|
|
3be4c3aa4a | ||
|
|
e1c9ebd047 | ||
|
|
1d9c844cad
|
||
|
|
8e57236f0d | ||
|
|
4c41c21799 | ||
|
|
f60f10c6dd | ||
|
|
d8f5c23897 | ||
|
|
7e4cbce41e | ||
|
|
6619501f5c | ||
|
|
53d7f765ae | ||
|
|
fcf1ca56d3 | ||
|
|
15a795affd | ||
|
|
38c426178a | ||
|
|
38920ae3de | ||
|
|
6e6c235acd | ||
|
|
10fdbc92b4 | ||
|
|
8ce1b9cf30 | ||
|
|
29431d2a14 | ||
|
|
66fdde358e | ||
|
|
19e7fbb648 | ||
|
|
6113ccedde | ||
|
|
0d0c3b3266 | ||
|
|
45d1985ddc | ||
|
|
d49f3c4ef8 | ||
|
|
a2395c6399 | ||
|
|
e4b3bc4f22 | ||
|
|
21ea1daf83
|
||
|
|
ec5934e191 | ||
|
|
4c3f6fa14d | ||
|
|
eb3816b9c2 | ||
|
|
8b7ed8142e | ||
|
|
87b064c773 | ||
|
|
d6a77fac4d | ||
|
|
f27ea1a2cc | ||
|
|
c952020194 |
-35
@@ -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
|
||||
|
||||
+17
-1
@@ -1,5 +1,5 @@
|
||||
TYPE=nextcloud
|
||||
TIMEOUT=900
|
||||
#TIMEOUT=900
|
||||
ENABLE_AUTO_UPDATE=true
|
||||
ENABLE_BACKUPS=true
|
||||
|
||||
@@ -15,6 +15,7 @@ COMPOSE_FILE="$COMPOSE_FILE:compose.mariadb.yml"
|
||||
#MAX_DB_CONNECTIONS=500
|
||||
|
||||
ADMIN_USER=admin
|
||||
TZ=Etc/UTC
|
||||
|
||||
SECRET_DB_ROOT_PASSWORD_VERSION=v1
|
||||
SECRET_DB_PASSWORD_VERSION=v1
|
||||
@@ -86,6 +87,21 @@ DEFAULT_QUOTA="10 GB"
|
||||
#COMPOSE_FILE="$COMPOSE_FILE:compose.fulltextsearch.yml"
|
||||
#SECRET_ELASTICSEARCH_PASSWORD_VERSION=v1
|
||||
|
||||
#COMPOSE_FILE="$COMPOSE_FILE:compose.talk.yml"
|
||||
#TALK_DOMAIN=talk.example.com
|
||||
#SECRET_TALK_INTERNAL_SECRET_VERSION=v1 # length=64 charset=default
|
||||
#SECRET_TALK_TURN_SECRET_VERSION=v1 # length=64 charset=default
|
||||
#SECRET_TALK_SIGNALING_SECRET_VERSION=v1 # length=64 charset=default
|
||||
|
||||
# COMPOSE_FILE="$COMPOSE_FILE:compose.user_oidc.yml"
|
||||
# APPS="$APPS user_oidc"
|
||||
# USER_OIDC_PROVIDER=
|
||||
# USER_OIDC_ID=
|
||||
# USER_OIDC_DISCOVERY_URI=
|
||||
# USER_OIDC_END_SESSION_URI=
|
||||
# USER_OIDC_LOGIN_ONLY=false
|
||||
# SECRET_USER_OIDC_SECRET_VERSION=v1
|
||||
|
||||
# HSTS Options
|
||||
# Uncomment this line to enable HSTS: https://docs.nextcloud.com/server/30/admin_manual/installation/harden_server.html
|
||||
#HSTS_ENABLED=1
|
||||
|
||||
@@ -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 1–2 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.
|
||||
@@ -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), [@javielico](https://git.coopcloud.tech/javielico)
|
||||
* **Category**: Apps
|
||||
* **Status**: 5
|
||||
* **Image**: [`nextcloud`](https://hub.docker.com/_/nextcloud), 4, upstream
|
||||
@@ -25,20 +26,28 @@ Fully automated luxury Nextcloud via docker-swarm.
|
||||
|
||||
### Onlyoffice Integration
|
||||
|
||||
First, install onlyoffice following the instructions in the
|
||||
[OnlyOffice Recipe](https://recipes.coopcloud.tech/onlyoffice), and enable
|
||||
the JWT secret. Then configure your nextcloud instance with:
|
||||
|
||||
`abra app config <app-name>`
|
||||
Configure the following envs:
|
||||
|
||||
Configure the following envs with the URL of the onlyoffice service:
|
||||
```
|
||||
COMPOSE_FILE="$COMPOSE_FILE:compose.apps.yml"
|
||||
ONLYOFFICE_URL=https://onlyoffice.example.com
|
||||
SECRET_ONLYOFFICE_JWT_VERSION=v1
|
||||
```
|
||||
|
||||
`abra app secret insert <app-name> onlyoffice_jwt v1 <jwt_secret>`
|
||||
`abra app cmd <app-name> app install_onlyoffice`
|
||||
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`
|
||||
|
||||
### BBB Integration
|
||||
|
||||
`abra app config <app-name>`
|
||||
|
||||
Configure the following envs:
|
||||
```
|
||||
COMPOSE_FILE="$COMPOSE_FILE:compose.apps.yml"
|
||||
@@ -46,8 +55,44 @@ BBB_URL=https://talk.example.org/bigbluebutton/ # trailing slash!
|
||||
SECRET_BBB_SECRET_VERSION=v1
|
||||
```
|
||||
|
||||
`abra app secret insert <app-name> bbb_secret v1 <bbb_secret>`
|
||||
`abra app cmd <app-name> app install_bbb`
|
||||
* `abra app secret insert <app-name> bbb_secret v1 <bbb_secret>`
|
||||
* `abra app cmd <app-name> app install_bbb`
|
||||
|
||||
### Nextcloud Talk High performance Backend
|
||||
|
||||
Note: at the moment you are limited to run one Nextcloud high performance backend per docker host with this setup.
|
||||
|
||||
`abra app config <app-name>`
|
||||
|
||||
Configure the following envs:
|
||||
```
|
||||
#COMPOSE_FILE="$COMPOSE_FILE:compose.talk.yml"
|
||||
#TALK_DOMAIN=talk.example.com
|
||||
#SECRET_TALK_INTERNAL_SECRET_VERSION=v1 # length=64 charset=default
|
||||
#SECRET_TALK_TURN_SECRET_VERSION=v1 # length=64 charset=default
|
||||
#SECRET_TALK_SIGNALING_SECRET_VERSION=v1 # length=64 charset=default
|
||||
```
|
||||
|
||||
* `abra app secret insert <app-name> talk_internal_secret v1 <talk_internal_secret>`
|
||||
* `abra app secret insert <app-name> talk_turn_secret v1 <talk_turn_secret>`
|
||||
* `abra app secret insert <app-name> talk_signaling_secret v1 <talk_signaling_secret>`
|
||||
* `abra app cmd <app-name> app install_talk`
|
||||
|
||||
Don't forget to enable the additional env's in your hosts traefik instance:
|
||||
```
|
||||
COMPOSE_FILE="$COMPOSE_FILE:compose.nextcloud-talk-hpb.yml"
|
||||
NEXTCLOUD_TALK_HPB_ENABLED=1
|
||||
```
|
||||
|
||||
Due to a bug in compose that deletes duplacted ports without checking for the protocol, traefik need to get the additional udp binding added after the deployment via ssh (this might take longer than expected!):
|
||||
```
|
||||
docker service update --publish-add published=3478,target=3478,protocol=udp traefik_XXX_XXX_app
|
||||
```
|
||||
|
||||
To check if tcp and udp was binded, you can use:
|
||||
```
|
||||
docker service inspect traefik_XXX_XXX_app | grep 3478 -a2
|
||||
```
|
||||
|
||||
### Authentik Integration
|
||||
|
||||
@@ -85,9 +130,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)
|
||||
|
||||
@@ -150,6 +235,31 @@ We've been able to get this setup by using the [social login](https://apps.nextc
|
||||
|
||||
If using Keycloak, you'll want to do [this trick](https://janikvonrotz.ch/2020/10/20/openid-connect-with-nextcloud-and-keycloak/) also.
|
||||
|
||||
## How do I enable OpenID Connect (OIDC) providers?
|
||||
[user_oidc](https://github.com/nextcloud/user_oidc) is the recommended way to integrate Nextcloud with OIDC providers.
|
||||
|
||||
Run `abra app config <app-name>`
|
||||
|
||||
Set the following envs:
|
||||
```env
|
||||
COMPOSE_FILE="$COMPOSE_FILE:compose.user_oidc.yml"
|
||||
APPS="$APPS user_oidc"
|
||||
USER_OIDC_PROVIDER=example-provider # this has been tested with keycloak
|
||||
USER_OIDC_ID=example-client-id # get this from your oidc provider
|
||||
USER_OIDC_DISCOVERY_URI=example-oidc-provider.com/.well-known/openid-configuration # get this from your oidc provider
|
||||
USER_OIDC_END_SESSION_URI=example-oidc-provider.com/protocol/openid-connect/logout # get this from your oidc provider
|
||||
USER_OIDC_LOGIN_ONLY=false # set this to true to automatically redirect all logins to your oidc provider
|
||||
SECRET_USER_OIDC_SECRET_VERSION=v1
|
||||
```
|
||||
|
||||
Then insert the client secret from your OIDC provider:
|
||||
```sh
|
||||
abra app secret insert <app-name> user_oidc_secret v1 <client-secret from oidc provider>
|
||||
```
|
||||
|
||||
After you deploy (or redeploy), run the following to set up the user_oidc Nextcloud app:
|
||||
`abra app cmd <app-name> app set_user_oidc`
|
||||
|
||||
## How can I customise the CSS?
|
||||
|
||||
There is some basic stuff in the admin settings.
|
||||
|
||||
@@ -5,11 +5,13 @@ export NGINX_CONF_VERSION=v8
|
||||
export MY_CNF_VERSION=v6
|
||||
export ENTRYPOINT_VERSION=v3
|
||||
export ENTRYPOINT_WHITEBOARD_VERSION=v1
|
||||
export ENTRYPOINT_TALK_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() {
|
||||
@@ -97,6 +99,15 @@ install_whiteboard() {
|
||||
}
|
||||
|
||||
|
||||
install_talk() {
|
||||
install_apps spreed
|
||||
run_occ "talk:signaling:add --verify 'wss://${TALK_DOMAIN}' '$(cat /run/secrets/talk_signaling_secret)'"
|
||||
run_occ "talk:stun:add '${TALK_DOMAIN}:3478'"
|
||||
run_occ "talk:stun:add '${TALK_DOMAIN}:443'"
|
||||
run_occ "talk:turn:add --secret='$(cat /run/secrets/talk_turn_secret)' turn '${TALK_DOMAIN}:3478' udp,tcp"
|
||||
|
||||
}
|
||||
|
||||
install_fulltextsearch() {
|
||||
install_apps fulltextsearch
|
||||
install_apps fulltextsearch_elasticsearch
|
||||
@@ -149,6 +160,23 @@ set_authentik() {
|
||||
run_occ 'config:system:set lost_password_link --value=disabled'
|
||||
}
|
||||
|
||||
set_user_oidc() {
|
||||
install_apps user_oidc
|
||||
USER_OIDC_SECRET=$(cat /run/secrets/user_oidc_secret)
|
||||
run_occ "user_oidc:provider \
|
||||
--clientid=${USER_OIDC_ID} \
|
||||
--clientsecret=${USER_OIDC_SECRET} \
|
||||
--discoveryuri=${USER_OIDC_DISCOVERY_URI} \
|
||||
--endsessionendpointuri=${USER_OIDC_END_SESSION_URI} \
|
||||
--postlogouturi=https://${DOMAIN} \
|
||||
--scope='openid email profile' \
|
||||
${USER_OIDC_PROVIDER}"
|
||||
# disable non user_oidc login
|
||||
if [[ ${USER_OIDC_LOGIN_ONLY:-false} = "true" ]]; then
|
||||
run_occ "config:app:set --value=0 user_oidc allow_multiple_user_backends"
|
||||
fi
|
||||
}
|
||||
|
||||
disable_skeletondirectory() {
|
||||
run_occ "config:system:set skeletondirectory --value ''"
|
||||
}
|
||||
@@ -166,3 +194,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
|
||||
}
|
||||
|
||||
@@ -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.20"
|
||||
environment:
|
||||
- cluster.name=docker-cluster
|
||||
- bootstrap.memory_lock=true
|
||||
@@ -29,7 +29,7 @@ services:
|
||||
mode: 0600
|
||||
|
||||
searchindexer:
|
||||
image: nextcloud:31.0.6-fpm
|
||||
image: nextcloud:33.0.8-fpm
|
||||
volumes:
|
||||
- nextcloud:/var/www/html/
|
||||
- nextapps:/var/www/html/custom_apps:cached
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
talk:
|
||||
image: "nextcloud/aio-talk:20251128_084214"
|
||||
environment:
|
||||
- NC_DOMAIN=${DOMAIN}
|
||||
- TALK_HOST=${TALK_DOMAIN}
|
||||
- TZ
|
||||
- TALK_PORT=3478
|
||||
- INTERNAL_SECRET_FILE=/run/secrets/talk_internal_secret
|
||||
- TURN_SECRET_FILE=/run/secrets/talk_turn_secret
|
||||
- SIGNALING_SECRET_FILE=/run/secrets/talk_signaling_secret
|
||||
deploy:
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.swarm.network=proxy
|
||||
- traefik.http.services.${STACK_NAME}_talk.loadbalancer.server.port=8081
|
||||
- traefik.http.routers.${STACK_NAME}_talk.rule=Host(`${TALK_DOMAIN}`)
|
||||
- traefik.http.routers.${STACK_NAME}_talk.entrypoints=web-secure
|
||||
- traefik.http.routers.${STACK_NAME}_talk.tls.certresolver=${LETS_ENCRYPT_ENV}
|
||||
- traefik.tcp.routers.${STACK_NAME}_nextcloud-talk-hpb.rule=HostSNI(`*`)
|
||||
- traefik.tcp.routers.${STACK_NAME}_nextcloud-talk-hpb.entrypoints=nextcloud-talk-hpb
|
||||
- traefik.tcp.routers.${STACK_NAME}_nextcloud-talk-hpb.service=${STACK_NAME}_nextcloud-talk-hpb-svc
|
||||
- traefik.tcp.services.${STACK_NAME}_nextcloud-talk-hpb-svc.loadbalancer.server.port=3478
|
||||
- traefik.udp.routers.${STACK_NAME}_nextcloud-talk-hpb-udp.entrypoints=nextcloud-talk-hpb-udp
|
||||
- traefik.udp.routers.${STACK_NAME}_nextcloud-talk-hpb-udp.service=${STACK_NAME}_nextcloud-talk-hpb-udp-svc
|
||||
- traefik.udp.services.${STACK_NAME}_nextcloud-talk-hpb-udp-svc.loadbalancer.server.port=3478
|
||||
networks:
|
||||
- proxy
|
||||
configs:
|
||||
- source: entrypoint_talk
|
||||
target: /custom-entrypoint.sh
|
||||
mode: 775
|
||||
entrypoint: /custom-entrypoint.sh
|
||||
secrets:
|
||||
- source: talk_internal_secret
|
||||
uid: "1000"
|
||||
gid: "122"
|
||||
mode: 0600
|
||||
- source: talk_turn_secret
|
||||
uid: "1000"
|
||||
gid: "122"
|
||||
mode: 0600
|
||||
- source: talk_signaling_secret
|
||||
uid: "1000"
|
||||
gid: "122"
|
||||
mode: 0600
|
||||
|
||||
app:
|
||||
secrets:
|
||||
- talk_turn_secret
|
||||
- talk_signaling_secret
|
||||
|
||||
secrets:
|
||||
talk_internal_secret:
|
||||
external: true
|
||||
name: ${STACK_NAME}_talk_internal_secret_${SECRET_TALK_INTERNAL_SECRET_VERSION}
|
||||
talk_turn_secret:
|
||||
external: true
|
||||
name: ${STACK_NAME}_talk_turn_secret_${SECRET_TALK_TURN_SECRET_VERSION}
|
||||
talk_signaling_secret:
|
||||
external: true
|
||||
name: ${STACK_NAME}_talk_signaling_secret_${SECRET_TALK_SIGNALING_SECRET_VERSION}
|
||||
|
||||
configs:
|
||||
entrypoint_talk:
|
||||
name: ${STACK_NAME}_entrypoint_talk_${ENTRYPOINT_TALK_VERSION}
|
||||
file: entrypoint.talk.sh.tmpl
|
||||
template_driver: golang
|
||||
@@ -0,0 +1,10 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
app:
|
||||
secrets:
|
||||
- user_oidc_secret
|
||||
|
||||
secrets:
|
||||
user_oidc_secret:
|
||||
external: true
|
||||
name: ${STACK_NAME}_user_oidc_secret_${SECRET_USER_OIDC_SECRET_VERSION}
|
||||
@@ -6,11 +6,11 @@ services:
|
||||
- whiteboard_jwt
|
||||
|
||||
whiteboard:
|
||||
image: ghcr.io/nextcloud-releases/whiteboard:v1.1.2
|
||||
image: ghcr.io/nextcloud-releases/whiteboard:v1.5.9
|
||||
deploy:
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.docker.network=proxy
|
||||
- traefik.swarm.network=proxy
|
||||
- traefik.http.services.${STACK_NAME}_whiteboard.loadbalancer.server.port=3002
|
||||
- traefik.http.routers.${STACK_NAME}_whiteboard.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS}) && PathPrefix(`/whiteboard`)
|
||||
- traefik.http.routers.${STACK_NAME}_whiteboard.entrypoints=web-secure
|
||||
@@ -41,4 +41,4 @@ configs:
|
||||
entrypoint_whiteboard:
|
||||
name: ${STACK_NAME}_entrypoint_whiteboard_${ENTRYPOINT_WHITEBOARD_VERSION}
|
||||
file: entrypoint.whiteboard.sh.tmpl
|
||||
template_driver: golang
|
||||
template_driver: golang
|
||||
|
||||
+9
-9
@@ -1,7 +1,7 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
web:
|
||||
image: nginx:1.29.0
|
||||
image: nginx:1.31.3
|
||||
depends_on:
|
||||
- app
|
||||
configs:
|
||||
@@ -29,7 +29,7 @@ services:
|
||||
order: start-first
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=proxy"
|
||||
- "traefik.swarm.network=proxy"
|
||||
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80"
|
||||
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})"
|
||||
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
|
||||
@@ -41,14 +41,14 @@ services:
|
||||
- "caddy.reverse_proxy={{upstreams 80}}"
|
||||
- "caddy.tls.on_demand="
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", 'curl -s -N curl -Ns localhost/status.php | grep "installed\":true"']
|
||||
test: ["CMD-SHELL", "curl -fsS http://localhost/status.php | grep -q '\"installed\":true'"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
start_period: 5m
|
||||
|
||||
app:
|
||||
image: nextcloud:31.0.6-fpm
|
||||
image: nextcloud:33.0.8-fpm
|
||||
depends_on:
|
||||
- db
|
||||
configs:
|
||||
@@ -95,8 +95,8 @@ services:
|
||||
failure_action: rollback
|
||||
order: start-first
|
||||
labels:
|
||||
- "coop-cloud.${STACK_NAME}.version=12.0.1+31.0.6-fpm"
|
||||
- "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT:-120}"
|
||||
- "coop-cloud.${STACK_NAME}.version=14.1.0+33.0.7-fpm"
|
||||
- "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT}"
|
||||
- "backupbot.backup=${ENABLE_BACKUPS:-true}"
|
||||
- "backupbot.backup.volumes.redis=false"
|
||||
#- "backupbot.backup.volumes.nextcloud=false"
|
||||
@@ -109,7 +109,7 @@ services:
|
||||
start_period: 15m
|
||||
|
||||
cron:
|
||||
image: nextcloud:31.0.6-fpm
|
||||
image: nextcloud:33.0.8-fpm
|
||||
volumes:
|
||||
- nextcloud:/var/www/html/
|
||||
- nextapps:/var/www/html/custom_apps:cached
|
||||
@@ -125,7 +125,7 @@ services:
|
||||
|
||||
|
||||
cache:
|
||||
image: redis:8.0.2-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:
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
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 "INTERNAL_SECRET"
|
||||
file_env "TURN_SECRET"
|
||||
file_env "SIGNALING_SECRET"
|
||||
|
||||
/start.sh supervisord -c /supervisord.conf
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -0,0 +1 @@
|
||||
Last release for nextcloud-32, pointing to the latest version of nextcloud-32.
|
||||
@@ -0,0 +1,13 @@
|
||||
Upgrades Nextcloud from 32.0.13 to 33 (major version upgrade).
|
||||
|
||||
IMPORTANT:
|
||||
- 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.
|
||||
- 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.
|
||||
- Nextcloud does NOT support downgrades. Take a backup before deploying.
|
||||
- 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.
|
||||
@@ -0,0 +1 @@
|
||||
Update pgautoupgrade to postgresql v17
|
||||
Reference in New Issue
Block a user