Текст и данные · Инструкция
Docker credential store: как настроить credsStore и credHelpers
Docker credential store нужен, чтобы registry-токены не лежали в обычном config.
Короткий ответ
Docker credential store настраивается через credsStore или credHelpers в клиентском ~/.docker/config.json. Внешний helper хранит registry-учётные данные в системном keychain или менеджере секретов; без него Docker может сохранить их в config.json только в base64, что заметно слабее защищённого хранилища.
Что именно хранит Docker и почему base64 недостаточно
Команда docker login должна где-то сохранить токен или пароль, чтобы последующие pull и push могли пройти аутентификацию. Если настроен внешний credential store, Docker передаёт данные helper-программе, а та использует системный keychain или другое хранилище. Если helper отсутствует и credsStore не задан, Docker хранит авторизацию в config.json в base64-кодированном виде. Base64 — это кодирование, а не шифрование: строку легко декодировать, если файл прочитан. Поэтому задача credential store — уменьшить риск утечки секрета из обычного текстового конфигурационного файла. На Docker Desktop нативное хранилище обычно используется автоматически, а на Docker Engine/CLI без Desktop настройку стоит проверить явно.
Совет: Сначала проверьте, где реально выполняется docker CLI: helper нужен на машине клиента, а не внутри registry.
Настройка credsStore без лишних секретов в файлах
- Откройте ~/.docker/config.json на Linux/macOS или %USERPROFILE%/.docker/config.json на Windows и убедитесь, что файл не публикуется в Git и не копируется в логи. Если credential store не настроен, записи auths могут содержать base64-кодированные данные авторизации, что не равно шифрованию.
- Docker поддерживает helpers для macOS Keychain, Windows Credential Manager, pass и D-Bus Secret Service. Бинарник docker-credential-<name> должен находиться в PATH клиента. В Docker Desktop хранилище обычно уже настроено.
- Для общего хранилища задайте поле credsStore, например "credsStore": "secretservice". Для разных registry используйте credHelpers, где ключ — домен registry, а значение — суффикс helper.
- Выполните docker logout для старой записи, затем docker login заново. Проверьте, что авторизация работает, а чувствительный секрет не появился в открытом виде в конфиге или shell history; для CI используйте --password-stdin вместо аргумента командной строки.
Предупреждение: Не вставляйте пароль в команду вида docker login -p secret: он может попасть в историю shell и список процессов; для автоматизации используйте --password-stdin.
credsStore и credHelpers: что выбрать
- credsStore задаёт один credential helper по умолчанию для всех registry. Это удобно на личной рабочей станции: например, secretservice в Linux или osxkeychain на macOS. credHelpers позволяет назначить helper для конкретного домена registry и имеет приоритет для него; так можно хранить Docker Hub в одном backend, а корпоративный registry — в другом. Значение — это только суффикс исполняемого файла: при "secretservice" Docker ищет docker-credential-secretservice в PATH. Если используется Docker Desktop и штатное хранилище уже работает, дополнительная ручная настройка обычно не нужна. В CI часто разумнее вообще не сохранять долгоживущий логин, а подавать короткоживущий токен в docker login --password-stdin на время job.
Важно: Если после изменения config.json login перестал работать, первым делом проверьте наличие helper в PATH и точное имя суффикса.
Частые ошибки и безопасная диагностика
Ошибка «executable file not found» почти всегда означает, что Docker не нашёл нужный docker-credential-* бинарник. Неправильный домен в credHelpers приводит к тому, что для registry выбирается не тот backend или общий credsStore. Ещё одна ловушка — ожидание, что docker logout удалит секрет из любого стороннего менеджера одинаково: поведение зависит от helper, поэтому после миграции полезно проверить хранилище отдельно. Если вы переносите конфиг между компьютерами, не копируйте только config.json и не рассчитывайте, что там есть сам пароль: при нормальном credsStore он остаётся в keychain исходной системы. Для диагностики не публикуйте содержимое auths и не вставляйте токены в issue-трекеры. Достаточно показать названия полей, домены и ошибку helper без значений секретов.
Совет: При подозрении на утечку сначала отзовите токен в registry, а уже потом чините локальное хранилище.
Проверка после настройки
- config.json не отслеживается Git; credsStore или credHelpers содержит ожидаемое имя; helper доступен в PATH; docker logout/login проходит успешно; pull приватного image работает; пароль не передаётся через -p в shell; CI использует --password-stdin или секреты платформы; старые токены, если они могли утечь, отозваны.
Практический сценарий миграции со старого auths
Предположим, в ~/.docker/config.json уже есть auths после обычного docker login. Сначала убедитесь, что файл не попал в Git, резервные логи или общий домашний каталог. Установите подходящий helper, добавьте credsStore и выполните docker logout для нужного registry, а затем новый login. После этого проверьте pull приватного образа и убедитесь, что helper действительно вызывается. Не публикуйте получившийся config.json целиком для проверки: достаточно увидеть, что настройка store присутствует и чувствительный auth не хранится там как прежняя base64-запись. Если используется несколько registry, перенесите их по одному через credHelpers, чтобы ошибка одного backend не блокировала все остальные. Для CI не копируйте пользовательский keychain на runner: правильнее выдавать job короткоживущий токен через secret store и подавать его в docker login --password-stdin. Такой подход разделяет интерактивную рабочую станцию и автоматизацию, вместо попытки решить обе задачи одним постоянным паролем.
Совет: После смены helper проверяйте и `docker logout`, и новый `docker login`: старый токен в прежнем backend не исчезает только от правки JSON-файла.
Как проверить, что Docker действительно использует credential helper
После правки `config.json` не ограничивайтесь успешным `docker login`. Сначала проверьте, что нужный бинарник виден клиенту, например через `command -v docker-credential-secretservice`, `docker-credential-pass`, `docker-credential-osxkeychain` или `docker-credential-wincred` в зависимости от платформы. Затем выполните `docker logout` для конкретного registry и войдите заново. После этого `docker pull` приватного образа должен проходить без ручного ввода секрета, а в `config.json` не должна появляться прежняя base64-запись `auth` для этого registry, если credentials обслуживает helper. Не публикуйте файл целиком: даже без пароля там могут быть приватные адреса registry и служебные настройки. При использовании `credHelpers` проверяйте точное имя домена, потому что запись для одного registry не применяется автоматически к похожему hostname. В CI не пытайтесь переносить пользовательский keychain с рабочей станции: выдайте job отдельный токен из secret store и передайте его через `--password-stdin`. Так интерактивные логины и автоматизация получают разные секреты и разные сроки жизни, а компрометация одного контура не раскрывает второй.
Что учитывать
Команда docker login должна где-то сохранить токен или пароль, чтобы последующие pull и push могли пройти аутентификацию. Если настроен внешний credential store, Docker передаёт данные helper-программе, а та использует системный keychain или другое хранилище. Если helper отсутствует и credsStore не задан, Docker хранит авторизацию в config.json в base64-кодированном виде. Base64 — это кодирование, а не шифрование: строку легко декодировать, если файл прочитан. Поэтому задача credential store…
Источники и проверка
Фактическая часть сверена по первичным источникам (в т.ч. docker login). Пример и формулировки — редакция N1RO на 2026-09-21.