mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-11 18:34:04 +01:00
setup_syncyomi.sh 408 -> 138 (two cuts), setup_personal_website.sh 396 -> 192, fix_thorium.sh 377 -> 208. All three already declared SCRIPT_DIR and the splitter added a second one, which aborts at runtime with "readonly variable" while bash -n and shellcheck stay clean. The stubbed run caught it; the splitter now reuses an existing declaration. Fixed SC2164 in build_website rather than suppressing it: a bare cd "$WEBSITE_SRC" inside a subshell, with pnpm install and pnpm run build after it. A failed cd would have built in the caller's directory. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
141 lines
5.1 KiB
Bash
Executable File
141 lines
5.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# setup_syncyomi.sh — Self-hosted SyncYomi manga-sync server on this Arch PC.
|
|
#
|
|
# Stands up SyncYomi (github.com/SyncYomi/SyncYomi) in Docker, bound to
|
|
# 127.0.0.1:8282, and fronts it with the EXISTING Caddy reverse proxy (from
|
|
# setup_gitea.sh) for automatic public HTTPS at a new DuckDNS subdomain, so
|
|
# TachiyomiSY on the phone can sync its library from a mobile network.
|
|
#
|
|
# It reuses the host's existing exposure stack — it does NOT add a second Caddy,
|
|
# a second DuckDNS updater, or hand-edit /etc/nftables.conf. It also creates the
|
|
# first SyncYomi account and mints an API key over the local REST API, then
|
|
# prints the host address + API key ready to paste into TachiyomiSY.
|
|
#
|
|
# Run as your normal user (NOT root). It uses sudo only for pacman, the firewall
|
|
# flag and enabling docker. Idempotent — safe to re-run.
|
|
#
|
|
# Usage:
|
|
# ./setup_syncyomi.sh Install / update everything (default)
|
|
# ./setup_syncyomi.sh setup Same as above
|
|
# ./setup_syncyomi.sh status Show health / exposure diagnostics
|
|
# ./setup_syncyomi.sh help Show this help
|
|
|
|
set -euo pipefail
|
|
|
|
# --- Pinned SyncYomi image ---------------------------------------------------
|
|
readonly SYNCYOMI_IMAGE="ghcr.io/syncyomi/syncyomi:v1.1.11"
|
|
readonly SYNCYOMI_PORT=8282
|
|
readonly SYNCYOMI_LOCAL="http://127.0.0.1:${SYNCYOMI_PORT}"
|
|
|
|
# --- Data dir + secrets (outside the git repo, like ~/gitea) -----------------
|
|
readonly DATA_DIR="${HOME}/syncyomi"
|
|
readonly COMPOSE_FILE="${DATA_DIR}/docker-compose.yml"
|
|
readonly CONFIG_TOML="${DATA_DIR}/config/config.toml"
|
|
readonly CONF_FILE="${DATA_DIR}/.syncyomi.conf"
|
|
readonly TOKEN_FILE="${DATA_DIR}/.api_token"
|
|
|
|
# --- Existing host infrastructure (from setup_gitea.sh / install_joplin.sh) --
|
|
readonly CADDY_CONTAINER="gitea-caddy"
|
|
readonly CADDYFILE="${HOME}/gitea/Caddyfile"
|
|
readonly CADDYFILE_IN_CONTAINER="/etc/caddy/Caddyfile"
|
|
readonly DUCKDNS_UPDATER="${HOME}/.joplin-server/duckdns-update.sh"
|
|
|
|
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
|
readonly SCRIPT_DIR
|
|
readonly WG_SCRIPT="${SCRIPT_DIR}/setup_wireguard_ssh.sh"
|
|
|
|
# shellcheck source=../../lib/common.sh
|
|
# shellcheck disable=SC1091
|
|
source "${SCRIPT_DIR}/../../lib/common.sh"
|
|
|
|
# Config values (populated from CONF_FILE / defaults).
|
|
SYNCYOMI_USER=""
|
|
SYNCYOMI_PASSWORD=""
|
|
SYNCYOMI_SUBDOMAIN=""
|
|
|
|
# Local timezone for the container (falls back if timedatectl is unavailable).
|
|
TZ_VALUE="$(timedatectl show -p Timezone --value 2>/dev/null || echo 'Europe/Warsaw')"
|
|
readonly TZ_VALUE
|
|
|
|
die() {
|
|
log_error "$1"
|
|
exit 1
|
|
}
|
|
|
|
usage() {
|
|
grep -E '^#( |$)' "$0" | sed -E 's/^# ?//'
|
|
exit 0
|
|
}
|
|
|
|
# --- Step 1: preflight -------------------------------------------------------
|
|
preflight() {
|
|
log_info "Preflight checks"
|
|
[[ ${EUID} -ne 0 ]] || die "Run as your normal user, not root (it will sudo where needed)."
|
|
|
|
# Runtime deps; install any that are missing from the official repos.
|
|
install_missing_pacman_packages docker docker-compose jq curl openssl
|
|
|
|
# Ensure the docker daemon is enabled+running (auto-start after reboot). Only
|
|
# touch systemd via sudo when it is not already active, to stay a no-op on the
|
|
# common case where docker is already up (Gitea/dufs run on it).
|
|
has_cmd docker || die "docker not found — run setup_gitea.sh first."
|
|
if ! is_service_active docker; then
|
|
log_info "Enabling and starting docker.service"
|
|
sudo systemctl enable --now docker
|
|
fi
|
|
|
|
# The public-exposure stack must already exist (Caddy from setup_gitea.sh).
|
|
docker ps --format '{{.Names}}' | grep -qx "${CADDY_CONTAINER}" ||
|
|
die "Caddy container '${CADDY_CONTAINER}' not running — run setup_gitea.sh first."
|
|
[[ -f ${CADDYFILE} ]] || die "Caddyfile ${CADDYFILE} missing — run setup_gitea.sh first."
|
|
[[ -x ${DUCKDNS_UPDATER} ]] || die "DuckDNS updater ${DUCKDNS_UPDATER} missing — run install_joplin.sh first."
|
|
log_ok "Host exposure stack present (docker + ${CADDY_CONTAINER} + DuckDNS updater)"
|
|
}
|
|
|
|
# --- Step 2: config (auto-generate credentials, store 0600) ------------------
|
|
load_config() {
|
|
ensure_dir "${DATA_DIR}"
|
|
chmod 700 "${DATA_DIR}"
|
|
if [[ -f ${CONF_FILE} ]]; then
|
|
# shellcheck source=/dev/null
|
|
source "${CONF_FILE}"
|
|
fi
|
|
SYNCYOMI_USER="${SYNCYOMI_USER:-$(get_actual_user)}"
|
|
SYNCYOMI_SUBDOMAIN="${SYNCYOMI_SUBDOMAIN:-kuhy-sync.duckdns.org}"
|
|
# Generate the web/API password once; never regenerate on re-run.
|
|
if [[ -z ${SYNCYOMI_PASSWORD:-} ]]; then
|
|
SYNCYOMI_PASSWORD="$(openssl rand -base64 24)"
|
|
fi
|
|
save_config
|
|
}
|
|
|
|
save_config() {
|
|
# 0600 — holds the plaintext SyncYomi password so re-runs stay
|
|
# non-interactive. Lives under ~/syncyomi (outside the git repo).
|
|
umask 077
|
|
{
|
|
printf 'SYNCYOMI_USER=%q\n' "${SYNCYOMI_USER}"
|
|
printf 'SYNCYOMI_PASSWORD=%q\n' "${SYNCYOMI_PASSWORD}"
|
|
printf 'SYNCYOMI_SUBDOMAIN=%q\n' "${SYNCYOMI_SUBDOMAIN}"
|
|
} >"${CONF_FILE}"
|
|
chmod 600 "${CONF_FILE}"
|
|
log_ok "Saved config to ${CONF_FILE} (0600)"
|
|
}
|
|
|
|
# shellcheck source=lib/syncyomi_stack.sh
|
|
source "$SCRIPT_DIR/lib/syncyomi_stack.sh"
|
|
# shellcheck source=lib/syncyomi_expose.sh
|
|
source "$SCRIPT_DIR/lib/syncyomi_expose.sh"
|
|
|
|
main() {
|
|
local cmd="${1:-setup}"
|
|
case "${cmd}" in
|
|
setup) setup_cmd ;;
|
|
status) status_cmd ;;
|
|
help | -h | --help) usage ;;
|
|
*) die "Unknown command '${cmd}' (use: setup | status | help)" ;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|