← Back to Blog

Building a Sovereign Nextcloud & Matrix Cluster – Replacing Google Workspace with 100% Self-hosted Infrastructure

A production guide to deploying Nextcloud for file collaboration and Matrix (Element) for secure, decentralised messaging – fully self-hosted, GDPR-compliant, and independent of big tech.

8 min read Roman Swetly

Building a Sovereign Nextcloud & Matrix Cluster

Replacing Google Workspace with 100% self-hosted infrastructure – secure, private, and fully under your control.


The Problem

For years, my team relied on Google Workspace and Slack for collaboration. But as we grew, the limitations became clear:

  • Data sovereignty: Our files, messages, and metadata lived on foreign servers subject to unknown jurisdictions.
  • Privacy: We had no control over who accessed our data or how it was used.
  • Cost: Per-user licensing became expensive as the team scaled.
  • Lock-in: Migrating away from Google was nearly impossible.

The solution: Build a self-hosted, sovereign collaboration suite using Nextcloud (file sharing) and Matrix (decentralised messaging). This stack gives us:

  • 100% data ownership – everything lives on our servers.
  • GDPR compliance – full control over data processing and storage.
  • No vendor lock-in – all services are open-source and portable.
  • End-to-end encryption – for sensitive communications.

Why Nextcloud + Matrix? Why Not Telegram?

This is a common question. Here’s my reasoning:

PlatformProsCons
TelegramEasy to use, widely adopted, good mobile app.❌ Proprietary, US-based, no end-to-end encryption by default, data stored on foreign servers.
Slack / TeamsEnterprise features, integrations.❌ Closed source, expensive, data locked in, privacy concerns.
Nextcloud + Matrix100% self-hosted, open-source, end-to-end encrypted, GDPR-compliant, file sharing + messaging integrated.Slightly more setup required (but Docker makes it easy).

The verdict: For industrial IoT and sensitive engineering work, sovereignty is non-negotiable. Nextcloud handles file storage and sharing. Matrix handles messaging (with Element as the frontend). Together, they replace Google Drive, Slack, and Teams.


Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                         Internet                            │
└──────────────────────────┬──────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│                    Traefik (Reverse Proxy)                  │
│   nextcloud.redfred.site → Nextcloud (Port 2223)            │
│   matrix.redfred.site    → Matrix Synapse (Port 8448)       │
└──────────────────────────┬──────────────────────────────────┘
                           │
               ┌───────────┴───────────┐
               ▼                       ▼
    ┌─────────────────────┐  ┌─────────────────────┐
    │    Nextcloud        │  │  Matrix Synapse     │
    │  File Sharing &     │  │  Messaging &        │
    │  Collaboration      │  │  Chat (Element)     │
    └─────────────────────┘  └─────────────────────┘

Key design decisions:

DecisionWhy
Docker containersPortable, maintainable, and upgradeable.
Separate databasesBetter isolation and backup strategies.
Traefik for SSLAutomatic Let’s Encrypt certificates for both services.
Persistent volumesConfig and data survive container restarts.

Part 1: Deploying Nextcloud

Docker Compose Configuration

Here’s my production docker-compose.yml for Nextcloud:

version: '3.8'

services:
  db_nextcloud:
    image: mariadb:latest
    environment:
      - MYSQL_ROOT_PASSWORD=your_root_password
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=patron
      - MYSQL_PASSWORD=your_db_password
    volumes:
      - ./app/db:/var/lib/mysql
    restart: unless-stopped
    networks:
      - nextcloud_network

  nextcloud:
    image: lscr.io/linuxserver/nextcloud:latest
    environment:
      - PUID=1000
      - PGID=1000
      - MYSQL_PASSWORD=your_db_password
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=patron
      - NEXTCLOUD_ADMIN_USER=admin
      - NEXTCLOUD_ADMIN_PASSWORD=your_admin_password
      - TZ=Etc/UTC
    volumes:
      - ./app/config:/config
      - ./app/data:/data
    ports:
      - 2223:80  # Map host port 2223 to container port 80
    restart: unless-stopped
    networks:
      - nextcloud_network

networks:
  nextcloud_network:

Why This Configuration?

ComponentChoiceWhy
DatabaseMariaDBBetter performance for file metadata than SQLite.
ImageLinuxServer.ioWell-maintained, stable, and easy to configure.
Port2223:80Non-standard port to avoid conflicts; Traefik handles HTTPS externally.
Volumesapp/config and app/dataPersistent storage – config and files survive container rebuilds.

Part 2: Traefik Configuration for Nextcloud

To expose Nextcloud securely, I use Traefik with automatic SSL termination:

# dynamic/nextcloud.yml
http:
  routers:
    https-nextcloud-router:
      entryPoints:
        - https
      service: https_nextcloud_srvs
      rule: Host(`nextcloud.redfred.site`)
      tls:
        certResolver: letsEncrypt

  services:
    https_nextcloud_srvs:
      loadBalancer:
        servers:
          - url: http://99.99.99.99:2223/
        passHostHeader: true

What this does:

  • Routes https://nextcloud.redfred.site to the Nextcloud container on port 2223.
  • Automatically issues and renews Let’s Encrypt certificates.
  • Preserves the original Host header for proper routing.

Part 3: Nextcloud Post-Installation Tuning

After installation, there are three critical configuration changes for production use:

1. Nginx Configuration – Upload Size

# app/config/nginx/nginx.conf
# Update the client_max_body_size directive:
client_max_body_size 5G;

This allows uploading large files (e.g., 5GB) – essential for IoT logs, video footage, and design files.

2. PHP Configuration – Timeouts and Memory

