Özel git repo'yu dockerfile ile klonlayın


240

Bu kodu çeşitli çalışma dockerfiles gibi görünüyor ne kopyaladım, işte benim:

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

Bu bana hata veriyor

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

Bu benim ilk kez dockerfiles kullanarak, ama okudum (ve çalışma yapılandırmalarından alınan) bu neden işe yaramaz göremiyorum.

Benim id_rsa benim dockerfile ile aynı klasörde ve hiçbir sorun bu repo klonlayabilir benim yerel anahtar bir kopyasıdır.

Düzenle:

Dockerfile dosyama şunları ekleyebilirim:

RUN cat /root/.ssh/id_rsa

Ve doğru anahtarı yazdırıyor, bu yüzden doğru kopyalandığını biliyorum.

Ayrıca noah'ın tavsiye ettiği ve koştuğu gibi yapmaya çalıştım:

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

Bu ne yazık ki işe yaramıyor.

Yanıtlar:


300

Anahtarım soruna neden olan parola korumalı, aşağıda çalışan bir dosya listeleniyor (gelecekteki Google çalışanlarının yardımı için)

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
Her ihtimale karşı, burada anahtarın şifre korumasının nasıl kaldırılacağını açıklayan bir bağlantı var
Thomas

82
Sadece bir FYI, RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts'ı çalıştırdıktan sonra, Görüntü bunu bir katman olarak kaydedecektir. Herhangi bir kişi görüntünüzü ele geçirirse, anahtarı alabilir ... bu dosyayı daha sonraki bir katmanda silseniz bile, b / c eklediğinizde Adım 7'ye geri dönebilirler.
Bernie Perez

23
Yararlı cevap için teşekkürler. Ancak bizim için yapı rastgele başarısız oldu ve araştırmadan sonra ssh-keyscan, bitbucket'in genellikle aşıldığı varsayılan 5 saniye zaman aşımına sahip olduğunu fark ettik . ssh-keyscanbir hata bile bildirmez. RUN ssh-keyscan -T 60 bitbucket.org >> /root/.ssh/known_hostsGüvende olmak için daha iyi koş .
fluidsonic

5
Birisi koşmanın neden ssh-keyscanbir sorun olduğunu açıklayabilir mi? Anladığım kadarıyla, Github / Bitbucket'in ortak anahtarını çekecek. Bir katmanla sonuçlanmamak için hangi alternatif kullanılabilir?
Pedro

9
@Pedro Özellikle anahtar tarama adımı hiç sorun değil, açıkça haklısınız. Eğer bir şey varsa, bu ev sahibi ortak anahtarlar mümkün olduğunca yayılmalıdır. known_hostsDosyayla ilgili ayrıntılar için bkz. Sshd (8) . İnsanlar yeterince endişe verici olduklarında rastgele şeyleri onaylarlar.
tne

99

Muhtemelen orada kendi özel anahtarınızı gömmek istemediğiniz için, Docker görüntüsü için yeni SSH anahtar kümesi oluşturmanız gerekir. Çalıştırmak için bu anahtarı git deponuzdaki dağıtım anahtarlarına eklemeniz gerekir. İşte tam tarif:

  1. ssh-keygen -q -t rsa -N '' -f repo-keySize repo-key ve repo-key.pub dosyalarını verecek ssh anahtarları oluşturun .

  2. Havuz dağıtım anahtarlarınıza repo-key.pub dosyasını ekleyin.
    GitHub'da [deponuz] -> Ayarlar -> Anahtarları dağıt seçeneğine gidin

  3. Dockerfile'ınıza böyle bir şey ekleyin:

    Repo anahtarı EKLE /
    ÇALIŞTIRMAK \
      chmod 600 / repo-tuşu && \  
      echo "IdentityFile / repo-key" >> / etc / ssh / ssh_config && \  
      echo -e "StrictHostKeyChecking no" >> / etc / ssh / ssh_config && \  
      // buraya git klon komutlarınız ...
    

Yukarıdaki StrictHostKeyChecking'i kapattığından, .ssh / bilinen_hosts'a ihtiyacınız olmadığını unutmayın. Her ne kadar yukarıdaki cevaplardan birinde ssh-keyscan ile çözümü daha çok sevsem de.


6
Uyarı: benim yapılandırma üzerinde, echo -e "..." de dosyanın içine -e yazar. Sadece bayrağı kaldırın ve iyi çalışıyor.
Conchylicultor

Yanıtınız, sorunumu çözmeme yardımcı olmak için mükemmeldi. Teşekkür ederim!
David Pointer

Hala aynı sorunum var:fatal: Could not read from remote repository.
Alex

1
Milyonlarca teşekkürler! Sana sevgiyi ilan etme noktasındayım. Günlerdir savaştığım bir sorunu çözdün!
alexandra

Bu soru için seçilen cevap artık iyi bir cevap değil. 2014'te doğruydu ama 2020 için bu doğru cevap.
Bikal Basnet

