#!/bin/bash
# ==== CONFIGURATION ====
NEXTCLOUD_PATH="/var/www/html"
DATA_PATH="/var/www/html/data"
BACKUP_PATH="/var/backups/nextcloud"
DB_USER="nextcloud"
DB_PASS="dbpassword"
DB_NAME="nextcloud"
FTP_HOST="yourftphost.com"
FTP_USER="yourftpuser"
FTP_PASS="yourftppassword"
FTP_DIR="/path/to/save/file"
DATE=$(date +"%Y-%m-%d_%H-%M")
ARCHIVE_NAME="nextcloud-backup-$DATE.tar.gz"
MAX_LOCAL_BACKUPS=3
# ==== START BACKUP ====
echo "Starting streamed Nextcloud backup..."
mkdir -p "$BACKUP_PATH"
# Export database (small file)
DB_DUMP="/tmp/db_$DATE.sql"
mysqldump --no-tablespaces -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" > "$DB_DUMP"
# === Stream tar directly to FTP ===
echo "Creating and streaming archive directly to FTP..."
tar -czf - \
--exclude="$DATA_PATH/appdata_*/preview" \
--exclude="$NEXTCLOUD_PATH/updater-*" \
--exclude="$NEXTCLOUD_PATH/data/tmp" \
-C / \
"${NEXTCLOUD_PATH#/}" \
"${DATA_PATH#/}" \
"$DB_DUMP" \
| curl --ftp-pasv -T - "ftp://$FTP_HOST$FTP_DIR/$ARCHIVE_NAME" --user "$FTP_USER:$FTP_PASS"
# Remove temp database dump
rm -f "$DB_DUMP"
# Optional: keep a few local backups (not needed for streamed uploads)
echo "Cleaning up old local backups..."
cd "$BACKUP_PATH" || exit
ls -1t nextcloud-backup-*.tar.gz 2>/dev/null | tail -n +$((MAX_LOCAL_BACKUPS + 1)) | xargs -r rm -f --
echo "Backup complete: streamed directly to FTP as $ARCHIVE_NAME"Monthly Archives: October 2025
Setting up a NAS on a Raspberry Pi 5 that boots from NVME
# curl https://download.argon40.com/argonneo5.sh | bash
# nano /boot/firmware/config.txt
kernel=kernel8.img
dtparam=nvme
dtparam=pciex1_gen=3
usb_max_current_enable=1
# sudo apt update
# sudo apt install snapd
# sudo snap install snapd
# sudo snap install nextcloud
# sudo /snap/bin/nextcloud.enable-https lets-encrypt
# sudo /snap/bin/nextcloud.occ maintenance:repair --include-expensive
# sudo /snap/bin/nextcloud.occ background:cron
# apt install syncthing
# systemctl enable syncthing@pi-nas.service
# systemctl start syncthing@pi-nas.service
# nano /usr/lib/systemd/system/syncthing@.service
Group=users
UMask=0002
# apt install proftpd
# nano /etc/proftpd/proftpd.conf
DefaultRoot ~
Umask 002 002
# nano /usr/local/bin/fix_ownership.sh
#!/bin/bash
WATCHDIR="/volume1"
LOGFILE="/var/log/fix_ownership.log"
# Function to fix ownership of a file or directory
fix_ownership() {
local file="$1"
if [ -e "$file" ]; then
if [ -d "$file" ]; then
chown -R pi-nas:users "$file" 2>/dev/null
else
chown pi-nas:users "$file" 2>/dev/null
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') Fixed ownership: $file" >> "$LOGFILE"
fi
}
# Watch for changes
inotifywait -m -r -e close_write,create,move,delete --format '%w%f' "$WATCHDIR" | while read -r file; do
fix_ownership "$file"
done
# nano /etc/systemd/system/fix_ownership.service
[Unit]
Description=Recursive ownership watcher for Volume1 folder
After=network.target
[Service]
ExecStart=/usr/local/bin/fix_ownership.sh
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
# systemctl daemon-reload
# systemctl enable fix_ownership.service
# systemctl start fix_ownership.serviceSetting Up Radicale and Infcloud in Debian 13 (Trixie)
# apt update # apt install git python3-pip python3-venv # useradd -r -m -d /var/lib/radicale -s /bin/bash radicale # mkdir /etc/radicale # nano /etc/radicale/radicale.conf [server] # Bind to all IP addresses (0.0.0.0) instead of just localhost hosts = 0.0.0.0:5232 [auth] type = htpasswd htpasswd_filename = /etc/radicale/users htpasswd_encryption = bcrypt [storage] filesystem_folder = /var/lib/radicale/collections [web] type = radicale_infcloud # htpasswd -c -B /etc/radicale/users yourusername # htpasswd -B /etc/radicale/users anotheruser # ufw allow 5232/tcp # ufw reload # su radicale $ cd ~ $ python3 -m venv venv $ source venv/bin/activate $ pip install radicale bcrypt git+https://github.com/Unrud/RadicaleInfCloud.git $ radicale --config /etc/radicale/radicale.conf http://your-server-ip:5232/ $ exit # nano /etc/systemd/system/radicale.service [Unit] Description=Radicale CalDAV and CardDAV Server After=network.target [Service] User=radicale Group=radicale ExecStart=/var/lib/radicale/venv/bin/radicale --config /etc/radicale/radicale.conf WorkingDirectory=/var/lib/radicale Restart=on-failure LimitNOFILE=4096 [Install] WantedBy=multi-user.target # systemctl daemon-reload # systemctl enable radicale # systemctl start radicale # systemctl status radicale # apt install apache2 certbot python3-certbot-apache # nano /etc/apache2/sites-available/radicale.conf <VirtualHost *:80> ServerName your_domain.com ProxyPass / http://localhost:5232/ ProxyPassReverse / http://localhost:5232/ </VirtualHost> # ufw allow 80/tcp # ufw allow 443/tcp # ufw reload # certbot --apache -d your_domain.com https://your_domain.com # sudo systemctl status certbot.timer # sudo certbot renew --dry-run