Skip to content

ryannix123/nextcloud-on-openshift

Repository files navigation

Nextcloud on OpenShift β€” A fast, complete, repeatable, zero root privilege deployment

OpenShift Nextcloud SCC MariaDB PHP CentOS Quay.io Build and Push Nextcloud

Deploy Nextcloud on OpenShift quickly without ANY elevated privileges.
No anyuid. No privileged. Just pure, security-hardened container goodness designed for multi-tenancy.

Nextcloud Logo


πŸ€” Already self-host Nextcloud? Here's why OpenShift

If you run Nextcloud with Docker Compose today, you can spin it up in five minutes β€” so why bother with a platform? Because most of the toil you do by hand to keep that compose stack healthy, secure, and reachable is built into OpenShift. Every row below is something you've probably already wrestled with:

What you do by hand with Docker Compose What OpenShift does for you
Certbot + cron + a reverse proxy to get and renew TLS certs Routes issue and auto-renew TLS β€” HTTPS with zero cert plumbing
Run as root (or pin a UID) and hope nothing in the image minds Enforced non-root: a random high UID is assigned and the image runs anyway
restart: unless-stopped and hope it actually comes back Self-healing: kill a pod and the platform reconciles it back automatically
Edit the compose file, SSH to the host, docker compose up -d Declarative state: describe what you want; the cluster converges to it (GitOps-ready)
iptables / firewall rules to limit who can reach the instance One route annotation for IP allow-listing (see below)
Manage volumes, networks, and restart ordering yourself PVCs, services, and health probes are first-class, declarative objects

None of this requires elevated privileges, and all of it runs on the free Red Hat Developer Sandbox. The point of this project isn't "a harder way to run Nextcloud" β€” it's the manual work you already do, automated and hardened by the platform.

The non-root part is the headline

Most self-hosters have never run Nextcloud under an arbitrary user ID. This image does: whether OpenShift hands it UID 1000760000 or any other number from your namespace's range, the same image starts and serves β€” no chown, no --user flag, no root, no custom SCC. That portability is exactly what makes a container safe to run in a shared, multi-tenant cluster, and it's the single biggest thing that separates a platform-ready image from a typical compose image.


πŸ†“ Red Hat Developer Sandbox

The Red Hat Developer Sandbox is a free OpenShift environment perfect for testing Nextcloud:

  • Free tier β€” No credit card required, no setup, no cluster to install
  • Generous resources β€” 3 CPU cores, 14 GB RAM, and 40 GB storage per user β€” plenty to run this entire stack
  • Latest OpenShift β€” Always running a recent version (4.18+)
  • Auto-hibernation β€” Deployments scale to zero after 12 hours of inactivity

πŸ’‘ New to OpenShift? The Sandbox is the fastest way to try the platform β€” you get a real, current OpenShift cluster in your browser in minutes, with zero install. This entire Nextcloud stack is designed to deploy there on the free tier. Grab a free Sandbox and run sh deploy.sh.

Confirm your own namespace's quota at any time:

oc describe resourcequota

Waking Up Your Deployment

When you return after the sandbox has hibernated, your pods will be scaled down. Run this command to bring everything back up:

# Scale all deployments back to 1 replica
oc scale deployment --all --replicas=1

# Or specify your namespace explicitly
oc scale deployment --all --replicas=1 -n $(oc project -q)

Your data persists in the PVCs β€” only the pods are stopped during hibernation.


🎯 Two Deployment Options

Option Best For Document Editing Complexity
Custom Container Production, simplicity βœ… Collabora built-in Simple
Helm Chart GitOps, existing Helm users ⚠️ Manual setup Moderate

Option 1: Custom Container (Recommended)

A purpose-built Nextcloud container optimized for OpenShift's restricted Security Context Constraints (SCC) with Nextcloud Office (Collabora) document editing included.

✨ Features

  • βœ… CentOS Stream 10 + PHP 8.5 + nginx β€” Latest stack
  • βœ… Runs as non-root (OpenShift restricted SCC compatible)
  • βœ… Nextcloud Office (Collabora) document editing β€” edit docs, spreadsheets, presentations in-browser
  • βœ… MariaDB 11.8 + Redis 8 for performance
  • βœ… Persistent storage for data, config, and apps
  • βœ… Automatic WOPI configuration for document editing
  • βœ… Background cron jobs included

πŸš€ Quick Start

