417 votes

Déployer un projet en utilisant Git push

Est-il possible de déployer un site web en utilisant git push ? J'ai l'intuition que cela a quelque chose à voir avec le fait d'utiliser crochets git pour effectuer un git reset --hard du côté du serveur, mais comment dois-je m'y prendre pour y parvenir ?

3 votes

Je suppose que cela ne s'applique que dans les situations où il n'y a qu'un seul serveur de production, n'est-ce pas ?

6 votes

@Rijk Eh bien, vous pouvez pousser sur plusieurs serveurs simultanément avec Git, mais une fois que vous atteignez ce niveau, vous pourriez vouloir une solution réelle, pas un hack comme celui-ci.

0 votes

J'ai réussi à utiliser capistrano avec mes projets, qui bien qu'ayant été conçu à l'origine pour le déploiement d'applications Ruby on Rails, fonctionne bien avec PHP et d'autres projets.

290voto

Kyle Cronin Points 35834

J'ai trouvé ce script sur ce site et cela semble fonctionner assez bien.

  1. Copiez votre répertoire .git sur votre serveur web.

  2. Sur votre copie locale, modifiez votre fichier .git/config et ajoutez votre serveur web comme distant :

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
  3. Sur le serveur, remplacez .git/hooks/post-update par ce fichier (dans la réponse ci-dessous)

  4. Ajoutez l'accès d'exécution au fichier (encore une fois, sur le serveur) :

    chmod +x .git/hooks/post-update
  5. Maintenant, il suffit de pousser localement vers votre serveur web et il devrait automatiquement mettre à jour la copie de travail :

    git push production

129 votes

Assurez-vous que vous avez une politique .htaccess qui protège le répertoire .git contre la lecture. Quelqu'un qui a envie de plonger dans les URL pourrait s'en donner à cœur joie avec l'ensemble du code source s'il est accessible.

39 votes

Sinon, il suffit de faire du répertoire public un sous-répertoire du dépôt git. Vous pouvez alors avoir des fichiers privés dont vous pouvez être sûr qu'ils ne seront pas rendus publics.

0 votes

Je ne suis pas sûr d'avoir bien compris. Où dois-je créer mon premier repo git, sur le serveur web de production ou sur le serveur web de test ?

83voto

Utilisation de la post-mise à jour ci-dessous :

  1. Copiez votre répertoire .git sur votre serveur web.

  2. Sur votre copie locale, modifiez votre fichier .git/config et ajoutez votre serveur web comme distant :

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
  3. Sur le serveur, remplacez .git/hooks/post-update par le fichier suivant

  4. Ajoutez l'accès d'exécution au fichier (encore une fois, sur le serveur) :

    chmod +x .git/hooks/post-update
  5. Maintenant, il suffit de pousser localement vers votre serveur web et il devrait automatiquement mettre à jour la copie de travail :

    git push production

    !/bin/sh

    #

    This hook does two things:

    #

    1. update the "info" files that allow the list of references to be

    queries over dumb transports such as http

    #

    2. if this repository looks like it is a non-bare repository, and

    the checked-out branch is pushed to, then update the working copy.

    This makes "push" function somewhat similarly to darcs and bzr.

    #

    To enable this hook, make this file executable by "chmod +x post-update".

    git-update-server-info is_bare=$(git-config --get --bool core.bare) if [ -z "$is_bare" ] then

    for compatibility's sake, guess

      git_dir_full=$(cd $GIT_DIR; pwd)
      case $git_dir_full in */.git) is_bare=false;; *) is_bare=true;; esac

    fi update_wc() { ref=$1 echo "Push to checked out branch $ref" >&2 if [ ! -f $GIT_DIR/logs/HEAD ] then echo "E:push to non-bare repository requires a HEAD reflog" >&2 exit 1 fi if (cd $GIT_WORK_TREE; git-diff-files -q --exit-code >/dev/null) then wc_dirty=0 else echo "W:unstaged changes found in working copy" >&2 wc_dirty=1 desc="working copy" fi if git diff-index --cached HEAD@{1} >/dev/null then index_dirty=0 else echo "W:uncommitted, staged changes found" >&2 index_dirty=1 if [ -n "$desc" ] then desc="$desc and index" else desc="index" fi fi if [ "$wc_dirty" -ne 0 -o "$index_dirty" -ne 0 ] then new=$(git rev-parse HEAD) echo "W:stashing dirty $desc - see git-stash(1)" >&2 ( trap 'echo trapped $$; git symbolic-ref HEAD "'"$ref"'"' 2 3 13 15 ERR EXIT git-update-ref --no-deref HEAD HEAD@{1} cd $GIT_WORK_TREE git stash save "dirty $desc before update to $new"; git-symbolic-ref HEAD "$ref" ) fi

    eye candy - show the WC updates :)

      echo "Updating working copy" >&2
      (cd $GIT_WORK_TREE
      git-diff-index -R --name-status HEAD >&2
      git-reset --hard HEAD)

    } if [ "$is_bare" = "false" ] then active_branch=git-symbolic-ref HEAD export GIT_DIR=$(cd $GIT_DIR; pwd) GIT_WORK_TREE=${GIT_WORK_TREE-..} for ref do if [ "$ref" = "$active_branch" ] then update_wc $ref fi done fi

