It was really hard for me to understand how to install a private package into my docker container, after some long hours I realized that there are many ways (often hard for me) to do it. I finally stumbled into some really useful articles which I am going to link and I finally managed to do it… I would say the easy way.

In my example I already have the ssh keys available onto my PC so I decided to go with the ssh agent forwarding since it seemed easier to do so than the other methods. Also in my example I am pulling modules via git+ssh in my requirements.txt file, I think that this method would also work with private package indexes as well.

This is how I am forwarding my ssh agent into the Container.

First in docker-compose.yml file I am binding an environment variable called SSH_AUTH_SOCK

environment:

SSH_AUTH_SOCK: $SSH_AUTH_SOCK

This would bind our host environment variable to the container’s variable.

Note: Make sure that you have SSH_AUTH_SOCK variable exported!

$ printenv SSH_AUTH_SOCK

Note: If the container is showing you warning about an empty string, run your command with sudo -E

Next you have to bind the volumes of your sock path.

volumes:

# Main Files

- .:/code



...



# SSH Settings

- $SSH_AUTH_SOCK:$SSH_AUTH_SOCK

Now, you’ve successfully forwarded your ssh agent into the container. But now how do you install these packages?

Firstly I want to point out some very important things about the dockerfile

The command which are executed in it are not sequential but rather serial.

So If you are depending on a sequential commands do them with a single RUN like so

RUN apk update \

&& apk add gettext \

# https://docs.djangoproject.com/en/dev/ref/django-admin/#dbshell

&& apk add postgresql-client \

# XML Dependencies

&& apk add --update --no-cache g++ gcc libxslt-dev \

# Git for requirements.txt

&& apk add git \

# ssh for private repo

&& apk add openssh-client

Also it is always nice to comment things out.

Help links:

Why sudo -e ? https://forums.docker.com/t/docker-compose-not-seeing-environment-variables-on-the-host/11837/3

https://unix.stackexchange.com/questions/3507/difference-between-shell-variables-which-are-exported-and-those-which-are-not-in

So now lets prepare our git host first, you’ll need to add your git host into your known hosts in the container, so you won’t get asked for permissions when running pip install . To do that we have to add one more thing to our dockerfile

# Add YOURHOST.IO to known hosts

&& touch /etc/ssh/ssh_known_hosts \

&& ssh-keyscan YOURHOST.IO >> /etc/ssh/ssh_known_hosts

First we create the ssh_known_hosts file and then we are executing the

ssh-keyscan with our host and then adding it to the known hosts. We don’t need to set permissions because the touch command is making the ssh_known_hosts file already with 0644.

At this point you should be able to pull the modules and install them via manually logging into the container. But that’s an extra step to take we want to automate this.

Here was my biggest stuck and I didn’t realized for some hours that I cannot just run pip install after installing all of my dependencies in the dockerfile so I’ve googled a lot and I finally realized that the ssh agent isn’t available at run-time. After this realization I’ve decided to create a start script instead.

I got some ideas of how to do that from the django-cookiecutter template by pydanny. So I’ve created a new file called start

#!/bin/sh



set -o errexit

set -o pipefail

set -o nounset





pip install -r requirements.txt

With that content in it, I’ve slightly modified the one in the cookiecutter template, that way we would have the ssh agent available when running the pip installs. One important thing to note is that you’ll have to set your work directory into the project otherwise it won’t find the file. In the end of your dockerfile add WORKDIR /code

So after we create the start file we’ll need to make it executable so we can add it as a command in our compose file.

COPY ./start /start

RUN sed -i 's/\r$//g' /start

RUN chmod +x /start

And then add it as a command in our compose file. command: /start

After a successful compose build you should be able to run

docker-compose up which will trigger the /start command and it will execute the pip installation, since the ssh agent would be available there you shouldn’t have problems installing the private repositories.

Full Dockerfile.

I got some of the ideas from these articles: