Chez ouam

/home/jmfrouin

View on GitHub
8 July 2013

Déploiement d'application django (1.6.5) en Production avec git

by Jean-Michel Frouin

Historique

16/05/2014 : Changement de 'cleanup' to 'clearsessions', car :

The `cleanup` command has been deprecated in favor of `clearsessions`.

Assumptions

Partons du principe que l'on déploie, en production, dans /var/www/mon_app
Que la gestion des dépôts git à été faite sous gitolite.
L'user de déploiement est publisher.
Enfin dans git, on à deux branches (entre autre), une dans laquelle, master, on verse les modifications à mettre en production, et une production, qui contient les commits avec la configuration de production, que l'on rebase sur master avant de la pousser.

Préparation / Mise en place

On créé initialise donc le dépôt git :

git init

Depuis le poste du déployeur, on ajoute une branche production.

git branch production

On y fait les modifications pour la production (settings.py entre autre) et on commit.
Ensuite quand des modifications seront faite sur le master, il suffira de ce remettre à jour :

git rebase master

Une fois cela fait il faut, initialiser la copie en production.
Pour pouvoir déployer il faut avant tout ajouter la cible de déploiement pour la mise en prod :

git remote add prod publisher@srv1.domain.tld:/var/www/mon_app

Ne pas oublier de ce mettre sur la branche production en ... production.

git checkout production

Pour que le commit puisse fonctionner il faut définir :

git config receive.denyCurrentBranch ignore

Puis dans un second temps, mettre en place un hook git pour initialiser l'application django.
On utilise le hook post-update c'est à dire, une fois que le dépôt à reçu la mise à jour du code.

  #!/bin/sh
#
# This hook does three 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.
#
#  3. clear the django cache, clear session and collect static assets (without use interactions)
#
# To enable this hook, make this file executable by "chmod +x post-update".

PYTHON="python"
MANAGE="$PYTHON manage.py"

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)

	# Clear the django cache
	echo "Clearing the django cache" >&2
	(cd $GIT_WORK_TREE
	$MANAGE clearsessions)

	# Clear the django sessions
	echo "Clearing the django sessions" >&2
	(cd $GIT_WORK_TREE
	$MANAGE clearsessions)

    	# Collect static assets
	echo "Collect static assets" >&2
	(cd $GIT_WORK_TREE
	$MANAGE collectstatic --noinput)
}

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

Références : GitFaq non-bar repo et post-update

tags: