From a804c4a7cf9247bb49437209f84da687ab86ed34 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Wed, 23 Sep 2026 12:43:02 +0600 Subject: [PATCH] =?UTF-8?q?[2026-09-23]=20hermes-docker-kraken:=20SSH=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=E2=86=92?= =?UTF-8?q?=D1=85=D0=BE=D1=81=D1=82=20=D0=BF=D0=BE=D1=87=D0=B8=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=20=E2=80=94=20passwd/group=20=D1=87=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=B7=20bind-mount=20=D0=B4=D0=BB=D1=8F=20uid=201000?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- family/how-to/hermes-docker-kraken.md | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/family/how-to/hermes-docker-kraken.md b/family/how-to/hermes-docker-kraken.md index 91c846b7..72c5598e 100644 --- a/family/how-to/hermes-docker-kraken.md +++ b/family/how-to/hermes-docker-kraken.md @@ -267,6 +267,54 @@ USER kraken **Открытый вопрос при применении:** второй вариант compose (с `config/.ssh → /root/.ssh`) — оставить mount как есть и починить `$HOME`, или перевесить на `/opt/data/.ssh`? Alex ещё не решал. +## ✅ SSH контейнер → хост починен 2026-09-23 (passwd через bind-mount) + +> **Симптом:** `docker exec hermes-kraken ssh kraken-host "…"` → `No user exists for uid 1000`. Старые доки называли это «passwd сбрасывается» — на деле причина глубже, см. ниже. +> +> **Проверенный диагноз (сырьё):** +> - Контейнер стартует под **uid 1000**, заданным `USER` в образе (`ps -o uid,pid,cmd` → PID 1 = `tini` под uid 1000). В compose строки `user:` НЕ было. +> - `/etc/passwd` образа создаёт только `hermes:x:10000` (`RUN useradd -u 10000 -m -d /opt/data hermes` в Dockerfile). Записи для uid 1000 **нет**. +> - `ssh` падает на `getpwuid(euid)` **до** чтения `~/.ssh/config` и ключа → пересоздание ключа не помогает. +> - `/etc/passwd` принадлежит `root:root`, процесс uid 1000 → `touch /etc/passwd` = `Permission denied`. **Записать запись изнутри контейнера невозможно.** Оригинальный `entrypoint.sh` поэтому и оборачивал всё в `if [ "$(id -u)" = "0" ]`, а `gosu hermes` / `usermod` / `chown` для uid 1000 не выполняются вообще. +> - `.ssh` монтировался в `/root/.ssh` (недоступен под uid 1000, `HOME=/opt/data`) — ключи до SSH не доезжали. +> +> **Фикс (2 файла, пересборки образа НЕ требует → версия Hermes не меняется):** +> +> 1. Создать копию passwd/group с записью для uid 1000: +> ```bash +> cd /srv/dev-disk-by-uuid-49e8f586-.../docker/hermes/config +> sudo docker exec hermes-kraken cat /etc/passwd > /tmp/passwd.new +> printf 'kraken:x:1000:1000::/opt/data:/bin/sh\n' >> /tmp/passwd.new +> sudo docker exec hermes-kraken cat /etc/group > /tmp/group.new +> printf 'kraken:x:1000:\n' >> /tmp/group.new +> sudo cp /tmp/passwd.new etc-passwd && sudo cp /tmp/group.new etc-group +> sudo chown root:root etc-passwd etc-group && sudo chmod 644 etc-passwd etc-group +> ``` +> 2. В `hermes-build/docker-compose.yml`: +> ```yaml +> user: "1000:1000" # явно, раньше приходило из USER образа +> volumes: +> - …/docker/hermes/config/etc-passwd:/etc/passwd:ro +> - …/docker/hermes/config/etc-group:/etc/group:ro +> - …/docker/hermes/config/.ssh:/opt/data/.ssh # было /root/.ssh — мимо $HOME +> ``` +> 3. Пересоздать: `docker compose up -d` (⚠️ **не** `--force-recreate`) — контейнер создан вручную, compose конфликтует по имени. +> +> **Приёмка (проверено 2026-09-23):** +> ```bash +> ssh kraken 'sudo docker exec hermes-kraken sh -c "getent passwd 1000; ssh kraken-host \"id; echo OK\""' +> # → kraken:x:1000:1000::/opt/data:/bin/sh +> # → uid=1000(kraken) ... OK +> ``` +> +> **Питфоллы:** +> - `chown`/`cp` в `hermes-build/` и `docker/hermes/config/` требуют `sudo` — каталог принадлежит `root`, обычный `cp` даёт `Permission denied`. +> - `docker compose up -d --force-recreate` падает с `Conflict. The container name "/hermes-kraken" is already in use` — контейнер создан вне compose-проекта. Использовать `docker rm -f hermes-kraken` + `compose up -d`, либо просто `compose up -d`. +> - Правка `entrypoint.sh` (добавить `printf … >> /etc/passwd`) **не работает** — файл root-owned, запись пропускается на `[ -w /etc/passwd ]`. +> - `useradd` в контейнере тоже невозможен по той же причине. +> - `etc-passwd` — **статичный снимок** passwd образа. При смене базового образа (новые uid) файл надо пересоздать. +> - Не путать «контейнер поднялся, но внутри своя ошибка» с гонкой docker↔mount (см. `personal/tech/docker-data-root-mount-race.md`). + ## Notes - `network_mode: host` — port 8642 is directly on the Kraken host, no port mapping needed