mirror of
https://github.com/aarmea/fahrengit-451.git
synced 2026-03-22 00:54:19 +00:00
Change written by Claude Sonnet 4.6: I need to set up a Git hosting service for personal projects where certain repositories need to be blocked using the locale corresponding to the user’s IP address. Here are my constraints: * The entire system will be running on a single VPS instance. I should be able to `docker compose up -d` the whole thing. * For each repository that this feature is enabled, I need to be able to set the blocked locales down to the state level, along with a custom HTTP status code and response body. * You may assume that the IP address of the request is where it actually came from — for this exercise, if the user uses a VPN to bypass the restriction, that is on them. * To simplify a reverse proxy setup, you may assume that all Git operations will happen over HTTPS. I will firewall off SSH access. * I will be using Let's Encrypt for HTTPS. Some suggestions from prior research: * nginx seems like a reasonable reverse proxy that supports all of the requirements, but you may use a different one if it is simpler to implement or maintain. * I can obtain a MaxMind API key to get a geo-IP lookup table. If you use this, you will need to add a service that automatically retrieves the table at a reasonable frequency. * Forgejo seems like a reasonable, lightweight Git service, but you may use a different one if you’re aware of one that actually supports these requirements out of the box. Write me a production-ready `docker-compose.yml` and supporting scripts or configuration scaffolding for me to implement this.
91 lines
4.2 KiB
Bash
91 lines
4.2 KiB
Bash
#!/usr/bin/env bash
|
|
# bootstrap_certs.sh
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Run this ONCE before `docker compose up -d` to obtain the initial Let's
|
|
# Encrypt certificate. nginx must be able to serve the ACME challenge, so we
|
|
# bring up only the services needed for that, run certbot, then download the
|
|
# Certbot recommended TLS options, and finally start everything.
|
|
#
|
|
# Prerequisites:
|
|
# • docker compose v2 installed
|
|
# • DNS for $DOMAIN already pointing to this server's IP
|
|
# • Ports 80 and 443 open in your firewall
|
|
# • .env file present (copy from .env.example and fill in)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
set -euo pipefail
|
|
|
|
if [[ ! -f .env ]]; then
|
|
echo "ERROR: .env file not found. Copy .env.example → .env and fill in your values."
|
|
exit 1
|
|
fi
|
|
|
|
# shellcheck disable=SC1091
|
|
source .env
|
|
|
|
DOMAIN="${DOMAIN:?DOMAIN must be set in .env}"
|
|
EMAIL="${LETSENCRYPT_EMAIL:?LETSENCRYPT_EMAIL must be set in .env}"
|
|
CERTS_DIR="./certs"
|
|
|
|
echo "==> Creating certificate directory structure..."
|
|
mkdir -p "${CERTS_DIR}/live/${DOMAIN}"
|
|
mkdir -p "${CERTS_DIR}/archive"
|
|
|
|
# ── Download Certbot recommended TLS options ──────────────────────────────────
|
|
if [[ ! -f "${CERTS_DIR}/options-ssl-nginx.conf" ]]; then
|
|
echo "==> Downloading recommended TLS options..."
|
|
curl -sSL \
|
|
"https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf" \
|
|
-o "${CERTS_DIR}/options-ssl-nginx.conf"
|
|
fi
|
|
|
|
if [[ ! -f "${CERTS_DIR}/ssl-dhparams.pem" ]]; then
|
|
echo "==> Downloading DH parameters..."
|
|
curl -sSL \
|
|
"https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem" \
|
|
-o "${CERTS_DIR}/ssl-dhparams.pem"
|
|
fi
|
|
|
|
# ── Create a dummy certificate so nginx can start (needed for ACME challenge) ─
|
|
DUMMY_LIVE="${CERTS_DIR}/live/${DOMAIN}"
|
|
if [[ ! -f "${DUMMY_LIVE}/fullchain.pem" ]]; then
|
|
echo "==> Generating temporary self-signed certificate..."
|
|
openssl req -x509 -nodes -newkey rsa:4096 -days 1 \
|
|
-keyout "${DUMMY_LIVE}/privkey.pem" \
|
|
-out "${DUMMY_LIVE}/fullchain.pem" \
|
|
-subj "/CN=${DOMAIN}"
|
|
fi
|
|
|
|
# ── Start nginx (and dependencies) ───────────────────────────────────────────
|
|
echo "==> Starting nginx with temporary certificate..."
|
|
docker compose up -d nginx forgejo geoipupdate geoblock_watcher
|
|
|
|
echo "==> Waiting for nginx to be ready..."
|
|
sleep 5
|
|
|
|
# ── Obtain the real certificate via webroot challenge ────────────────────────
|
|
echo "==> Requesting Let's Encrypt certificate for ${DOMAIN}..."
|
|
docker compose run --rm certbot certonly \
|
|
--webroot \
|
|
--webroot-path /var/www/certbot \
|
|
--email "${EMAIL}" \
|
|
--agree-tos \
|
|
--no-eff-email \
|
|
-d "${DOMAIN}"
|
|
|
|
# ── Reload nginx with the real certificate ────────────────────────────────────
|
|
echo "==> Reloading nginx with the real certificate..."
|
|
docker compose exec nginx nginx -s reload
|
|
|
|
# ── Start remaining services ──────────────────────────────────────────────────
|
|
echo "==> Starting all services..."
|
|
docker compose up -d
|
|
|
|
echo ""
|
|
echo "✓ Bootstrap complete. Your Git service should be live at https://${DOMAIN}/"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo " 1. Visit https://${DOMAIN}/ and complete the Forgejo setup wizard."
|
|
echo " 2. Create your admin account."
|
|
echo " 3. Set DISABLE_REGISTRATION=true in .env, then: docker compose up -d forgejo"
|
|
echo " 4. Edit geo_rules.yml to configure per-repo geo-blocking."
|