# 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 ```bash cd ansible ansible-playbook nextcloud/deploy.yml ``` ### Files | File | Purpose | |------|---------| | `nextcloud/deploy.yml` | Main deployment playbook | | `nextcloud/nextcloud.conf.j2` | Apache VirtualHost template | 2. **Create Data Directory**: `/mnt/nextcloud` on Incus storage volume 3. **Download Nextcloud**: Latest tarball from official site (if not already present) 4. **Extract to Web Root**: `/var/www/nextcloud` (if new installation) 5. **Set Permissions**: `www-data:www-data` ownership 6. **Configure Apache**: Template vhost with port 22083, enable mods, disable default site 7. **Run Installation**: OCC command-line installer (generates config.php with secrets) 8. **Configure via OCC**: Set trusted domains, Memcached, background job mode 9. **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: ```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 - **Server URL**: https://nextcloud.ouranos.helu.ca - **Username**: admin (or created user) - **Password**: From vault - **Desktop Client**: https://nextcloud.com/install/#install-clients - **Mobile Apps**: iOS App Store / Google Play Store ### 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**: ```bash 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 ```yaml vault_nextcloud_db_password: "PostgresSecurePassword123!" ``` **Requirements:** - Minimum 12 characters - Used by PostgreSQL authentication ### 2. Admin Password ```yaml 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: ```yaml 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` ```yaml # 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` ```hcl resource "incus_storage_volume" "nextcloud_data" { name = "nextcloud-data" pool = "default" project = "ouranos" 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`): ```yaml - 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 ```bash ssh rosalind.incus sudo systemctl status apache2 ``` ### View Logs ```bash # 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 ```bash # 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 ```bash psql -h portia.incus -U nextcloud -d nextcloud ``` ### Check Memcached ```bash echo "stats" | nc localhost 11211 ``` ### Verify Storage Volume ```bash # 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 ```bash # 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! ```bash # 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 ```bash # 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 - **Official Documentation**: https://docs.nextcloud.com/ - **Admin Manual**: https://docs.nextcloud.com/server/latest/admin_manual/ - **Installation Guide**: https://docs.nextcloud.com/server/latest/admin_manual/installation/ - **OCC Commands**: https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html