70

Ssh konfigürasyonları ile uğraşmanıza gerek yok. Ortam değişkenlerini içeren bir yapılandırma dosyası (Dockerfile değil) kullanın ve çalışma zamanında docker dosyanızı güncelleyen bir kabuk komut dosyasına sahip olun. Jetonları Docker dosyalarınızdan uzak tutarsınız ve https üzerinden klonlayabilirsiniz (ssh anahtarları oluşturmanıza veya aktarmanıza gerek yoktur).

Gidin Ayarlar> Kişisel Erişim Jetonlar

  • repoKapsam etkinken kişisel erişim belirteci oluşturun .
  • Bunun gibi klonlayın: git clone https://MY_TOKEN@github.com/user-or-org/repo

Bazı yorumcular, paylaşılan bir Dockerfile kullanırsanız, erişim anahtarınızı projenizdeki diğer kişilere gösterebilir. Bu, özel kullanım durumunuzla ilgili bir endişe olsa da olmasa da, bununla başa çıkmanın bazı yolları şunlardır:

  • Anahtarınızı değişken olarak içerebilecek bağımsız değişkenleri kabul etmek için bir kabuk komut dosyası kullanın. Dockerfile dosyanızdaki bir değişkeni sedveya benzeriyle değiştirin, yani sh rundocker.sh MYTOKEN=foodeğiştirilecek komut dosyasını çağırarak https://{{MY_TOKEN}}@github.com/user-or-org/repo. Aynı şeyi ancak ortam değişkenleriyle yapmak için bir yapılandırma dosyası (.yml veya istediğiniz biçimde) kullanabileceğinizi unutmayın.
  • Yalnızca o proje için bir github kullanıcısı oluşturun (ve bunun için bir erişim belirteci oluşturun)

Ne bağlamından bahsediyorsun Settings > Applications?
turboladen

1
Bu yaklaşımın dezavantajı, Dockerfile'dan ayrı olarak depolanan bir anahtara başvurmanıza izin verecek olan @ crooksey yaklaşımının aksine Dockerfile içinde özel bir repo için kimlik bilgilerini saklamanızdır. OP'nin Dockerfile'ı nasıl sakladığı bağlamı olmadan bunun bir soruna neden olup olmayacağını belirleyemeyiz, ancak kişisel deneyimlerimden Dockerfillerimi bir VCS'de saklamak istiyorum ve kimlik bilgileri içeren hiçbir şey işlemek istemiyorum. Docker, komut oluşturmak için env değişkenlerini geçirme yeteneğini uyguladıktan sonra bunun en temiz çözüm olacağını kabul ediyorum.
Jabbslad

2
@CalvinFroedge tarafından yerel olarak Ben ev sahibi demek olduğunu varsayalım? Ana bilgisayardaki ortam değişkenlerini oluşturma sırasında bir kapsayıcıya maruz bırakmanın bir yolunun farkında değilim, bu yüzden bu github.com/docker/docker/issues/6822 gibi açık sorunlarımız var . Lütfen açıklığa kavuşturabilir misiniz?
Jabbslad

1
Daha da temiz (endişelerin ayrılması): klonlanmış repo için bağlantılı bir birim + sadece klonlama görevi için özel bir kapsayıcı + yalnızca SSH anahtarları (veya önerdiğiniz gibi jeton) ile bağlantılı bir birim. Bkz. Stackoverflow.com/a/30992047 , belki stackoverflow.com/a/29981990 ile birlikte kullanılabilir .
Peterino

9
Ayrıca soru, bir GITUB repo değil, bir BITBUCKET repo için.
Michael Draper

25

Başka bir seçenek de, SSH anahtarlarınızın son görüntüye dahil edilmediğinden emin olmak için çok aşamalı bir docker yapısı kullanmaktır.

Benim anlatıldığı gibi yazı daha sonra gerekli git klon için bağımlılıkları ve ile ara görüntüyü hazırlayabilirsiniz COPYson görüntü içine gerekli dosyaları.

Ayrıca LABELara katmanlarımız varsa, bittikten sonra bunları makineden silebiliriz.

# 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

Sonra inşa edebiliriz:

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

SSH anahtarlarımızın kaybolduğunu kanıtlayın:

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

Yapım makinesinden ara görüntüleri temizleyin:

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

ARG SSH_PRIVATE_KEY, ARG SSH_KEY ile değiştirilmelidir
Joseph Persie

Git klonu yapıldıktan sonra sadece tuşları silemeyiz mi?
Broncha

1
Yapabilirsiniz, ancak tek bir parçanın parçası olarak yapmanız gerekir, RUNböylece anahtarı önceki bir görüntü katmanında bırakmazsınız. Liman işçisi olarak son görüntü katmanlarınızdaki SSH anahtarını da kaldıracak deneysel argümanı 1.13kullanabilirsiniz . --squash
jaker

19

