Privacy Tools Guide

Running your own cloud storage service gives you complete control over your data. Nextcloud on a Raspberry Pi provides a cost-effective way to host file sync, calendar, contacts, and collaborative features without relying on third-party services. This guide covers the complete setup process using Docker, including reverse proxy configuration, performance optimizations, and security hardening.

Prerequisites

You need a Raspberry Pi 4 or 5 with at least 4GB of RAM. A 32GB SD card works for the operating system, but your data should live on external storage—an USB SSD or HDD provides better performance and reliability than SD cards.

Install Raspberry Pi OS Lite (64-bit) and ensure your system is updated:

sudo apt update && sudo apt upgrade -y
sudo reboot

Enable SSH for remote management:

sudo systemctl enable ssh
sudo systemctl start ssh

Installing Docker and Docker Compose

Docker simplifies Nextcloud installation by isolating dependencies and enabling straightforward updates. Install Docker using the convenience script:

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER

Install Docker Compose as a standalone binary:

sudo apt install -y libcompose-dev
# Or download directly for the latest version
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Verify the installation:

docker --version
docker-compose --version

Configuring External Storage

Nextcloud needs persistent storage for data and the database. Mount your external drive and set proper permissions:

# Find your drive
lsblk -f

# Create mount point
sudo mkdir -p /mnt/nextcloud-data

# Mount (replace sda1 with your drive identifier)
sudo mount /dev/sda1 /mnt/nextcloud-data

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

For automatic mounting on reboot, add an entry to /etc/fstab:

# Get UUID
sudo blkid /dev/sda1

# Edit fstab
sudo nano /etc/fstab
# Add: UUID=your-uuid-here /mnt/nextcloud-data ext4 defaults,nofail 0 2

Docker Compose Configuration

Create a directory for Nextcloud and write your compose file:

mkdir -p ~/nextcloud && cd ~/nextcloud
nano docker-compose.yml

Use this production-ready configuration:

version: '3.8'

services:
  db:
    image: mariadb:10.11
    container_name: nextcloud_db
    restart: unless-stopped
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    volumes:
      - ./db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=strong_root_password
      - MYSQL_PASSWORD=strong_nextcloud_password
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
    networks:
      - nextcloud_network

  redis:
    image: redis:7-alpine
    container_name: nextcloud_redis
    restart: unless-stopped
    networks:
      - nextcloud_network

  app:
    image: nextcloud:29-apache
    container_name: nextcloud_app
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - ./nextcloud:/var/www/html
      - /mnt/nextcloud-data:/var/www/html/data
    environment:
      - PHP_MEMORY_LIMIT=512M
      - PHP_UPLOAD_LIMIT=1G
      - NEXTCLOUD_TRUSTED_DOMAINS=your-domain.com 192.168.1.100
    depends_on:
      - db
      - redis
    networks:
      - nextcloud_network

networks:
  nextcloud_network:
    driver: bridge

Replace the passwords with strong values and update NEXTCLOUD_TRUSTED_DOMAINS with your domain or local IP address.

Start the containers:

docker-compose up -d

Check status:

docker-compose ps
docker-compose logs -f app

Completing Nextcloud Setup

Access Nextcloud through your browser at http://192.168.1.100:8080 (replace with your Pi’s IP). Create an admin account with a strong password. The initial setup takes a few minutes.

After installation, install essential apps from the app store:

Reverse Proxy with Nginx

Running Nextcloud behind a reverse proxy enables HTTPS and handles multiple services. Install Nginx:

sudo apt install -y nginx

Create a configuration file:

sudo nano /etc/nginx/sites-available/nextcloud

Add this configuration:

upstream nextcloud_backend {
    server 127.0.0.1:8080;
}

server {
    listen 80;
    server_name cloud.yourdomain.com;

    location / {
        proxy_pass http://nextcloud_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Enable the site and restart Nginx:

sudo ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

For HTTPS, use Certbot:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d cloud.yourdomain.com

Performance Tuning

The Raspberry Pi has limited resources. Optimize Nextcloud for better performance:

PHP-FPM Configuration

Create a custom PHP configuration:

mkdir -p ~/nextcloud/php
nano ~/nextcloud/php/www.conf

Adjust these settings for the Pi’s capabilities:

[www]
pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500

Mount this custom config in your compose file by adding to the app service:

volumes:
  - ./php/www.conf:/usr/local/etc/php-fpm.d/zz-docker.conf

Redis Caching

Redis significantly improves performance by caching data. Ensure your config.php includes:

'memcache.distributed' => '\\OC\\Memcache\\Redis',
'memcache.local' => '\\OC\\Memcache\\Redis',
'redis' => [
    'host' => 'redis',
    'port' => 6379,
],

Access the config:

docker exec -it nextcloud_app bash
nano /var/www/html/config/config.php

Database Optimization

Create an optimization script:

docker exec -it nextcloud_db mysql -u root -p nextcloud -e "
CREATE TABLE IF NOT EXISTS oc_migrations (
    app VARCHAR(255) NOT NULL,
    version VARCHAR(255) NOT NULL,
    PRIMARY KEY (app, version)
);
"

Run database optimizations periodically:

docker exec --user www-data nextcloud_app php occ db:convert-filecache-bigint
docker exec --user www-data nextcloud_app php occ maintenance:repair

Security Hardening

Protect your Nextcloud instance with these measures:

Two-Factor Authentication

Enable 2FA for all users through the admin panel. Install the Two-Factor TOTP Provider app for time-based codes.

Fail2Ban Protection

Install Fail2Ban to block brute force attempts:

sudo apt install -y fail2ban

Create a Nextcloud filter:

sudo nano /etc/fail2ban/filter.d/nextcloud.conf
[Definition]
failregex = {"app":"core","message":"Login failed:.*","level":2,"time".*}

Add to Fail2Ban config:

sudo nano /etc/fail2ban/jail.local
[nextcloud]
enabled = true
port = http,https
filter = nextcloud
logpath = /var/www/nextcloud/data/nextcloud.log
maxretry = 5
bantime = 3600

Regular Backups

Create a backup script:

#!/bin/bash
BACKUP_DIR="/backup/nextcloud"
DATE=$(date +%Y%m%d)

mkdir -p $BACKUP_DIR

# Backup data directory
tar -czf $BACKUP_DIR/data-$DATE.tar.gz /mnt/nextcloud-data

# Backup database
docker exec nextcloud_db mysqldump -u nextcloud -p strong_nextcloud_password nextcloud > $BACKUP_DIR/db-$DATE.sql

# Keep only last 7 days
find $BACKUP_DIR -type f -mtime +7 -delete

Schedule daily backups with cron:

crontab -e
# Add: 0 2 * * * /path/to/backup.sh

Updating Nextcloud

Regular updates patch security vulnerabilities. Before updating, create a backup:

cd ~/nextcloud
docker-compose down
tar -czf backup-$(date +%Y%m%d).tar.gz ./
docker-compose up -d

Pull the latest image and recreate containers:

docker-compose pull
docker-compose up -d
docker-compose logs -f

Run post-update commands:

docker exec --user www-data nextcloud_app php occ maintenance:mode --on
docker exec --user www-data nextcloud_app php occ upgrade
docker exec --user www-data nextcloud_app php occ maintenance:mode --off

Built by theluckystrike — More at zovo.one