0% прочитано

Composer Cannot Access GitLab from Docker: Fix with SSH Agent

SSH to GitLab works on the host, but Composer inside Docker asks for a username and password or fails with Permission denied (publickey). I show how I diagnosed the issue in Laradock and forwarded the host SSH Agent into the container.

17 серпня 2026 р. 4 хв читанняLaradock
Composer inside Docker could not access a private GitLab repository even though SSH worked perfectly on the host. While updating a private Composer package, I started getting Permission denied (publickey), and Composer suddenly asked for a GitLab username and password.

At first, it looked like a GitLab permission problem or an issue with the package itself. But SSH to GitLab worked from the host, so instead of changing credentials I started comparing the host environment with the Docker workspace.

In my setup, Composer runs inside a Laradock workspace. That is where I found the actual problem: the container could not see the SSH Agent that was already available on the host.

Symptom: Composer asks for GitLab credentials

The issue appeared during a normal update of a private Composer package.

Composer update
dcomposer update avn/laravel-localization --with-dependencies

Instead of updating the package, Composer tried to access the private GitLab repository and could not authenticate over SSH.

It then offered to create credentials and asked for a username and password. That was an important clue: Composer was not necessarily the problem. It simply could not use the GitLab access method that already worked on my host.

What Composer asked for
Permission denied (publickey). Username:Password:

Checking SSH on the host

I started with the simplest check: whether SSH to GitLab worked outside Docker at all.

Check GitLab SSH on host
ssh -T git@gitlab.com
Successful SSH response
Welcome to GitLab, @xmarynkam!
This immediately narrowed the problem down. The SSH key was valid, GitLab accepted it, and my account had access. Creating another Personal Access Token or changing credentials would not solve the actual issue.

What does the Docker workspace see?

I repeated the same check inside the Laradock workspace where Composer actually runs.

Check GitLab SSH inside Docker
docker compose exec workspace-85 ssh -T git@gitlab.com
Docker SSH error
git@gitlab.com: Permission denied (publickey).

That made the difference obvious: GitLab SSH worked on the host but failed inside the container on the same machine.

The next thing I checked was the SSH Agent. My keys were loaded correctly on the host, while SSH_AUTH_SOCK inside the Docker workspace was empty.

Check SSH Agent
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK"ssh-add -l
До
text
Host SSH key → ssh-agent → GitLab ✓  Docker Composer → Git → SSH          no SSH agent ✗
Після
text
Host ssh-agent      │ mounted socketDocker workspace      └── Git / Composer → GitLab ✓

The real issue was SSH_AUTH_SOCK

SSH Agent runs as a separate process on the host and provides access to loaded SSH keys. Applications communicate with it through a socket whose path is exposed through SSH_AUTH_SOCK.

A Docker container does not automatically receive that socket. Git inside my workspace therefore had no way to use the SSH Agent even though everything was configured correctly on the host.

That was the key point for me: I did not need to copy an SSH key into the container. I needed to give the container access to the SSH Agent that was already running on the host.

Forwarding the SSH Agent into Laradock

I moved the SSH Agent configuration into a reusable Docker Compose anchor so I could apply it to several PHP workspaces without duplicating it.

YAML
x-local-ssh-agent: &local-ssh-agent  environment:    SSH_AUTH_SOCK: /ssh-agent  volumes:    - "${SSH_AUTH_SOCK}:/ssh-agent"

The host socket is mounted inside the container as /ssh-agent, and SSH_AUTH_SOCK inside the workspace points to that location.

I use several Laradock workspaces for different PHP versions, so I applied the same anchor to every CLI workspace.

YAML
services:  workspace:    <<: [*local-host-config, *local-ssh-agent]   workspace-84:    <<: [*local-host-config, *local-ssh-agent]   workspace-85:    <<: [*local-host-config, *local-ssh-agent]
I do not copy private SSH keys into a Docker image or container. The container only receives access to the socket of the SSH Agent that is already running on the host.

Recreating the workspace after the Compose change

Recreate Laradock workspace
docker compose up -d \  --force-recreate \  --no-deps \  workspace-85

Verifying SSH Agent inside the container

After recreating the container, I checked the SSH Agent before trying Composer again. This makes it much easier to see whether the infrastructure part is actually fixed.

Verify forwarded SSH Agent
docker compose exec --user laradock workspace-85 sh -lc 'echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK"ssh-add -l'

Once the keys were visible inside the workspace, I tested the direct SSH connection to GitLab again.

bash
docker compose exec --user laradock workspace-85 \  ssh -o StrictHostKeyChecking=accept-new -T git@gitlab.com
Successful Docker SSH response
Welcome to GitLab, @xmarynkam!

Only then I went back to Composer

After that, I repeated the same Composer command that originally failed. This time Composer could access the private GitLab repository through Git and update the package without asking for a username or password.

dcomposer itself is part of my local multi-PHP workflow with dphp, dartisan, and dcomposer, where the correct Laradock workspace is selected automatically for each project.

For me, this was a good example of why it helps to debug the problem layer by layer:

  1. GitLab SSH first,

  2. Docker next,

  3. then SSH Agent,

  4. and Composer only after that.

Composer update after the fix
dcomposer update avn/laravel-localization --with-dependencies

What I would not do here

  • Copy a private SSH key into a Docker image or container.

  • Store a GitLab password inside the container.

  • Enter a Personal Access Token every time Composer asks for credentials.

  • Treat it as a Composer problem before checking plain Git and SSH access from the same environment.

What I took away from this case

In my case, Composer was only showing the symptom. The actual problem existed one layer lower: Git inside Docker could not access the host SSH Agent.

Once I forwarded SSH_AUTH_SOCK through Docker Compose and mounted the agent socket into the Laradock workspace, the same SSH key worked both on the host and inside the container.

That configuration is now shared by my PHP workspaces, and private Composer packages can be updated without copying SSH keys or storing separate GitLab credentials inside Docker.