02.03 Upgrading on Bare Metal
Download the new SimpleRisk release, replace the application files while preserving config.php and uploads, then run the database upgrade. Same underlying upgrade architecture as Docker; the file-replacement step is what differs.
Why this matters
The bare-metal upgrade workflow is the original SimpleRisk upgrade pattern. It's also the one with the most pitfalls because the operator has to manually replace the application files while preserving the install-specific files (config.php, the contents of uploads/, possibly customizations) that don't come from the new release. Get the file replacement wrong and the install loses its database credentials, or its uploaded evidence, or its accumulated logs.
The Docker upgrade workflow (Upgrading via Docker) avoids most of these pitfalls by separating the application code (in the image) from the persistent state (in the volumes). The bare-metal workflow doesn't have that separation; the application code and the persistent state both live in the same simplerisk/ directory tree, and the operator has to know which files are which.
The other thing worth knowing: the underlying SimpleRisk upgrade architecture is identical to Docker. Whether you're upgrading via container swap or via file replacement, the database upgrade is the same chain of upgrade_from_
functions documented in The Upgrade Process. The bare-metal-specific work is just getting the new application files in place; the database upgrade afterward is the same.
Before you start
Have these in hand:
- A current SimpleRisk install running on bare metal per Installing on Linux.
- The current SimpleRisk version — check
simplerisk/includes/version.phpfor theAPP_VERSIONconstant, or hitGET /api/upgrade/version/app. - The target SimpleRisk version — typically the latest stable release tag from the SimpleRisk releases page.
- The release notes for every version between current and target — under
release_notes/in the SimpleRisk repository. - A current database backup — see Database Backup and Restore. This is the rollback path.
- A current backup of
simplerisk/includes/config.php— the install-specific configuration that the upgrade must NOT overwrite. - A maintenance window if your install has active users.
- Root or sudo access to the SimpleRisk host for replacing files and restarting the web server.
Step-by-step
1. Take a database backup
mysqldump -u root -p simplerisk > simplerisk-backup-$(date +%Y%m%d-%H%M%S).sql
Verify the backup is non-empty and looks reasonable.
2. Take a config.php backup
sudo cp /var/www/simplerisk/includes/config.php /tmp/config.php.backup
(Adjust /var/www/simplerisk to your actual install path.)
This file holds the database credentials and other install-specific values. The upgrade workflow below explicitly preserves it; the backup is in case something goes wrong with the preservation.
3. Note the contents of any other install-specific files
The standard SimpleRisk install has the following install-specific paths that should be preserved across upgrades:
simplerisk/includes/config.php— the database credentials and core configuration.simplerisk/uploads/— uploaded evidence files, document attachments, and other user-supplied content.simplerisk/logs/— operational logs (depending on your log configuration; see Log Rotation and Disk Management).- Any custom files your install has under
simplerisk/— custom CSS overrides, custom branding assets, customer-specific scripts. These get overwritten by the upgrade unless explicitly preserved.
For most installs, the first three are the load-bearing ones. The fourth is install-specific; if your team has added custom files, document them somewhere so they're not forgotten during upgrades.
4. Download the new SimpleRisk release
cd /tmp
wget https://github.com/simplerisk/code-development/archive/refs/tags/
.tar.gz tar xzf
.tar.gz
The extracted directory is code-development-
, containing the new SimpleRisk source. The actual application code is in code-development-
.
5. Stop the web server (or scale to maintenance mode)
To prevent users hitting the application during the file swap and to avoid concurrent file access:
sudo systemctl stop apache2 # or nginx, or php8.1-fpm
For deployments behind a load balancer, the alternative is to drain the load balancer to a maintenance page; the result is the same operationally.
6. Replace the application files (preserving the install-specific ones)
The cleanest pattern is:
# Move the existing install aside
sudo mv /var/www/simplerisk /var/www/simplerisk.old
# Place the new install
sudo mv /tmp/code-development-
/simplerisk /var/www/simplerisk # Restore the install-specific files sudo cp /var/www/simplerisk.old/includes/config.php /var/www/simplerisk/includes/config.php sudo cp -r /var/www/simplerisk.old/uploads /var/www/simplerisk/uploads # (And any other custom files identified in Step 3) # Restore ownership and permissions sudo chown -R www-data:www-data /var/www/simplerisk sudo find /var/www/simplerisk -type d -exec chmod 750 {} \; sudo find /var/www/simplerisk -type f -exec chmod 640 {} \;
(Adjust user/group www-data for your distribution; RHEL/Rocky/Alma typically use apache.)
After verification, you can remove /var/www/simplerisk.old/ to reclaim disk space — but keep it for at least a few days as the rollback artifact in case post-upgrade issues surface.
7. Restart the web server
sudo systemctl start apache2 # or nginx, or php8.1-fpm
Verify the application loads (browser to the SimpleRisk URL; you should see the login page or a "database upgrade required" notice).
8. Run the database upgrade
The application code is now at the new version. The database schema is still at the old version. Run the upgrade.
Browser-based:
- Log in to
https://with admin credentials./admin/upgrade.php - The page detects that
db_versionlagsAPP_VERSIONand runs the chain ofupgrade_from_*functions. - Wait for completion.
API-based:
curl -H "X-API-KEY:
" \ https://
/api/upgrade/upgrade/simplerisk/db
The full upgrade architecture is in The Upgrade Process.
9. Upgrade the activated Extras
Walk the activated Extras and run each one's upgrade. See Upgrading Extras.
10. Verify end-to-end
- Confirm
APP_VERSIONanddb_versionmatch. - Open the dashboard and confirm it loads.
- Submit a test risk; trigger a test notification.
- Spot-check
simplerisk/logs/for any new errors.
If issues appear, the rollback path is to restore /var/www/simplerisk.old/ over /var/www/simplerisk/ (and restore the database from the Step 1 backup if the schema upgrade ran).
11. Clean up
After successful verification:
- Remove
/var/www/simplerisk.old/(after a few days of confirmed-good operation). - Remove the
/tmp/artifacts:rm /tmp/code-development-..tar.gz - Update operational runbooks to reference the new version.
Common pitfalls
A handful of patterns recur with bare-metal upgrades.
-
Overwriting
config.php. The single most common bare-metal upgrade failure. Operators extract the new release directly over the existing install (tar xzf release.tar.gz -C /var/www/), which overwritesconfig.phpwith the (empty or default) version from the new release. The install loses its database credentials. Recovery: restoreconfig.phpfrom the backup taken in Step 2. Prevention: always use the move-aside pattern in Step 6, never extract directly over the existing install. -
Losing the uploads directory. Same failure mode as
config.php, but for evidence files. Some bare-metal install patterns putuploads/insidesimplerisk/; if the upgrade replacessimplerisk/without preservinguploads/, the evidence is gone. Restore from the move-aside copy if it happened; prevent by following Step 6. -
Wrong file ownership after the swap. The new files extracted from the tarball are owned by whoever extracted them (root if extracted as root). The web server user can't read them. Apache/Nginx errors with permission-denied. Run the
chownandchmodsteps after every file swap; verify withsudo -u www-data ls /var/www/simplerisk/index.php(should succeed). -
Skipping the database upgrade after the file swap. New code, old schema. The application starts erroring as code paths reference schema elements that don't exist. Always run the database upgrade promptly after the file swap.
-
Not stopping the web server during the swap. Concurrent web requests during the file swap can hit half-replaced state, producing confusing errors and possibly leaving log files in an inconsistent state. Stop the web server (or drain the load balancer) for the duration of the swap.
-
Skipping the backup. The backup is the rollback path. Without it, a failed upgrade is recoverable only by running the upgrade forward through whatever issue blocked it. Take the backup; verify it's valid; then upgrade.
-
Upgrading without reading the release notes. Each release's notes document version-specific concerns: data migrations that take significant time, new configuration settings the upgrade introduces, deprecations, breaking changes. Skipping the notes invites surprises mid-upgrade. Read the notes for every version between current and target.
-
Replacing the application files but not restarting the web server. Some web servers (PHP-FPM with opcache enabled) cache the parsed PHP and don't pick up new files until the cache is cleared. Restart the web server (or the PHP-FPM service specifically) after the file swap; without this, the application keeps running the old code even though the new files are on disk.
-
Cleaning up the
.old/directory too quickly. The rollback path requires the previous install. Keeping/var/www/simplerisk.old/for a few days after the upgrade gives you a quick rollback if a post-upgrade issue surfaces. Don't delete immediately. -
Treating bare-metal upgrades as a manual one-off each time. If you're doing this regularly, consider scripting the workflow. A shell script that does the backup, file swap, ownership fix, and database upgrade in sequence reduces the chance of human error and produces a repeatable artifact you can iterate on.
Related
- The Upgrade Process
- Upgrading via Docker
- Upgrading Extras
- Database Backup and Restore
- Installing on Linux
- Log Rotation and Disk Management
Reference
- Permission required: Server-side: root/sudo for file replacement and web server restart; MySQL admin for backup. SimpleRisk-side:
check_adminfor the upgrade UI; valid API key for programmatic upgrade. - API endpoint(s): Same as Docker:
GET /api/upgrade/version/app,GET /api/upgrade/backup/db,GET /api/upgrade/upgrade/simplerisk/db. - Implementing files: Application code:
/var/www/simplerisk/(or wherever your install lives); release tarballs fromhttps://github.com/simplerisk/code-development/releases; the upgrade architecture insimplerisk/includes/upgrade.phpandsimplerisk/admin/upgrade.php. - Database tables:
settings(thedb_versionkey); the schema of every other table is what the upgrade functions modify. config_settingskeys:db_version(updated atomically as the upgrade chain progresses).- Files that must persist:
simplerisk/includes/config.php(database credentials);simplerisk/uploads/(evidence and attachments); custom files undersimplerisk/. - External dependencies: The release tarball download from GitHub; outbound HTTPS to
github.comfor the download.