# Clone the repository
git clone https://github.com/ryannix123/nextcloud-on-openshift.git
cd nextcloud-on-openshift/nextcloud-simple-custom

# Deploy to OpenShift (auto-generates route from cluster domain)
sh deploy.sh

That's it! The script:

  • Auto-detects your cluster's ingress domain
  • Generates a route hostname (nextcloud-<namespace>.<cluster-domain>)
  • Creates all resources (secrets, PVCs, deployments, services, route)
  • Configures Nextcloud Office (Collabora)
  • Outputs your admin credentials at the end β€” save them!

πŸ“¦ Using a Custom Image

# Build and push your own image
podman build --platform linux/amd64 -t quay.io/YOUR_USERNAME/nextcloud-openshift:latest -f Containerfile .
podman push quay.io/YOUR_USERNAME/nextcloud-openshift:latest

# Deploy with your image
NEXTCLOUD_IMAGE=quay.io/YOUR_USERNAME/nextcloud-openshift:latest sh deploy.sh

βš™οΈ Environment Variables

Variable Default Description
NEXTCLOUD_IMAGE quay.io/ryan_nix/nextcloud-openshift:latest Container image to deploy
ROUTE_HOST Auto-generated Custom route hostname
NAMESPACE Current project Target namespace

Document editing is automatically enabled β€” Nextcloud Office (Collabora) is installed and configured on first boot. You can start editing .docx, .xlsx, .pptx, .odt, and more right away!

⚠️ Collabora CODE Server Warnings

This deployment uses the built-in CODE server that ships with Nextcloud Office. It runs inside the Nextcloud pod, which keeps the whole stack self-contained and easy to deploy. Because it runs under OpenShift's restricted SCC, you'll see these warnings in the Nextcloud Office admin settings:

Warning Cause Impact
Missing capabilities/namespaces OpenShift restricted SCC doesn't allow namespace creation Documents aren't sandboxed as securely
Slow Kit jail setup Can't bind-mount in containers, must copy files Slower document loading
Poorly performing proxying All traffic goes through PHP proxy Higher latency

These warnings are expected and can be safely ignored for demo, personal, or small team use. The built-in CODE server is designed for "home use or small groups" β€” document editing works fine despite these warnings.

For heavier, multi-user workloads, the built-in server is the wrong tool: Collabora's chroot-jail isolation relies on Linux capabilities the restricted SCC won't grant. The supported answer is a dedicated Collabora Online server running with its own privileges β€” either on a cluster where you can grant anyuid, or in an OpenShift Virtualization VM where the jails run intact. That's beyond the scope of this self-contained POC, but it's the path to take when you outgrow the bundled server.

🧹 Automatic Post-Installation Optimization

The entrypoint automatically handles common Nextcloud warnings on each startup:

  • βœ… Removes lost+found directory from custom_apps (PVC filesystem artifact)
  • βœ… Adds missing database indices for better performance
  • βœ… Runs mimetype migrations

Note: The "AppAPI deploy daemon" warning can be safely ignored β€” it's for running containerized external apps which require Docker socket access that OpenShift doesn't allow.

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      OpenShift Cluster                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚                   Nextcloud Pod                       β”‚   β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚
β”‚  β”‚  β”‚   nginx    β”‚  β”‚  PHP-FPM   β”‚  β”‚   Collabora    β”‚  β”‚   β”‚
β”‚  β”‚  β”‚  :8080     │─▢│   :9000    β”‚  β”‚   (CODE)       β”‚  β”‚   β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                              β”‚                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚  β”‚ MariaDB   β”‚  β”‚  Redis Cache  β”‚  β”‚   PVCs    β”‚            β”‚
β”‚  β”‚  11.8     β”‚  β”‚     8.x       β”‚  β”‚ Data/Cfg  β”‚            β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ Files

File Description
Containerfile Container build definition (CentOS Stream 10 + PHP 8.5)
entrypoint.sh Startup script with auto-configuration
nginx.conf Web server configuration with .mjs MIME fix
supervisord.conf Process manager for nginx + PHP-FPM + cron
deploy.sh OpenShift deployment script

βš™οΈ Configuration

Environment Variables (Runtime)

Variable Default Description
NC_MYSQL_HOST mariadb Database hostname
NC_MYSQL_DATABASE nextcloud Database name
NC_REDIS_HOST redis Redis hostname
NEXTCLOUD_ADMIN_USER admin Admin username
NEXTCLOUD_TRUSTED_DOMAINS (auto-configured) Space-separated trusted domains

