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.

Note

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

ComponentFile in the releaseInstallation
Spigot plugin (all modules)Eternal-<ver>.jarinto plugins/update/ – Bukkit swaps it on the next restart
ProxyEternal-<ver>.jarJar is replaced in place, active after restart
REST APIEternalApi-<ver>.jarits own jar is replaced, active after restart (or immediately with restart-on-update)
Plugin folders on the API hostEternal-<ver>.jardirectly as Eternal.jar into every folder from plugin-dirs
Dashboardeternal-web-<ver>.ziptools/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.repo is missing in api.yml or updates.enabled: false is set.
Warning

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.version sits next to it as a marker.
  • Old Eternal-<ver>.jar files 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: false in the config.yml inside 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 variableMeaning
PORT, BINDListen address, default in the unit: 8099 on 127.0.0.1
API_URLAddress of the REST API (for the permission check and the network-wide toggle)
WEB_DIRFolder with the served dashboard
STATE_DIRSettings, history, previous build (default .eternal-updater/ next to WEB_DIR)
REPOFallback repo if no API_URL is set
GITHUB_TOKENoptional, against GitHub rate limits
REQUIRED_PERMPermission 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/me and requires eternal.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.

PackageWhat happens
Landing pageThe build in the landing folder (LANDING_DIR, default /var/www/html/eternal-landing) is swapped, the previous one is kept for a rollback.
License serverserver.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.

Note

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.repo is missing in api.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.jar and an old Eternal-<ver>.jar – the API only cleans up in plugin-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.json is cached – the FilesMatch rule is missing or comes before the general JSON rule.