dockerfile을 사용하여 개인 git repo 복제


240

나는 여러 가지 작동하는 dockerfiles 인 것에서이 코드를 복사했습니다.

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

슬프게도 작동하지 않습니다.

답변:


300

내 키는 비밀번호로 보호되어 문제를 일으켰습니다. 작업 파일이 아래에 나열되어 있습니다 (향후 Google 직원을 돕기 위해).

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
# 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 git@bitbucket.org:User/repo.git

11
만일을 위해, 여기 에 열쇠의 암호 보호를 제거하는 방법을 설명하는 링크 가 있습니다
Thomas

82
참고로 RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts를 실행하면 이미지가 레이어로 저장됩니다. 누군가 이미지를 가지고 있으면 키를 검색 할 수 있습니다. 나중에 레이어에서 해당 파일을 삭제하더라도 b / c 추가 한 경우 7 단계로 돌아갈 수 있습니다.
Bernie Perez

23
유용한 답변에 감사드립니다. 그러나 우리에게는 빌드가 무작위로 실패했으며 조사 후 ssh-keyscan비트 버킷이 종종 초과되는 5 초의 기본 시간 초과 가 있음을 알았 습니다. ssh-keyscan오류를보고하지도 않습니다. RUN ssh-keyscan -T 60 bitbucket.org >> /root/.ssh/known_hosts안전을 위해 더 나은 달리기 .
fluidsonic

5
달리기 ssh-keyscan가 왜 문제가 되는지 설명해 줄 수 있습니까? 내 이해는 그것이 단순히 Github / Bitbucket의 공개 키를 가져올 것이라는 것입니다. 어떤 대안이 레이어에서 끝나지 않도록 사용할 수 있습니까?
페드로

9
@Pedro 특히 키 스캔 단계는 전혀 문제가되지 않습니다. 분명히 옳습니다. 이 호스트 공개 키는 가능한 한 많이 확산되어야합니다. known_hosts파일 에 대한 자세한 내용은 sshd (8)를 참조 하십시오. 사람들은 충분히 놀랍게 들릴 때 임의의 것을 찬성했습니다.
tne

99

고유 한 개인 키를 포함하지 않으려는 경우 해당 Docker 이미지에 대해 새 SSH 키 세트를 작성해야합니다. 작동하려면 git 저장소의 배포 키에 해당 키를 추가해야합니다. 완전한 레시피는 다음과 같습니다.

  1. ssh-keygen -q -t rsa -N '' -f repo-keyrepo-key 및 repo-key.pub 파일을 제공하는 ssh 키를 생성 하십시오.

  2. 저장소 배치 키에 repo-key.pub를 추가하십시오.
    GitHub에서 [저장소]-> 설정-> 배포 키로 이동하십시오.

  3. Dockerfile에 다음과 같은 것을 추가하십시오.

    리포 키 추가 /
    운영 \
      chmod 600 / repo- 키 && \  
      echo "IdentityFile / repo-key">> / etc / ssh / ssh_config && \  
      echo -e "StrictHostKeyChecking no">> / etc / ssh / ssh_config && \  
      // 여기 git clone 명령 ...
    

위의 StrictHostKeyChecking을 끄므로 .ssh / known_hosts가 필요하지 않습니다. 위의 답변 중 하나에서 ssh-keyscan을 사용하여 더 많은 솔루션을 원할 것입니다.


6
경고 : 내 구성에서 echo -e "..."도 파일 안에 -e를 씁니다. 플래그를 제거하면 정상적으로 작동합니다.
Conchylicultor

귀하의 답변은 제 문제를 해결하는 데 절대적으로 완벽했습니다. 감사합니다!
David Pointer

나는 여전히 같은 문제가 있습니다 :fatal: Could not read from remote repository.
Alex

1
수백만 감사합니다! 나는 당신에게 사랑을 선언하는 가장자리에 있습니다. 며칠 동안 싸우고있는 문제를 해결했습니다!
alexandra

이 질문에 선택된 답변은 더 이상 좋은 답변이 아닙니다. 2014 년에는 맞았지만 2020 년에는 이것이 정답입니다.
Bikal Basnet

70

ssh 구성으로 주위를 둘러 볼 필요가 없습니다. 환경 변수가 포함 된 구성 파일 (Dockerfile 아님)을 사용하고 런타임시 쉘 스크립트가 Docker 파일을 업데이트하도록합니다. Dockerfile에서 토큰을 보관하지 않고 https를 복제 할 수 있습니다 (ssh 키를 생성하거나 전달할 필요가 없음).

이동 설정> 개인 액세스 토큰

  • repo범위가 활성화 된 개인 액세스 토큰을 생성하십시오 .
  • 다음과 같이 복제하십시오. git clone https://MY_TOKEN@github.com/user-or-org/repo

일부 의견 제시 자들은 공유 Dockerfile을 사용하면 프로젝트의 다른 사람들에게 액세스 키가 노출 될 수 있다고 언급했습니다. 특정 사용 사례에서는 이것이 문제가 될 수도 있고 아닐 수도 있지만 다음과 같은 방법으로 처리 할 수 ​​있습니다.

  • 쉘 스크립트를 사용하여 키를 변수로 포함 할 수있는 인수를 승인하십시오. Dockerfile의 변수를 sed또는 이와 유사한 sh rundocker.sh MYTOKEN=foo것으로 바꾸십시오 (예 : on을 대체 할 스크립트 호출) https://{{MY_TOKEN}}@github.com/user-or-org/repo. 환경 변수와 동일한 작업을 수행하기 위해 구성 파일 (.yml 또는 원하는 형식)을 사용할 수도 있습니다.
  • 해당 프로젝트에 대해서만 github 사용자 생성 및 액세스 토큰 생성

