init
This commit is contained in:
commit
27c4191be8
17 changed files with 730 additions and 0 deletions
16
bin/backup-init.sh
Executable file
16
bin/backup-init.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
: "${AWS_ACCESS_KEY_ID:?AWS_ACCESS_KEY_ID must be set}"
|
||||
: "${AWS_SECRET_ACCESS_KEY:?AWS_SECRET_ACCESS_KEY must be set}"
|
||||
: "${RESTIC_REPOSITORY:?RESTIC_REPOSITORY must be set}"
|
||||
: "${RESTIC_PASSWORD:?RESTIC_PASSWORD must be set}"
|
||||
|
||||
if restic snapshots >/dev/null 2>&1; then
|
||||
echo "Restic repository is already initialized."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Initializing restic repository at $RESTIC_REPOSITORY..."
|
||||
restic init
|
||||
echo "Restic repository initialized successfully."
|
||||
54
bin/backup-restore.sh
Executable file
54
bin/backup-restore.sh
Executable file
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat >&2 <<'EOF'
|
||||
Usage:
|
||||
backup-restore.sh [snapshot]
|
||||
|
||||
Environment:
|
||||
AWS_ACCESS_KEY_ID
|
||||
AWS_SECRET_ACCESS_KEY
|
||||
RESTIC_REPOSITORY
|
||||
RESTIC_PASSWORD
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ $# -gt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
: "${AWS_ACCESS_KEY_ID:?AWS_ACCESS_KEY_ID must be set}"
|
||||
: "${AWS_SECRET_ACCESS_KEY:?AWS_SECRET_ACCESS_KEY must be set}"
|
||||
: "${RESTIC_REPOSITORY:?RESTIC_REPOSITORY must be set}"
|
||||
: "${RESTIC_PASSWORD:?RESTIC_PASSWORD must be set}"
|
||||
|
||||
snapshot="${1:-latest}"
|
||||
restore_path='/data/forgejo'
|
||||
|
||||
clear_directory() {
|
||||
local dir=$1
|
||||
|
||||
mkdir -p "$dir"
|
||||
find "$dir" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +
|
||||
}
|
||||
|
||||
staging_dir="$(mktemp -d)"
|
||||
cleanup() {
|
||||
rm -rf "$staging_dir"
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "Restoring snapshot '$snapshot' from $RESTIC_REPOSITORY into $restore_path ..."
|
||||
restic restore "$snapshot" --target "$staging_dir" --include "$restore_path"
|
||||
|
||||
restored_path="$staging_dir$restore_path"
|
||||
if [ ! -e "$restored_path" ]; then
|
||||
echo "Snapshot '$snapshot' did not contain $restore_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
clear_directory "$restore_path"
|
||||
cp -a "$restored_path"/. "$restore_path"/
|
||||
echo "Restore completed at $restore_path."
|
||||
27
bin/debug-deploy.sh
Executable file
27
bin/debug-deploy.sh
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
usage() {
|
||||
printf 'Usage: %s <start|stop>\n' "$0" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
script_dir="$(CDPATH= cd -- "$(dirname "$0")" && pwd)"
|
||||
repo_root="$(dirname "$script_dir")"
|
||||
config_path="$repo_root/fly.toml"
|
||||
|
||||
[ $# -eq 1 ] || usage
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
printf 'Enabling DEBUGDEPLOY using %s\n' "$config_path"
|
||||
exec fly secrets set -c "$config_path" DEBUGDEPLOY=1
|
||||
;;
|
||||
stop)
|
||||
printf 'Disabling DEBUGDEPLOY using %s\n' "$config_path"
|
||||
exec fly secrets unset -c "$config_path" DEBUGDEPLOY
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
44
bin/initialize-forgejo.sh
Executable file
44
bin/initialize-forgejo.sh
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
: "${FORGEJO_ADMIN_USERNAME:?FORGEJO_ADMIN_USERNAME must be set}"
|
||||
: "${FORGEJO_ADMIN_EMAIL:?FORGEJO_ADMIN_EMAIL must be set}"
|
||||
: "${FORGEJO_ADMIN_PASSWORD:?FORGEJO_ADMIN_PASSWORD must be set}"
|
||||
|
||||
shell_quote() {
|
||||
printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\\\\''/g")"
|
||||
}
|
||||
|
||||
run_forgejo() {
|
||||
command="exec /usr/local/bin/forgejo"
|
||||
for argument in "$@"; do
|
||||
command="$command $(shell_quote "$argument")"
|
||||
done
|
||||
su forgejo -s /bin/sh -c "$command"
|
||||
}
|
||||
|
||||
if ! run_forgejo -c "$GITEA_APP_INI" migrate >/tmp/forgejo-migrate.log 2>&1; then
|
||||
cat /tmp/forgejo-migrate.log >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if run_forgejo -c "$GITEA_APP_INI" admin user create \
|
||||
--username "$FORGEJO_ADMIN_USERNAME" \
|
||||
--password "$FORGEJO_ADMIN_PASSWORD" \
|
||||
--email "$FORGEJO_ADMIN_EMAIL" \
|
||||
--admin \
|
||||
--must-change-password=false >/tmp/forgejo-admin-create.log 2>&1; then
|
||||
printf 'Created Forgejo admin user %s.\n' "$FORGEJO_ADMIN_USERNAME"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
run_forgejo -c "$GITEA_APP_INI" admin user list >/tmp/forgejo-admin-list.log 2>/dev/null || true
|
||||
while read -r _id username _rest; do
|
||||
if [ "$username" = "$FORGEJO_ADMIN_USERNAME" ]; then
|
||||
printf 'Forgejo admin user %s already exists; leaving it unchanged.\n' "$FORGEJO_ADMIN_USERNAME"
|
||||
exit 0
|
||||
fi
|
||||
done < /tmp/forgejo-admin-list.log
|
||||
|
||||
cat /tmp/forgejo-admin-create.log >&2
|
||||
exit 1
|
||||
35
bin/prepare-caddy.sh
Executable file
35
bin/prepare-caddy.sh
Executable file
|
|
@ -0,0 +1,35 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
auth_file=/etc/caddy/auth.caddy
|
||||
username="${CADDY_BASIC_AUTH_USERNAME:-}"
|
||||
password="${CADDY_BASIC_AUTH_PASSWORD:-}"
|
||||
|
||||
if [ -z "$username" ] && [ -z "$password" ]; then
|
||||
: > "$auth_file"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "$username" ] || [ -z "$password" ]; then
|
||||
printf 'CADDY_BASIC_AUTH_USERNAME and CADDY_BASIC_AUTH_PASSWORD must both be set.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$username" in
|
||||
*[!A-Za-z0-9._@-]*)
|
||||
printf 'CADDY_BASIC_AUTH_USERNAME contains unsupported characters.\n' >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
password_hash="$(/usr/local/bin/caddy hash-password --plaintext "$password")"
|
||||
cat > "$auth_file" <<EOF
|
||||
@protected {
|
||||
not path /healthz
|
||||
not path_regexp public ^(/[^/]+/[^/]+\.git/.*|/api/packages(/.*)?)$
|
||||
}
|
||||
|
||||
basic_auth @protected {
|
||||
$username $password_hash
|
||||
}
|
||||
EOF
|
||||
85
bin/prepare-forgejo.sh
Executable file
85
bin/prepare-forgejo.sh
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
: "${GITEA_WORK_DIR:=/data/forgejo}"
|
||||
: "${GITEA_CUSTOM:=$GITEA_WORK_DIR/custom}"
|
||||
: "${GITEA_TEMP:=/tmp/gitea}"
|
||||
: "${GITEA_APP_INI:=$GITEA_CUSTOM/conf/app.ini}"
|
||||
: "${FORGEJO_HOME:=/data/forgejo/git}"
|
||||
|
||||
sed_escape() {
|
||||
printf '%s' "$1" | sed 's/[\\/&]/\\&/g'
|
||||
}
|
||||
|
||||
set_top_level_key() {
|
||||
key="$1"
|
||||
value="$2"
|
||||
escaped_value="$(sed_escape "$value")"
|
||||
|
||||
if grep -q "^$key[[:space:]]*=" "$GITEA_APP_INI"; then
|
||||
sed -i "s/^$key[[:space:]]*=.*/$key = $escaped_value/" "$GITEA_APP_INI"
|
||||
return
|
||||
fi
|
||||
|
||||
tmp_file="$(mktemp)"
|
||||
{
|
||||
printf '%s = %s\n' "$key" "$value"
|
||||
cat "$GITEA_APP_INI"
|
||||
} > "$tmp_file"
|
||||
mv "$tmp_file" "$GITEA_APP_INI"
|
||||
}
|
||||
|
||||
mkdir -p \
|
||||
"$FORGEJO_HOME" \
|
||||
"$GITEA_CUSTOM" \
|
||||
"$GITEA_TEMP" \
|
||||
"$GITEA_WORK_DIR/data" \
|
||||
"$GITEA_WORK_DIR/git/repositories" \
|
||||
"$GITEA_WORK_DIR/git/lfs" \
|
||||
"$(dirname "$GITEA_APP_INI")"
|
||||
|
||||
chown -R forgejo:forgejo "$GITEA_WORK_DIR" "$GITEA_TEMP"
|
||||
chmod 700 "$FORGEJO_HOME" "$GITEA_CUSTOM" "$GITEA_TEMP" "$(dirname "$GITEA_APP_INI")"
|
||||
|
||||
APP_NAME="${APP_NAME:-Forgejo: Beyond coding. We forge.}"
|
||||
RUN_MODE="${RUN_MODE:-prod}"
|
||||
RUN_USER="${RUN_USER:-forgejo}"
|
||||
|
||||
if [ ! -f "$GITEA_APP_INI" ]; then
|
||||
SSH_DOMAIN="${SSH_DOMAIN:-localhost}"
|
||||
HTTP_PORT="${HTTP_PORT:-3000}"
|
||||
ROOT_URL="${ROOT_URL:-${GITEA__server__ROOT_URL:-}}"
|
||||
DISABLE_SSH="${DISABLE_SSH:-false}"
|
||||
SSH_PORT="${SSH_PORT:-2222}"
|
||||
SSH_LISTEN_PORT="${SSH_LISTEN_PORT:-$SSH_PORT}"
|
||||
LFS_START_SERVER="${LFS_START_SERVER:-true}"
|
||||
DB_TYPE="${DB_TYPE:-sqlite3}"
|
||||
DB_HOST="${DB_HOST:-localhost:3306}"
|
||||
DB_NAME="${DB_NAME:-gitea}"
|
||||
DB_USER="${DB_USER:-root}"
|
||||
DB_PASSWD="${DB_PASSWD:-}"
|
||||
INSTALL_LOCK="${INSTALL_LOCK:-false}"
|
||||
DISABLE_REGISTRATION="${DISABLE_REGISTRATION:-false}"
|
||||
REQUIRE_SIGNIN_VIEW="${REQUIRE_SIGNIN_VIEW:-false}"
|
||||
SECRET_KEY="${SECRET_KEY:-}"
|
||||
export APP_NAME RUN_MODE RUN_USER SSH_DOMAIN HTTP_PORT ROOT_URL DISABLE_SSH SSH_PORT SSH_LISTEN_PORT LFS_START_SERVER DB_TYPE DB_HOST DB_NAME DB_USER DB_PASSWD INSTALL_LOCK DISABLE_REGISTRATION REQUIRE_SIGNIN_VIEW SECRET_KEY
|
||||
envsubst < /etc/templates/forgejo-app.ini.tmpl > "$GITEA_APP_INI"
|
||||
fi
|
||||
|
||||
set_top_level_key APP_NAME "$APP_NAME"
|
||||
set_top_level_key RUN_USER "$RUN_USER"
|
||||
set_top_level_key RUN_MODE "$RUN_MODE"
|
||||
crudini --set "$GITEA_APP_INI" server BUILTIN_SSH_SERVER_USER "$RUN_USER"
|
||||
|
||||
printenv | while IFS='=' read -r name value; do
|
||||
case "$name" in
|
||||
GITEA__*__*)
|
||||
rest="${name#GITEA__}"
|
||||
section="${rest%%__*}"
|
||||
key="${rest#*__}"
|
||||
crudini --set "$GITEA_APP_INI" "$section" "$key" "$value"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
chown forgejo:forgejo "$GITEA_APP_INI"
|
||||
5
bin/run-forgejo.sh
Executable file
5
bin/run-forgejo.sh
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
/usr/local/bin/prepare-forgejo.sh
|
||||
exec su forgejo -s /bin/sh -c "exec /usr/local/bin/forgejo -c \"$GITEA_APP_INI\" web"
|
||||
57
bin/run-restic-backups.sh
Executable file
57
bin/run-restic-backups.sh
Executable file
|
|
@ -0,0 +1,57 @@
|
|||
#!/bin/bash
|
||||
set -uo pipefail
|
||||
|
||||
required_vars=(
|
||||
AWS_ACCESS_KEY_ID
|
||||
AWS_SECRET_ACCESS_KEY
|
||||
RESTIC_REPOSITORY
|
||||
RESTIC_PASSWORD
|
||||
)
|
||||
|
||||
missing_vars=()
|
||||
for var_name in "${required_vars[@]}"; do
|
||||
if [ -z "${!var_name:-}" ]; then
|
||||
missing_vars+=("$var_name")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "${#missing_vars[@]}" -gt 0 ]; then
|
||||
echo "Restic backups disabled; missing ${missing_vars[*]}." >&2
|
||||
exec sleep infinity
|
||||
fi
|
||||
|
||||
BACKUP_INTERVAL_SECONDS="${RESTIC_BACKUP_INTERVAL_SECONDS:-3600}"
|
||||
BACKUP_PATHS=("/data")
|
||||
|
||||
KEEP_HOURLY=24
|
||||
KEEP_DAILY=7
|
||||
KEEP_WEEKLY=4
|
||||
KEEP_MONTHLY=6
|
||||
|
||||
run_backup() {
|
||||
echo "Starting restic backup..."
|
||||
restic backup "${BACKUP_PATHS[@]}" || return $?
|
||||
|
||||
echo "Pruning old backups..."
|
||||
restic forget \
|
||||
--keep-hourly "$KEEP_HOURLY" \
|
||||
--keep-daily "$KEEP_DAILY" \
|
||||
--keep-weekly "$KEEP_WEEKLY" \
|
||||
--keep-monthly "$KEEP_MONTHLY" \
|
||||
--prune || return $?
|
||||
|
||||
echo "Checking repository..."
|
||||
restic check || return $?
|
||||
echo "Backup completed successfully."
|
||||
}
|
||||
|
||||
while true; do
|
||||
if run_backup; then
|
||||
:
|
||||
else
|
||||
status=$?
|
||||
echo "Restic backup failed with status $status." >&2
|
||||
fi
|
||||
|
||||
sleep "$BACKUP_INTERVAL_SECONDS"
|
||||
done
|
||||
13
bin/start-services.sh
Executable file
13
bin/start-services.sh
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
if [ -n "${DEBUGDEPLOY:-}" ]; then
|
||||
printf 'DEBUGDEPLOY is set; skipping startup and waiting indefinitely.\n' >&2
|
||||
exec sleep infinity
|
||||
fi
|
||||
|
||||
/usr/local/bin/prepare-caddy.sh
|
||||
/usr/local/bin/prepare-forgejo.sh
|
||||
/usr/local/bin/initialize-forgejo.sh
|
||||
|
||||
exec /usr/local/bin/hivemind /etc/Procfile
|
||||
Loading…
Add table
Add a link
Reference in a new issue