Welcome to another playground: “Gitolite + Docker”
Lately, we started a new series of blog posts accompanied by ready-to-use Git repositories:
In this post, we present how to run Docker commands from a server-side Git hook.
The git backend itself is a Docker image based on jgiannuzzi/gitolite with a Docker client installed.
FROM jgiannuzzi/gitolite
RUN apk add --no-cache docker
RUN addgroup git docker
…
Prepare the environment - Gitolite
Prepare and build the Gitolite image with an embedded Docker..../build.sh
.
In essence, the script contains the steps described in the cookbook mentioned below…
gitolite cookbook - (a.k.a. "stop all that rambling and just tell me what I need to do!")
Generate a gitolite-admin
key:
ssh-keygen -t rsa -b 4096 -f credentials/gitolite-admin_id_rsa -N "" -C "gitolite-admin@sandbox"
…setup Gitolite
docker run --rm \
-e SSH_KEY="$(cat credentials/gitolite-admin_id_rsa.pub)" \
-e SSH_KEY_NAME="admin" \
-v $(pwd)/docker/gitolite/keys:/etc/ssh/keys \
-v $(pwd)/docker/gitolite/git:/var/lib/git \
jgiannuzzi/gitolite true
…fire up the sandbox with up.sh
.
Verify the Gitolite set up with a simple ssh
command like follows:
$ ssh -T -p 2222 -i credentials/gitolite-admin_id_rsa git@localhost
…
hello admin, this is git@8b85d586c069 running gitolite3 3.6.11 on git 2.22.0
R W gitolite-admin
R W testing
Congratulations! Your basic Gitolite set up is alive and kicking!
Double-check the Docker environment via
$ docker exec -it gitolite-playground_git-sandbox_1 docker ps --format "{{.Names}}"
gitolite-playground_git-sandbox_1
🎉 - Gitolite + Docker is up and running…
Enable server-side hooks
Edit docker/gitolite/git/.gitolite.rc
and uncomment the line containing LOCAL_CODE
as shown below:
LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local",
Check the configuration with
$ docker exec -it --user git --workdir /var/lib/git gitolite-playground_git-sandbox_1 gitolite query-rc LOCAL_CODE
/var/lib/git/.gitolite/local
Install the prepared server-side post-receive
hook
Clone the gitolite-admin
repo into the prepared workspace
.
git clone --config core.sshCommand="ssh -i credentials/gitolite-admin_id_rsa -p 2222" git@localhost:gitolite-admin workspace/gitolite-admin
Add the prepared hook:
cd workspace/gitolite-admin
mkdir -p local/hooks/common
cp ../../hooks/post-receive.sample local/hooks/common/post-receive
git add local
git commit -m "Add post-receive hook"
Note: You might need to update
.git/config
if you want to run thepush
command from within the repository itself.
[core]
...
sshcommand = ssh -i ../../credentials/gitolite-admin_id_rsa -p 2222
...
Use git push
to update gitolite.
Git hook in Action
Generate a new user key and add it to the gitolite configuration:
Note: This step is optional - for testing purposes, you could reuse the admin user.
Switch back into the main repository:
ssh-keygen -t rsa -b 4096 -f credentials/gitolite-user_id_rsa -N "" -C "gitolite-user@sandbox"
cp credentials/gitolite-user_id_rsa.pub workspace/gitolite-admin/keydir/user.pub
Again add and commit the changes plus git push
to update gitolite.
Check the setup with the freshly created user:
ssh -T -p 2222 -i credentials/gitolite-user_id_rsa git@localhost
Finally…
$ git clone --config core.sshCommand="ssh -i credentials/gitolite-user_id_rsa -p 2222" git@localhost:testing workspace/testing
Do some changes, add, commit and push
[main 8cbdc79] initial commit
1 file changed, 1 insertion(+)
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 16 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 319 bytes | 319.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Running 'post-receive' hook...
To localhost:testing
324be7d..8cbdc79 main -> main
Did you spot the remote:
tagged line?
The server-side hook was triggered. Yay! 🏆
Hey Olli, many thanks! For carfully testing the setup.
Bonus - Do it yourself
In case you got hooked 🧐 - check out the playground availble on Github datenkollektiv/gitolite-playground and roll up your sleeves.
Bonus - Create a Working Copy
To create a working copy (inside the commit hook script) we create a temporary clone inside /workspace
:
HEAD_REF=$(git --git-dir=${GL_REPO_BASE}/${GL_REPO}.git rev-parse --verify HEAD)
sudo mkdir /workspace/${HEAD_REF}
sudo chown git:git /workspace/${HEAD_REF}
git clone ${GL_REPO_BASE}/${GL_REPO}.git /workspace/${HEAD_REF}
Random Resources
In case you ask yourself How to retrieve the hash for the current commit in Git? - git-rev-parse
- Pick out and massage parameters is the answer.
Photo by Immo Wegmann on Unsplash