Как установить приватное git-репо с pip в Dockerfile

Я скопировал этот код из того, что кажется различным рабочим докер файлом, вот мой:

FROM ubuntu

MAINTAINER Luke Crooks "[email protected]"

# Update aptitude with new repo
RUN apt-get update

# Install software 
RUN apt-get install -y git python-virtualenv

# Make ssh dir
RUN mkdir /root/.ssh/

# Copy over private key, and set permissions
ADD id_rsa /root/.ssh/id_rsa
RUN chmod 700 /root/.ssh/id_rsa
RUN chown -R root:root /root/.ssh

# Create known_hosts
RUN touch /root/.ssh/known_hosts

# Remove host checking
RUN echo "Host bitbucket.org\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config

# Clone the conf files into the docker container
RUN git clone [email protected]:Pumalo/docker-conf.git /home/docker-conf

Это дает мне ошибку

Step 10 : RUN git clone [email protected]:Pumalo/docker-conf.git /home/docker-conf
 ---> Running in 0d244d812a54
Cloning into '/home/docker-conf'...
Warning: Permanently added 'bitbucket.org,131.103.20.167' (RSA) to the list of known hosts.
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
2014/04/30 16:07:28 The command [/bin/sh -c git clone [email protected]:Pumalo/docker-conf.git /home/docker-conf] returned a non-zero code: 128

Это мой первый раз, когда я использую dockerfiles, но из того, что я прочитал (и взял из рабочих конфигураций), я не понимаю, почему это не работает.

Мой id_rsa находится в той же папке, что и мой файл docker, и является копией моего локального ключа, который не может клонировать это репо без проблем.

Изменить:

В моем файле docker я могу добавить:

RUN cat /root/.ssh/id_rsa

И он печатает правильный ключ, поэтому я знаю, что он правильно копируется.

Я также пытался сделать то, что советовал ной, и побежал:

RUN echo "Host bitbucket.org\n\tIdentityFile /root/.ssh/id_rsa\n\tStrictHostKeyChecking no" >> /etc/ssh/ssh_config

Это, к сожалению, тоже не работает.

Ответ 1

Мой ключ был защищен паролем, что вызывало проблему, рабочий файл теперь указан ниже (для помощи будущим гуглерам)

FROM ubuntu

MAINTAINER Luke Crooks "[email protected]"

# Update aptitude with new repo
RUN apt-get update

# Install software 
RUN apt-get install -y git
# Make ssh dir
RUN mkdir /root/.ssh/

# Copy over private key, and set permissions
# Warning! Anyone who gets their hands on this image will be able
# to retrieve this private key file from the corresponding image layer
ADD id_rsa /root/.ssh/id_rsa

# Create known_hosts
RUN touch /root/.ssh/known_hosts
# Add bitbuckets key
RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts

# Clone the conf files into the docker container
RUN git clone [email protected]:User/repo.git

Ответ 2

Вам нужно создать новый набор ключей SSH для этого образа Docker, поскольку вы, вероятно, не хотите вставлять туда свой собственный закрытый ключ. Чтобы он работал, вам нужно добавить этот ключ к ключам развертывания в репозитории git. Вот полный рецепт:

  • Сгенерируйте ключи ssh с помощью ssh-keygen -q -t rsa -N '' -f repo-key, которые предоставят вам файлы repo-key и repo-key.pub.

  • Добавьте repo-key.pub в ключи развертывания вашего репозитория.
    В GitHub перейдите в [ваш репозиторий] → Настройки → Развернуть ключи

  • Добавьте что-то вроде этого в файл Docker:

    ADD repo-key /
    RUN \
      chmod 600 /repo-key && \  
      echo "IdentityFile /repo-key" >> /etc/ssh/ssh_config && \  
      echo -e "StrictHostKeyChecking no" >> /etc/ssh/ssh_config && \  
      // your git clone commands here...
    

Обратите внимание, что выше отключает StrictHostKeyChecking, поэтому вам не нужны .ssh/known_hosts. Хотя мне, вероятно, больше нравится решение с ssh-keyscan в одном из ответов выше.

Ответ 3

Нет необходимости возиться с конфигурациями ssh. Используйте файл конфигурации (а не файл Docker), содержащий переменные среды, а оболочку script обновите файл докеров во время выполнения. Вы держите маркеры из своих Dockerfiles, и вы можете клонировать через https (нет необходимости генерировать или передавать файлы ssh).

Перейдите в Настройки > Идентификаторы персонального доступа

  • Создайте токен персонального доступа с включенной областью repo.
  • Клонировать вот так: git clone https://[email protected]/user-or-org/repo

Некоторые комментаторы отметили, что если вы используете общий файл Docker, это может открыть ваш ключ доступа другим людям в вашем проекте. Хотя это может быть или не быть проблемой для вашего конкретного случая использования, вот несколько способов, которыми вы можете справиться с этим:

  • Используйте оболочку script для принятия аргументов, которые могут содержать ваш ключ как переменную. Замените переменную в вашем файле Docker с помощью sed или аналогичной, то есть вызовите script с sh rundocker.sh MYTOKEN=foo, который заменит на https://{{MY_TOKEN}}@github.com/user-or-org/repo. Обратите внимание, что вы также можете использовать файл конфигурации (в формате .yml или любом другом формате), чтобы сделать то же самое, но с переменными среды.
  • Создайте пользователя github (и создайте токен доступа для) только для этого проекта

Ответ 4

Для репозитория bitbucket сгенерируйте пароль приложения (настройки Bitbucket → Управление доступом → Пароль приложения, см. Изображение) с доступом для чтения к репозиторию и проекту.

bitbucket user menu

Тогда команда, которую вы должны использовать:

git clone https://username:[email protected]/reponame/projectname.git

Ответ 5

Другой вариант - использовать многоэтапную сборку Docker, чтобы гарантировать, что ваши ключи SSH не включены в окончательный образ.

Как описано в моем посте, вы можете подготовить ваше промежуточное изображение с необходимыми зависимостями для git clone, а затем COPY необходимые файлы в ваше окончательное изображение.

Кроме того, если мы LABEL наши промежуточные слои, мы можем даже удалить их из машины, когда закончим.

# Choose and name our temporary image.
FROM alpine as intermediate
# Add metadata identifying these images as our build containers (this will be useful later!)
LABEL stage=intermediate

# Take an SSH key as a build argument.
ARG SSH_KEY

# Install dependencies required to git clone.
RUN apk update && \
    apk add --update git && \
    apk add --update openssh

# 1. Create the SSH directory.
# 2. Populate the private key file.
# 3. Set the required permissions.
# 4. Add github to our list of known hosts for ssh.
RUN mkdir -p /root/.ssh/ && \
    echo "$SSH_KEY" > /root/.ssh/id_rsa && \
    chmod -R 600 /root/.ssh/ && \
    ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts

# Clone a repository (my website in this case)
RUN git clone [email protected]:janakerman/janakerman.git

# Choose the base image for our final image
FROM alpine

# Copy across the files from our 'intermediate' container
RUN mkdir files
COPY --from=intermediate /janakerman/README.md /files/README.md

Затем мы можем построить:

MY_KEY=$(cat ~/.ssh/id_rsa)
docker build --build-arg SSH_KEY="$MY_KEY" --tag clone-example .

Докажите, что наши ключи SSH пропали:

docker run -ti --rm clone-example cat /root/.ssh/id_rsa

Очистите промежуточные изображения со сборочной машины:

docker rmi -f $(docker images -q --filter label=stage=intermediate)

Ответ 6

Вышеуказанные решения не работали для bitbucket. Я подумал, что это делает трюк:

RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts \
    && eval 'ssh-agent' \
    && ssh-add ~/.ssh/[key] \
    && git clone [email protected]:[team]/[repo].git

Ответ 7

Вы часто не хотите выполнять git clone частного репозитория из сборки docker. Выполнение клона предполагает размещение личных учетных данных ssh внутри изображения, где они могут быть впоследствии извлечены любым пользователем, имеющим доступ к вашему изображению.

