added ADR 0005 and step 13: reintroduce managed nginx+certbot as an opt-in feature for hosts without a reverse proxy (e.g. Hostsharing); partially supersedes ADR 0004; updated plans, documentation, and migration guides

This commit is contained in:
Michael Hoennig
2026-07-07 14:40:11 +02:00
parent f6a876b29b
commit 142bc87604
8 changed files with 123 additions and 5 deletions
+2 -1
View File
@@ -79,6 +79,7 @@ No status changes observable during a build (control loop):
## Not Ported (decided)
- nginx + certbot/Let's Encrypt container management — replaced by deployment documentation (step 12).
Revised by ADR 0005: it IS needed for Hostsharing container hosts and returns as an opt-in feature (step 13).
- Self-install (`--install`), self-update script generation — replaced by jar deployment plus systemd docs (step 12).
- Legacy `HSADMIN_NG_*` environment fallbacks and env-file config — replaced by YAML config (done).
- Regex-based in-place HTML patching — replaced by server-rendered pages/JSON endpoints.
@@ -90,6 +91,6 @@ No status changes observable during a build (control loop):
Verify need before porting any of these:
- `GITTALLY_BUILD_DOCKER_PREFLIGHT_COMMAND`, `GITTALLY_BUILD_DOCKER_JAVA_TOOL_OPTIONS` — highly hsadmin-ng-specific defaults.
- `GITTALLY_ARTIFACT_NGINX_*`, `GITTALLY_ARTIFACT_LETSENCRYPT_EMAIL` — dropped with nginx management.
- `GITTALLY_ARTIFACT_NGINX_*`, `GITTALLY_ARTIFACT_LETSENCRYPT_EMAIL` — dropped with nginx management; revived as `server.nginx.*` by step 13 (ADR 0005).
- `GITTALLY_IMPRESSUM_URL` — keep as optional simple footer link if wanted.
- `GITTALLY_INSTALL_DIR` — dropped with self-install.
+41
View File
@@ -0,0 +1,41 @@
# Step 13: Managed nginx/TLS Container
Prerequisites: steps 07, 11, 12.
Read `README.md`, `00-legacy-analysis.md`, and ADR 0005 first.
Consult `legacy/gitTally` for the functions referenced below.
## Goal
Serve GitTally over HTTPS on hosts that provide Docker but no host reverse proxy (e.g. Hostsharing managed container environments).
GitTally optionally manages an nginx Docker container with Let's Encrypt certificates, ported from the legacy subsystem.
This is opt-in; the reverse-proxy deployment from step 12 stays the default (ADR 0005).
## Design
Port the legacy nginx subsystem (functions `configure_artifact_nginx_defaults` ~1545, `artifact_nginx_write_ssl_options` ~4051, `artifact_nginx_write_config` ~4077, `artifact_nginx_ports_free` ~4242, `cleanup_stale_artifact_nginx_containers` ~4274, `artifact_nginx_run_container` ~4281, `artifact_nginx_obtain_or_renew_certificate` ~4310, `start_artifact_nginx` ~4342, shutdown cleanup ~723):
- Config under `server.nginx.*`: `enabled` (default false), `serverName`, `httpPort` (8080), `httpsPort` (8443), `upstreamHost` (default: `serverName`), `containerName` (default: `gittally-nginx-<repo-name>`), `stateDir` (default: `${XDG_STATE_HOME:-~/.local/state}/gittally/nginx/<repoKey>`), `letsencryptEmail`.
Update all three config places (`GitTallyConfig`, `init` templates, `docs/configuration.md`).
- When `server.publicBaseUrl` is empty and `serverName` is set, default it to `https://<serverName>/` (legacy line ~541).
- Shell out to the `docker` CLI like `DockerBuildRunner` (no SDK); label the container `org.hoennig.gittally` for stale-container cleanup.
- Lifecycle as a server-profile component (like `ServerWatcherLifecycle`/`ServerMetricsLifecycle`): start after the web server is up, stop and remove the container on shutdown.
Nothing runs in CLI mode or tests.
- Two-phase startup, ported from legacy: write an HTTP-only nginx config for the ACME webroot challenge, run the container, obtain the certificate via a certbot container (webroot mode), then rewrite the full HTTPS config and restart nginx.
If a certificate already exists in the state dir, start with the full config directly.
- All failures are non-fatal warnings; the plain HTTP server keeps running (legacy behavior).
- Improvement over legacy (fix by design, do not port): legacy renewed certificates only at process start, relying on frequent self-update restarts.
Schedule a periodic renewal check (e.g. daily) in the lifecycle component instead.
## Tests
- Unit tests for nginx config generation (init vs. full mode, upstream/port substitution, server name escaping).
- Unit tests for docker argv assembly (run, certbot, cleanup), mocking the command runner — no real Docker or ACME interaction.
- Renewal scheduling logic with a fake clock/scheduler.
## Acceptance Criteria
- `./gradlew ktlintFormat` then `./gradlew build` is green.
- With `server.nginx.enabled: false` (default) nothing changes; no container is touched.
- Manual walkthrough on a Docker host: nginx container starts with the init config and proxies HTTP to GitTally.
Full ACME issuance needs a public DNS name; if none is available, verify the certbot argv and the full-config path against the legacy script and document that in this file.
- `docs/deployment.md` gains a section for hosts without a reverse proxy; `docs/migration-from-legacy.md` maps the `GITTALLY_ARTIFACT_NGINX_*`/`GITTALLY_ARTIFACT_LETSENCRYPT_EMAIL` variables.
+6
View File
@@ -37,6 +37,7 @@ Revisit them in an ADR if a step uncovers problems.
- The web UI is server-rendered HTML plus small JavaScript polling JSON endpoints (no SPA framework).
- The watcher is a Spring-managed scheduled component, decoupled from the build executor via the result repository and events.
- nginx/Let's Encrypt container management is NOT ported; deployment behind an existing reverse proxy is documented instead.
Revised after step 12 (ADR 0005): an opt-in managed nginx/TLS container is required for Hostsharing container hosts — see step 13.
## Steps
@@ -64,7 +65,12 @@ Completion:
- [x] `11-docker-build-runtime.md` — optional Docker build execution
- [x] `12-deployment.md` — systemd service, migration from legacy, docs
Added after the initial plan (ADR 0005):
- [ ] `13-nginx-tls.md` — opt-in managed nginx/TLS container for hosts without a reverse proxy
Steps 0103 are independent of each other.
Steps 0406 depend on 0103.
Steps 0709 depend on 0406.
Steps 11 and 12 are optional/deferrable; 10 only needs 0406.
Step 13 depends on 07, 11, and 12.