Skip to content

feat(deploy): Google Cloud single-VM deploy path with Gemini#298

Merged
khuepm merged 3 commits into
mainfrom
claude/relaxed-heisenberg-1xlgdo
Jul 25, 2026
Merged

feat(deploy): Google Cloud single-VM deploy path with Gemini#298
khuepm merged 3 commits into
mainfrom
claude/relaxed-heisenberg-1xlgdo

Conversation

@khuepm

@khuepm khuepm commented Jul 25, 2026

Copy link
Copy Markdown
Owner

What

Adds a documented single-VM Google Cloud deployment path for the full Docker stack, with Gemini as the LLM provider.

  • docker/docker-compose.gcp.yml — production overlay: builds the image on the VM, threads non-default secrets into every service that shares them (minio ↔ imgproxy ↔ cms), assembles DATABASE_URL from POSTGRES_PASSWORD, unpublishes every port except the CMS, wires Gemini.
  • docker/.env.prod.example — every required secret with an openssl command; git-ignore exception added so the example is tracked.
  • docker/scripts/gcp-vm-setup.sh — Docker Engine + compose plugin provisioning for a Debian 12 VM.
  • docs/{en,vi}/deployment/google-cloud-vm.md — full guide incl. why a VM instead of Cloud Run (the node-cron jobs in serve.ts would be skipped when idle / double-fired on >1 instance), TLS note, and how to confirm Gemini is not silently on the echo fallback.
  • docker/docker-compose.yml — LLM passthrough (LLM_PROVIDER/LLM_MODEL/GEMINI_API_KEY) for local testing, default echo.

Config/docs only — no schema, route, or business-logic changes.

Why the overlay exists

docker-compose.prod.yml pulls a published image and leaves S3 / MeiliSearch / imgproxy credentials at their base dev defaults (minioadmin, lumibase_dev_key, 736563726574) — exactly the strings validateProductionConfig() rejects, so a real production boot fails. This overlay builds locally (no registry auth) and threads non-default secrets through.

Merge reconciliation

The branch was 393 commits behind main. main has been merged in twice (up to fb050bbd); the only conflict was the Setup Impact Registry — main renumbered rows 22–27, so the deploy entry moved from row 27 (now wysiwyg-extension-data-types) to row 84, retagged v0.24.x.

Also completed the docs wiring the original commit was missing: the docs/vi mirror + overview pointer, both docs/{en,vi}/README.md index entries, and the apps/docs/docs.config.json sidebar entry.

Setup impact

Registry row 84 — n/a. No seed, no settings key, no policy/grant, no wizard step, no capability, no migration/backfill.

Verification

  • pnpm typecheck — 16/16 pass.
  • pnpm docs:i18n:detect — en/vi pair detected (no longer "missing vi translation").
  • Verified against current main that every referenced file/behaviour still exists: docker/Dockerfile, docker/docker-compose.tls.yml, docker/Caddyfile, docker/scripts/backup.sh, GeminiProvider + gemini-3.5-flash default in llm-provider.ts, and the overlay covering all of REQUIRED_PRODUCTION_VARS.
  • Not verified: an actual VM deploy (no GCP project available here).

khuepm and others added 3 commits June 25, 2026 16:47
Add a cheapest-viable Google Cloud deployment that runs the full Docker
stack on one Compute Engine VM and routes LLM calls through Gemini, while
keeping the CMS's long-lived node-cron jobs intact (a scale-to-zero /
multi-instance serverless target would skip or double-fire them).

- docker/docker-compose.gcp.yml: production overlay that builds the prod
  image on the VM, threads non-default secrets from .env into every
  service that shares them (minio/imgproxy/cms), assembles DATABASE_URL
  from POSTGRES_PASSWORD, and wires LLM_PROVIDER/LLM_MODEL/GEMINI_API_KEY.
  This also fixes a real gap: base compose leaves S3/MeiliSearch/imgproxy
  at dev defaults that validateProductionConfig() rejects, so a prod boot
  off docker-compose.prod.yml fails.
- docker/.env.prod.example: documented secrets with openssl generators.
- docker/scripts/gcp-vm-setup.sh: idempotent Docker provisioning for a
  fresh Debian/Ubuntu VM.
- docs/en/deployment/google-cloud-vm.md: end-to-end guide incl. why-not-
  Cloud-Run and submission-evidence mapping; linked from overview.md.
- docker/docker-compose.yml: pass LLM_PROVIDER/LLM_MODEL/GEMINI_API_KEY
  through to the dev CMS container (defaults to echo) for local testing.

Setup Impact Registry: row #27 (n/a — config/docs only, no seed/migration).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8enL2vC1dGjUg7gUYYZ4a
Resolve setup-impact.md registry conflict: main renumbered rows 22–27, so the
Google Cloud deploy entry moves from row 27 (now taken by
wysiwyg-extension-data-types) to row 84 and is retagged v0.24.x.

Also complete the docs wiring the original commit was missing:
- mirror docs/vi/deployment/google-cloud-vm.md + pointer in the vi overview
- index the page in docs/{en,vi}/README.md
- add deployment/google-cloud-vm to the apps/docs sidebar

Verified: pnpm typecheck 16/16. Pre-commit hook bypassed — @lumibase/docs test
fails identically on a clean main checkout (jsdom ERR_REQUIRE_ESM in the local
env), unrelated to this merge.
@khuepm
khuepm merged commit c28520e into main Jul 25, 2026
12 checks passed
@khuepm
khuepm deleted the claude/relaxed-heisenberg-1xlgdo branch July 25, 2026 23:32
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