Skip to content

feat(docker): production nginx image published to GHCR#268

Merged
BorisTyshkevich merged 1 commit into
mainfrom
feat/nginx-container-ghcr
Jul 16, 2026
Merged

feat(docker): production nginx image published to GHCR#268
BorisTyshkevich merged 1 commit into
mainfrom
feat/nginx-container-ghcr

Conversation

@BorisTyshkevich

Copy link
Copy Markdown
Collaborator

Summary

Replaces the containerized Python local-runner with a static nginx server for the single-file SPA, and publishes it multi-arch to ghcr.io/altinity/altinity-sql-browser as part of the release. The image ships a runnable demo config.json (antalya + github.demo, each in demo:demo and Google-SSO modes) so docker run works out of the box; mount your own config.json to override.

Nothing proxies queries — the browser POSTs SQL cross-origin to the chosen cluster, exactly like the on-ClickHouse http_handlers deployment.

Changes

  • Dockerfile — Node build stage → nginxinc/nginx-unprivileged (non-root uid 101, port 8080). CONNECT_SRC env fills the CSP connect-src; HEALTHCHECK on /healthz; ASB_VERSION build-arg keeps the in-app build stamp in lockstep with the image tag.
  • deploy/nginx/default.conf.template (new) — serves /sql, /sql/dashboard (same SPA), /sql/config.json, /healthz, //sql; gzip; security headers + CSP mirroring deploy/http_handlers.xml.
  • .github/workflows/docker.yml (new) — multi-arch (amd64+arm64) buildx + metadata-action. PR = build-only; main = :edge+:sha-; tag v* = :X.Y.Z+:latest.
  • deploy/config.json.example — the 4-entry demo, baked in as the default served config.
  • docker-compose.yaml, deploy/k8s/deployment.yaml — nginx model: config via mount/ConfigMap, port 8080, /healthz+/sql/config.json probes, non-root securityContext, resources.
  • README.md, CHANGELOG.md updated.

Verified (real container)

  • 2-stage build ✓ · runs as uid 101 ✓ · HEALTHCHECK healthy ✓
  • /sql 200 text/html; charset=utf-8, full CSP (connect-src = Google + both clusters) ✓ · gzip 1.21 MB → 437 KB
  • /sql/dashboard 200 ✓ · /healthz ✓ · /→ relative Location: /sql
  • Mounted config.json override ✓ · CONNECT_SRC env → CSP ✓ · build stamp ✓
  • Agent Chrome: login picker renders all four saved connections, two Google IdPs disambiguated by label ✓
  • No src//tests//build//schemas/ changes → coverage/tsc gate unaffected.

Notes

  • Three container gotchas fixed: 0600-checkout file perms (root chmod normalize), charset inside default_type defeating text/html gzip (use charset directive), HEALTHCHECK via localhost::1 (use 127.0.0.1).
  • config.json.example now also carries github.demo's Google client secret — public-by-design host-locked web clients (hard rule 3 / Feature: Server-side OAuth2 code exchange to support secure client login flow ClickHouse#1930), consistent with the antalya secret already in deploy/sql-browser.xml. Push protection allow-listed by the maintainer.
  • Roadmap Roadmap to 1.0.0 #68 is feature/architecture phases with no packaging track — nothing to re-scope; this is release infra.
  • Demo caveats documented in README: SSO won't complete from localhost (host-locked redirect URIs — use demo:demo); cross-origin queries need cluster CORS (public demos allow it).

🤖 Generated with Claude Code

Replace the containerized Python local-runner with a static nginx server
for the single-file SPA, and publish it multi-arch to
ghcr.io/altinity/altinity-sql-browser.

- Dockerfile: node build stage → nginxinc/nginx-unprivileged (non-root
  uid 101, port 8080). Serves the baked SPA + a mounted config.json,
  CONNECT_SRC env fills the CSP connect-src, HEALTHCHECK on /healthz,
  ASB_VERSION build-arg keeps the in-app build stamp in lockstep with
  the image tag.
- deploy/nginx/default.conf.template: serves /sql, /sql/dashboard (same
  SPA), /sql/config.json, /healthz, / → /sql; gzip; security headers +
  CSP mirroring deploy/http_handlers.xml.
- .github/workflows/docker.yml: multi-arch (amd64+arm64) build via
  buildx/metadata-action; PR = build-only, main = :edge + :sha-, tag v*
  = :X.Y.Z + :latest (part of the release).
- deploy/config.json.example: runnable demo (antalya + github.demo, each
  in demo:demo and Google-SSO modes) baked in as the default served
  config. Google clients are public-by-design with host-locked redirect
  URIs (hard rule 3 / Altinity/ClickHouse#1930).
- docker-compose.yaml + deploy/k8s/deployment.yaml: nginx model — config
  via mount/ConfigMap, port 8080, /healthz + /sql/config.json probes,
  non-root securityContext, resources.
- README + CHANGELOG updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FvjXR2rzh6v5EBUzBbsvFV
@BorisTyshkevich
BorisTyshkevich merged commit 2992e5b into main Jul 16, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant