MIGRATION_POLL_INTERVAL_SEC and MIGRATION_POLL_TIMEOUT_SEC were in
.env.example and used by phase4, but missing from validate_env()
arrays and configure_env.sh prompts. Preflight would not catch
invalid values. Now validated as positive_integer and prompted
in the REPOSITORIES section of the wizard.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CADDY_DOMAIN was required/validated/prompted but never used — the
Caddyfile only referenced GITEA_DOMAIN, producing a single-domain
cert. Now the template uses *.CADDY_DOMAIN as the site address
(wildcard cert) with a host matcher routing GITEA_DOMAIN to Gitea.
This means the cert covers all subdomains under the base domain.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, a failure on any repo (clone, commit, push) would kill the
entire script via set -e. Remaining repos were never processed and the
FAILED counter was always 0. Now clone and commit/push failures
increment FAILED and continue to the next repo, matching the pattern
used in phase4_migrate_repos.sh.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
get_repo_list() — never called, scripts use read -ra directly
wait_for_ssh() — never called, scripts use ssh_check
validate_optional() — never called, optional type unused in arrays
manifest_exists() — never called
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Identical copies of _set_db_vars() and _strip_block() existed in
phase1, phase2, and phase8. Moved to lib/common.sh as set_db_vars()
and strip_template_block() (public API, no underscore prefix).
Removed dead _strip_block definition from phase8 (defined but never called).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
No phase script deploys Caddy on Fedora — only Unraid gets a Caddy
container. Removed from .env.example, validation arrays, preflight
required vars, IP ping check, wizard prompts, and doc references.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 5 authenticates via GITEA_ADMIN_TOKEN only (git_with_auth uses
the token, not the password). Phase 9 already correctly omits it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
restore_to_primary.sh uses GITEA_DB_USER, GITEA_DB_PASSWD, and
GITEA_DB_NAME for external DB restore but never required them upfront.
Adds conditional require_vars when GITEA_DB_TYPE != sqlite3.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added note that plan describes original architecture with diffs noted
- Architecture table: Nginx+Certbot→Caddy+Cloudflare DNS-01
- File structure: nginx-gitea.conf.tpl→Caddyfile.tpl + caddy compose
- Variable table: NGINX_*/SSL_MODE/SSL_EMAIL→TLS_MODE/CADDY_*/CLOUDFLARE_*
- Preflight checks: port checks→container IP availability, Nginx→Caddy path
- Phase 8: complete rewrite from 10-step Nginx flow to 6-step Caddy flow
- Template section: replaced nginx template spec with Caddy template spec
- Removed stale port variables from "Not checked" list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
RUNNER_DEFAULT_IMAGE_ENV was never defined anywhere in the codebase.
The nested default was dead code left from a prior refactor.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The case statement matched uppercase UNRAID/FEDORA but $r_host is always
lowercase from validate_runner_host(). Unraid and Fedora runners were
silently falling through to the default capacity of 1 instead of 2.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add validate_tls_mode() (cloudflare|existing). Replace
NGINX_CONTAINER_NAME, NGINX_CONF_PATH, SSL_MODE in validation arrays
with TLS_MODE, CADDY_DOMAIN, CADDY_DATA_PATH. Update conditional
arrays from SSL_MODE-based to TLS_MODE-based (CLOUDFLARE_API_TOKEN
for cloudflare, SSL_CERT_PATH/SSL_KEY_PATH for existing).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Caddy reverse proxy container using slothcroissant/caddy-cloudflaredns
image for DNS-01 TLS. Joins the macvlan gitea_net network with a
static IP. CADDY_ENV_VARS and CADDY_EXTRA_VOLUMES are populated by
phase8 based on TLS_MODE (cloudflare vs existing cert paths).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Template uses TLS_BLOCK placeholder that phase8 populates based on
TLS_MODE: cloudflare (DNS-01 wildcard via Cloudflare API) or
existing (manual cert/key paths). Reverse proxies to Gitea container
on its macvlan IP.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove UNRAID_GITEA_PORT, UNRAID_GITEA_SSH_PORT, FEDORA_GITEA_PORT,
FEDORA_GITEA_SSH_PORT prompts. Add DOCKER NETWORKING section with 14
macvlan prompts (parent NIC, subnet, gateway, IP range, container
IPs for gitea/db/caddy on each host). Update TOTAL_PROMPTS to 59.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add macvlan vars to REQUIRED_VARS. Replace port-free checks (13/14)
with container IP availability check that pings requested IPs to
verify they're not already in use on the LAN.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace host port vars with macvlan vars in require_vars. Add Step 2
to create macvlan gitea_net network on Fedora. Update docker-compose
rendering to use GITEA_CONTAINER_IP and DB_CONTAINER_IP. Use
FEDORA_GITEA_IP as domain for backup instance app.ini. Renumber steps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace host port vars with macvlan vars in require_vars. Add Step 2
to create the macvlan gitea_net network on Unraid. Update
docker-compose rendering to use GITEA_CONTAINER_IP and
DB_CONTAINER_IP instead of port mapping. Renumber steps accordingly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove ports: section (no more host port mapping). Add networks:
with static ipv4_address for gitea and db containers. Reference
external gitea_net network (macvlan created by phase scripts).
Add DB_CONTAINER_IP for database service networking.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove UNRAID_GITEA_PORT, UNRAID_GITEA_SSH_PORT, FEDORA_GITEA_PORT,
FEDORA_GITEA_SSH_PORT from required validation. Add macvlan vars
(parent, subnet, gateway, ip_range, gitea_ip, caddy_ip) for both
hosts. Add UNRAID_DB_IP and FEDORA_DB_IP as optional validated vars.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove UNRAID_GITEA_PORT, UNRAID_GITEA_SSH_PORT, FEDORA_GITEA_PORT,
FEDORA_GITEA_SSH_PORT — containers now use their own LAN IPs on
standard ports. Add DOCKER NETWORKING section with macvlan config
(parent interface, subnet, gateway, IP range) and per-container
static IPs (gitea, db, caddy) for both hosts. Update internal URL
comments to reference container IPs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace single-DB rationale with description of all four supported
backends (sqlite3, mysql, postgres, mssql) and how the toolkit
handles each.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When GITEA_DB_TYPE is not sqlite3, validate that GITEA_DB_HOST,
GITEA_DB_PORT, GITEA_DB_NAME, GITEA_DB_USER, and GITEA_DB_PASSWD
are set in the required vars check.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After extracting the archive, import gitea-db.sql into the running
DB container for postgres/mysql/mssql. Each DB type uses its native
CLI tool inside the container. SQLite restores remain unchanged.
Add GITEA_DB_TYPE to require_vars.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add db_type validation case. After GITEA_DB_TYPE prompt, conditionally
show 5 database connection prompts (host, port, name, user, passwd)
when DB type is not sqlite3. Auto-suggest default port per DB type
(mysql=3306, postgres=5432, mssql=1433). Update TOTAL_PROMPTS
dynamically.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mirror phase1 DB support: add _set_db_vars() and _strip_block()
helpers, conditional require_vars for DB connection, DB data directory
creation, and conditional template rendering for docker-compose and
app.ini based on GITEA_DB_TYPE.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add _set_db_vars() helper to configure DB-specific docker-compose
vars (image, env, healthcheck, data dir) for postgres/mysql/mssql.
Add _strip_block() to remove conditional template markers. Update
docker-compose and app.ini rendering to strip/populate DB blocks
based on GITEA_DB_TYPE. Conditionally require DB connection vars.
Create DB data directory for external databases.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add DB_SERVICE_START/END markers for the database container and
DB_DEPENDS_START/END for the gitea service depends_on. Phase scripts
strip these blocks for sqlite3 and populate DB-specific vars
(image, env, healthcheck, data dir) for mysql/postgres/mssql.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase scripts strip the irrelevant block after render_template:
sqlite3 removes EXTDB_BLOCK, external DBs remove SQLITE_BLOCK.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add GITEA_DB_HOST, GITEA_DB_PORT, GITEA_DB_NAME, GITEA_DB_USER, and
GITEA_DB_PASSWD. These are only required when GITEA_DB_TYPE is not
sqlite3. Update DB_TYPE comment to list all valid options.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add validate_db_type() accepting sqlite3/mysql/postgres/mssql. Update
GITEA_DB_TYPE validator from nonempty to db_type. Add conditional DB
validation arrays (host, port, name, user, passwd) required when DB
type is not sqlite3. Rename SSL conditional arrays for clarity.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Capacity is now always set per-runner in runners.conf (smart defaults
applied during configure_runners.sh wizard).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>