Skip to content

[BUG] kasm_manager has no healthcheck start_period, so a cold start leaves kasm_proxy created but never started #103

Description

@tigerblue77

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

On a cold start, kasm_manager reports unhealthy before it has finished starting. Since the Dockerfile makes proxy depend on it with condition: service_healthy, compose aborts the whole up:

 Container kasm_api Healthy
 Container kasm_manager Error dependency kasm_manager failed to start
dependency failed to start: container kasm_manager is unhealthy
s6-rc: warning: unable to start service svc-kasm: command exited 1

proxy is left in created and never started, and so is kasm_rdp_https_gateway, which the Dockerfile makes depend on proxy:

NAMES                    STATUS                    PORTS
kasm_rdp_https_gateway   Created
kasm_proxy               Created
kasm_rdp_gateway         Up 18 seconds (health: starting)   0.0.0.0:3389->3389/tcp
kasm_agent               Up 12 minutes (healthy)
kasm_api                 Up 12 minutes (healthy)
kasm_manager             Up 12 minutes (healthy)      <-- healthy, but too late
kasm_guac                Up 12 minutes (unhealthy)
kasm_db                  Up 12 minutes (healthy)

kasm_manager becomes healthy seconds later, but svc-kasm is a oneshot, so nothing runs /opt/kasm/bin/start again and the container stays half started indefinitely. The installation wizard on port 3000 answers, because it runs in the outer container, while KASM_PORT is dead. Running docker exec kasm /opt/kasm/bin/start by hand fixes it immediately, since the dependency is satisfied by then.

This is what I believe is the cause. The Dockerfile gates proxy on both kasm_manager and kasm_api being healthy:

# Fix dependencies so containers start in the right order
yq -i '.services.proxy.depends_on = {"kasm_manager":{"condition": "service_healthy"},"kasm_api":{"condition": "service_healthy"}, ...}'

and then gives a healthcheck grace period to kasm_api only:

yq -i '.services.kasm_api.healthcheck += {"start_period": "60s","start_interval": "30s"}'

kasm_manager is gated the same way but keeps the stock healthcheck, with no grace period suited to being used as a startup gate. That matters because compose only aborts a service_healthy wait when the dependency reports unhealthy — while it reports starting it waits indefinitely (pkg/compose/convergence.go):

case container.Healthy:    // continue
case container.Unhealthy:  return false, fmt.Errorf("container %s is unhealthy", name)
case container.Starting:   return false, nil   // keep waiting

So a start_period on kasm_manager is exactly what turns this failure into a successful wait.

One more consequence worth mentioning: this fails completely silently behind a reverse proxy that uses Docker service discovery. Traefik's Docker provider skips any container whose health is not healthy (pkg/provider/docker/config.go) without logging anything, so Kasm simply never gets a route and there is no error anywhere to point at the real problem.

Expected Behavior

kasm_manager should stay in starting until it is genuinely ready, so that compose waits for it instead of aborting, and all Kasm services should be started after a cold start without any manual intervention.

Steps To Reproduce

  1. Deploy linuxserver/kasm on a host where kasm_manager takes longer than interval x retries to become ready, and complete the installation wizard.
  2. Recreate the container (docker compose up -d --force-recreate, or reboot the host).
  3. Watch docker logs kasm: the startup ends with dependency failed to start: container kasm_manager is unhealthy followed by s6-rc: warning: unable to start service svc-kasm: command exited 1.
  4. Run docker exec kasm docker ps -a: kasm_proxy and kasm_rdp_https_gateway are in created, while kasm_manager is healthy.
  5. https://<host>:3000 (wizard) answers, https://<host>:<KASM_PORT> does not.
  6. Run docker exec kasm /opt/kasm/bin/start: everything starts and works, until the next recreation.

Reproduces on every recreation of the container.

Environment

- OS: Debian 13 (Proxmox 9.2.6 VM)
- How docker service was installed: from Docker's official APT repository (download.docker.com)

CPU architecture

x86-64

Docker creation

