Клонировать приватный репозиторий git с помощью dockerfile
Я скопировал этот код из того, что похоже на различные рабочие файлы Docker, вот мое:
FROM ubuntu
MAINTAINER Luke Crooks "luke@pumalo.org"
# 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 git@bitbucket.org:Pumalo/docker-conf.git /home/docker-conf
Это дает мне ошибку
Step 10 : RUN git clone git@bitbucket.org: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 git@bitbucket.org:Pumalo/docker-conf.git /home/docker-conf] returned a non-zero code: 128
Я впервые использую dockerfiles, но из того, что я прочитал (и взял из рабочих конфигов), я не могу понять, почему это не работает.
Мой id_rsa находится в той же папке, что и мой dockerfile, и является копией моего локального ключа, который может без проблем клонировать этот репозиторий.
Редактировать:
В моем dockerfile я могу добавить:
RUN cat /root/.ssh/id_rsa
И он печатает правильный ключ, поэтому я знаю, что он копируется правильно.
Я также попытался сделать, как советовал Ной, и побежал:
RUN echo "Host bitbucket.org\n\tIdentityFile /root/.ssh/id_rsa\n\tStrictHostKeyChecking no" >> /etc/ssh/ssh_config
К сожалению, это тоже не работает.
13 ответов
Мой ключ был защищен паролем, что вызывало проблему, рабочий файл теперь указан ниже (для помощи будущим гуглерам)
FROM ubuntu
MAINTAINER Luke Crooks "luke@pumalo.org"
# 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
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 git@bitbucket.org:User/repo.git
Вам следует создать новый набор ключей SSH для этого образа Docker, так как вы, вероятно, не хотите вставлять туда свой собственный закрытый ключ. Чтобы он работал, вам нужно добавить этот ключ к ключам развертывания в вашем git-репозитории. Вот полный рецепт:
Генерация ключей SSH с
ssh-keygen -q -t rsa -N '' -f repo-key
который даст вам файлы repo-key и repo-key.pub.Добавьте repo-key.pub к ключам развертывания вашего репозитория.
На GitHub перейдите в [ваш репозиторий] -> Настройки -> Развернуть ключиДобавьте что-то подобное в ваш Dockerfile:
ДОБАВИТЬ РЕПО-КЛЮЧ / БЕЖАТЬ \ CHMOD 600 / РЕПО-ключ && \ echo "IdentityFile /repo-key" >> /etc/ssh/ssh_config && \ echo -e "StrictHostKeyChecking no" >> /etc/ssh/ssh_config && \ // ваши команды git clone здесь...
Обратите внимание, что выше отключает StrictHostKeyChecking, поэтому вам не нужно.ssh/known_hosts. Хотя мне, вероятно, больше нравится решение с ssh-keyscan в одном из ответов выше.
Там нет необходимости возиться с конфигурациями SSH. Используйте файл конфигурации (не файл Docker), который содержит переменные среды, и попросите сценарий оболочки обновить файл Docker во время выполнения. Вы храните токены в своих файлах Docker и можете клонировать через https (не нужно генерировать или передавать ключи ssh).
Зайдите в Настройки> Личные токены доступа
- Создать личный токен доступа с
repo
область включена. - Клон, как это:
git clone https://MY_TOKEN@github.com/user-or-org/repo
Некоторые комментаторы отметили, что если вы используете общий Dockerfile, это может предоставить ваш ключ доступа другим людям в вашем проекте. Хотя это может или не может быть проблемой для вашего конкретного случая использования, вот несколько способов, которые вы можете решить:
- Используйте сценарий оболочки, чтобы принимать аргументы, которые могут содержать ваш ключ в качестве переменной. Замените переменную в вашем Dockerfile на
sed
или аналогичный, то есть вызов сценария сsh rundocker.sh MYTOKEN=foo
который заменит наhttps://{{MY_TOKEN}}@github.com/user-or-org/repo
, Обратите внимание, что вы также можете использовать файл конфигурации (в формате.yml или в любом другом формате), чтобы сделать то же самое, но с переменными среды. - Создать пользователя github (и сгенерировать токен доступа) только для этого проекта
Вы часто не хотите выполнять git clone
частного репо из сборки докера. Выполнение клона предполагает размещение личных учетных данных 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 git@bitbucket.org:User/repo.git
FROM ubuntu as release
LABEL maintainer="Luke Crooks <luke@pumalo.org>"
COPY --from=clone /repo /repo
...
Совсем недавно BuildKit тестировал некоторые экспериментальные функции, которые позволяют передавать ключ ssh как монтирование, которое никогда не записывается в образ:
# syntax=docker/dockerfile:experimental
FROM ubuntu as clone
LABEL maintainer="Luke Crooks <luke@pumalo.org>"
# 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 git@bitbucket.org: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 <luke@pumalo.org>"
# 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 git@bitbucket.org: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 .
Опять же, это внедряется в сборку без записи в слой изображения, что устраняет риск случайной утечки учетных данных.
Заставить докер запустить 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 git@bitbucket.org:User/repo.git
Затем вы вводите этот изменяемый аргумент в команду сборки docker:
date_stamp=$(date +%Y%m%d-%H%M%S)
docker build --build-arg DATE_STAMP=$date_stamp .
Другой вариант - использовать многоэтапную сборку 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_PRIVATE_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 git@github.com: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)
Для репозитория bitbucket сгенерируйте пароль приложения (настройки Bitbucket -> Управление доступом -> Пароль приложения, см. Изображение) с доступом для чтения к репозиторию и проекту.
Тогда команда, которую вы должны использовать:
git clone https://username:generated_password@bitbucket.org/reponame/projectname.git
В настоящее время вы можете использовать опцию Buildkit
--ssh default
когда вы строите свой контейнер; Перед сборкой вам необходимо добавить ключ развертывания SSH к вашему ssh-agent.
Вот полный процесс с самого начала:
Создайте пару ключей на своем сервере развертывания. Просто беги
ssh-keygen -t ecdsa
Сохраните вашу пару ключей в ~ / .sshДобавьте сгенерированный открытый ключ (расширение .pub) на веб-сайт поставщика git (gitlab, github..)
Добавьте свой ключ в ssh-agent (программа, которая в основном управляет вашими ключами проще, чем каждый файл)
ssh-add /path/to/your/private/key
- Добавьте это в свой Dockerfile:# эти 3 первые строки добавляют открытые ключи вашего провайдера в known_host#, чтобы git не получал ошибку от SSH.
RUN mkdir -m 700 /root/.ssh && \
touch -m 600 /root/.ssh/known_hosts && \
ssh-keyscan your-git-provider.com > /root/.ssh/known_hosts
# now you can clone with --mount=type=ssh option,
# forwarding to Docker your hosting machine ssh agent
RUN mkdir -p /wherever/you/want/to/clone && cd /wherever/you/want/to/clone && \
--mount=type=ssh git clone git@gitlab.com:stunset/server/stunset-core.git
- И теперь вы, наконец, можете создать свой Dockerfile (с включенным buildkit)
DOCKER_BUILDKIT=1 docker build . --ssh default
Создайте токен доступа: https://github.com/settings/tokens
передайте его в качестве аргумента докеру (ps, если вы используете
CapRover
, установите его под
App Configs
)
В вашем Dockerfile:
ARG GITHUB_TOKEN=${GITHUB_TOKEN}
RUN git config --global url."https://${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"
RUN pip install -r requirements.txt
ps это предполагает, что частные репозитории находятся в следующем формате в
requirements.txt
:
git+https://github.com/<YOUR-USERNAME>/<YOUR-REPO>.git
Мы используем AWS Secret Manager (вы можете использовать любой, к которому у вас есть доступ).
- Создайте ключ SSH и добавьте открытый ключ в авторизованную учетную запись GitHub. Возможно, это общая учетная запись GitHub в вашей организации, к которой, например, имеет доступ команда DevOPs.
- В вашем личном ключе есть новые строки. Если вы скопируете это непосредственно в свой секретный менеджер, новые строки будут удалены. Поэтому base64 закодирует ваш закрытый ключ с помощью
cat ssh_private_file | base64 -w 0
- Добавьте свой закрытый ключ в кодировке Base64 в секретный менеджер aws (или любой секретный менеджер).
- Допустим, ключ называется «ssh_private» внутри вашего секретного имени «Private_Repo», вы можете получить доступ к своему секретному ключу.
aws secretsmanager get-secret-value \
--secret-id Private_Repo --query "SecretString" --output text --region $region_name \
| jq -r ".ssh_private" | base64 -d
Убедитесь, что у вас установлен jq.
- Когда вы создаете свой образ, вам необходимо передать свои учетные данные команде сборки docker, чтобы аутентифицировать процесс для использования диспетчера секретов. Ниже приведен фрагмент нашего Dockerfile:
ARG AWS_DEFAULT_REGION
ARG AWS_ACCESS_KEY_ID
ARG AWS_SECRET_ACCESS_KEY
ARG ssh_file=id_rsa
ENV AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION
ENV AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
ENV AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" \
&& unzip awscliv2.zip \
&& ./aws/install \
&& aws secretsmanager get-secret-value \
--secret-id Private_Repo --query "SecretString" --output text --region $AWS_DEFAULT_REGION \
| jq -r ".ssh_private" | base64 -d > ${ssh_file} \
&& chmod 0700 id_rsa
RUN eval "$(ssh-agent -s)" \
&& ssh-add ${ssh_file} \
&& mkdir ~/.ssh/ \
&& echo "Host github.com\n\tIdentityFile ${ssh_file}\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
Выше
- читает закрытый ключ из секретного менеджера и записывает в файл, -
- ssh-добавляет файлы
- редактирует ваш файл конфигурации ssh для доступа к хосту Github.com с помощью этого закрытого ключа.
Вы можете передать учетные данные с помощью следующей команды, если они сохранены как переменные среды.
DOCKER_BUILDKIT=1 docker build --build-arg AWS_ACCESS_KEY_ID=$env:AWS_ACCESS_KEY_ID --build-arg AWS_SECRET_ACCESS_KEY=$env:AWS_SECRET_ACCESS_KEY --build-arg AWS_DEFAULT_REGION=$env:AWS_DEFAULT_REGION -f docker/Dockerfile .
Этот подход позволяет вам удалить закрытый ключ из вашего образа после завершения всех установок, и контейнеру не требуется доступ к частным репозиториям во время выполнения.
Я считаю, что основным недостатком этого подхода является отключение StringHostKeyChecking в вашей конфигурации ssh (я не знаю о последствиях здесь), и то, что секретные менеджеры стоят несколько центов.
Вышеуказанные решения не работали для bitbucket. Я подумал, что это делает трюк:
RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts \
&& eval `ssh-agent` \
&& ssh-add ~/.ssh/[key] \
&& git clone git@bitbucket.org:[team]/[repo].git
В дополнение к
@Calvin Froedge
подход к использованию токена личного доступа (PAT),
Возможно, вам потребуется добавить
oauth
или же
oauth2
в качестве имени пользователя перед вашим PAT для аутентификации следующим образом:
https://oauth:<token>@git-url.com/user/repo.git
недавно была аналогичная проблема с частным репозиторием в проекте Rust. Я предлагаю вообще избегать разрешений/конфигурации ssh.
Вместо:
- клонировать репозиторий в среде сборки, например, CI, где разрешения уже существуют (или могут быть легко настроены)
- скопируйте файлы в Dockerfile (это также можно кэшировать внутри CI)
Пример
часть 1) внутри КИ
CARGO_HOME=tmp-home cargo fetch
часть 2) в Dockerfile
COPY tmp-home $CARGO_HOME
процесс одинаков независимо от языка/системы пакетов
For other people searching I had the same issue adding
--ssh default
flag made it work