Search code examples
gitdockerssh-agent

How to deploy code from Github using deploy key in Docker?


I want to pull code from Github into my Docker image while building. I have a deploy key generated from the repository, but it seems to me the ssh-agent is not working on my Docker image.

What I did (my Dockerfile):

FROM python:2.7-stretch
ADD ./id_rsa /root/.ssh/id_rsa
RUN eval "$(ssh-agent -s)"
RUN ssh-add -K /root/.ssh/id_rsa

Output:

Step 12/22 : RUN eval "$(ssh-agent -s)"
 ---> Running in f9ad80981cee
Agent pid 6
Removing intermediate container f9ad80981cee
 ---> d773f7ce5917
Step 13/22 : RUN ssh-add -K /root/.ssh/id_rsa
 ---> Running in 95efeed6a7ad
Could not open a connection to your authentication agent.
The command '/bin/sh -c ssh-add -K /root/.ssh/id_rsa' returned a non-zero code: 2

As you can see, ssh-agent is started, but keys are not adding in it.

If I skip the ssh-add step then my git pull fails later because of privileges, which is failing as expected as no authentication happened.


Solution

  • Actually you don't need to copy your private key to your container (and you better not do it).

    All you need is the ssh-agent installed and launched on both: your host and your docker container then all you need to do is to mount the ssh-aget's socket file:

    If you are using docker-compose:

    environment:
      - "SSH_AUTH_SOCK=/tmp/ssh-agent"
    volumes:
      - $SSH_AUTH_SOCK:/tmp/ssh-agent
    

    With docker:

    docker run -v $SSH_AUTH_SOCK:/tmp/ssh-agent 8be57bbc9561 sleep 1000000 # 8be57bbc9561 is an id of the image
    docker exec -it -e SSH_AUTH_SOCK=/tmp/ssh-agent 5b6f4a8f8661 /bin/ash # 5b6f4a8f8661 is an id of the container
    

    P.S

    As of your case, I think the problem can be related to the export command which is normally evaled from the code from the output of the ssh-agent.

    It should provide you two variables: SSH_AUTH_SOCK and SSH_AGENT_PID. But the export won't persist across images.

    You've used RUN two times: first for launching the ssh-agent and exporting variables and then for adding a key. And each Dockerfile directive will generate an intermediate container (and export won't persist across them).

    If you still want to use it this way (which I stronly recommend to avoid), you can try to bind both command in a single RUN:

    RUN eval "$(ssh-agent -s)" && ssh-add /root/.ssh/id_rsa
    

    I've written a short post based on my answer above.