Persistent Volumes

PVC Size Purpose
nextcloud-data-pvc 20Gi User files
nextcloud-config-pvc 100Mi Nextcloud configuration
nextcloud-apps-pvc 1Gi Custom/installed apps
mariadb-pvc 5Gi Database storage

πŸ”§ Management Commands

# View admin password
oc get secret nextcloud-secret -o jsonpath='{.data.admin-password}' | base64 -d

# Check Nextcloud status
oc exec deployment/nextcloud -- php /var/www/html/occ status

# Run maintenance
oc exec deployment/nextcloud -- php /var/www/html/occ maintenance:repair

# Add missing database indices
oc exec deployment/nextcloud -- php /var/www/html/occ db:add-missing-indices

# List installed apps
oc exec deployment/nextcloud -- php /var/www/html/occ app:list

# Check Collabora configuration
oc exec deployment/nextcloud -- php /var/www/html/occ richdocuments:activate-config

# Full cleanup including PVCs (prompts for confirmation)
sh deploy.sh cleanup

# Cleanup preserving PVCs β€” use this for image rebuilds/upgrades
sh deploy.sh cleanup --keep-data

# Sync MariaDB password to secret after a broken re-run
sh deploy.sh fix-db-password

πŸ”‘ Secret Management

All credentials are generated randomly at first deploy and stored as OpenShift Secrets. They are never saved to disk or the manifests folder β€” the base64 encoding used by Kubernetes Secrets is not encryption, so committing them to a repository would expose credentials in plaintext.

Retrieve Credentials

# Admin password
oc get secret nextcloud-secret -o jsonpath='{.data.admin-password}' | base64 -d && echo

# MariaDB nextcloud user password
oc get secret mariadb-secret -o jsonpath='{.data.password}' | base64 -d && echo

# MariaDB root password
oc get secret mariadb-secret -o jsonpath='{.data.root-password}' | base64 -d && echo

# Redis password
oc get secret redis-secret -o jsonpath='{.data.password}' | base64 -d && echo

How Secrets and Data Stay in Sync

The MariaDB password in config.php (stored on the nextcloud-config-pvc) and the password in mariadb-secret must always match. The deploy script handles this automatically:

  • Re-running deploy.sh β€” existing secrets are preserved, never overwritten
  • cleanup then deploy.sh β€” PVCs are deleted along with secrets, so a fresh password is written to both MariaDB and config.php on the new install
  • cleanup --keep-data β€” PVCs are preserved; redeploy immediately so the same secrets are reused before the pod starts

If a credential mismatch occurs (e.g., a secret was manually changed), fix it without redeploying:

sh deploy.sh fix-db-password

Production Secret Management

For production use, replace generated secrets with an external secrets provider:

Tool Use Case
External Secrets Operator Pull from AWS Secrets Manager, Azure Key Vault, HashiCorp Vault
Sealed Secrets Encrypt secrets for safe git storage
OpenShift Secrets Store CSI Mount secrets from a vault as pod volumes

πŸ› Troubleshooting

Document editing shows "Loading..." forever

Check the WOPI configuration:

oc exec deployment/nextcloud -- php /var/www/html/occ richdocuments:activate-config

The URLs should point to your external domain, not localhost.

JavaScript MIME type errors in browser console

Rebuild the container β€” the Containerfile includes a fix for .mjs files.

Pod CrashLoopBackOff

oc logs deployment/nextcloud

Common causes: database not ready (script waits 60s), PVC mount issues.


Option 2: Helm Chart

Use the official Nextcloud Helm chart with OpenShift-specific modifications. Better for GitOps workflows or if you're already using Helm.

πŸ“‹ Prerequisites

  • Helm 3.x installed
  • oc CLI logged in

πŸš€ Quick Start (Developer Sandbox)

# Clone the repo
git clone https://github.com/ryannix123/nextcloud-on-openshift.git
cd nextcloud-on-openshift

# Login to your sandbox
oc login --token=YOUR_TOKEN --server=https://api.sandbox.openshiftapps.com:6443

# Deploy!
./deploy-nextcloud-sandbox.sh

πŸš€ Full OpenShift Cluster

# Create namespace
oc new-project nextcloud

# Add Helm repo
helm repo add nextcloud https://nextcloud.github.io/helm/
helm repo update

