diff --git a/client/src/i18n/translations/de.js b/client/src/i18n/translations/de.js index 6e4ebb4..99e3542 100644 --- a/client/src/i18n/translations/de.js +++ b/client/src/i18n/translations/de.js @@ -277,6 +277,8 @@ const de = { 'admin.update.failed': 'Update fehlgeschlagen', 'admin.update.backupHint': 'Wir empfehlen, vor dem Update ein Backup zu erstellen und herunterzuladen.', 'admin.update.backupLink': 'Zum Backup', + 'admin.update.howTo': 'Update-Anleitung', + 'admin.update.dockerText': 'Deine NOMAD-Instanz läuft in Docker. Um auf {version} zu aktualisieren, führe folgende Befehle auf deinem Server aus:', 'admin.update.reloadHint': 'Bitte lade die Seite in wenigen Sekunden neu.', // Vacay addon diff --git a/client/src/i18n/translations/en.js b/client/src/i18n/translations/en.js index 3dea650..1d9faeb 100644 --- a/client/src/i18n/translations/en.js +++ b/client/src/i18n/translations/en.js @@ -277,6 +277,8 @@ const en = { 'admin.update.failed': 'Update failed', 'admin.update.backupHint': 'We recommend creating a backup before updating.', 'admin.update.backupLink': 'Go to Backup', + 'admin.update.howTo': 'How to Update', + 'admin.update.dockerText': 'Your NOMAD instance runs in Docker. To update to {version}, run the following commands on your server:', 'admin.update.reloadHint': 'Please reload the page in a few seconds.', // Vacay addon diff --git a/client/src/pages/AdminPage.jsx b/client/src/pages/AdminPage.jsx index 6b35edf..737849e 100644 --- a/client/src/pages/AdminPage.jsx +++ b/client/src/pages/AdminPage.jsx @@ -277,13 +277,23 @@ export default function AdminPage() { {t('admin.update.button')} )} - + {updateInfo.is_docker ? ( + + ) : ( + + )} )} @@ -874,42 +884,74 @@ export default function AdminPage() { {/* Body */}
-

- {updateInfo && t('admin.update.confirmText').replace('{current}', `v${updateInfo.current}`).replace('{version}', `v${updateInfo.latest}`)} -

+ {updateInfo?.is_docker ? ( + <> +

+ {t('admin.update.dockerText').replace('{version}', `v${updateInfo.latest}`)} +

-
-
- - {t('admin.update.dataInfo')} -
-
+
+{`docker pull mauriceboe/nomad:latest +docker stop nomad && docker rm nomad +docker run -d --name nomad \\ + -p 3000:3000 \\ + -v /opt/nomad/data:/app/data \\ + -v /opt/nomad/uploads:/app/uploads \\ + --restart unless-stopped \\ + mauriceboe/nomad:latest`} +
-
-
- - - {t('admin.update.backupHint')}{' '} - - -
-
+
+
+ + {t('admin.update.dataInfo')} +
+
+ + ) : ( + <> +

+ {updateInfo && t('admin.update.confirmText').replace('{current}', `v${updateInfo.current}`).replace('{version}', `v${updateInfo.latest}`)} +

-
-
- - {t('admin.update.warning')} -
-
+
+
+ + {t('admin.update.dataInfo')} +
+
+ +
+
+ + + {t('admin.update.backupHint')}{' '} + + +
+
+ +
+
+ + {t('admin.update.warning')} +
+
+ + )}
{/* Footer */} @@ -922,19 +964,21 @@ export default function AdminPage() { > {t('common.cancel')} - + {!updateInfo?.is_docker && ( + + )} )} diff --git a/server/src/routes/admin.js b/server/src/routes/admin.js index ca9fab0..6a87fec 100644 --- a/server/src/routes/admin.js +++ b/server/src/routes/admin.js @@ -156,6 +156,14 @@ router.post('/save-demo-baseline', (req, res) => { // ── Version check ────────────────────────────────────────── +// Detect if running inside Docker +const isDocker = (() => { + try { + const fs = require('fs'); + return fs.existsSync('/.dockerenv') || (fs.existsSync('/proc/1/cgroup') && fs.readFileSync('/proc/1/cgroup', 'utf8').includes('docker')); + } catch { return false } +})(); + router.get('/version-check', async (req, res) => { const { version: currentVersion } = require('../../package.json'); try { @@ -167,9 +175,9 @@ router.get('/version-check', async (req, res) => { const data = await resp.json(); const latest = (data.tag_name || '').replace(/^v/, ''); const update_available = latest && latest !== currentVersion && compareVersions(latest, currentVersion) > 0; - res.json({ current: currentVersion, latest, update_available, release_url: data.html_url || '' }); + res.json({ current: currentVersion, latest, update_available, release_url: data.html_url || '', is_docker: isDocker }); } catch { - res.json({ current: currentVersion, latest: currentVersion, update_available: false }); + res.json({ current: currentVersion, latest: currentVersion, update_available: false, is_docker: isDocker }); } });