- config.json: tipi_version 1->2, version 1.0.0->1.0.1, updated_at bumped;
added missing required fields supported_architectures (["amd64"]) and
dynamic_config (true) so the app passes schema validation
- docker-compose.json: main service image mergedrop:1.0.0 -> mergedrop:1.0.1
- build/build.sh: default IMAGE_TAG 1.0.0 -> 1.0.1; default SOURCE_REPO
corrected from stale video-merger.git to vid-merger.git
- build/README.md: corrected source repo pointer from video-merger to
vid-merger
Image git.alexzaw.dev/alexz/mergedrop:1.0.1 is being built from
git.alexzaw.dev/alexz/vid-merger @ 9b27376 in a separate process.
Deploy chain (appstore update / app update) to be run separately once the
image build completes.
- apricot-blossom: cherry-blossom mark (OpenMoji), matches the name
- docspace: ONLYOFFICE logo (dashboard-icons)
- mcp-manager: Model Context Protocol logo (dashboard-icons)
- md2html: official Markdown mark on white
- mergedrop: clapperboard mark (OpenMoji) for the video merger
- scalar: replace broken 2.9MB BMP (mislabeled .jpg) with Scalar's logo
sap-mcp-bridge intentionally skipped (being uninstalled).
Runtipi 'app update' validates required form_fields against its own
DB-tracked form state, not against app.env. Adding new required fields
to a pre-installed app blocks every update with 'Variable X is required'.
The manager binary already gracefully no-ops basic auth if either env
var is empty (logs a WARN). Drop required:true so updates pass; values
that exist in app.env keep working at runtime.
- README.md explains the image is built from the separate fork repo at
git.alexzaw.dev/alexz/cloudflare-ddns, lists what's in the image, and
documents how to rebuild + redeploy.
- build.sh clones (or refreshes) /tmp/cfddns-build from the fork via SSH,
runs docker build, and pushes to git.alexzaw.dev/alexz/cloudflare-ddns:latest.
Supports IMAGE_NAME/IMAGE_TAG/SOURCE_REPO overrides and passes positional
args through to docker build (e.g. --no-cache).
- .gitignore for build artifacts.
The previous 'password' type required a manual value during app
update, which blocked Runtipi from regenerating the compose file
(error: 'Variable Web UI Password is required'). Switch to the
'random' field type with min=24 hex chars so a strong password is
auto-generated on install and persisted in app.env, viewable in
the dashboard.
- Swap image from favonia/cloudflare-ddns:latest to
git.alexzaw.dev/alexz/cloudflare-ddns:latest (private fork with
cmd/manager binary that wraps the original ddns updater)
- Expose web UI on internal port 8080, traefik-routable
- Add CFDDNS_WEB_USER/CFDDNS_WEB_PASSWORD basic-auth form fields
- Repurpose existing DOMAINS/PROXIED/UPDATE_CRON/TZ as first-run seed
for the YAML config that the UI manages thereafter
- Mount ${APP_DATA_DIR}/data:/config for persistent cfddns.yaml
- Healthcheck on /healthz via 127.0.0.1 (alpine wget)
- Bump tipi_version 7 -> 8 to trigger app update
- Each user gets a Linux + Samba account and home dir at /nas/home/<username>/
- Web UI file browsing scoped to per-user directories
- Creating/deleting users from web UI also manages system + Samba accounts
- Replaced hardcoded [data] SMB share with [homes] (per-user automatic shares)
- Removed hardcoded alexz user from entrypoint — server.js handles all user management
- Removed storage quotas from backend and frontend
- Existing users get home directories auto-created on startup (migration)
- Add health check (curl /api/health) so Traefik can verify container health
- Set container hostname to nas.alexzaw.dev
- Remove hardcoded demo credentials from login page
- Remove admin123 fallback password — require SMB_PASSWORD env var
- Fail fast if no admin password is configured
Online office suite with document, spreadsheet, and presentation editing.
Includes external PostgreSQL, Redis, and RabbitMQ services with auto-generated
secrets for JWT, database, and message queue credentials.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The nft|grep|grep|head pipeline fails when no masquerade rule exists,
causing the script to exit under set -euo pipefail. Add || true to
match the cistech-tunnel version.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move entrypoint.sh from build/scripts/ to shared/
- Create startup-vnc.sh in shared/ (was base64-encoded in Dockerfile)
- Remove baked-in scripts and CMD from Dockerfile (keep vnc.service unit only)
- Entrypoint now: chmod +x all shared scripts, symlinks startup-vnc.sh
to /opt/scripts/ so systemd vnc.service still finds it
- Fix host watcher: use /bin/bash in ExecStart for permission resilience
- Bump tipi_version to 7
All scripts are now dynamically controlled via volume mounts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Invoke host-routing.sh via /bin/bash so the watcher service works
even if the execute bit gets cleared by permission resets.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add chmod +x in entrypoint.sh to ensure all shared scripts are
executable even if permissions get reverted by git pull or appstore
update operations.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Runtipi's compose generator doesn't translate the entrypoint field.
The entrypoint is instead set via user-config override.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move entrypoint.sh from build/scripts/ to shared/ (no longer baked into image)
- Add entrypoint directive to docker-compose.json pointing to /shared/entrypoint.sh
- Update entrypoint.sh to reference /shared/startup-vnc.sh instead of /opt/scripts/
- Bump tipi_version to 7
All scripts are now dynamically controlled via volume mounts from the shared/
directory. The Docker image is a clean base with only packages installed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>