Deployed through Ansible, which renders this compose file (domain replaced with a placeholder). The Traefik labels and the external network are not related to the failure — it is triggered by the container being recreated, whatever else is in the file.


services:
  application:
    container_name: kasm
    image: linuxserver/kasm
    restart: unless-stopped
    privileged: true
    stop_grace_period: "90s"
    healthcheck:
      test: ["CMD-SHELL", "curl --silent --head --insecure --retry 1 https://localhost:3000 && curl --silent --head --insecure --retry 1 https://localhost:84"]
      interval: 30s
      timeout: 30s
      start_period: 0s
      retries: 3
    environment:
      PUID: "1000"
      PGID: "1000"
      TZ: "Europe/Paris"
      KASM_PORT: "84"
    volumes:
      - "data:/opt:rw"
      - "profiles:/profiles:rw"
    ports:
      - "83:3000"
      - "84:84"
    labels:
      traefik.enable: "true"
      traefik.http.services.Kasm_application.loadbalancer.server.port: "84"
      traefik.http.services.Kasm_application.loadbalancer.server.scheme: https
      traefik.http.services.Kasm_application.loadbalancer.serverstransport: insecure_HTTPS_backend@file
      traefik.http.routers.Kasm_application.service: Kasm_application
      traefik.http.routers.Kasm_application.rule: Host(`kasm.example.com`)
      traefik.http.routers.Kasm_application.entrypoints: websecure
      traefik.http.routers.Kasm_application.middlewares: no_index@file
    networks:
      - "DMZ"

volumes:
  data:
  profiles:

networks:
  DMZ:
    external: true
    name: DMZ

Container logs

[migrations] started
[migrations] no migrations found
───────────────────────────────────────

      ██╗     ███████╗██╗ ██████╗
      ██║     ██╔════╝██║██╔═══██╗
      ██║     ███████╗██║██║   ██║
      ██║     ╚════██║██║██║   ██║
      ███████╗███████║██║╚██████╔╝
      ╚══════╝╚══════╝╚═╝ ╚═════╝

   Brought to you by linuxserver.io
───────────────────────────────────────

To support LSIO projects visit:
https://www.linuxserver.io/donate/

───────────────────────────────────────
GID/UID
───────────────────────────────────────

User UID:    1000
User GID:    1000
───────────────────────────────────────
Linuxserver.io version: 1.19.0-ls139
Build-date: 2026-07-14T22:37:23+00:00
───────────────────────────────────────

[custom-init] No custom files found, skipping...
time="2026-08-04T14:08:54+02:00" level=error msg="+ echo '[ENTRYPOINT] STARTED'" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:54+02:00" level=info msg="[ENTRYPOINT] STARTED" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:54+02:00" level=error msg="+ SOCKET_PATH=/run/docker/plugins/kasmlogger.sock" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:54+02:00" level=error msg="+ '[' -e /run/docker/plugins/kasmlogger.sock ]" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:54+02:00" level=info msg="[ENTRYPOINT] Launching plugin.py..." plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:54+02:00" level=error msg="+ echo '[ENTRYPOINT] Launching plugin.py...'" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:54+02:00" level=error msg="+ export 'PATH=/opt/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:54+02:00" level=error msg="+ sleep 5" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:54+02:00" level=error msg="+ python3 /plugin.py" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:55+02:00" level=info msg=" * Serving Flask app 'plugin'" plugin=88b6cf90a0cbf477347339d8e2dee30399e3f3034109890dff92f757d8290518
time="2026-08-04T14:08:55+02:00" level=info msg=" * Debug mode: off" plugin=88b6cf90a0cbf477347339d8e2dee30399e3f3034109890dff92f757d8290518
time="2026-08-04T14:08:55+02:00" level=info msg=" * Serving Flask app 'plugin'" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:55+02:00" level=info msg=" * Debug mode: off" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
Pulling Latest Kasm Service Images
time="2026-08-04T14:08:56+02:00" level=warning msg="/opt/kasm/1.19.0/docker/docker-compose.yaml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion"
 Image kasmweb/proxy:1.19.0-rolling Pulling
 Image kasmweb/api:1.19.0-rolling Pulling
 Image kasmweb/kasm-guac:1.19.0-rolling Pulling
 Image kasmweb/rdp-https-gateway:1.19.0-rolling Pulling
 Image kasmweb/postgres:1.19.0-rolling Pulling
 Image kasmweb/manager:1.19.0-rolling Pulling
 Image kasmweb/rdp-gateway:1.19.0-rolling Pulling
 Image kasmweb/agent:1.19.0-rolling Pulling
 Image kasmweb/rdp-https-gateway:1.19.0-rolling Pulled
 Image kasmweb/manager:1.19.0-rolling Pulled
 Image kasmweb/rdp-gateway:1.19.0-rolling Pulled
 Image kasmweb/agent:1.19.0-rolling Pulled
 Image kasmweb/kasm-guac:1.19.0-rolling Pulled
 Image kasmweb/proxy:1.19.0-rolling Pulled
 Image kasmweb/api:1.19.0-rolling Pulled
 Image kasmweb/postgres:1.19.0-rolling Pulled
