foxygit / foxygit Log in
A tiny read-only git web frontend — browse bare repos with just PHP and git, no database, no framework.
commits tags

/deploy.sh · 4.22 KB

raw
#!/usr/bin/env bash
# One-time deploy of foxygit, replacing stagit on git.kristoffersson.info.
#
# Run as root from anywhere:
#   sudo bash /home/mrfox/foxygit/deploy.sh
#
# What it does:
#   1. Copies index.php, inc/, views/, assets/ and themes/ to /var/www/foxygit/
#   2. Installs a dedicated php-fpm pool running as the `git` user (the bare
#      repos at /var/git/repos are 0700 git:git — the default www-data pool
#      can't read them, so this needs its own pool rather than loosening
#      those permissions).
#   3. Swaps the git.kristoffersson.info block in /etc/caddy/Caddyfile from
#      static-file-serving (stagit's output) to php_fastcgi against the new
#      pool. A timestamped backup of the Caddyfile is kept.
#   4. Reloads php-fpm and Caddy.
#
# Does NOT touch /var/git/repos, does NOT delete stagit or its generated
# HTML in /var/www/git, and does NOT touch the post-receive hooks that
# regenerate it — so stagit's output is simply orphaned (Caddy stops
# serving it) rather than destroyed. See the printed notes at the end for
# how to retire it once you're happy with foxygit.

set -euo pipefail

if [ "$(id -u)" -ne 0 ]; then
    echo "run as root: sudo bash $0" >&2
    exit 1
fi

SRC_DIR="/home/mrfox/foxygit"
WEB_ROOT="/var/www/foxygit"
POOL_FILE="/etc/php/8.4/fpm/pool.d/foxygit.conf"
SOCK="/run/php/foxygit.sock"
CADDYFILE="/etc/caddy/Caddyfile"

echo "==> 1/5  web root: $WEB_ROOT"
mkdir -p "$WEB_ROOT"
install -m 0644 -o root -g root "$SRC_DIR/index.php" "$WEB_ROOT/index.php"
# wipe+recopy so files removed from the source don't linger on the server
for d in inc views assets themes; do
    rm -rf "${WEB_ROOT:?}/$d"
    cp -r "$SRC_DIR/$d" "$WEB_ROOT/$d"
done
chown -R root:root "$WEB_ROOT"
find "$WEB_ROOT" -type d -exec chmod 0755 {} +
find "$WEB_ROOT" -type f -exec chmod 0644 {} +

echo "==> 2/5  php-fpm pool: $POOL_FILE"
cat > "$POOL_FILE" <<EOF
[foxygit]
user = git
group = git
listen = $SOCK
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = ondemand
pm.max_children = 4
pm.process_idle_timeout = 10s
EOF

echo "==> 3/5  testing php-fpm config"
php-fpm8.4 -t

echo "==> reloading php8.4-fpm"
systemctl reload php8.4-fpm

if [ ! -S "$SOCK" ]; then
    echo "WARNING: $SOCK did not appear after reload, restarting php8.4-fpm instead" >&2
    systemctl restart php8.4-fpm
fi

echo "==> 4/5  updating Caddyfile ($CADDYFILE)"

python3 - "$CADDYFILE" <<'PYEOF'
import sys

path = sys.argv[1]
with open(path, "r", encoding="utf-8") as f:
    content = f.read()

old_block = '''git.kristoffersson.info {
\troot * /var/www/git/
\tfile_server
\tencode gzip zstd

\theader {
\t\tStrict-Transport-Security "max-age=31536000; includeSubDomains"
\t\tX-Content-Type-Options "nosniff"
\t\tX-Frame-Options "DENY"
\t\t-Server
\t}

\tlog {
\t\toutput file /var/log/caddy/git.kristoffersson.info.log
\t}
}'''

new_block = '''git.kristoffersson.info {
\troot * /var/www/foxygit/
\tphp_fastcgi unix//run/php/foxygit.sock
\tfile_server
\tencode gzip zstd

\theader {
\t\tStrict-Transport-Security "max-age=31536000; includeSubDomains"
\t\tX-Content-Type-Options "nosniff"
\t\tX-Frame-Options "DENY"
\t\t-Server
\t}

\tlog {
\t\toutput file /var/log/caddy/git.kristoffersson.info.log
\t}
}'''

if new_block in content:
    print("    already up to date, nothing to change")
    sys.exit(0)

if old_block not in content:
    print("ERROR: expected git.kristoffersson.info block not found verbatim in "
          + path + " -- Caddyfile has changed since this script was written, "
          + "edit it by hand instead. No changes made.", file=sys.stderr)
    sys.exit(1)

import subprocess, datetime
backup = path + ".bak." + datetime.datetime.now().strftime("%Y%m%d%H%M%S")
subprocess.run(["cp", path, backup], check=True)
print("    backup saved to " + backup)

content = content.replace(old_block, new_block, 1)
with open(path, "w", encoding="utf-8") as f:
    f.write(content)
print("    block replaced")
PYEOF

echo "==> validating Caddy config"
caddy validate --config "$CADDYFILE"

echo "==> 5/5  reloading caddy"
systemctl reload caddy

cat <<'EOF'

Done. https://git.kristoffersson.info should now be served by foxygit.

If stagit is still installed, it's just orphaned now (Caddy no longer
serves /var/www/git) -- see retire-stagit.sh to remove it fully.
EOF