diff --git a/app/Actions/Server/StartSentinel.php b/app/Actions/Server/StartSentinel.php index 3dcc2650ac..b888892cea 100644 --- a/app/Actions/Server/StartSentinel.php +++ b/app/Actions/Server/StartSentinel.php @@ -148,7 +148,9 @@ class StartSentinel ? '-v '.escapeshellarg("{$trafficLogDirectory}:{$trafficLogDirectory}:ro").' ' : ''; $network = $server->isLocalhost() ? ' --network coolify' : ''; - $dockerCommand = "docker run -d$network $dockerEnvironments --name coolify-sentinel --restart unless-stopped -v /var/run/docker.sock:/var/run/docker.sock -v $mountDir:/app/db {$trafficMount}--pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-start-period 120s --health-interval 10s --health-retries 3 --add-host=host.docker.internal:host-gateway --label $dockerLabels $image"; + // A userns-remap daemon refuses --pid host unless the container opts out of remapping. + // On other daemons --userns host has no effect. https://docs.docker.com/engine/security/userns-remap/ + $dockerCommand = "docker run -d$network $dockerEnvironments --name coolify-sentinel --restart unless-stopped -v /var/run/docker.sock:/var/run/docker.sock -v $mountDir:/app/db {$trafficMount}--userns host --pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-start-period 120s --health-interval 10s --health-retries 3 --add-host=host.docker.internal:host-gateway --label $dockerLabels $image"; $server->sentinelHeartbeat(isReset: true); $server->forceFill(['sentinel_waiting_since' => now()])->save(); diff --git a/tests/Feature/TrafficAnalytics/StartSentinelTrafficTest.php b/tests/Feature/TrafficAnalytics/StartSentinelTrafficTest.php index 9d53564fb7..3bb5a818f8 100644 --- a/tests/Feature/TrafficAnalytics/StartSentinelTrafficTest.php +++ b/tests/Feature/TrafficAnalytics/StartSentinelTrafficTest.php @@ -180,6 +180,12 @@ it('starts sentinel with a restart policy so Docker restarts it after a crash or expect($script)->toContain('--name coolify-sentinel --restart unless-stopped '); }); +it('starts sentinel in the host user namespace so --pid host works on a userns-remap daemon', function () { + $script = runStartSentinelAndCaptureScript(sentinelTrafficServer($this, 'TRAEFIK', analyticsEnabled: false)); + + expect($script)->toContain('--userns host --pid host '); +}); + it('does not touch the access log when traffic analytics cannot run', function (?string $proxyType, bool $analyticsEnabled) { $server = sentinelTrafficServer($this, $proxyType, $analyticsEnabled);