# app/config/php/php-local.ini
# Insert these settings:
upload_max_filesize = 10000M
post_max_size = 10000M
max_execution_time = 300

Why: Large file uploads need more time and memory. These settings prevent PHP from timing out on 5GB uploads.

3. Nextcloud Configuration – Performance Tuning

// app/config/www/nextcloud/config/config.php
// Add or modify these settings:

'dbpassword' => 'your_db_password',
'installed' => true,

// APCu memory caching
'memcache.local' => '\\OC\\Memcache\\APCu',
'filelocking.enabled' => true,
'memcache.locking' => '\\OC\\Memcache\\APCu',

// Disable web-based upgrades (use CLI instead)
'upgrade.disable-web' => true,

// Large file upload settings
'uploadPartSize' => 524288000,      // 500MB per chunk
'max_upload_size' => 2048000000,    // 2GB maximum

Key settings explained:

SettingValueWhy
memcache.localAPCuFaster metadata operations, better performance.
filelocking.enabledtruePrevents file corruption on simultaneous edits.
uploadPartSize500MBBreaks large files into chunks for reliable uploads.
max_upload_size2GBSets the absolute upload cap (adjust as needed).

Part 4: Matrix Synapse – Decentralised Messaging

Matrix is a decentralised, open-standard messaging protocol. Unlike Telegram or Slack, no single company controls the network.

Why Matrix?

FeatureMatrixTelegram/Slack
Decentralised✅ Yes (federated)❌ No (centralised)
End-to-end encryption✅ Yes (default)❌ No (optional only)
Self-hosted✅ Yes❌ No
Data sovereignty✅ 100%❌ Controlled by provider
Open protocol✅ Yes❌ Proprietary

Matrix architecture:

  • Synapse: The server implementation (what you install).
  • Element: The web/mobile client (frontend).
  • Federation: Servers communicate with each other – you can chat with users on any Matrix server, not just yours.

Deploying Matrix with Synapse

I’ll provide a simplified deployment guide here. For full configuration, refer to the official documentation.

Docker Compose snippet:

version: '3.8'

services:
  synapse:
    image: matrixdotorg/synapse:latest
    container_name: synapse
    volumes:
      - ./data:/data
    environment:
      - SYNAPSE_SERVER_NAME=matrix.redfred.site
      - SYNAPSE_REPORT_STATS=no
    ports:
      - 8448:8008
    restart: unless-stopped

Traefik configuration:

http:
  routers:
    https-matrix-router:
      entryPoints:
        - https
      service: https_matrix_srvs
      rule: Host(`matrix.redfred.site`)
      tls:
        certResolver: letsEncrypt

  services:
    https_matrix_srvs:
      loadBalancer:
        servers:
          - url: http://99.99.99.99:8448/
        passHostHeader: true

Element client: After Synapse is running, deploy Element (the web client) or use the mobile app. Point it to https://matrix.redfred.site.


Part 5: Why Self-Hosted? The “Sovereign” Advantage

Here’s the real reason this is valuable for industrial and engineering teams:

BenefitBusiness Impact
Data residencyFiles and messages stay in your jurisdiction. Essential for GDPR, HIPAA, or government contracts.
No surveillanceNo corporate or third-party scanning of your files/metadata.
Complete controlYou decide who has access. No “shadow IT.”
PortabilityAll data is stored in open formats. You can leave the platform anytime.
AuditabilityFull logs and transparency – essential for compliance audits.
Cost stabilityFixed infrastructure costs, no per-user licensing fees.

For companies handling sensitive customer data, industrial designs, or classified RF communication logs, this is non-negotiable.


Real-World Deployment

This stack is running on one of my production servers:

# Nextcloud access points
https://nextcloud.redfred.site/remote.php/dav/files/admin
https://nextcloud.redfred.site/remote.php/dav/files/roman

# WebDAV for desktop sync
davs://nextcloud.redfred.site/remote.php/dav/files/admin
davs://nextcloud.redfred.site/remote.php/dav/files/roman

Usage Statistics (Live)

MetricValue
Active users12 engineering team members
Stored files8,700+
Total storage used1.2TB
Average upload size350MB (CAD files, firmware images)
Monthly active sessions450+
Matrix rooms14 active channels
Messages per month2,800+

Uptime

  • Nextcloud: 99.95% uptime over 6 months.
  • Matrix: 99.90% uptime over 6 months.
  • Zero data loss: Daily automated backups to offsite storage.

Summary Checklist

TaskStatusNotes
Nextcloud container runningDocker Compose with MariaDB
Traefik SSL configurationAutomatic certificates via Let’s Encrypt
Upload limits increasedNginx, PHP, and Nextcloud configs
WebDAV access configuredBoth HTTP and HTTPS endpoints
Matrix Synapse deployedFederated messaging server
Element client configuredWeb and mobile clients connected
Backup strategyDaily offsite backups of /app/data

Final Thoughts

Self-hosting is not just about saving money. It’s about control, privacy, and sovereignty.

For a company in the industrial IoT or RF communications space, your data is your most valuable asset. Trusting it to a third-party cloud provider is a risk I’m no longer willing to take.

This Nextcloud + Matrix stack has been running for over 6 months, serving 12 team members, handling 1.2TB of engineering data, and enabling seamless collaboration. It works, it’s reliable, and it’s fully independent.


This collaboration suite is part of my Industrial Infrastructure Platform (II-PaaS). For a detailed deployment walkthrough or architecture design, feel free to reach out.

← Previous Post
Monitoring with Grafana & Prometheus on Bare Metal – Custom Dashboards for Industrial Telemetry
Next Post →
Hardening Ubuntu for Industrial IoT – Firewall, Fail2ban, and Kernel Tuning for 24/7 Operation

Related Articles