igneum/infra/build-server/forgejo.sh

126 lines
3.7 KiB
Bash

#!/usr/bin/env bash
# The git host (main, 7 October 2026 20:29 BST; GitHub suspended): Forgejo 9 under docker on build-1, data under /srv/git (config
# app.ini written once with generated secrets, kept on the box only), ssh on 2222 public, http 3000 on loopback behind Caddy at
# git.igneum.network (ACME), deSEC A record by hand (dns.sh pattern). Then, by hand through the API as the owner user igneum-labs
# (credentials in ~/.config/igneum/forgejo-admin on the Mac): org igneum-network, private repos igneum and spec, the Mac key on the
# owner; registration off, anonymous read off, push-to-create off. Nightly dump to build-2 by /usr/local/bin/forgejo-backup.sh
# (forgejo-backup.timer 03:30 UTC). Runs as root on the box: scp it over and run it. Idempotent.
set -euo pipefail
mkdir -p /srv/git/data /srv/git/config
chown -R 1000:1000 /srv/git
if [ ! -s /srv/git/config/app.ini ]; then
SECRET=$(head -c 48 /dev/urandom | base64 | tr -d '/+=' | head -c 48)
JWT=$(head -c 48 /dev/urandom | base64 | tr -d '/+=' | head -c 48)
LFSJWT=$(head -c 48 /dev/urandom | base64 | tr -d '/+=' | head -c 48)
cat > /srv/git/config/app.ini <<INI
APP_NAME = Igneum
RUN_MODE = prod
RUN_USER = git
WORK_PATH = /data/gitea
[server]
PROTOCOL = http
DOMAIN = git.igneum.network
ROOT_URL = https://git.igneum.network/
HTTP_ADDR = 0.0.0.0
HTTP_PORT = 3000
SSH_DOMAIN = git.igneum.network
SSH_PORT = 2222
SSH_LISTEN_PORT = 22
START_SSH_SERVER = false
DISABLE_SSH = false
LFS_START_SERVER = true
LFS_JWT_SECRET = $LFSJWT
OFFLINE_MODE = true
LANDING_PAGE = login
[database]
DB_TYPE = sqlite3
PATH = /data/gitea/forgejo.db
[repository]
ROOT = /data/git/repositories
DEFAULT_PRIVATE = private
FORCE_PRIVATE = true
ENABLE_PUSH_CREATE_USER = false
ENABLE_PUSH_CREATE_ORG = false
DEFAULT_BRANCH = master
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = true
ENABLE_NOTIFY_MAIL = false
DEFAULT_KEEP_EMAIL_PRIVATE = true
DEFAULT_ALLOW_CREATE_ORGANIZATION = false
[security]
INSTALL_LOCK = true
SECRET_KEY = $SECRET
INTERNAL_TOKEN = $JWT
PASSWORD_HASH_ALGO = argon2
MIN_PASSWORD_LENGTH = 16
[oauth2]
ENABLED = false
[openid]
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = false
[mailer]
ENABLED = false
[session]
PROVIDER = file
COOKIE_SECURE = true
[log]
MODE = file
LEVEL = Info
ROOT_PATH = /data/gitea/log
[other]
SHOW_FOOTER_VERSION = false
[actions]
ENABLED = false
[packages]
ENABLED = false
[federation]
ENABLED = false
INI
chown 1000:1000 /srv/git/config/app.ini; chmod 600 /srv/git/config/app.ini
fi
if ! docker ps -a --format '{{.Names}}' | grep -qx forgejo; then
docker run -d --name forgejo --restart unless-stopped \
-e USER_UID=1000 -e USER_GID=1000 -e FORGEJO_CUSTOM=/data/gitea \
-v /srv/git/data:/data -v /srv/git/config/app.ini:/data/gitea/conf/app.ini \
-v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro \
-p 127.0.0.1:3000:3000 -p 2222:22 \
--cpus 4 --memory 8g \
codeberg.org/forgejo/forgejo:9 >/dev/null
fi
ufw allow 2222/tcp >/dev/null
if ! grep -q "^git.igneum.network" /etc/caddy/Caddyfile; then
cat >> /etc/caddy/Caddyfile <<'CADDY'
# the git host (Forgejo in docker, infra/build-server/forgejo.sh): everything proxied, nothing cached
git.igneum.network {
tls {
issuer acme
}
reverse_proxy 127.0.0.1:3000
request_body {
max_size 2GB
}
}
CADDY
caddy fmt --overwrite /etc/caddy/Caddyfile >/dev/null 2>&1 || true
systemctl reload caddy
fi
for i in $(seq 1 30); do curl -fsS -o /dev/null http://127.0.0.1:3000/ 2>/dev/null && break; sleep 2; done
echo "forgejo container: $(docker ps --format '{{.Names}} {{.Status}}' | grep forgejo)"
echo "http 3000: $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3000/)"
echo "ssh 2222: $(timeout 5 bash -c 'exec 3<>/dev/tcp/127.0.0.1/2222; head -c 40 <&3' 2>/dev/null | tr -d '\r\n' | cut -c1-40)"