Bitbucket deposu için, repo ve projeye okuma erişimi olan Uygulama Parolası (Bitbucket ayarları -> Erişim Yönetimi -> Uygulama Parolası, resme bakın) oluşturun.

bitbucket kullanıcı menüsü

Sonra kullanmanız gereken komut:

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

1
En basit :) SSH tabanlı bir yaklaşımı tercih edeceğimi itiraf etmeliyim, ancak yukarıdaki çalışmalardan herhangi birini alamadım ... dosyalar bulunamadı, vb.
Janos

"Erişim Yönetimi" ni görmüyorum ... Sanırım güncel değil mi?
Martin Thoma

1
Yaradı! Sade ve basit ... Harika!
Josemy

2
Tabii ki ... Sadece sol çubuktaki profil resmine, ardından Bitbucket ayarlarına tıklamanız gerekiyor ve şöyle bir şey göreceksiniz: imgur.com/EI33zj3
Josemy

1
Bu benim için çalıştı. Ancak, alt modüllerim var ve --recursiveişe yaramadı. git cloneHer alt modül için koymak zorunda kaldım , ki bu iyi ama özyinelemeli olsaydı harika olurdu.
Zailyn Tamayo

14

Sık sık bir git clone , docker yapısından özel bir repo . Orada klon yapmak, özel ssh kimlik bilgilerini daha sonra görüntünüze erişimi olan herkes tarafından çıkarılabilecekleri görüntünün içine yerleştirmeyi içerir.

Bunun yerine, yaygın uygulama, git repo'yu seçtiğiniz CI aracınızda docker'ın dışından ve sadece COPYdosyaları görüntüye klonlamaktır . Bunun ikinci bir yararı var: liman işçisinin önbelleğe alınması. Docker önbelleğe alma işlemi, çalıştırılan komutu, içerdiği ortam değişkenlerini, girdi dosyalarını vb. İnceler ve aynı üst adımdaki önceki bir derleme ile aynıysa, önceki önbelleği yeniden kullanır. Bir git clonekomutla komutun kendisi aynıdır, bu nedenle harici git repo değiştirilse bile docker önbelleği yeniden kullanır. Ancak, bir COPYkomut derleme bağlamındaki dosyalara bakacak ve aynı veya güncellenmiş olup olmadığını görebilir ve önbelleği yalnızca uygun olduğunda kullanabilir.


Yapınıza kimlik bilgileri ekleyecekseniz, bunu çok aşamalı bir yapı ile yapmayı ve bu kimlik bilgilerini yalnızca hiçbir zaman etiketlenmemiş ve yapı ana makinenizin dışına aktarılmamış olan erken bir aşamaya yerleştirmeyi düşünün. Sonuç şuna benzer:

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
...

Son zamanlarda, BuildKit bir ssh anahtarını görüntüye asla yazılmayan bir montaj parçası olarak geçirmenize izin veren bazı deneysel özellikleri test ediyor:

# 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

Ve bunu aşağıdakilerle oluşturabilirsiniz:

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

Bunun yine de ssh anahtarınızın parola korumalı olmamasını gerektirdiğini, ancak en azından bir COPY komutunu kaldırarak ve ssh kimlik bilgisinin görüntünün bir parçası olmasını önleyerek derlemeyi tek bir aşamada çalıştırabileceğinizi unutmayın.


BuildKit ayrıca ssh için sadece şifre korumalı ssh tuşlarına sahip olmanıza izin veren bir özellik ekledi, sonuç şöyle görünüyor:

# 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

Ve bunu aşağıdakilerle oluşturabilirsiniz:

$ 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 .

Yine, bu, bir görüntü katmanına yazılmadan yapıya enjekte edilir ve kimlik bilgisinin yanlışlıkla dışarı sızma riski ortadan kaldırılır.


Docker'ı git clonedaha önceki satırlar önbelleğe alındığında bile çalıştırmaya zorlamak için, önbelleği kırmak üzere her derlemede değişen bir yapı ARG'si enjekte edebilirsiniz. Şöyle görünüyor:

# 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

Sonra docker build komutunda bu değişen argümanı enjekte edersiniz:

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

Git'i Docker'ın dışından kullanmanızı öneririz, ancak yine de ssh tuşlarıyla nasıl başa çıkılacağını açıklarsınız. Bunu ne zaman gerekli / uygun buluyorsunuz?
JCarlosR

2
@JCarlosR, yapının çalıştırılacağı harici bir sisteminiz yoksa (örn. Önceden klonu çalıştırabilen bir CI / CD sistemi). İstisnalar olabilir, ancak Dockerfile içindeki bir klon bir kod kokusudur.
BMitch

1

Yukarıdaki çözümler bitbucket için işe yaramadı. Bunun hile yaptığını düşündüm:

RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts \
    && eval `ssh-agent` \
    && ssh-add ~/.ssh/[key] \
    && git clone git@bitbucket.org:[team]/[repo].git
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.