[2026-09-23] hermes-docker-kraken: SSH контейнер→хост починен — passwd/group через bind-mount для uid 1000
This commit is contained in:
1 parent
d00c95d76b
commit
a804c4a7cf
1 file changed
+48
@@ -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
|
||||
|
||||
Reference in new issue
Block a user