# Deploy with custom values
helm install nextcloud nextcloud/nextcloud \
    -f openshift-values.yaml \
    --set nextcloud.host=nextcloud.apps.mycluster.example.com \
    --set nextcloud.password=$(openssl rand -base64 16) \
    -n nextcloud

# Create Route
oc apply -f route.yaml

πŸ”§ What's Different About This Configuration?

The official Helm chart assumes you can run as specific UIDs and bind to port 80. OpenShift's restricted SCC blocks this.

Challenge Our Fix
Fixed UID requirement Let OpenShift assign from namespace range
Port 80 binding Use FPM + nginx-unprivileged on port 8080
Health probes on wrong port Patch probes to target nginx (8080)
Trusted domain errors Auto-configure via php occ

⚠️ Limitations

  • No built-in Collabora β€” requires separate deployment for document editing
  • Requires post-install patches β€” health probes, trusted domains
  • More complex troubleshooting β€” multiple containers and configurations

πŸ”’ Security

Both deployment options run under OpenShift's most restrictive security policy:

Security Feature Status
Runs as non-root βœ…
Random UID from namespace range βœ…
All capabilities dropped βœ…
No privilege escalation βœ…
Seccomp profile enforced βœ…
Works on Developer Sandbox βœ…

Verify your deployment:

# Check SCC assignment (should show "restricted" or "restricted-v2")
oc get pod -l app=nextcloud -o jsonpath='{.items[*].metadata.annotations.openshift\.io/scc}'

# Verify non-root UID
oc exec deployment/nextcloud -- id

πŸ›‘οΈ Securing Access with IP Whitelisting

OpenShift makes it easy to restrict access to your Nextcloud instance by IP address using route annotations β€” no firewall rules or external load balancer configuration needed. (This is the same row from the comparison table up top, made concrete.)

Allow Only Specific IPs

# Allow access only from your office and home IPs
oc annotate route nextcloud \
  haproxy.router.openshift.io/ip_whitelist="203.0.113.50 198.51.100.0/24"

Common Use Cases

Scenario Annotation Value
Single IP 203.0.113.50
Multiple IPs 203.0.113.50 198.51.100.25
CIDR range 10.0.0.0/8
Mixed 203.0.113.50 192.168.1.0/24 10.0.0.0/8

Remove Restriction

oc annotate route nextcloud haproxy.router.openshift.io/ip_whitelist-

Verify Configuration

oc get route nextcloud -o jsonpath='{.metadata.annotations.haproxy\.router\.openshift\.io/ip_whitelist}'

This is a great way to lock down a POC or demo instance to only your team's IPs without any infrastructure changes.


πŸ“Š Stack Summary

Component Version Notes
Nextcloud 34.x Auto-detected at build time
PHP 8.5 From Remi repository
CentOS Stream 10 Latest upstream RHEL
nginx System default From CentOS repos
MariaDB 11.8 quay.io/fedora/mariadb-118
Redis 8.x docker.io/redis:8-alpine

Why MariaDB and not PostgreSQL? Nextcloud officially supports both, and for a self-hosted or small-team instance there's no practical difference you'll notice. MariaDB was chosen here for its drop-in OpenShift-ready image and familiarity. If you prefer Postgres, Nextcloud runs equally well on it β€” swap the database deployment and point config.php at it.


πŸš€ Production Recommendations

  1. External Database β€” Use a managed MariaDB or PostgreSQL for reliability
  2. Object Storage β€” Configure S3-compatible backend for scalability
  3. Redis Cluster β€” Enable Redis Sentinel for HA caching
  4. Backup Strategy β€” Implement OADP or Velero for disaster recovery
  5. Resource Limits β€” Tune CPU/memory based on user count
  6. Dedicated Collabora β€” Move document editing to a standalone Collabora server for multi-user performance

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-fix)
  3. Commit your changes (git commit -m 'Add amazing fix')
  4. Push to the branch (git push origin feature/amazing-fix)
  5. Open a Pull Request

πŸ“š References


πŸ™ Acknowledgments

  • Nextcloud for the amazing self-hosted cloud platform
  • Collabora for the document editing engine
  • Red Hat for OpenShift and the Developer Sandbox

⭐ If this saved you hours of debugging, consider giving it a star! ⭐

About

Run Nextcloud on OpenShift

Resources

Stars

4 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors