web-dev-qa-db-fra.com

Cloner un dépôt git privé avec dockerfile

J'ai copié ce code à partir de ce qui semble être divers fichiers de docker fonctionnants, voici le mien:

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

Cela me donne l'erreur

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

C'est la première fois que j'utilise dockerfiles, mais d'après ce que j'ai lu (et tiré de configs), je ne vois pas pourquoi cela ne fonctionne pas.

Mon id_rsa est dans le même dossier que mon fichier docker et est une copie de ma clé locale qui peut cloner ce repo sans problème.

Modifier:

Dans mon fichier de docker, je peux ajouter:

RUN cat /root/.ssh/id_rsa

Et il imprime la clé correcte, donc je sais qu’elle est copiée correctement.

J'ai aussi essayé de faire comme noah a conseillé et a couru:

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

Malheureusement, cela ne fonctionne pas non plus.

216
crooksey

Ma clé était protégée par un mot de passe, ce qui posait problème, un fichier de travail est maintenant répertorié ci-dessous (pour l’aide des futurs utilisateurs).

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
277
crooksey

Vous devez créer un nouvel ensemble de clés SSH pour cette image Docker, car vous ne souhaitez probablement pas y intégrer votre propre clé privée. Pour que cela fonctionne, vous devez ajouter cette clé aux clés de déploiement de votre référentiel git. Voici la recette complète:

  1. Générez des clés ssh avec ssh-keygen -q -t rsa -N '' -f repo-key qui vous donnera les fichiers repo-key et repo-key.pub.

  2. Ajoutez repo-key.pub à vos clés de déploiement de référentiel.
    Sur GitHub, accédez à [votre référentiel] -> Paramètres -> Déployer les clés

  3. Ajoutez quelque chose comme ceci à votre Dockerfile:

     ADD repo-key /
    RUN\
     Chmod 600/repo-key &&\
     Echo "IdentityFile/repo-key" >>/etc/ssh/ssh_config &&\
     echo -e "StrictHostKeyChecking no" >>/etc/ssh/ssh_config &&\
     // vos commandes de clonage git ici ... 
    

Notez que ci-dessus désactive StrictHostKeyChecking, vous n'avez donc pas besoin de .ssh/known_hosts. Bien que j'aime probablement plus la solution avec ssh-keyscan dans l'une des réponses ci-dessus.

88
Marcin R

Il n'est pas nécessaire de bricoler avec les configurations ssh. Utilisez un fichier de configuration (pas un fichier Docker) contenant des variables d'environnement et demandez à un script Shell de mettre à jour votre fichier de docker au moment de l'exécution. Vous conservez les jetons hors de vos fichiers Dockerfiles et vous pouvez cloner via https (inutile de générer ou de transmettre des clés ssh).

Allez à Paramètres> Jetons d'accès personnel

  • Générez un jeton d'accès personnel avec repo scope activé.
  • Cloner comme ceci: git clone https://[email protected]/user-or-org/repo

Certains commentateurs ont noté que si vous utilisiez un fichier Docker partagé, cela pourrait exposer votre clé d'accès à d'autres personnes de votre projet. Bien que cela puisse être ou ne pas être une préoccupation pour votre cas d'utilisation spécifique, voici quelques façons de gérer cela:

  • Utilisez un script Shell pour accepter les arguments pouvant contenir votre clé en tant que variable. Remplacez une variable dans votre fichier Docker par sed ou similaire, c’est-à-dire en appelant le script avec sh rundocker.sh MYTOKEN=foo qui remplacerait on https://{{MY_TOKEN}}@github.com/user-or-org/repo. Notez que vous pouvez également utiliser un fichier de configuration (au format .yml ou au format souhaité) pour faire la même chose, mais avec des variables d’environnement.
  • Créer un utilisateur github (et générer un jeton d'accès pour) pour ce projet uniquement
62
Calvin Froedge

Une autre option consiste à utiliser un docker à plusieurs étapes pour vous assurer que vos clés SSH ne sont pas incluses dans l'image finale.

Comme décrit dans mon post , vous pouvez préparer votre image intermédiaire avec les dépendances requises pour git clone, puis COPY les fichiers requis dans votre image finale.

De plus, si nous LABEL nos couches intermédiaires, nous pouvons même les supprimer de la machine lorsque vous avez terminé.

# 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

Nous pouvons alors construire:

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

Prouvez que nos clés SSH sont parties:

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

Nettoyer les images intermédiaires de la machine de construction:

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

Pour le référentiel bitbucket, générez un mot de passe d'application (paramètres Bitbucket -> Gestion de l'accès -> Mot de passe d'application, voir l'image) avec un accès en lecture au référentiel et au projet.

bitbucket user menu

Ensuite, la commande à utiliser est la suivante:

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

Souvent, vous ne voulez pas exécuter un git clone d'un dépôt privé à partir de la construction du menu fixe. Faire le clone là-bas implique de placer les informations d'identification ssh privées dans l'image, où elles peuvent ensuite être extraites par quiconque ayant accès à votre image.

Au lieu de cela, la pratique courante consiste à cloner le référentiel git depuis l'extérieur du menu fixe dans l'outil de configuration de votre choix, et simplement COPY les fichiers dans l'image. Cela présente un deuxième avantage: la mise en cache du menu fixe. La mise en cache de Docker examine la commande en cours d'exécution, les variables d'environnement qu'elle inclut, les fichiers d'entrée, etc., et si elles sont identiques à une construction précédente de la même étape parente, elle réutilise ce cache précédent. Avec une commande git clone, la commande est identique, donc docker réutilisera le cache même si le référentiel git externe est modifié. Cependant, une commande COPY examinera les fichiers dans le contexte de construction et vérifiera s'ils sont identiques ou ont été mis à jour et n'utilisera le cache que s'il est approprié.


Si vous envisagez d'ajouter des informations d'identification à votre version, envisagez de le faire avec une version à plusieurs étapes et ne placez ces informations d'identification qu'à un stade précoce, qui ne soit jamais marqué ni poussé en dehors de votre hôte de génération. Le résultat ressemble à:

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

Plus récemment, BuildKit a testé certaines fonctionnalités expérimentales qui vous permettent de passer une clé ssh en tant que montage qui n'est jamais écrit dans l'image:

# 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

Et vous pouvez construire cela avec:

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

Notez que cela nécessite toujours que votre clé ssh ne soit pas protégée par mot de passe, mais vous pouvez au moins exécuter la construction en une seule étape, en supprimant une commande COPY et en évitant que les informations d'identification ssh fassent partie d'une image.


BuildKit a également ajouté une fonctionnalité réservée à ssh, qui vous permet de conserver vos clés ssh protégées par mot de passe. Le résultat est le suivant:

# 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

Et vous pouvez construire cela avec:

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

De nouveau, ceci est injecté dans la construction sans jamais être écrit sur une couche d'image, ce qui élimine le risque de fuite accidentelle des informations d'identification.


Pour forcer docker à exécuter le git clone même lorsque les lignes précédentes ont été mises en cache, vous pouvez injecter un ARG de construction qui change à chaque construction pour casser le cache. Cela ressemble à:

# 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

Ensuite, vous injectez cette modification d'argument dans la commande docker build:

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

Les solutions ci-dessus ne fonctionnaient pas pour bitbucket. Je pensais que cela faisait l'affaire:

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