Add Docker container name auto-detection to bootstrap UI

- Added DetectDockerContainerName() to detect container name from hostname
- Extended /api/security/status to expose dockerContainerName field
- Updated FirstRunSetup to show actual container name when detected:
  * Before: 'docker exec <container-name> cat /data/.bootstrap_token'
  * After: 'docker exec pulse cat /data/.bootstrap_token'

This reduces friction for users - no need to look up the container name.
Works when Docker container is named (--name flag), falls back to
placeholder for auto-generated container IDs.
This commit is contained in:
rcourtman 2025-11-15 10:45:00 +00:00
parent ae0481c982
commit 639635a84b
3 changed files with 38 additions and 2 deletions

View file

@ -28,6 +28,7 @@ export const FirstRunSetup: Component<{ force?: boolean; showLegacyBanner?: bool
const [isDocker, setIsDocker] = createSignal<boolean>(false);
const [inContainer, setInContainer] = createSignal<boolean>(false);
const [lxcCtid, setLxcCtid] = createSignal<string>('');
const [dockerContainerName, setDockerContainerName] = createSignal<string>('');
const [showAlternatives, setShowAlternatives] = createSignal(false);
const applyTheme = (mode: 'system' | 'light' | 'dark') => {
@ -77,6 +78,7 @@ export const FirstRunSetup: Component<{ force?: boolean; showLegacyBanner?: bool
setIsDocker(data.isDocker || false);
setInContainer(data.inContainer || false);
setLxcCtid(data.lxcCtid || '');
setDockerContainerName(data.dockerContainerName || '');
}
}
} catch (error) {
@ -336,10 +338,10 @@ IMPORTANT: Keep these credentials secure!
pct exec &lt;ctid&gt; -- cat {bootstrapTokenPath()}
</Show>
{/* Docker (generic) */}
{/* Docker (with detected name or placeholder) */}
<Show when={isDocker()}>
<div class="text-blue-600 dark:text-blue-400 mb-1 font-semibold"># From Docker host:</div>
docker exec &lt;container-name&gt; cat {bootstrapTokenPath()}
docker exec {dockerContainerName() || '<container-name>'} cat {bootstrapTokenPath()}
</Show>
{/* Bare metal / inside container */}

View file

@ -490,6 +490,9 @@ func (r *Router) setupRoutes() {
if ctid := system.DetectLXCCTID(); ctid != "" {
status["lxcCtid"] = ctid
}
if containerName := system.DetectDockerContainerName(); containerName != "" {
status["dockerContainerName"] = containerName
}
}
if r.config.DisableAuthEnvDetected {

View file

@ -56,6 +56,37 @@ func InContainer() bool {
return false
}
// DetectDockerContainerName attempts to detect the Docker container name.
// Returns empty string if not in Docker or name cannot be determined.
func DetectDockerContainerName() string {
// Method 1: Check hostname (Docker uses container ID or name as hostname)
if hostname, err := os.Hostname(); err == nil && hostname != "" {
// Docker hostnames are either short container ID (12 chars) or custom name
// If it looks like a container ID (hex), skip it - user needs to use name
if !isHexString(hostname) || len(hostname) > 12 {
return hostname
}
}
// Method 2: Try reading from /proc/self/cgroup
if data, err := os.ReadFile("/proc/self/cgroup"); err == nil {
// Look for patterns like: 0::/docker/<container-id>
// But we can't get name from cgroup, only ID
_ = data // placeholder for future enhancement
}
return ""
}
func isHexString(s string) bool {
for _, c := range s {
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
return false
}
}
return true
}
// DetectLXCCTID attempts to detect the Proxmox LXC container ID.
// Returns empty string if not in an LXC container or CTID cannot be determined.
func DetectLXCCTID() string {