Upgrading rolling plugins
Inspecting plugin:      kasmweb/logger:amd64-1.1-rolling-daily
* Type: log plugin
* Will not update rolling plugin: currently at the latest version
Inspecting plugin:      kasmweb/sidecar:amd64-1.5-rolling-daily
* Type: network plugin
* Will not update rolling plugin: currently at the latest version
Starting Kasm Services
time="2026-08-04T14:08:59+02:00" level=warning msg="/opt/kasm/1.19.0/docker/docker-compose.yaml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion"
 Container kasm_db Creating
 Container kasm_guac Creating
 Container kasm_guac Created
 Container kasm_db Created
 Container kasm_manager Creating
 Container kasm_api Creating
 Container kasm_manager Created
 Container kasm_agent Creating
 Container kasm_api Created
 Container kasm_rdp_gateway Creating
 Container kasm_rdp_gateway Created
 Container kasm_agent Created
 Container kasm_proxy Creating
 Container kasm_proxy Created
 Container kasm_rdp_https_gateway Creating
 Container kasm_rdp_https_gateway Created
 Container kasm_guac Starting
 Container kasm_db Starting
 Container kasm_guac Started
 Container kasm_db Started
 Container kasm_db Waiting
 Container kasm_db Waiting
time="2026-08-04T14:08:59+02:00" level=error msg="+ echo '[ENTRYPOINT] Checking socket existence...'" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:59+02:00" level=error msg="+ ls -l /run/docker/plugins" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:59+02:00" level=info msg="[ENTRYPOINT] Checking socket existence..." plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:59+02:00" level=info msg="total 0" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:59+02:00" level=info msg="prwx------    1 root     root             0 Aug  4 12:08 4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969-stderr" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:59+02:00" level=info msg="prwx------    1 root     root             0 Aug  4 12:08 4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969-stdout" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:59+02:00" level=info msg="srwxr-xr-x    1 root     root             0 Aug  4 12:08 kasmlogger.sock" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:59+02:00" level=error msg="+ '[' '!' -S /run/docker/plugins/kasmlogger.sock ]" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
time="2026-08-04T14:08:59+02:00" level=error msg="+ tail -f /dev/null" plugin=4049a71bc4ba4a1c9b44f3f60e186775aa649737608ffce2490bcd9e03f40969
 Container kasm_db Healthy
 Container kasm_api Starting
 Container kasm_db Healthy
 Container kasm_manager Starting
 Container kasm_manager Started
 Container kasm_agent Starting
 Container kasm_api Started
 Container kasm_rdp_gateway Starting
 Container kasm_agent Started
 Container kasm_manager Waiting
 Container kasm_api Waiting
 Container kasm_rdp_gateway Started
 Container kasm_api Healthy
 Container kasm_manager Error dependency kasm_manager failed to start
dependency failed to start: container kasm_manager is unhealthy
s6-rc: warning: unable to start service svc-kasm: command exited 1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions