# 11: Nextcloud - Cloud Storage Platform

Nextcloud is a full-featured, self-hosted collaboration and file storage platform. It provides file sync and share, WebDAV, CalDAV/CardDAV, and a rich app ecosystem. For full configuration details and the admin manual, see the [official Nextcloud documentation](https://docs.nextcloud.com/server/latest/admin_manual/).

## Architecture Overview

- ✅ **Core services:** Apache/PHP application with PostgreSQL database
- ✅ **Protocols:** WebDAV, CalDAV, CardDAV
- ✅ **Identity:** Local users; supports SSO/OIDC via apps
- ✅ **Networking:** Traefik reverse proxy (recommended) or standalone
- ✅ **Data:** Application files + user data volume + database

## Resource Requirements

- Minimum: 1 vCPU, 512 MB RAM, 10 GB disk (grows with user data)
- Recommended: 2+ vCPU, 2 GB+ RAM, 20 GB+ disk

## Prerequisites

- ✅ **Traefik installed** (Chapter 4) with Let's Encrypt
- ✅ **Docker installed** (Chapter 3)
- ✅ **Apprise installed** (Chapter 5) for notifications
- ✅ **Borgmatic installed** (Chapter 6) for automated backups
- ✅ **Domain configured** (Chapter 4.5) for production HTTPS

**Interdependencies:** The PostgreSQL service is attached to a `borgmatic-db` network for backup discovery. Borgmatic relies on Apprise for notifications.

## Installation Methods

### Via Infinity Tools Menu

```
📱 APPLICATIONS → Nextcloud → Install
```

### Command Line

```
# Show current status (no changes)
sudo bash /opt/InfinityTools/Solutions/setup-nextcloud.sh

# Run interactive installation
sudo bash /opt/InfinityTools/Solutions/setup-nextcloud.sh --install
```

## Configuration Parameters

- **SSL Mode:** Traefik (HTTPS, recommended) or standalone (HTTP or self-signed HTTPS)
- **Domain:** Required for Traefik (e.g., `cloud.example.com`)
- **Standalone Port:** If not using Traefik
- **Default Quota:** Per-user storage limit in GB (recommended)
- **Credentials:** Admin and DB passwords are generated and stored in `/opt/speedbits/nextcloud/.env`

## Generated Files &amp; Directories

- `/opt/speedbits/nextcloud/.env` — Installation parameters and credentials
- `/opt/speedbits/nextcloud/docker-compose.yml` — Service definition
- `/opt/speedbits/nextcloud/html` — App files
- `/opt/speedbits/nextcloud/data` — User data
- `/opt/speedbits/nextcloud/db` — PostgreSQL data

## Compose (Traefik Mode - Highlights)

```
services:
  db:
    image: postgres:${DB_VERSION}
    networks: [ ${NETWORK}, borgmatic-db ]

  nextcloud:
    image: nextcloud:${NEXTCLOUD_VERSION}
    environment:
      POSTGRES_HOST: nextcloud-db
      NEXTCLOUD_ADMIN_USER: ${NEXTCLOUD_ADMIN_USER}
      NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD}
      NEXTCLOUD_TRUSTED_DOMAINS: ${DOMAIN}
      OVERWRITEPROTOCOL: https
      OVERWRITEHOST: ${DOMAIN}
      PHP_UPLOAD_LIMIT: 16G
      PHP_MEMORY_LIMIT: 512M
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nextcloud.rule=Host(`${DOMAIN}`)"
      - "traefik.http.routers.nextcloud.entrypoints=websecure"
      - "traefik.http.routers.nextcloud.tls.certresolver=myresolver"
      - "traefik.http.services.nextcloud.loadbalancer.server.port=80"
      - "traefik.http.middlewares.nextcloud-redirectregex.redirectRegex.permanent=true"
      - "traefik.http.middlewares.nextcloud-redirectregex.redirectRegex.regex=https://(.*)/.well-known/(card|cal)dav"
      - "traefik.http.middlewares.nextcloud-redirectregex.redirectRegex.replacement=https://$${1}/remote.php/dav/"
      - "traefik.http.middlewares.nextcloud-security.headers.customResponseHeaders.X-Content-Type-Options=nosniff"
      - "traefik.http.middlewares.nextcloud-security.headers.customResponseHeaders.X-Frame-Options=SAMEORIGIN"
      - "traefik.http.middlewares.nextcloud-security.headers.customResponseHeaders.X-XSS-Protection=1; mode=block"
      - "traefik.http.routers.nextcloud.middlewares=nextcloud-redirectregex,nextcloud-security"
```

## Post-Install Hardening &amp; Tasks

- Trusted domains and overwrite settings are applied automatically (Traefik mode)
- Default quota is applied if configured
- Security hardening executed: brute-force protection, file locking, log level
- Background jobs switched to **Cron**

### Cron Setup

```
*/5 * * * * docker exec -u www-data nextcloud php -f /var/www/html/cron.php
```

## Backup Integration (Borgmatic)

- Database container is auto-registered with Borgmatic (if available)
- Include these paths in backups: 
    - `/opt/speedbits/nextcloud/data` — User files
    - `/opt/speedbits/nextcloud/db` — Database volume
    - `/opt/speedbits/nextcloud/config` (if present) — Config overrides
- Ensure Apprise is configured for notifications

## Operations

```
# Logs
docker logs nextcloud

# Restart
cd /opt/speedbits/nextcloud && docker compose restart

# Update
cd /opt/speedbits/nextcloud && docker compose pull && docker compose up -d

# OCC (run as www-data)
docker exec -u www-data nextcloud php occ status
docker exec -u www-data nextcloud php occ app:list
```

## Troubleshooting

- **SSL/Domain:** Verify Traefik routing, DNS A/AAAA, and ACME logs
- **Database:** Check container health; confirm credentials in `.env`
- **Storage:** Monitor `df -h /opt/speedbits/nextcloud`; enforce quotas
- **Trusted Domains:** `occ config:system:set trusted_domains 1 --value="cloud.example.com"`
- **Background Jobs:** Confirm cron runs; see `Settings → Basic settings`

## Security Best Practices

- Enable 2FA for admin and users
- Enforce sane quotas to prevent disk exhaustion
- Regularly apply updates and review logs
- Restrict admin access and consider IP allowlists
- Review app permissions and disable unused apps

## Verification Checklist

- ✅ Nextcloud and database containers running and healthy
- ✅ HTTPS reachable via Traefik with valid certificate
- ✅ Admin login works; quotas visible under Users
- ✅ Cron executing background jobs
- ✅ Backups configured and tested

## References

- [Nextcloud Admin Manual](https://docs.nextcloud.com/server/latest/admin_manual/)
- [Nextcloud desktop &amp; mobile clients](https://nextcloud.com/install/#install-clients)