diff --git a/client/src/pages/AdminPage.jsx b/client/src/pages/AdminPage.jsx
index cf4b62e..0d23b93 100644
--- a/client/src/pages/AdminPage.jsx
+++ b/client/src/pages/AdminPage.jsx
@@ -296,6 +296,14 @@ function MatchAdminCard({ m, run, busy, token, reload, setNotice }) {
{current.live?.roundsPlayed != null && Runde {current.live.roundsPlayed + 1}}
)}
+ {m.server?.address && m.server.status !== 'stopped' && (
+
+ Server {m.server.address.host}:{m.server.address.port}
+ {m.server.address.tvPort && (
+ CSTV {m.server.address.host}:{m.server.address.tvPort}
+ )}
+
+ )}
{paused && Pausiert}
diff --git a/client/src/styles.css b/client/src/styles.css
index 87abb8c..3ba7b9a 100644
--- a/client/src/styles.css
+++ b/client/src/styles.css
@@ -568,3 +568,5 @@ input:focus, select:focus { border-color: var(--link); outline: none; }
.host-matches li { padding: 3px 0; border-top: 1px solid var(--line); }
.host-disk { font-size: .85rem; color: var(--muted); margin: -2px 0 8px; font-variant-numeric: tabular-nums; }
.host-disk.is-low { color: var(--error); font-weight: 600; }
+.admin-address { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 8px; font-size: .85rem; }
+.admin-address code { font: 500 .85rem ui-monospace, SFMono-Regular, Consolas, monospace; padding: 1px 6px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); }
diff --git a/server/src/matchService.js b/server/src/matchService.js
index 7c6b597..f4a61d4 100644
--- a/server/src/matchService.js
+++ b/server/src/matchService.js
@@ -956,6 +956,9 @@ export class MatchService extends EventEmitter {
updatedAt: row.updated_at,
idleTimeoutMinutes: this.config.idleTimeoutMinutes,
};
+ if (viewer.isOrganizer && row.host) {
+ view.address = { host: row.host, port: row.port, tvPort: row.tv_port };
+ }
const configured = row.status === 'configured';
if (!configured || viewer.role === 'public') return view;
diff --git a/server/src/servers/dockerAdapter.js b/server/src/servers/dockerAdapter.js
index 261e680..98f26d7 100644
--- a/server/src/servers/dockerAdapter.js
+++ b/server/src/servers/dockerAdapter.js
@@ -251,7 +251,7 @@ export class DockerHostPool {
}
/**
- * Freier Speicher unter /var/lib/docker auf einem Host, per SSH. Ergebnis wird eine Minute lang
+ * Freier Speicher auf einem Host, per SSH: dort, wo das Gameserver-Volume liegt. Ergebnis wird eine Minute lang
* zwischengespeichert, weil die Admin-Seite alle paar Sekunden abfragt. Ohne ssh:// gibt es null.
*/
async diskUsage(name) {
@@ -265,7 +265,7 @@ export class DockerHostPool {
try {
const { stdout } = await exec('ssh', [
'-o', 'BatchMode=yes', '-o', 'ConnectTimeout=5', host.dockerHost.slice('ssh://'.length),
- 'df -B1 /var/lib/docker 2>/dev/null || df -B1 /',
+ `df -B1 "$(docker volume inspect ${host.volume} --format '{{with .Options}}{{.device}}{{end}}' 2>/dev/null | grep . || docker volume inspect ${host.volume} --format '{{.Mountpoint}}' 2>/dev/null || echo /var/lib/docker)" 2>/dev/null || df -B1 /var/lib/docker 2>/dev/null || df -B1 /`,
], { timeout: 10_000 });
value = parseDf(stdout.trim().split('\n').pop());
} catch {