Вместо обычной практикой является клонировать Git репо из - за пределов грузчиком в вашем CI инструмент выбора, а просто COPY файлы в образ. Это имеет второе преимущество: кэширование докера. Кэширование Docker проверяет выполняемую команду, включенные в нее переменные среды, входные файлы и т.д., И, если они идентичны предыдущей сборке из того же родительского шага, использует этот предыдущий кэш. С помощью команды git clone сама команда идентична, поэтому docker будет повторно использовать кэш, даже если внешнее git-репо изменилось. Однако команда COPY просматривает файлы в контексте сборки и может определить, идентичны ли они или были обновлены, и использовать кэш только в случае необходимости.


Если вы собираетесь добавить учетные данные в свою сборку, подумайте о том, чтобы сделать это с многоэтапной сборкой, и размещать эти учетные данные только на ранней стадии, которая никогда не будет помечена и выдвинута за пределы узла сборки. Результат выглядит так:

FROM ubuntu as clone

# Update aptitude with new repo
RUN apt-get update \
 && apt-get install -y git
# Make ssh dir
# Create known_hosts
# Add bitbuckets key
RUN mkdir /root/.ssh/ \
 && touch /root/.ssh/known_hosts \
 && ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts

# Copy over private key, and set permissions
# Warning! Anyone who gets their hands on this image will be able
# to retrieve this private key file from the corresponding image layer
COPY id_rsa /root/.ssh/id_rsa

# Clone the conf files into the docker container
RUN git clone [email protected]:User/repo.git

FROM ubuntu as release
LABEL maintainer="Luke Crooks <[email protected]>"

COPY --from=clone /repo /repo
...

Совсем недавно BuildKit тестировал некоторые экспериментальные функции, которые позволяют передавать ключ ssh как монтирование, которое никогда не записывается в образ:

# syntax=docker/dockerfile:experimental
FROM ubuntu as clone
LABEL maintainer="Luke Crooks <[email protected]>"

# Update aptitude with new repo
RUN apt-get update \
 && apt-get install -y git

# Make ssh dir
# Create known_hosts
# Add bitbuckets key
RUN mkdir /root/.ssh/ \
 && touch /root/.ssh/known_hosts \
 && ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts

# Clone the conf files into the docker container
RUN --mount=type=secret,id=ssh_id,target=/root/.ssh/id_rsa \
    git clone [email protected]:User/repo.git

И вы можете построить это с:

$ DOCKER_BUILDKIT=1 docker build -t your_image_name \
  --secret id=ssh_id,src=$(pwd)/id_rsa .

Обратите внимание, что для этого все еще требуется, чтобы ваш ключ ssh не был защищен паролем, но вы можете, по крайней мере, запустить сборку за один этап, удалив команду COPY и избегая того, чтобы учетные данные ssh были частью образа.


BuildKit также добавил функцию только для ssh, которая позволяет вам сохранить ваши ssh-ключи, защищенные паролем, результат выглядит так:

# syntax=docker/dockerfile:experimental
FROM ubuntu as clone
LABEL maintainer="Luke Crooks <[email protected]>"

# Update aptitude with new repo
RUN apt-get update \
 && apt-get install -y git

# Make ssh dir
# Create known_hosts
# Add bitbuckets key
RUN mkdir /root/.ssh/ \
 && touch /root/.ssh/known_hosts \
 && ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts

# Clone the conf files into the docker container
RUN --mount=type=ssh \
    git clone [email protected]:User/repo.git

И вы можете построить это с:

$ eval $(ssh-agent)
$ ssh-add ~/.ssh/id_rsa
(Input your passphrase here)
$ DOCKER_BUILDKIT=1 docker build -t your_image_name \
  --ssh default=$SSH_AUTH_SOCK .

Опять же, это внедряется в сборку без записи в слой изображения, что устраняет риск случайной утечки учетных данных.


Чтобы заставить docker запускать git clone даже если ранее кэшированные строки были добавлены, вы можете ввести ARG сборки, которая меняется с каждой сборкой, чтобы сломать кеш. Это выглядит так:

# inject a datestamp arg which is treated as an environment variable and
# will break the cache for the next RUN command
ARG DATE_STAMP
# Clone the conf files into the docker container
RUN git clone [email protected]:User/repo.git

Затем вы вводите этот изменяемый аргумент в команду сборки docker:

date_stamp=$(date +%Y%m%d-%H%M%S)
docker build --build-arg DATE_STAMP=$date_stamp .