#!/usr/bin/env bash # perf/apply-memory-shrink.sh — apply the t/316 memory shrink table via the # Cloudron API. Applied live 2026-09-02 (Redmine #731). Idempotent: re-running # sets the same values; 202 = accepted, app restarts. # # Requires: curl, jq. Creds: ~/.creds/cloudron.env (CLOUDRON_URL, CLOUDRON_API_TOKEN). # # Gotchas learned on this host: # - Route is POST /api/v1/apps//configure/memory_limit (NOT /memory_limit). # - Values <= manifest.memoryLimit (package floor) are rejected 400 "too small" # (e.g. photos/immich floor 3.5GB — left at 4096). # - This host's dockerd runs --log-driver=journald as a systemd-unit flag; # daemon.json must NOT set log-driver/log-opts (dockerd refuses to start). set -euo pipefail # shellcheck disable=SC1090 # creds path is env-overridable by design source "${CLOUDRON_CREDS:-$HOME/.creds/cloudron.env}" # fqdn|target MB (t/316 table; photos skipped — manifest floor 3.5GB) TABLE=' axiosheartstudios.com|512 community.turnsys.com|4096 nextcloud.knownelement.com|2048 bookmarks.knownelement.com|2048 share.knownelement.com|512 hfnfc.net|512 notes.knownelement.com|1024 digital-assets-manager.knownelement.com|512 finance.turnsys.com|512 finance.reachableceo.com|512 ' APPS=$(curl -s --max-time 20 -H "Authorization: Bearer $CLOUDRON_API_TOKEN" "$CLOUDRON_URL/api/v1/apps") echo "$TABLE" | while IFS='|' read -r fqdn mb; do [ -z "$fqdn" ] && continue app_id=$(jq -r --arg f "$fqdn" '.apps[] | select(.fqdn==$f) | .id' <<<"$APPS") [ -z "$app_id" ] && { echo "SKIP (not found): $fqdn"; continue; } code=$(curl -s --max-time 20 -X POST \ -H "Authorization: Bearer $CLOUDRON_API_TOKEN" -H "Content-Type: application/json" \ -d "{\"memoryLimit\": $((mb * 1048576))}" \ "$CLOUDRON_URL/api/v1/apps/$app_id/configure/memory_limit" -o /dev/null -w '%{http_code}') echo "$code $fqdn -> ${mb}MB" sleep 10 done