5 votes

Bon sang...il suffit d'écrire ce script sur un langage que vous utilisez pour le développement que ce soit php, python, groovy ou autre ! Je n'ai jamais compris cet amour pour les scripts shell qui ont (subjectivement) une syntaxe assez bizarre et si peu de fonctionnalités.

6 votes

@dVaffection de toute façon vous allez écrire des commandes shell si vous utilisez git. donc au lieu d'écrire un script dans un autre langage et de jongler constamment entre ce langage et le shell. écrire tout ça dans le shell semble logique non ?

0 votes

J'ai dû exécuter 'git config receive.denyCurrentBranch updateInstead' sur le serveur également, pour qu'il accepte le push. Je pense que c'est parce que la branche a été extraite ?

61voto

Earl Points 838

Après de nombreux faux départs et impasses, je suis enfin capable de déployer le code d'un site web avec simplement "git push". à distance " grâce à cet article .

Le script post-mise à jour de l'auteur ne fait qu'une ligne et sa solution ne nécessite pas de configuration .htaccess pour cacher le repo Git comme le font certains autres.

Il y a quelques pierres d'achoppement si vous déployez ce système sur une instance Amazon EC2 ;

1) Si vous utilisez sudo pour créer le dépôt de destination nu, vous devez changer le propriétaire du dépôt en ec2-user ou le push échouera. (Essayez "chown ec2-user:ec2-user repo .")

2) Le push échouera si vous ne configurez pas au préalable l'emplacement de votre amazon-private-key .pem, soit dans /etc/ssh/ssh_config en tant que paramètre IdentityFile, soit dans ~/.ssh/config en utilisant la disposition "[Host] - HostName - IdentityFile - User" décrite ici ...

...MAIS si Host est configuré dans ~/.ssh/config et différent de HostName, le push Git échouera. (C'est probablement un bug de Git)

0 votes

J'ai suivi les étapes de l'article que vous avez mentionné, et tout a fonctionné comme sur des roulettes. Je me demande seulement s'il y a des inconvénients concernant la sécurité ou la stabilité. Un conseil à ce sujet ?

0 votes

Xl-t : En supposant que vous utilisez Git via SSH, je dirais que le danger réside dans le fait de faire une erreur avec Git. Vous pourriez demander à l'auteur de l'article ; il le termine par "Les questions et les suggestions sont les bienvenues". Ma stratégie de réplication actuelle (sans cerveau) consiste à utiliser Transmit de Panic Software.

1 votes

L'article en lien présente une exigence importante lorsque vous utilisez des crochets. Les hooks échoueront si .git se trouve dans le même schéma de nommage que le répertoire de travail, c'est-à-dire /foo/bar (répertoire de travail) et /foo/bar.git (dépôt git de barebone). Donc assurez-vous de renommer /foo/bar en quelque chose d'autre, comme /foo/bar.live ou /foo/blah. Au cas où vous vous poseriez la question, le message d'erreur exact que vous recevriez si votre répertoire de travail avait le même nom que le dépôt barebone est "remote : fatal : Could not jump back into original cwd : No such file or directory"

21voto

Christian Points 1422

N'installez pas git sur un serveur et n'y copiez pas le dossier .git. Pour mettre à jour un serveur à partir d'un clone git, vous pouvez utiliser la commande suivante :

git ls-files -z | rsync --files-from - --copy-links -av0 . user@server.com:/var/www/project

vous devrez peut-être supprimer des fichiers qui ont été retirés du projet.

Ceci copie tous les fichiers archivés. rsync utilise ssh qui est installé sur un serveur de toute façon.

moins vous avez de logiciels installés sur un serveur, plus il est sécurisé et plus il est facile de gérer sa configuration et de la documenter. il n'est pas non plus nécessaire de conserver un clone git complet sur le serveur. cela ne fait que rendre plus complexe le fait de tout sécuriser correctement.

3 votes

Une mise en garde : il rsync les fichiers que vous avez dans votre répertoire de travail. Je pense que cela peut être évité en utilisant un script qui met en cache les changements actuels, nettoie tout, déploie et ensuite renverse la cache.

0 votes

Les serveurs sont des hommes ?

12voto

Lloyd Moore Points 1220

Pour l'essentiel, tout ce que vous devez faire est le suivant :

server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"

J'ai ces lignes dans mon application comme un exécutable appelé deploy .

donc quand je veux faire un déploiement, je tape ./deploy myserver mybranch .

0 votes

Voir ma réponse comment résoudre le problème si vous avez besoin d'une clé privée ou d'un nom d'utilisateur différent pour ssh.

0 votes

Cette solution est plus rapide que la mienne lors du déploiement sur plusieurs serveurs ! Il suffit de pousser vers le dépôt principal et de tirer en parallèle à partir de celui-ci. Et si vous ne voulez pas ou ne pouvez pas déployer vos clés sur chaque instance, utilisez l'agent de clés ! ssh -A ...

1 votes

Ce serait plus facile si vous incluiez un guide sur la configuration des clés SSH, sur lesquelles cette réponse repose pour fonctionner de manière "transparente".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X