Updating an existing installation - wiso-forschungslabor/hroot-documentation GitHub Wiki
This guide covers all update workflows for hroot, ranging from seamless One-Click In-App updates to manual bare-metal command-line upgrades.
Important
Safety First: Before performing any update or schema migration, always ensure a full database backup (mysqldump) and a copy of your uploaded files (uploads/) exist.
- Update Methods Comparison Matrix
- 1. In-App One-Click Auto-Update (Admin UI)
- 2. Docker Update with Precompiled Image (
docker compose pull) - 3. Docker Update with Source Code Build (
docker compose up -d --build) - 4. Manual Bare-Metal Update (Legacy CLI)
- 5. Major Version Migration: Upgrading from Legacy hroot (v3.x) to v4.0
- 6. Merging Upstream Updates & Building Images for Custom Forks
- 7. Changing the Update Path (Switching from Upstream to Custom Fork or Branch)
The table below explains what actions are required across the four different update methods:
| Step / Action | 1. In-App Auto-Update | 2. Docker Precompiled Image | 3. Docker Source Build | 4. Manual Bare-Metal Update |
|---|---|---|---|---|
| Trigger Mechanism | Admin Web UI button | docker compose pull |
docker compose up -d --build |
Manual shell commands |
| Safety DB Snapshot | Automated (Pre-update dump) | Manual command | Manual command | Manual command |
bundle install |
Pre-packaged in Image (0s) | Pre-packaged in Image (0s) | Automated in Docker build stage | Manual bundle install
|
assets:precompile |
Pre-compiled in Image (0s) | Pre-compiled in Image (0s) | Automated in Docker build stage | Manual rake assets:precompile
|
| Database Migrations | Automated in isolated container | Automated via container entrypoint | Executed via bin/rails db:migrate
|
Manual rake db:migrate
|
| Background Cronjobs |
Automated (cron container) |
Automated (cron container) |
Automated (cron container) |
Manual whenever --update-crontab
|
| Web Server Restart | Automated (Zero-downtime reload) | Automated container restart | Automated container restart |
touch tmp/restart.txt / systemd |
| Health Check & Rollback | Automated 5-stage rollback | Manual container rollback | Manual git rollback | Manual database & code restore |
Best for: Production installations using standard Docker deployment (ghcr.io image).
Administrators can check for updates and trigger upgrades directly within the web interface without opening a server terminal:
- Sign in as a Banking Administrator.
- Navigate to Admin
$\rightarrow$ Options$\rightarrow$ System Check & Updates (/admin/options/check). - The system compares your installed Git commit against the latest release on GitHub:
- System is up to date: No action required.
- Update Available: Displays the new version, commit message, and changes.
- Click Update System Now to trigger the automated 5-stage update pipeline:
-
Stage 1 (Database Snapshot): A safety dump of your MySQL database is saved to
tmp/backups/. -
Stage 2 (Image Download): The new Docker image layer is downloaded from
ghcr.ioin background. -
Stage 3 (Schema Migration): Database migrations (
db:migrate) execute safely inside an isolated container. - Stage 4 (Health Check): The new application container starts and polls readiness for up to 180 seconds.
- Stage 5 (Automatic Rollback): If any error occurs or the health check fails, the previous image and database state are restored automatically.
-
Stage 1 (Database Snapshot): A safety dump of your MySQL database is saved to
Tip
Security & Rootless Docker: When running under Rootless Docker, the updater container communicates with the user-space Docker socket without root privileges, combining convenient In-App updates with strict host-level isolation. On standard Docker engines, ensure deployment commands are executed via sudo docker compose instead of adding users to the docker group.
Migrating an existing setup? See Migrating an Existing Docker Installation to Rootless Docker for a quick 3-minute guide.
Best for: Production Docker setups managed via command line or automated server cronjobs.
-
Create a quick database backup:
docker compose exec db mysqldump -u hroot -p${DATABASE_PASSWORD} ${DATABASE_NAME:-hroot_production} > backup_pre_update_$(date +%F).sql
-
Pull the latest precompiled Docker image from
ghcr.io:docker compose pull
-
Restart containers with the updated image:
The container entrypoint automatically executes
docker compose up -d
db:prepareto apply any new database schema migrations. -
Verify container logs:
docker compose logs -f web cron
Best for: Laboratories running custom code modifications, forks, or self-compiled deployments.
-
Create a database backup:
docker compose exec db mysqldump -u hroot -p${DATABASE_PASSWORD} ${DATABASE_NAME:-hroot_production} > backup_pre_update_$(date +%F).sql
-
Pull latest source code updates:
git pull origin master # or your customized branch / tag -
Check for new environment variables:
diff -u .env .env.example
-
Rebuild the Docker image and restart services:
Docker compiles new Ruby gems and precompiles frontend assets during the multi-stage build process.
docker compose up -d --build
-
Run database migrations:
docker compose exec web bin/rails db:migrate -
Verify operation:
docker compose logs -f web cron
Best for: Legacy servers without Docker (running directly on Ubuntu with native Ruby, rbenv, Passenger/Puma, and MySQL).
Follow these steps sequentially:
-
Create a full database backup:
mysqldump -u <db_user> -p <db_name> > backup_pre_update_$(date +%F).sql
-
(Optional) Enable Maintenance Page:
RAILS_ENV=production bundle exec rake rack:turnout:down[reason="Scheduled Maintenance Update"]
-
Pull latest source code:
git pull origin master
-
Check environment variables:
diff -u .env .env.example
-
Check Ruby version:
Ensure your active Ruby matches.ruby-version(e.g.4.0.6):ruby -v # If an upgrade is required: rbenv install 4.0.6 && rbenv global 4.0.6 -
Install / Update Ruby Gems:
bundle install
-
Run Database Migrations:
RAILS_ENV=production bin/rails db:migrate
-
Recompile Frontend Assets:
RAILS_ENV=production bin/rails assets:clobber RAILS_ENV=production bin/rails assets:precompile
-
Update Background Jobs in Crontab (
whenever):RAILS_ENV=production bundle exec whenever --update-crontab -
Restart the Web Server:
-
Phusion Passenger:
touch tmp/restart.txt
-
Systemd / Puma / NGINX / Apache:
sudo systemctl restart hroot nginx # or apache2
-
Phusion Passenger:
-
Disable Maintenance Page:
RAILS_ENV=production bundle exec rake rack:turnout:up
If your laboratory is upgrading from an older major version of hroot (v2.x / v3.x with hardcoded settings in production.rb, database.yml, RVM, and bare-metal Apache/Passenger), choose one of the following two dedicated upgrade paths:
Switch your installation to containerized Docker deployment for 1-click updates, isolated dependencies, and zero maintenance overhead.
- Read the guide: Migrating from Legacy Installation to Docker
Keep your installation running directly on the Linux host with system Ruby, rbenv, Passenger/Puma, and MySQL, while upgrading the codebase to v4.0 and migrating configuration into .env.
- Read the guide: Upgrading Bare Metal from v3 to v4
If your laboratory or institution maintains a custom fork of hroot (e.g. https://github.com/<your-account>/hroot):
Caution
Strict Privacy & Licensing Notice:
Any Docker images built from your fork on GitHub Container Registry (ghcr.io) MUST remain Private (Private Packages). Making the container image public makes the underlying source code accessible to the public, which constitutes a violation of the software license / terms of use. Ensure in your GitHub Package Settings that the image visibility is set to Private.
To pull in updates published to the official wiso-forschungslabor/hroot repository:
-
Commit any local custom changes:
git status git add . && git commit -m "Save local customizations"
-
Add upstream repository as a remote (one-time setup):
git remote add upstream https://github.com/wiso-forschungslabor/hroot.git
-
Fetch and merge latest upstream releases:
git fetch upstream git merge upstream/master
-
Push the merged changes to your fork:
git push origin master # or your customized branch
You can build and publish your customized Docker image to ghcr.io/<your-account>/hroot using GitHub Actions:
-
Enable GitHub Actions in your Fork (one-time setup):
- Go to your forked repository on GitHub
$\rightarrow$ Actions tab. - Click "I understand my workflows, go ahead and enable them" if prompted.
- Go to your forked repository on GitHub
-
Trigger the Docker Build:
-
Option A (Via Git Tag): Create and push a version tag matching
v*:git tag v4.1.0-myCustomVersion git push origin v4.1.0-myCustomVerision
-
Option B (Manual UI Trigger): Go to GitHub
$\rightarrow$ Actions$\rightarrow$ select "Build and Publish Docker Image"$\rightarrow$ click Run workflow$\rightarrow$ select your branch and click Run workflow.
-
Option A (Via Git Tag): Create and push a version tag matching
GitHub Actions will automatically build the image and push it to ghcr.io/<your-account>/hroot.
To allow your server and the built-in In-App One-Click Update Routine (or docker compose pull) to track your custom fork (one-time-setup, after that, the system will automatically use that fork & Branch to check for updates):
-
Configure your server's
.envfile:# Point Docker Compose to your fork's image HROOT_IMAGE=ghcr.io/<your-account>/hroot:latest # Point the In-App Update Checker to your GitHub repository and branch UPDATE_GITHUB_REPO=<your-account>/hroot UPDATE_BRANCH=master # or your tracking branch
-
Authenticate Docker with GitHub Container Registry (for Private Packages): Since your fork's image is private, log in with a GitHub Personal Access Token (PAT with
read:packagesscope):echo $GITHUB_PAT | docker login ghcr.io -u <your-github-username> --password-stdin
-
Deploy or Update:
-
Via Web UI: Go to Admin
$\rightarrow$ Options$\rightarrow$ System Check & Updates and click Update System Now. -
Via Terminal: Run:
docker compose pull && docker compose up -d
-
Via Web UI: Go to Admin
If your installation previously pulled updates from the official upstream repository (ghcr.io/wiso-forschungslabor/hroot:latest / wiso-forschungslabor/hroot on master) and you now want to switch to a custom fork (or switch between different branches such as master staging), follow this step-by-step migration procedure.
- Your laboratory created a custom fork (e.g.
https://github.com/<your-account>/hroot) to implement institutional customizations, custom themes, or specialized integrations. - You built your own Docker images via GitHub Actions and want your running server (and the In-App Update button) to follow your fork's release cycle instead of the official upstream repository.
- You want to test a pre-release branch (e.g.,
feature/custom-authorstaging) before rolling it out to production.
- In your GitHub fork repository, ensure the Docker build workflow has executed successfully (via GitHub Actions) and pushed an image to
ghcr.io/<your-account>/hroot:<tag>. - Confirm the package visibility in GitHub is set to Private (mandatory per license).
- On your production server host, ensure Docker is authenticated with GitHub Container Registry using a Personal Access Token (PAT) with
read:packagespermissions:echo "<YOUR_GITHUB_PAT>" | docker login ghcr.io -u <YOUR_GITHUB_USERNAME> --password-stdin
Open .env in the root of your hroot deployment on the server and adjust the update path variables:
# 1. Target Docker image repository and tag
HROOT_IMAGE=ghcr.io/<your-account>/hroot:latest
# 2. GitHub repository checked for new commits & version comparison
UPDATE_GITHUB_REPO=<your-account>/hroot
# 3. Branch tracked for updates (e.g. master, staging, or custom branch)
UPDATE_BRANCH=masterNote
-
HROOT_IMAGE: Tellsdocker-compose.ymlwhich container image to download and run for thewebandcronservices. -
UPDATE_GITHUB_REPOandUPDATE_BRANCH: Tell the in-app version checker (/admin/options/check) which GitHub repository and branch API to query when checking if a newer commit is available.
Before transitioning to the new image, always create an explicit database backup:
docker compose exec db mysqldump -u hroot -p${DATABASE_PASSWORD} ${DATABASE_NAME:-hroot_production} > backup_pre_switch_$(date +%F).sqlExecute the transition by pulling the newly configured image and restarting the stack:
# 1. Pull the new image from your fork
docker compose pull
# 2. Recreate containers with the new image and reloaded .env configuration
docker compose up -dTip
On container startup, the entrypoint script automatically runs bin/rails db:prepare (db:migrate), applying any new database migrations introduced in your custom fork.
- Sign in as a Banking Administrator.
- Go to Admin
$\rightarrow$ Options$\rightarrow$ System Check & Updates (/admin/options/check). - Verify that:
- The GitHub Repository now links to
https://github.com/<your-account>/hroot. - The Tracked Branch shows your configured branch (
master). - The Commit Comparison compares your running container against the latest commit in your custom fork.
- The GitHub Repository now links to
To switch back to the official upstream repository or to a different branch at any time:
- Edit
.envto restore:HROOT_IMAGE=ghcr.io/wiso-forschungslabor/hroot:latest UPDATE_GITHUB_REPO=wiso-forschungslabor/hroot UPDATE_BRANCH=master
- Run
docker compose pull && docker compose up -d. - Check
/admin/options/checkto confirm the upstream update path is active again.