- Git deploy: - Algemeen
Algemene Deploy Werkwijze (Push-to-Deploy via Bare Repo)
Deze methode gebruikt Git uitsluitend als transportmechanisme om een build/snapshot van een project naar de server te publiceren.
- De ontwikkelaar bouwt lokaal.
- Alleen de publiceerbare artefacten worden gepusht.
- De server ontvangt de push in een bare repository en rolt deze uit naar een doelmap.
- Er wordt geen broncode of buildtooling op de server gebruikt.
Overzicht Architectuur
Lokaal (developer machine)
~/develop/projekt # working directory (bron + buildscript)
~/develop/projekt-publish # alleen publiceerbare output (transport-repo)
Server
/srv/git/projekt.git # bare repo (ontvangt pushes)
/var/opt/projekt # live deployment directory
Aanrader: push niet direct naar
/var/opt/projektmet Git. Gebruik altijd een bare repo + hook. Dat voorkomt permissie- en consistentieproblemen.
1. Server Setup
Maak de bare repository
sudo mkdir -p /srv/git
cd /srv/git
sudo git init --bare projekt.git
Zet permissies (voorbeeld met deploy group)
sudo chown -R root:deploy /srv/git/projekt.git
sudo chmod -R g+rwX /srv/git/projekt.git
sudo find /srv/git/projekt.git -type d -exec chmod g+s {} \;
Doeldirectory voor deploy
sudo mkdir -p /var/opt/projekt
sudo chown -R root:deploy /var/opt/projekt
sudo chmod -R 2775 /var/opt/projekt
2. post-receive Hook (Server)
Bestand:
/srv/git/projekt.git/hooks/post-receive
Inhoud:
#!/bin/bash
set -euo pipefail
REPO="/srv/git/projekt.git"
TARGET="/var/opt/projekt"
umask 002
TMPDIR="$(mktemp -d)"
trap 'rm -rf "$TMPDIR"' EXIT
while read -r oldrev newrev refname; do
[[ "$refname" == "refs/heads/main" ]] || continue
git --git-dir="$REPO" archive "$newrev" | tar -x -C "$TMPDIR"
rsync -rl --delete --no-times --omit-dir-times \
"$TMPDIR"/ \
"$TARGET"/
done
Activeer:
chmod +x /srv/git/projekt.git/hooks/post-receive
3. Developer Machine Setup
VPN host alias
Voeg toe aan /etc/hosts:
10.8.0.1 vpn
Server is dan bereikbaar als:
ssh pi@vpn
4. Publish Directory Aanmaken
In de ontwikkelomgeving:
cd ~/develop
mkdir projekt-publish
cd projekt-publish
Initialiseer transport-repo:
git init
git switch -c main
git remote add stage ssh://pi@vpn:/srv/git/projekt.git
Deze repo bevat alleen deployment-bestanden.
5. Working Directory Script
In ~/develop/projekt/ komt een script dat bepaalt welke bestanden worden gedeployed.
Bijvoorbeeld: deploy.sh
#!/usr/bin/env bash
set -euo pipefail
SRC="$HOME/develop/projekt"
PUB="$HOME/develop/projekt-publish"
# Leeg publish directory (behalve .git)
find "$PUB" -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} +
# Kopieer alleen relevante artefacten
cp -r "$SRC/bin" "$PUB/"
cp -r "$SRC/config" "$PUB/"
cp "$SRC/README.md" "$PUB/"
cd "$PUB"
# Single snapshot commit (geen historie)
git checkout --orphan main 2>/dev/null || true
git reset --mixed
git add -A
git diff --cached --quiet && { echo "No changes."; exit 0; }
git commit -m "deploy $(date -u +%Y-%m-%dT%H:%M:%SZ)"
git push --force stage main
6. Deploy Uitvoeren
Vanuit de working directory:
cd ~/develop/projekt
./deploy.sh
Dit doet:
1. Selecteert relevante bestanden
2. Zet ze in projekt-publish
3. Maakt een snapshot commit
4. Force-pusht naar server
5. Server rolt automatisch uit via hook
Runtime Voorbeeld: Shiny App achter Nginx
In dit voorbeeld is projekt een Shiny applicatie die op de server wordt uitgevoerd vanuit:
/var/opt/projekt
De post-receive hook plaatst daar de laatste snapshot, waarna de runtime (bijv. R + Shiny Server of een systemd service) direct met deze bestanden werkt.
Nginx fungeert alleen als reverse proxy naar de draaiende app.
Typische rolverdeling:
Git push → /srv/git/projekt.git → export → /var/opt/projekt → Shiny runtime
↑
Nginx proxy
Waarom /var/opt?
/opt= software geleverd door derden/var/opt= variabele runtime-instanties van die software- Deployed apps gedragen zich als "site-specific data" van de runtime
Dit past goed bij services zoals:
- Shiny apps
- self-contained Python venv apps
- statische bundles achter een appserver
Nginx (conceptueel)
Nginx kent alleen het runtime-endpoint, niet Git:
location /projekt/ {
proxy_pass http://127.0.0.1:3838/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Nginx leest dus nooit uit de git repo of publish directory. Alle lifecycle gebeurt via de deploy hook.
Filosofie
Deze methode behandelt Git als:
betrouwbare transportlaag + deploy trigger
Niet als versiebeheer op de server.
Alle broncontrole blijft lokaal bij de ontwikkelaar.
Voordelen
- Geen buildtools nodig op server
- Reproduceerbare deployments
- Geen configuratiedrift
- Zeer eenvoudige rollback (force push nieuwe snapshot)
- Server blijft "dom" en stabiel
Wanneer deze methode gebruiken
Geschikt voor: - statische sites - Shiny deployments - self-contained binaries - config bundles - kleine services
Minder geschikt voor: - multi-node CI/CD pipelines - artefact registries - complexe release workflows