Auto-updates
EternalSystem updates itself: the REST API regularly checks the public release repo and reports new versions to the database. Proxy, Spigot servers, API and dashboard then each fetch their own new version. An update always only becomes active after a restart of the respective component.
License: auto-updates are not a separate module; they are part of core and therefore of the free base (like punishments, reports, lobby). Which modules are free can change – the dashboard shows locked modules grayed out.
What goes where
| Component | File in the release | Installation |
|---|---|---|
| Spigot plugin (all modules) | Eternal-<ver>.jar | into plugins/update/ – Bukkit swaps it on the next restart |
| Proxy | Eternal-<ver>.jar | Jar is replaced in place, active after restart |
| REST API | EternalApi-<ver>.jar | its own jar is replaced, active after restart (or immediately with restart-on-update) |
| Plugin folders on the API host | Eternal-<ver>.jar | directly as Eternal.jar into every folder from plugin-dirs |
| Dashboard | eternal-web-<ver>.zip | tools/web-updater on the web host, operated from the dashboard |
The API never touches the dashboard's web root – the web updater takes care of that (see below).
Setup
1. API (api.yml)
updates:
enabled: true
repo: "LeqitAdam/EternalV1-releases" # public release repo, empty = no checks
check-interval-minutes: 60
restart-on-update: false # true: API exits after the swap (requires systemd Restart=always)
plugin-dirs: [] # plugin folders on this host that are supplied directly
plugin-jar-name: "Eternal.jar"
enabled: false on the API host means: the API keeps reporting new releases but installs nothing itself.
2. Servers (config.yml on proxy and Spigots)
updates:
enabled: true # default
check-interval-minutes: 60
3. Dashboard: Server → Updates
Permission: eternal.web.updates (default level Admin, requires eternal.web.admin).
- Toggle Auto-Update – applies network-wide.
- Jetzt prüfen ("Check now") and display of the latest release.
- Table Versionen ("Versions"): installed version of the REST API, of every plugin folder on the API host and of every server (offline servers are marked).
- Notices if
updates.repois missing inapi.ymlorupdates.enabled: falseis set.
For a component to actually install, both toggles must be on: updates.enabled locally and „Auto-Update“ in the dashboard. If you only want checks, set enabled: false on the respective host.
Plugin folders (plugin-dirs)
Cloud services are built from their template on every start. A plugins/update/Eternal.jar inside the running service would be gone after the restart. That is why the API copies the jar directly into the folders the servers get their plugins from – e.g. CloudNet templates or static servers on the same host:
updates:
plugin-dirs:
- /home/cloudnet/local/templates/Proxy/default/plugins
- /home/cloudnet/local/templates/Lobby/default/plugins
- /home/cloudnet/local/templates/Survival/default/plugins
plugin-jar-name: "Eternal.jar"
- One download, then an atomic swap in every folder.
Eternal.jar.versionsits next to it as a marker. - Old
Eternal-<ver>.jarfiles in the same folder are removed (they would otherwise be loaded twice). - Services get the new version on their next start/restart.
- Set
updates.enabled: falsein theconfig.ymlinside the templates – otherwise the updater in the service would download into nowhere. - Simply add static servers with their
plugins/folder. The API writes directly into the plugin directory, so restart the server afterwards.
Eternal Cloud: cloud folder included automatically
With cloud.enabled: true in api.yml, the API automatically adds the cloud folder (cloud.directory, default cloud) to plugin-dirs. The node copies cloud/Eternal.jar into every service on start – so every newly started service automatically gets the current version. Services under Eternal Cloud disable their own updater themselves; no entry in the templates is needed.
cloud:
enabled: true
directory: cloud
updates:
plugin-dirs: [] # the cloud folder is added automatically
Dashboard (separate web host)
If the dashboard runs on a different server than the API, tools/web-updater/server.mjs handles the updates there (Node ≥ 18, no dependencies, no unzip needed). It is operated in the dashboard under Server → Wartung ("Maintenance"; page „Dashboard & Wartung“, permission eternal.web.updates).
Installation
sudo mkdir -p /opt/eternal/web-updater
sudo cp tools/web-updater/server.mjs /opt/eternal/web-updater/
sudo cp tools/web-updater/eternal-web-updater.service /etc/systemd/system/
sudo editor /etc/systemd/system/eternal-web-updater.service # API_URL, WEB_DIR, User
sudo chown -R www-data:www-data /var/www/html/eternal-web # parent folder of WEB_DIR must be writable
sudo systemctl enable --now eternal-web-updater
| Environment variable | Meaning |
|---|---|
PORT, BIND | Listen address, default in the unit: 8099 on 127.0.0.1 |
API_URL | Address of the REST API (for the permission check and the network-wide toggle) |
WEB_DIR | Folder with the served dashboard |
STATE_DIR | Settings, history, previous build (default .eternal-updater/ next to WEB_DIR) |
REPO | Fallback repo if no API_URL is set |
GITHUB_TOKEN | optional, against GitHub rate limits |
REQUIRED_PERM | Permission for all actions, default eternal.web.updates |
Apache example (the updater behind the dashboard; never cache the maintenance file and version):
ProxyPass /updater/ http://127.0.0.1:8099/ connectiontimeout=5 timeout=600
ProxyPassReverse /updater/ http://127.0.0.1:8099/
<Location /updater/>
SetEnv no-gzip 1
</Location>
<FilesMatch "^(maintenance\.json|VERSION)$">
Header set Cache-Control "no-cache, no-store, must-revalidate"
</FilesMatch>
The FilesMatch rule must come after a general cache rule for .json (the last rule wins).
Features
- Installiert / neues Release einspielen ("Installed / install new release"), including a specific tag.
- Rollback to the previous build.
- Auto-Update with interval (default: off, every 15 minutes, at least 5); additionally respects the API's network-wide toggle (
GET /public/updates). - Verlauf ("History": updates, rollbacks, maintenance on/off, errors; 50 entries).
- Permission check: every request carries the dashboard token; the service queries
API_URL/meand requireseternal.web.updates.
Files: WEB_DIR/VERSION (installed release), WEB_DIR/maintenance.json (maintenance flag), STATE_DIR/updater.json (settings + history), STATE_DIR/previous/ (previous build).
Landing page and license server
Own installations of the landing page and the license server (both on one host) get the same update function under Landing admin → Updates. It updates each package on its own, rolls back and auto-updates (interval adjustable). The license server does this itself: it downloads eternal-landing-<ver>.zip and eternal-license-server-<ver>.zip from the releases.
| Package | What happens |
|---|---|
| Landing page | The build in the landing folder (LANDING_DIR, default /var/www/html/eternal-landing) is swapped, the previous one is kept for a rollback. |
| License server | server.mjs/updater.mjs are replaced, then the service restarts (systemd Restart=always). state.json, keys and tokens stay untouched. |
One-time setup (afterwards everything runs from the admin page):
sudo chown -R eternal-license: /var/www/html/eternal-landing
sudo cp tools/license-server/eternal-license.service /etc/systemd/system/ # LANDING_DIR + ReadWritePaths
sudo cp tools/license-server/updater.mjs /opt/eternal/license-server/
sudo systemctl daemon-reload && sudo systemctl restart eternal-license
Maintenance mode
On the same page: toggle, message and expected end. The updater writes WEB_DIR/maintenance.json; the dashboard checks the file every minute and shows a maintenance page to everyone without eternal.web.updates. While an update is being installed, this happens automatically. /login stays reachable so admins can get in; they see a notice „Wartungsmodus aktiv“ ("Maintenance mode active") at the top.
This is the maintenance mode of the dashboard. Maintenance for game servers is configured per task in Eternal Cloud (entry only with eternal.cloud.maintenance).
Versions
Version comparison: v1.2.3 > 1.2.3-SNAPSHOT > 1.2.2. The release repo contains only binaries; the updaters need no token.
Common pitfalls
- Nothing happens: one of the two toggles is off, or
updates.repois missing inapi.yml. - New version is there but not active: the jar swap only takes effect after restarting the server or the API.
- Plugin loaded twice: the plugin folder contains
Eternal.jarand an oldEternal-<ver>.jar– the API only cleans up inplugin-dirs; delete by hand in other folders. - Web updater cannot swap: the service needs write access to the parent folder of
WEB_DIR(atomic folder swap). - Maintenance page stays after turning it off:
maintenance.jsonis cached – theFilesMatchrule is missing or comes before the general JSON rule.