어떤 상황에 대해 이야기하고 Settings > Applications있습니까?
turboladen

1
이 접근법의 단점은 Dockerfile과 별도로 저장된 키를 참조 할 수있는 @crooksey의 접근법과 달리 Dockerfile 내에 개인 저장소의 자격 증명을 저장한다는 것입니다. OP가 Dockerfile을 저장하는 방법에 대한 컨텍스트가 없으면 문제가 발생할지 여부를 결정할 수 없지만 개인적인 경험을 통해 Dockerfile을 VCS에 저장하고 자격 증명이 포함 된 것을 커밋하고 싶지 않습니다. Docker가 env 변수를 전달하여 명령을 작성하는 기능을 구현하면 이것이 가장 깨끗한 솔루션이라는 데 동의합니다.
Jabbslad

2
@CalvinFroedge 로컬로 나는 당신이 당신의 호스트를 의미한다고 생각합니까? 빌드 타임에 호스트의 환경 변수를 컨테이너에 노출시키는 방법을 알지 못 하므로이 github.com/docker/docker/issues/6822 와 같은 열린 문제가 있습니다 . 명확히 할 수 있습니까?
Jabbslad

1
더 깨끗한 (관심있는 분리) : 복제 된 리포지토리의 연결된 볼륨 + 복제 작업 전용의 전용 컨테이너 + SSH 키 (또는 제안한대로 토큰 만)의 연결된 볼륨. stackoverflow.com/a/30992047을 참조하십시오 ( 아마도 stackoverflow.com/a/29981990) .
Peterino

9
또한 질문은 github 저장소가 아닌 BITBUCKET 저장소에 대한 것입니다.
Michael Draper

25

다른 옵션은 다단계 도커 빌드를 사용하여 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 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)

ARG SSH_PRIVATE_KEY는 ARG SSH_KEY로 교체해야합니다
조셉 페르시에게

git clone이 완료되면 키를 삭제할 수 없습니까?
Broncha

1
할 수는 있지만 RUN이전 이미지 레이어에 키를 두지 않도록 싱글의 일부로해야합니다 . 도커 현재 최종 이미지 레이어에서 SSH 키를 제거하는 실험적인 인수를 1.13사용할 수 있습니다 . --squash
jaker

19

비트 버킷 리포지토리의 경우 리포지토리 및 프로젝트에 대한 읽기 액세스 권한으로 앱 비밀번호 (Bitbucket 설정-> 액세스 관리-> 앱 비밀번호, 이미지 참조)를 생성하십시오.

비트 버킷 사용자 메뉴

그런 다음 사용해야하는 명령은 다음과 같습니다.

git clone https://username:generated_password@bitbucket.org/reponame/projectname.git

1
가장 간단한 :) SSH 기반 접근 방식을 선호하지만, 위와 같은 작업을 수행 할 수 없습니다 ... 파일을 찾을 수 없습니다.
Janos

"액세스 관리"가 보이지 않습니다. 구식이라고 생각하십니까?
Martin Thoma

1
일했다! 평범하고 단순합니다 ... 훌륭합니다!
Josemy

2
물론 ... 왼쪽 막대에서 프로필 사진을 클릭 한 다음 Bitbucket 설정 을 클릭하면 다음과 같이 표시됩니다. imgur.com/EI33zj3
Josemy

1
이것은 나를 위해 일했습니다. 그러나 하위 모듈이 있으며 --recursive작동하지 않았습니다. 나는 git clone각 서브 모듈 에 넣어야 했지만 괜찮지 만 재귀 적으로 작동한다면 좋을 것입니다.
Zailyn Tamayo

14

git clone도커 빌드 내에서 개인 리포지토리 를 수행하고 싶지 않은 경우가 종종 있습니다. 복제를 수행하면 이미지에 비공개 ssh 자격 증명을 배치하여 나중에 이미지에 액세스 할 수있는 사람이 추출 할 수 있습니다.

대신 일반적인 CI 도구는 선택한 CI 도구의 도커 외부에서 git repo를 복제하고 단순히 COPY파일을 이미지 에 복제하는 것 입니다. 도커 캐싱이라는 두 번째 이점이 있습니다. Docker 캐싱은 실행중인 명령, 포함 된 환경 변수, 입력 파일 등을보고 동일한 상위 단계의 이전 빌드와 동일한 경우 해당 이전 캐시를 재사용합니다. A의 git clone고정 표시기 외부 자식 REPO 변경 되더라도 캐시를 재사용 할 수 있도록 명령을 명령 자체는 동일하다. 그러나 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 build 명령에 변경 arg를 주입하십시오.

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

Docker 외부에서 git을 사용하는 것이 좋지만 ssh 키를 처리하는 방법을 설명합니다. 언제 필요 / 적절하다고 생각하십니까?
JCarlosR

2
빌드를 실행할 외부 시스템이없는 경우 @JCarlosR (예 : 복제본을 미리 실행할 수있는 CI / CD 시스템). 예외가있을 수 있지만 Dockerfile 내부의 복제본은 코드 냄새입니다.
BMitch

1

위의 솔루션은 비트 버킷에서 작동하지 않았습니다. 나는 이것이 트릭을 수행한다고 생각했다.

RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts \
    && eval `ssh-agent` \
    && ssh-add ~/.ssh/[key] \
    && git clone git@bitbucket.org:[team]/[repo].git
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.