🌌 Ключар: передати ключ без звуку — Ключ, вигукнутий у команді запуску, чує кожен, хто зазирне в docker inspect чи історію команд; Ключар С.І.Д. цей трюк давно опанував і залюбки навчить: просувати ключ під двері — файлом, а не через -e, — щоб у метаданих капсули не лишилося ні звуку.
Найпростіший спосіб передати конфіденційне значення в контейнер — змінна середовища
(docker run -e API_KEY=xyz). Проблема в тому, що змінні середовища контейнера
зберігаються у відкритому вигляді в кількох легкодоступних місцях: docker inspect <container> показує повний список Config.Env будь-кому з доступом до Docker-сокета;
файл /proc/<pid>/environ на хості читається з правами root і показує ті самі значення
для процесу контейнера; якщо значення передане прямо в командному рядку — воно
осідає в історії shell і в виводі docker history, якщо секрет випадково потрапив
у Dockerfile через ENV чи ARG (останній до того ж може «просочитися» в
проміжні шари образу, навіть якщо фінальний ENV його не встановлює). Крім того,
змінні середовища часто успадковуються дочірніми процесами й потрапляють у
трасування помилок чи crash-дампи, якщо застосунок їх не фільтрує явно.
Значно безпечніший підхід — монтування секрету як файлу (bind mount або
tmpfs-mount у read-only режимі), а не як змінної середовища. Файл не потрапляє в
docker inspect, не успадковується автоматично дочірніми процесами (застосунок сам
повинен його прочитати) і може бути змонтований із правами доступу 0400, обмежуючи
коло процесів, здатних його прочитати, навіть усередині самого контейнера. Багато
офіційних образів (наприклад, postgres) підтримують конвенцію *_FILE
(POSTGRES_PASSWORD_FILE=/run/secrets/db_password) саме для цього — замість значення
передається шлях до файлу з ним.
Формальний, «промисловий» механізм — Docker secrets, доступний у Swarm-режимі
(docker secret create, потім docker service create --secret). Секрет зберігається
в зашифрованому вигляді в консенсус-сховищі Swarm (Raft-лог менеджерів), передається
воркер-вузлам лише через TLS і монтується всередину контейнера як файл у
tmpfs-каталозі /run/secrets/<ім'я> — тобто фізично ніколи не торкається постійного
диска ні на хості, ні у шарах образу; після зупинки контейнера tmpfs очищується разом
з усім вмістом. Це найближчий аналог рішень на кшталт HashiCorp Vault чи AWS Secrets
Manager у межах штатної екосистеми Docker, хоч і прив'язаний до Swarm-оркестрації.
Для одноконтейнерного docker run (без Swarm) практичний компроміс — bind-mount
файлу секрету з хоста в режимі :ro (-v ./secrets/db_password:/run/secrets/ db_password:ro), за умови, що сам файл на хості не потрапляє в систему контролю
версій (додається в .gitignore) і має обмежені права доступу (chmod 400). Важливо
розуміти ієрархію ризику: ENV/ARG у Dockerfile — найгірший варіант (секрет
«запечений» у образ і в будь-який його публічний реєстр); -e під час docker run
— краще, але видимий у метаданих контейнера; змонтований файл — прийнятно для
розробки; Docker secrets/зовнішній секрет-менеджер — правильний вибір для продакшну.
Прочитати Docker docs «Manage sensitive data with secrets» і порівняти три способи передати секрет контейнеру: змінну середовища, змонтований файл, docker secret (Swarm-режим); звернути увагу на видимість кожного способу в docker inspect та в списку процесів.
Чому змінна середовища, передана через -e, менш безпечна за секрет, змонтований файлом, з погляду видимості в docker inspect і /proc/<pid>/environ?
-e, ні у файлі: вони вигравіювали його на дні голопроєктора — три символи C1D, які всі приймали за серійний номер. С.І.Д. вважає це найкращим уроком про секрети: найгірше сховати ключ — там, де його прочитає перший-ліпший docker inspect; найкраще — там, де його ніхто не візьме за ключ. Що відмикає 0xC1D, він поки що не каже.Кожна команда терміналу з цієї сторінки — одним реченням. Позначка нове — команда зустрічається в курсі вперше; далі вважаємо її знайомою.
docker rundocker run -it ubuntu:24.04 bash — інтерактивно з терміналом; -d — у фоні; --rm — видалити після виходу; -p 8080:80 — прокинути порт).dockerdocker <підкоманда> --help — довідка).docker inspect-f '{{.State.Pid}}' — витягнути одне поле.chmodновеchmod 400 f — читати може лише власник; chmod 000 f — нікому).docker historydocker secret/run/secrets/, а не передаються через змінні середовища.docker serviceновеdocker service create --secret ...).💡 Прочитати README прямо в терміналі: cat README.md (виведе весь файл) або less README.md (посторінково; вихід — клавіша q).
Довідка з будь-якої команди: man curl (повний посібник, вихід — q) або коротко curl --help; для підкоманд — docker run --help, cargo build --help.