linux/doc/Push-to-Deploy.md

100 lines
3.0 KiB
Markdown
Raw Permalink Normal View History

2015-10-25 23:57:06 +01:00
# Introduction
This document describes how to setup a Git hook
to enable the update of a repository when a new commit is received.
This effectively is an implementation of a **Push-to-Deploy**
update/continuous integration strategy.
For the described approach to work, the Git server and the deployment target
must be running on the same machine.
However, the files do not need to be accessible by both Git and the application server.
That is why a safe indirection over root is necessary.
The deployment tree is a working directory of the Git repository.
This has the advantage that no files accidentally get overwritten by Git.
For example, for projects using PHP, this might be important.
Although the increased amount of storage space is a tradeoff,
it can be optimized by reducing the history depth of the repository
from time to time.
A brief hint hereof can be found at the end of this document.
The main work of the implementation is done by a universal script.
Actually, it could be used in any situation where a safe update
of a repository is needed.
# Files
The following files are used to describe the implementation:
* `/path/to/main.git`
The main bare repository receiving the updates.
* `/path/to/deploy-target`
The deployment target directory.
It is a working directory of a git repository.
* `/path/to/safe-update`
The safe update script which is listed below.
## Universal Safe Update
2015-12-14 03:13:59 +01:00
Copy the file [git-safe-update.sh](../scripts/git-safe-update.sh) and make it executable.
2015-10-26 15:43:01 +01:00
It can be used to update any repository. It takes two arguments:
2015-10-25 23:57:06 +01:00
1. Path of a non-bare Git repository
2. Intended owner of the files
The `chown` line at the end of the script is the reason
why the script needs to be run as root.
The chapter below describes how to configure `sudo` to enable root access.
Note that the user always knows what is going on in case of a failure.
## Git Hook
Install the following script as the `post-receive` hook.
2015-10-26 15:43:01 +01:00
In this case to `/path/to/main.git/hooks/post-receive`.
2015-10-25 23:57:06 +01:00
It executes `safe-update` only when the master branch is updated.
```sh
#!/bin/sh
read oldid newid ref
if [ "$ref" = "refs/heads/master" ]; then
2015-12-14 03:13:59 +01:00
sudo /path/to/safe-update /path/to/deploy-target www-data.www-data
2015-10-25 23:57:06 +01:00
fi
```
## Deployment Target Git Configuration
Because the Git repository lies on the same machine,
and is owned by a different user, it is safer to use
a `file:` URL as the remote.
The *master* branch is assumed to be a deployable version.
Hence, use the following command to add the remote:
2015-12-14 03:13:59 +01:00
cd /path/to/deploy-target
git init
2015-10-25 23:57:06 +01:00
git remote add -t master origin file:///path/to/main.git
2015-12-14 03:13:59 +01:00
git fetch --depth=1
git checkout master
2015-10-25 23:57:06 +01:00
## Sudo Configuration
Paste the following line to `/etc/sudoers.d/safe-update`
or append it to `/etc/sudoers`:
git ALL=(root) NOPASSWD: /path/to/safe-update
This enables user `git` to run `safe-update` as `root` without password.
So be careful..!
# Miscellaneous
To "forget" old git history, I had success with the following commands:
rm -r .git/objects
mkdir .git/objects
git fetch --depth=1