Files
ouranos/docs/nextcloud.md
Robert Helewka b4d60f2f38 docs: rewrite README with structured overview and quick start guide
Replaces the minimal project description with a comprehensive README
including a component overview table, quick start instructions, common
Ansible operations, and links to detailed documentation. Aligns with
Red Panda Approval™ standards.
2026-03-03 12:49:06 +00:00

12 KiB
Raw Blame History

Nextcloud - Self-Hosted Cloud Collaboration

Overview

Nextcloud is a self-hosted cloud collaboration platform providing file storage, sharing, calendar, contacts, and productivity tools. Deployed as a native LAPP stack (Linux, Apache, PostgreSQL, PHP) on Rosalind with Memcached caching and Incus storage volume for data.

Host: rosalind.incus
Role: Collaboration (PHP, Go, Node.js runtimes)
Container Port: 22083
External Access: https://nextcloud.ouranos.helu.ca/ (via HAProxy on Titania)
Installation Method: Native (tar.bz2 extraction to /var/www/nextcloud)

Architecture

┌──────────┐      ┌────────────┐      ┌───────────┐      ┌───────────┐
│  Client  │─────▶│  HAProxy   │─────▶│  Apache2  │─────▶│PostgreSQL │
│          │      │ (Titania)  │      │ Nextcloud │      │ (Portia)  │
└──────────┘      └────────────┘      │(Rosalind) │      └───────────┘
                                      └───────────┘
                                            │
                                            ├─────────▶ Memcached (Local)
                                            │
                                            └─────────▶ /mnt/nextcloud (Volume)

Deployment

Playbook

cd ansible
ansible-playbook nextcloud/deploy.yml

Files

File Purpose
nextcloud/deploy.yml Main deployment playbook
nextcloud/nextcloud.conf.j2 Apache VirtualHost template
  1. Create Data Directory: /mnt/nextcloud on Incus storage volume
  2. Download Nextcloud: Latest tarball from official site (if not already present)
  3. Extract to Web Root: /var/www/nextcloud (if new installation)
  4. Set Permissions: www-data:www-data ownership
  5. Configure Apache: Template vhost with port 22083, enable mods, disable default site
  6. Run Installation: OCC command-line installer (generates config.php with secrets)
  7. Configure via OCC: Set trusted domains, Memcached, background job mode
  8. Setup Cron: Background jobs every 5 minutes as www-data

⚠️ Important: The playbook does NOT template over config.php after installation. All configuration changes are made via OCC commands to preserve auto-generated secrets (instanceid, passwordsalt, secret).

Configuration

Key Features

  • PostgreSQL Backend: Database on Portia
  • Memcached Caching: Local distributed cache with nc_ prefix
  • Incus Storage Volume: Dedicated 100GB volume at /mnt/nextcloud
  • Apache Web Server: mod_php with rewrite/headers modules
  • Cron Background Jobs: System cron (not Docker/AJAX)
  • Native Installation: No Docker overhead, matches production pattern

Storage Configuration

Path Purpose Owner Mount
/var/www/nextcloud Application files www-data Local
/mnt/nextcloud User data directory www-data Incus volume
/var/log/apache2 Web server logs root Local

Apache Modules

Required modules enabled by playbook:

  • rewrite - URL rewriting
  • headers - HTTP header manipulation
  • env - Environment variable passing
  • dir - Directory index handling
  • mime - MIME type configuration

PHP Configuration

Installed PHP extensions:

  • php-gd - Image manipulation
  • php-pgsql - PostgreSQL database
  • php-curl - HTTP client
  • php-mbstring - Multibyte string handling
  • php-intl - Internationalization
  • php-gmp - GNU Multiple Precision
  • php-bcmath - Binary calculator
  • php-xml - XML processing
  • php-imagick - ImageMagick integration
  • php-zip - ZIP archive handling
  • php-memcached - Memcached caching

Memcached Configuration

  • Host: localhost:11211
  • Prefix: nc_ (Nextcloud-specific keys)
  • Local: \OC\Memcache\Memcached
  • Distributed: \OC\Memcache\Memcached

Cron Jobs

Background jobs configured via system cron:

*/5 * * * * php /var/www/nextcloud/cron.php

Runs as www-data user every 5 minutes.

Access After Deployment

  1. Web Interface: https://nextcloud.ouranos.helu.ca/
  2. First Login: Use admin credentials from vault
  3. Initial Setup: Configure apps and settings via web UI
  4. Client Apps: Download desktop/mobile clients from Nextcloud website

Desktop/Mobile Sync

WebDAV Access

  • WebDAV URL: https://nextcloud.ouranos.helu.ca/remote.php/dav/files/USERNAME/
  • Use Cases: File sync, calendar (CalDAV), contacts (CardDAV)

Monitoring

Alloy Configuration

File: ansible/alloy/rosalind/config.alloy.j2

  • Apache Access Logs: /var/log/apache2/access.log → Loki
  • Apache Error Logs: /var/log/apache2/error.log → Loki
  • System Metrics: Process exporter tracks Apache/PHP processes
  • Labels: job=apache_access, job=apache_error

Health Checks

HAProxy Health Endpoint: /status.php

Manual Health Check:

curl http://rosalind.incus:22082/status.php

Expected response: JSON with status information

Required Vault Secrets

Add to ansible/inventory/group_vars/all/vault.yml:

1. Database Password

vault_nextcloud_db_password: "PostgresSecurePassword123!"

Requirements:

  • Minimum 12 characters
  • Used by PostgreSQL authentication

