Спочатку це виглядало як проблема з GitLab або доступом до самого пакета. Але на хості я могла підключитися до GitLab через SSH, тому почала перевіряти не credentials, а різницю між host environment і Docker workspace.
У моєму випадку Composer запускається всередині Laradock workspace. І саме там виявилася справжня причина: Docker container не бачив SSH Agent, який уже працював на хості.
Симптом: Composer просить GitLab credentials
Проблема проявилася під час звичайного оновлення приватного пакета через Composer.
dcomposer update avn/laravel-localization --with-dependenciesЗамість оновлення package Composer спробував звернутися до приватного GitLab repository і не зміг пройти SSH authentication.
Після цього він запропонував ввести GitLab credentials. Це було важливим сигналом: проблема не обов'язково була в Composer. Він просто не міг використати той спосіб доступу до GitLab, який працював у мене на хості.
Permission denied (publickey). Username:Password:Перевіряю SSH на хості
Першою я перевірила найпростішу річ: чи взагалі працює SSH до GitLab поза Docker.
ssh -T git@gitlab.comWelcome to GitLab, @xmarynkam!А що бачить Docker workspace?
Ту саму перевірку я запустила вже всередині Laradock workspace, де реально працює Composer.
docker compose exec workspace-85 ssh -T git@gitlab.comgit@gitlab.com: Permission denied (publickey).Ось тут різниця стала очевидною: на тому самому комп'ютері GitLab SSH працював на хості, але не працював усередині container.
Наступною перевіркою був SSH Agent. На хості він уже містив мої ключі, а в Docker workspace змінна SSH_AUTH_SOCK була порожньою.
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK"ssh-add -lHost SSH key → ssh-agent → GitLab ✓ Docker Composer → Git → SSH ↓ no SSH agent ✗Host ssh-agent │ │ mounted socket ▼Docker workspace │ └── Git / Composer → GitLab ✓Причина була в SSH_AUTH_SOCK
SSH Agent працює як окремий процес на хості й тримає доступ до вже завантажених SSH keys. Програми звертаються до нього через socket, шлях до якого знаходиться в SSH_AUTH_SOCK.
Docker container автоматично не отримує цей socket. Тому Git усередині workspace не міг скористатися моїм SSH Agent, навіть попри те, що на хості все було налаштовано правильно.
Для мене це і було ключем до проблеми: не потрібно було переносити SSH key у container. Потрібно було дати container доступ до вже працюючого host SSH Agent.
Передаю SSH Agent у Laradock
Я винесла налаштування SSH Agent в окремий Docker Compose anchor, щоб не дублювати його для кожної PHP workspace.
x-local-ssh-agent: &local-ssh-agent environment: SSH_AUTH_SOCK: /ssh-agent volumes: - "${SSH_AUTH_SOCK}:/ssh-agent"Host socket монтується всередину container як /ssh-agent, а SSH_AUTH_SOCK уже всередині workspace вказує саме на нього.
У мене є кілька Laradock workspace для різних PHP versions, тому цей anchor я підключила до кожної CLI workspace.
services: workspace: <<: [*local-host-config, *local-ssh-agent] workspace-84: <<: [*local-host-config, *local-ssh-agent] workspace-85: <<: [*local-host-config, *local-ssh-agent]Recreate workspace після зміни Compose
Зміна volume та environment не з'явиться в уже запущеному container сама, тому workspace потрібно recreate.
docker compose up -d \ --force-recreate \ --no-deps \ workspace-85Перевіряю SSH Agent усередині container
Після recreate я спочатку перевірила не Composer, а сам SSH Agent. Так простіше зрозуміти, чи інфраструктурна частина вже працює.
docker compose exec --user laradock workspace-85 sh -lc 'echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK"ssh-add -l'Коли список ключів з'явився всередині workspace, я повторила пряме SSH-підключення до GitLab.
docker compose exec --user laradock workspace-85 \ ssh -o StrictHostKeyChecking=accept-new -T git@gitlab.comWelcome to GitLab, @xmarynkam!І тільки тоді повертаюся до Composer
Після цього я повторила ту саму Composer-команду, з якої все почалося. Цього разу Composer зміг звернутися до приватного GitLab repository через Git і оновив package без запиту username або password.
Сам dcomposer у мене є частиною локального multi-PHP workflow з dphp, dartisan і dcomposer, де для кожного проєкту автоматично вибирається правильний Laradock workspace.
Для мене це хороший приклад того, чому корисно перевіряти проблему шарами:
спочатку GitLab SSH,
потім Docker,
потім SSH Agent
і лише після цього Composer.
dcomposer update avn/laravel-localization --with-dependenciesЧого я б тут не робила
Копіювати приватний SSH key всередину Docker image або container.
Зберігати GitLab password у container.
Вводити Personal Access Token щоразу, коли Composer просить credentials.
Вважати проблему Composer-проблемою, не перевіривши спочатку звичайний git/SSH доступ із того самого environment.
Що я вз'яла з цього кейсу
У моєму випадку Composer лише показав симптом. Реальна проблема була на рівень нижче: Git усередині Docker не мав доступу до host SSH Agent.
Після того як я передала SSH_AUTH_SOCK через Docker Compose і змонтувала agent socket у Laradock workspace, той самий SSH key почав працювати і на хості, і всередині container.
Тепер це налаштування використовується всіма моїми PHP workspaces, а приватні Composer packages можна оновлювати без копіювання ключів і без окремих credentials усередині Docker.



