summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-11-21 18:27:06 +0200
committerPaul Buetow <paul@buetow.org>2025-11-21 18:27:06 +0200
commita8695edcd9c36fff8452948834e819af4e965d21 (patch)
tree8b56d39f5ce9021c1af9d20cc259a72bf0c4d7ff
parent254bbeb7990df9d5c55cac3ce8eca1c33e7420fe (diff)
initial filerise
-rw-r--r--f3s/filerise/Justfile14
-rw-r--r--f3s/filerise/README.md69
-rw-r--r--f3s/filerise/helm-chart/Chart.yaml5
-rw-r--r--f3s/filerise/helm-chart/templates/configmap.yaml199
-rw-r--r--f3s/filerise/helm-chart/templates/deployment.yaml110
-rw-r--r--f3s/filerise/helm-chart/templates/ingress.yaml20
-rw-r--r--f3s/filerise/helm-chart/templates/persistent-volume.yaml111
-rw-r--r--f3s/filerise/helm-chart/templates/service.yaml15
-rw-r--r--frontends/Rexfile2
9 files changed, 544 insertions, 1 deletions
diff --git a/f3s/filerise/Justfile b/f3s/filerise/Justfile
new file mode 100644
index 0000000..3a3a41b
--- /dev/null
+++ b/f3s/filerise/Justfile
@@ -0,0 +1,14 @@
+NAMESPACE := "services"
+RELEASE_NAME := "filerise"
+CHART_PATH := "./helm-chart"
+
+install:
+ helm install {{RELEASE_NAME}} {{CHART_PATH}} --namespace {{NAMESPACE}} --create-namespace
+
+upgrade:
+ helm upgrade {{RELEASE_NAME}} {{CHART_PATH}} --namespace {{NAMESPACE}}
+
+delete:
+ helm uninstall {{RELEASE_NAME}} --namespace {{NAMESPACE}}
+
+deinstall: delete
diff --git a/f3s/filerise/README.md b/f3s/filerise/README.md
new file mode 100644
index 0000000..c48a53a
--- /dev/null
+++ b/f3s/filerise/README.md
@@ -0,0 +1,69 @@
+
+# FileRise Kubernetes Deployment
+
+This directory contains the Kubernetes configuration for deploying FileRise to a k3s cluster.
+
+## Deployment
+
+To deploy FileRise, use the Justfile commands:
+
+```bash
+just install
+```
+
+## Prerequisites
+
+Before deploying, ensure the following are set up:
+
+### 1. Create Persistent Volume Directories
+
+The deployment requires three persistent volumes. Create the directories on the k3s node:
+
+```bash
+mkdir -p /data/nfs/k3svolumes/filerise/uploads
+mkdir -p /data/nfs/k3svolumes/filerise/users
+mkdir -p /data/nfs/k3svolumes/filerise/metadata
+mkdir -p /data/nfs/k3svolumes/filerise/config
+chown -R 1000:1000 /data/nfs/k3svolumes/filerise/
+chmod -R 775 /data/nfs/k3svolumes/filerise/
+```
+
+### 2. Create the Secret
+
+FileRise uses a Kubernetes secret to manage the `PERSISTENT_TOKENS_KEY` environment variable. This secret is not included in the repository for security reasons. You must create it manually in the `services` namespace.
+
+Create the secret with the following command:
+
+```bash
+kubectl create secret generic filerise-secret --from-literal=PERSISTENT_TOKENS_KEY='your_random_secure_key_here' -n services
+```
+
+Replace `your_random_secure_key_here` with a strong random string.
+
+### Updating the Secret
+
+To update the secret, you can delete and recreate it, or use `kubectl edit`:
+
+```bash
+kubectl edit secret filerise-secret -n services
+```
+
+## Configuration
+
+FileRise will be accessible at: `http://filerise.f3s.buetow.org`
+
+On first launch, you'll be guided through creating the initial admin user.
+
+## Storage
+
+The deployment uses four persistent volumes:
+- **uploads** (50Gi): Stores uploaded files
+- **users** (1Gi): Stores user data and configurations
+- **metadata** (5Gi): Stores file metadata and database
+- **config** (1Gi): Stores application configuration files
+
+## Justfile Commands
+
+- `just install` - Install FileRise using Helm
+- `just upgrade` - Upgrade the FileRise deployment
+- `just delete` - Uninstall FileRise from the cluster
diff --git a/f3s/filerise/helm-chart/Chart.yaml b/f3s/filerise/helm-chart/Chart.yaml
new file mode 100644
index 0000000..17863c9
--- /dev/null
+++ b/f3s/filerise/helm-chart/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v2
+name: filerise
+description: A Helm chart for deploying FileRise file manager.
+version: 0.1.0
+appVersion: "latest"
diff --git a/f3s/filerise/helm-chart/templates/configmap.yaml b/f3s/filerise/helm-chart/templates/configmap.yaml
new file mode 100644
index 0000000..bd901cb
--- /dev/null
+++ b/f3s/filerise/helm-chart/templates/configmap.yaml
@@ -0,0 +1,199 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: filerise-start-script
+ namespace: services
+data:
+ start.sh: |
+ #!/bin/bash
+ set -euo pipefail
+ umask 002
+ echo "πŸš€ Running start.sh..."
+
+ # ──────────────────────────────────────────────────────────────
+ # 0) If NOT root, we can't remap/chown. Log a hint and skip those parts.
+ # If root, remap www-data to PUID/PGID and (optionally) chown data dirs.
+ if [ "$(id -u)" -ne 0 ]; then
+ echo "[startup] Running as non-root. Skipping PUID/PGID remap and chown."
+ echo "[startup] Tip: remove '--user' and set PUID/PGID env vars instead."
+ else
+ # Remap www-data to match provided PUID/PGID (e.g., Unraid 99:100 or 1000:1000)
+ if [ -n "${PGID:-}" ]; then
+ current_gid="$(getent group www-data | cut -d: -f3 || true)"
+ if [ "${current_gid}" != "${PGID}" ]; then
+ groupmod -o -g "${PGID}" www-data || true
+ fi
+ fi
+ if [ -n "${PUID:-}" ]; then
+ current_uid="$(id -u www-data 2>/dev/null || echo '')"
+ target_gid="${PGID:-$(getent group www-data | cut -d: -f3)}"
+ if [ "${current_uid}" != "${PUID}" ]; then
+ usermod -o -u "${PUID}" -g "${target_gid}" www-data || true
+ fi
+ fi
+
+ # Optional: normalize ownership on data dirs (good for first run on existing shares)
+ if [ "${CHOWN_ON_START:-true}" = "true" ]; then
+ echo "[startup] Normalizing ownership on uploads/metadata..."
+ chown -R www-data:www-data /var/www/metadata /var/www/uploads || echo "[startup] chown failed (continuing)"
+ chmod -R u+rwX /var/www/metadata /var/www/uploads || echo "[startup] chmod failed (continuing)"
+ fi
+ fi
+
+ # ──────────────────────────────────────────────────────────────
+ # 1) Token‐key warning (guarded for -u)
+ if [ "${PERSISTENT_TOKENS_KEY:-}" = "default_please_change_this_key" ] || [ -z "${PERSISTENT_TOKENS_KEY:-}" ]; then
+ echo "⚠️ WARNING: Using default/empty persistent tokens keyβ€”override for production."
+ fi
+
+ # 2) Update config.php based on environment variables
+ CONFIG_FILE="/var/www/config/config.php"
+ if [ -f "${CONFIG_FILE}" ]; then
+ echo "πŸ”„ Updating config.php from env vars..."
+ [ -n "${TIMEZONE:-}" ] && sed -i "s|define('TIMEZONE',[[:space:]]*'[^']*');|define('TIMEZONE', '${TIMEZONE}');|" "${CONFIG_FILE}"
+ [ -n "${DATE_TIME_FORMAT:-}" ] && sed -i "s|define('DATE_TIME_FORMAT',[[:space:]]*'[^']*');|define('DATE_TIME_FORMAT', '${DATE_TIME_FORMAT}');|" "${CONFIG_FILE}"
+ if [ -n "${TOTAL_UPLOAD_SIZE:-}" ]; then
+ sed -i "s|define('TOTAL_UPLOAD_SIZE',[[:space:]]*'[^']*');|define('TOTAL_UPLOAD_SIZE', '${TOTAL_UPLOAD_SIZE}');|" "${CONFIG_FILE}"
+ fi
+ [ -n "${SECURE:-}" ] && sed -i "s|\$envSecure = getenv('SECURE');|\$envSecure = '${SECURE}';|" "${CONFIG_FILE}"
+ # NOTE: SHARE_URL is read from getenv in PHP; no sed needed.
+ fi
+
+ # 2.1) Prepare metadata/log & sessions (skip chown if non-root)
+ mkdir -p /var/www/metadata/log
+ if [ "$(id -u)" -eq 0 ]; then
+ chown www-data:www-data /var/www/metadata/log || true
+ chmod 775 /var/www/metadata/log || true
+ fi
+ : > /var/www/metadata/log/error.log || true
+ : > /var/www/metadata/log/access.log || true
+ if [ "$(id -u)" -eq 0 ]; then
+ chown www-data:www-data /var/www/metadata/log/*.log || true
+ fi
+
+ mkdir -p /var/www/sessions
+ if [ "$(id -u)" -eq 0 ]; then
+ chown www-data:www-data /var/www/sessions || true
+ chmod 700 /var/www/sessions || true
+ else
+ chmod 700 /var/www/sessions || true
+ fi
+
+ # 2.2) Prepare dynamic dirs (uploads/users/metadata)
+ for d in uploads users metadata; do
+ tgt="/var/www/${d}"
+ mkdir -p "${tgt}"
+ if [ "$(id -u)" -eq 0 ]; then
+ chown www-data:www-data "${tgt}" || true
+ chmod 775 "${tgt}" || true
+ else
+ chmod 775 "${tgt}" || true
+ fi
+ done
+
+ # 3) Ensure PHP conf dir & set upload limits
+ mkdir -p /etc/php/8.3/apache2/conf.d
+ if [ -n "${TOTAL_UPLOAD_SIZE:-}" ]; then
+ echo "πŸ”„ Setting PHP upload limits to ${TOTAL_UPLOAD_SIZE}"
+ cat > /etc/php/8.3/apache2/conf.d/99-custom.ini <<EOF
+ upload_max_filesize = ${TOTAL_UPLOAD_SIZE}
+ post_max_size = ${TOTAL_UPLOAD_SIZE}
+ EOF
+ fi
+
+ # 4) Adjust Apache LimitRequestBody
+ if [ -n "${TOTAL_UPLOAD_SIZE:-}" ]; then
+ size_str="$(echo "${TOTAL_UPLOAD_SIZE}" | tr '[:upper:]' '[:lower:]')"
+ case "${size_str: -1}" in
+ g) factor=$((1024*1024*1024)); num=${size_str%g} ;;
+ m) factor=$((1024*1024)); num=${size_str%m} ;;
+ k) factor=1024; num=${size_str%k} ;;
+ *) factor=1; num=${size_str} ;;
+ esac
+ LIMIT_REQUEST_BODY=$(( num * factor ))
+ echo "πŸ”„ Setting Apache LimitRequestBody to ${LIMIT_REQUEST_BODY} bytes"
+ cat > /etc/apache2/conf-enabled/limit_request_body.conf <<EOF
+ <Directory "/var/www/public">
+ LimitRequestBody ${LIMIT_REQUEST_BODY}
+ </Directory>
+ EOF
+ fi
+
+ # 5) Configure Apache timeout (600s)
+ cat > /etc/apache2/conf-enabled/timeout.conf <<EOF
+ Timeout 600
+ EOF
+
+ # 6) Override ports if provided
+ if [ -n "${HTTP_PORT:-}" ]; then
+ sed -i "s/^Listen 80$/Listen ${HTTP_PORT}/" /etc/apache2/ports.conf || true
+ sed -i "s/<VirtualHost \*:80>/<VirtualHost *:${HTTP_PORT}>/" /etc/apache2/sites-available/000-default.conf || true
+ fi
+ if [ -n "${HTTPS_PORT:-}" ]; then
+ sed -i "s/^Listen 443$/Listen ${HTTPS_PORT}/" /etc/apache2/ports.conf || true
+ fi
+
+ # 7) Set ServerName (idempotent)
+ SN="${SERVER_NAME:-FileRise}"
+ if grep -qE '^ServerName\s' /etc/apache2/apache2.conf; then
+ sed -i "s|^ServerName .*|ServerName ${SN}|" /etc/apache2/apache2.conf
+ else
+ echo "ServerName ${SN}" >> /etc/apache2/apache2.conf
+ fi
+
+ # 8) Initialize persistent files if absent
+ if [ ! -f /var/www/users/users.txt ]; then
+ echo "" > /var/www/users/users.txt
+ if [ "$(id -u)" -eq 0 ]; then
+ chown www-data:www-data /var/www/users/users.txt || true
+ chmod 664 /var/www/users/users.txt || true
+ else
+ chmod 664 /var/www/users/users.txt || true
+ fi
+ fi
+
+ if [ ! -f /var/www/metadata/createdTags.json ]; then
+ echo "[]" > /var/www/metadata/createdTags.json
+ if [ "$(id -u)" -eq 0 ]; then
+ chown www-data:www-data /var/www/metadata/createdTags.json || true
+ chmod 664 /var/www/metadata/createdTags.json || true
+ else
+ chmod 664 /var/www/metadata/createdTags.json || true
+ fi
+ fi
+
+ # 8.5) Harden scan script perms (only if root)
+ if [ -f /var/www/scripts/scan_uploads.php ] && [ "$(id -u)" -eq 0 ]; then
+ chown root:root /var/www/scripts/scan_uploads.php
+ chmod 0644 /var/www/scripts/scan_uploads.php
+ fi
+
+ # 9) One-shot scan when the container starts (opt-in via SCAN_ON_START)
+ if [ "${SCAN_ON_START:-}" = "true" ]; then
+ echo "[startup] Scanning uploads directory to build metadata..."
+ if [ "$(id -u)" -eq 0 ]; then
+ if command -v runuser >/dev/null 2>&1; then
+ runuser -u www-data -- /usr/bin/php /var/www/scripts/scan_uploads.php || echo "[startup] Scan failed (continuing)"
+ else
+ su -s /bin/sh -c "/usr/bin/php /var/www/scripts/scan_uploads.php" www-data || echo "[startup] Scan failed (continuing)"
+ fi
+ else
+ # Non-root fallback: run as current user (permissions may limit writes)
+ /usr/bin/php /var/www/scripts/scan_uploads.php || echo "[startup] Scan failed (continuing)"
+ fi
+ fi
+
+ # 9.6) Stream Apache logs to the container console (optional toggle)
+ LOG_STREAM="${LOG_STREAM:-error}"
+ case "${LOG_STREAM,,}" in
+ none) STREAM_ERR=false; STREAM_ACC=false ;;
+ access) STREAM_ERR=false; STREAM_ACC=true ;;
+ both) STREAM_ERR=true; STREAM_ACC=true ;;
+ error|*)STREAM_ERR=true; STREAM_ACC=false ;;
+ esac
+
+ echo "πŸ”₯ Starting Apache..."
+ # Stream only the chosen logs; -n0 = don't dump history, -F = follow across rotations/creation
+ [ "${STREAM_ERR}" = "true" ] && tail -n0 -F /var/www/metadata/log/error.log 2>/dev/null &
+ [ "${STREAM_ACC}" = "true" ] && tail -n0 -F /var/www/metadata/log/access.log 2>/dev/null &
+ exec apachectl -D FOREGROUND
diff --git a/f3s/filerise/helm-chart/templates/deployment.yaml b/f3s/filerise/helm-chart/templates/deployment.yaml
new file mode 100644
index 0000000..db0990b
--- /dev/null
+++ b/f3s/filerise/helm-chart/templates/deployment.yaml
@@ -0,0 +1,110 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: filerise
+ namespace: services
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: filerise
+ template:
+ metadata:
+ labels:
+ app: filerise
+ spec:
+ securityContext:
+ fsGroup: 1000
+ initContainers:
+ - name: setup-directories
+ image: busybox:latest
+ command:
+ - sh
+ - -c
+ - |
+ mkdir -p /var/www/metadata/log
+ mkdir -p /var/www/uploads
+ mkdir -p /var/www/users
+ mkdir -p /var/www/config
+ mkdir -p /var/www/sessions
+ touch /var/www/metadata/log/error.log
+ touch /var/www/metadata/log/access.log
+ touch /var/www/users/users.txt
+ echo "[]" > /var/www/metadata/createdTags.json
+ chown -R 1000:1000 /var/www/metadata /var/www/uploads /var/www/users /var/www/config /var/www/sessions
+ chmod -R 775 /var/www/metadata /var/www/uploads /var/www/users /var/www/config
+ chmod 700 /var/www/sessions
+ chmod 664 /var/www/users/users.txt
+ chmod 664 /var/www/metadata/createdTags.json
+ volumeMounts:
+ - name: filerise-uploads
+ mountPath: /var/www/uploads
+ - name: filerise-users
+ mountPath: /var/www/users
+ - name: filerise-metadata
+ mountPath: /var/www/metadata
+ - name: filerise-config
+ mountPath: /var/www/config
+ - name: filerise-sessions
+ mountPath: /var/www/sessions
+ containers:
+ - name: filerise
+ image: error311/filerise-docker:latest
+ command: ["/bin/bash", "/usr/local/bin/start-override.sh"]
+ ports:
+ - containerPort: 80
+ env:
+ - name: TIMEZONE
+ value: "UTC"
+ - name: DATE_TIME_FORMAT
+ value: "m/d/y h:iA"
+ - name: TOTAL_UPLOAD_SIZE
+ value: "5G"
+ - name: SECURE
+ value: "false"
+ - name: PERSISTENT_TOKENS_KEY
+ valueFrom:
+ secretKeyRef:
+ name: filerise-secret
+ key: PERSISTENT_TOKENS_KEY
+ - name: PUID
+ value: "1000"
+ - name: PGID
+ value: "1000"
+ - name: CHOWN_ON_START
+ value: "false"
+ - name: SCAN_ON_START
+ value: "true"
+ volumeMounts:
+ - name: filerise-uploads
+ mountPath: /var/www/uploads
+ - name: filerise-users
+ mountPath: /var/www/users
+ - name: filerise-metadata
+ mountPath: /var/www/metadata
+ - name: filerise-config
+ mountPath: /var/www/config
+ - name: filerise-sessions
+ mountPath: /var/www/sessions
+ - name: start-script
+ mountPath: /usr/local/bin/start-override.sh
+ subPath: start.sh
+ volumes:
+ - name: filerise-uploads
+ persistentVolumeClaim:
+ claimName: filerise-uploads-pvc
+ - name: filerise-users
+ persistentVolumeClaim:
+ claimName: filerise-users-pvc
+ - name: filerise-metadata
+ persistentVolumeClaim:
+ claimName: filerise-metadata-pvc
+ - name: filerise-config
+ persistentVolumeClaim:
+ claimName: filerise-config-pvc
+ - name: start-script
+ configMap:
+ name: filerise-start-script
+ defaultMode: 0755
+ - name: filerise-sessions
+ emptyDir: {}
diff --git a/f3s/filerise/helm-chart/templates/ingress.yaml b/f3s/filerise/helm-chart/templates/ingress.yaml
new file mode 100644
index 0000000..5c31db1
--- /dev/null
+++ b/f3s/filerise/helm-chart/templates/ingress.yaml
@@ -0,0 +1,20 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: filerise-ingress
+ namespace: services
+ annotations:
+ spec.ingressClassName: traefik
+ traefik.ingress.kubernetes.io/router.entrypoints: web
+spec:
+ rules:
+ - host: filerise.f3s.buetow.org
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: filerise-service
+ port:
+ number: 80
diff --git a/f3s/filerise/helm-chart/templates/persistent-volume.yaml b/f3s/filerise/helm-chart/templates/persistent-volume.yaml
new file mode 100644
index 0000000..22cd75e
--- /dev/null
+++ b/f3s/filerise/helm-chart/templates/persistent-volume.yaml
@@ -0,0 +1,111 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: filerise-uploads-pv
+spec:
+ capacity:
+ storage: 50Gi
+ volumeMode: Filesystem
+ accessModes:
+ - ReadWriteOnce
+ persistentVolumeReclaimPolicy: Retain
+ hostPath:
+ path: /data/nfs/k3svolumes/filerise/uploads
+ type: Directory
+---
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: filerise-users-pv
+spec:
+ capacity:
+ storage: 1Gi
+ volumeMode: Filesystem
+ accessModes:
+ - ReadWriteOnce
+ persistentVolumeReclaimPolicy: Retain
+ hostPath:
+ path: /data/nfs/k3svolumes/filerise/users
+ type: Directory
+---
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: filerise-metadata-pv
+spec:
+ capacity:
+ storage: 5Gi
+ volumeMode: Filesystem
+ accessModes:
+ - ReadWriteOnce
+ persistentVolumeReclaimPolicy: Retain
+ hostPath:
+ path: /data/nfs/k3svolumes/filerise/metadata
+ type: Directory
+---
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: filerise-config-pv
+spec:
+ capacity:
+ storage: 1Gi
+ volumeMode: Filesystem
+ accessModes:
+ - ReadWriteOnce
+ persistentVolumeReclaimPolicy: Retain
+ hostPath:
+ path: /data/nfs/k3svolumes/filerise/config
+ type: Directory
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: filerise-uploads-pvc
+ namespace: services
+spec:
+ storageClassName: ""
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 50Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: filerise-users-pvc
+ namespace: services
+spec:
+ storageClassName: ""
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: filerise-metadata-pvc
+ namespace: services
+spec:
+ storageClassName: ""
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 5Gi
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: filerise-config-pvc
+ namespace: services
+spec:
+ storageClassName: ""
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
diff --git a/f3s/filerise/helm-chart/templates/service.yaml b/f3s/filerise/helm-chart/templates/service.yaml
new file mode 100644
index 0000000..cbae845
--- /dev/null
+++ b/f3s/filerise/helm-chart/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app: filerise
+ name: filerise-service
+ namespace: services
+spec:
+ ports:
+ - name: web
+ port: 80
+ protocol: TCP
+ targetPort: 80
+ selector:
+ app: filerise
diff --git a/frontends/Rexfile b/frontends/Rexfile
index e023aaa..6cc91d3 100644
--- a/frontends/Rexfile
+++ b/frontends/Rexfile
@@ -77,7 +77,7 @@ our @dns_zones_remove = qw//;
# k3s cluster running on FreeBSD in my LAN
our @f3s_hosts =
- qw/f3s.buetow.org anki.f3s.buetow.org bag.f3s.buetow.org flux.f3s.buetow.org audiobookshelf.f3s.buetow.org grafana.f3s.buetow.org radicale.f3s.buetow.org vault.f3s.buetow.org syncthing.f3s.buetow.org uprecords.f3s.buetow.org koreader.f3s.buetow.org/;
+ qw/f3s.buetow.org anki.f3s.buetow.org bag.f3s.buetow.org flux.f3s.buetow.org audiobookshelf.f3s.buetow.org grafana.f3s.buetow.org radicale.f3s.buetow.org vault.f3s.buetow.org syncthing.f3s.buetow.org uprecords.f3s.buetow.org koreader.f3s.buetow.org filerise.f3s.buetow.org/;
# optionally, only enable manually for temp time, as no password protection yet
# push @f3s_hosts, 'registry.f3s.buetow.org';