2. Admin Password

vault_nextcloud_admin_password: "AdminSecurePassword123!"

Requirements:

  • Minimum 8 characters (Nextcloud requirement)
  • Used for admin user login
  • Important: Store securely, used for web interface access

3. Instance Secrets (Auto-Generated)

These are automatically generated during installation by the OCC installer and stored in /var/www/nextcloud/config/config.php. The host_vars should leave these empty:

nextcloud_instance_id: ""  # Auto-generated, leave empty
nextcloud_password_salt: ""  # Auto-generated, leave empty
nextcloud_secret: ""  # Auto-generated, leave empty

These secrets persist in config.php and do not need to be stored in vault or host_vars. They are only referenced in these variables for consistency with the original template design.

Host Variables

File: ansible/inventory/host_vars/rosalind.incus.yml

# Nextcloud Configuration
nextcloud_web_port: 22083
nextcloud_data_dir: /mnt/nextcloud

# Database Configuration
nextcloud_db_type: pgsql
nextcloud_db_host: portia.incus
nextcloud_db_port: 5432
nextcloud_db_name: nextcloud
nextcloud_db_user: nextcloud
nextcloud_db_password: "{{vault_nextcloud_db_password}}"

# Admin Configuration
nextcloud_admin_user: admin
nextcloud_admin_password: "{{vault_nextcloud_admin_password}}"

# Domain Configuration
nextcloud_domain: nextcloud.ouranos.helu.ca

# Instance secrets (generated during install)
nextcloud_instance_id: ""
nextcloud_password_salt: ""
nextcloud_secret: ""

Database Setup

Nextcloud requires a PostgreSQL database on Portia. This is automatically created by the postgresql/deploy.yml playbook.

Database Details:

  • Name: nextcloud
  • User: nextcloud
  • Owner: nextcloud
  • Extensions: None required

Storage Setup

Incus Storage Volume

Terraform Resource: terraform/storage.tf

resource "incus_storage_volume" "nextcloud_data" {
  name    = "nextcloud-data"
  pool    = "default"
  project = "agathos"
  config = { size = "100GB" }
}

Mounted at /mnt/nextcloud on Rosalind container. This volume stores all Nextcloud user data, including uploaded files, app data, and user-specific configurations.

Integration with Other Services

HAProxy Routing

Backend Configuration (titania.incus.yml):

- subdomain: "nextcloud"
  backend_host: "rosalind.incus"
  backend_port: 22083
  health_path: "/status.php"

Memcached Integration

  • Host: localhost:11211
  • Prefix: nc_
  • Shared Instance: Rosalind hosts Memcached for all services

Troubleshooting

Service Status

ssh rosalind.incus
sudo systemctl status apache2

View Logs

# Apache access logs
sudo tail -f /var/log/apache2/access.log

# Apache error logs
sudo tail -f /var/log/apache2/error.log

# Nextcloud logs (via web UI)
# Settings → Logging

OCC Command-Line Tool

# As www-data user
sudo -u www-data php /var/www/nextcloud/occ

# Examples:
sudo -u www-data php /var/www/nextcloud/occ status
sudo -u www-data php /var/www/nextcloud/occ config:list
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on

Database Connection

psql -h portia.incus -U nextcloud -d nextcloud

Check Memcached

echo "stats" | nc localhost 11211

Verify Storage Volume

# Reset ownership
sudo chown -R www-data:www-data /var/www/nextcloud
sudo chown -R www-data:www-data /mnt/nextcloud

# Reset permissions
sudo chmod -R 0750 /var/www/nextcloud

Maintenance Mode

# Enable maintenance mode
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on

# Disable maintenance mode
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off

Updates and Maintenance

Updating Nextcloud

⚠️ Important: Always backup before updating!

# 1. Enable maintenance mode
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on

# 2. Backup config and database
sudo cp -r /var/www/nextcloud/config /backup/nextcloud-config-$(date +%Y%m%d)
pg_dump -h portia.incus -U nextcloud nextcloud > /backup/nextcloud-db-$(date +%Y%m%d).sql

# 3. Download new version
wget https://download.nextcloud.com/server/releases/latest.tar.bz2

# 4. Extract and replace (preserve config/)
tar -xjf latest.tar.bz2
sudo rsync -av --delete --exclude config/ nextcloud/ /var/www/nextcloud/

# 5. Run upgrade
sudo -u www-data php /var/www/nextcloud/occ upgrade

# 6. Disable maintenance mode
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off

Database Maintenance

# Add missing indices
sudo -u www-data php /var/www/nextcloud/occ db:add-missing-indices

# Convert to bigint
sudo -u www-data php /var/www/nextcloud/occ db:convert-filecache-bigint

Version Information

  • Installation Method: Tarball extraction (official releases)
  • Current Version: Check web UI → Settings → Overview
  • Update Channel: Stable (latest.tar.bz2)
  • PHP Version: Installed by apt (Ubuntu repository version)

Docker vs Native Comparison

Why Native Installation?

Aspect Native (Chosen) Docker
Performance Better (no container overhead) Good
Updates Manual tarball extraction Container image pull
Cron Jobs System cron (reliable) Requires sidecar/exec
App Updates Direct via web UI Limited/complex
Customization Full PHP/Apache control Constrained by image
Production Match Yes (same pattern) No
Complexity Lower for LAMP stack Higher for orchestration

Recommendation: Native installation matches production deployment pattern and avoids Docker-specific limitations with Nextcloud's app ecosystem and cron requirements.

References