Nextcloud 33 on OpenShift (CentOS Stream 10 + PHP 8.5 + Collabora) — updated deployment with several fixes

Hey all — I’ve been running Nextcloud on Red Hat OpenShift for a while and recently did a major refresh of my deployment project. Sharing here in case it saves anyone time, especially if you’ve hit the same OpenShift-specific gotchas I have.

What it does: deploys a fully self-contained Nextcloud stack (Nextcloud 33, MariaDB 11.8, Redis 8, Collabora CODE built-in) on OpenShift using zero elevated privileges — no anyuid, no privileged SCC. Works on the free Red Hat Developer Sandbox if you just want to kick the tires.
:link: GitHub - ryannix123/nextcloud-on-openshift: Run Nextcloud on OpenShift · GitHub

What’s new in this update
CentOS Stream 10 + PHP 8.5 (Remi)
The container is now based on CentOS Stream 10 with PHP 8.5 from Remi’s repository. The main migration pain point was getting the OpenShift permission model right — Stream 10 tightened up /run directory handling, which required fixing supervisord, php-fpm, and nginx pid/socket paths so they were all group-writable for arbitrary UIDs.

Collabora WOPI hairpin fix
This one took some digging. On ROSA (and managed OpenShift generally), a pod cannot reach itself through the external ingress route — the traffic loops and times out. The fix is to let entrypoint.sh own WOPI configuration entirely, using NEXTCLOUD_TRUSTED_DOMAINS to derive the correct URL at startup rather than hardcoding anything post-deploy. The key insight: wopi_url (server-to-server) and public_wopi_url (browser-to-server) need to be configured from the same source of truth, and that has to happen before supervisord starts.
Idempotent secret management

The original deploy script used oc create … | oc apply -f - for secrets, which silently regenerated passwords on every re-run. If you redeployed the app without wiping the PVCs, config.php still had the old password, but MariaDB got a new one — instant Access denied. The fix: secrets are now created once and never touched on subsequent runs. A fix-db-password subcommand handles recovery if they somehow get out of sync.

Ansible playbook
Added an ansible/ subfolder with a full playbook using kubernetes.core as an alternative to the shell script. Same idempotent secret logic, same WOPI handling, vars_prompt for the manifest-saving option.

Optional manifest export
Both the shell script and Ansible playbook now prompt whether to save the Kubernetes manifests to a ./manifests/ folder after deployment. Secrets are intentionally excluded — base64 is not encryption.

Happy to answer questions about the OpenShift-specific bits — SCC compatibility, WOPI routing on managed clusters, or the Stream 10 migration details.

2 Likes