Skip to content

fix(hosting): bundled PostgreSQL for one-click installs (#3159); version 1.0.0-aws.1 - #3147

Merged
vybe merged 2 commits into
devfrom
chore/release-1.0.0-aws.1
Oct 1, 2026
Merged

vybe merged 2 commits into
devfrom
chore/release-1.0.0-aws.1

Conversation

@obasilakis

@obasilakis obasilakis commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Two changes, one review, before the v1.0.0-aws.1 RC tag:

  1. bug: one-click hosted installs (DigitalOcean 1-Click first) create new instances on SQLite after its end-of-support — bundle PostgreSQL in the hosted compose #3159: hosted installs (DigitalOcean 1-Click, AWS AMI, Vultr, compose-only templates) start on a PostgreSQL service bundled in docker-compose.hosted.yml. SQLite reached end-of-support on 2026-09-01 (Define SQLite end-of-support date + Postgres migration release notes #1278).
  2. Version: VERSION and the DigitalOcean installer's default tag (pinned by test_2380_installer_release_pin.py) set to 1.0.0-aws.1. After merge, v1.0.0-aws.1 is tagged on dev so publish-images.yml publishes the images the AWS AMI (feat: AWS one-click — Marketplace free AMI (Launch from Website) + CloudFormation Launch Stack link #3004) is built from. The hyphen makes it a pre-release: latest does not move, nothing merges to main.

Changes (#3159)

  • docker-compose.hosted.yml: postgres service (postgres:16-alpine, volume postgres-data, *default-logging, no-new-privileges, TCP pg_isready healthcheck, no published port), on trinity-platform-network only. Backend and scheduler depends_on: postgres: service_healthy. POSTGRES_PASSWORD is required (:?).
  • Backend + scheduler: DATABASE_URL=${DATABASE_URL-postgresql://trinity:${POSTGRES_PASSWORD}@postgres:5432/trinity}.
  • start.sh ensure_hosted_database (hosted only; after the HOST-015 data-switch guard, before compose pull).
  • packer/digitalocean/scripts/01-provision.sh pre-pulls postgres:16-alpine (the AWS AMI reuses the script).
  • test_2280_hosted_compose_parity.py allowlists the hosted-only service, volume, depends_on edges and DATABASE_URL lines by name. CI compose render (container-security.yml) and the local render tests (test_2528, test_ent580) supply POSTGRES_PASSWORD.
  • Docs: requirement HOST-022 (requirements/infrastructure.md), SQLITE_TO_POSTGRES.md hosted section, DEPLOYMENT.md, .env.example, DO + AWS listings, DO deploy guide, network topology table in architecture.md.

Decisions

  • Fresh detection: no DATABASE_URL in the shell or .env (any line, even empty, counts as decided) AND no <TRINITY_DATA_PATH or ./trinity-data>/trinity.db. Then start.sh writes the bundled URL.
  • Existing SQLite install: start.sh writes DATABASE_URL= (empty), which keeps SQLite, and prints the SQLITE_TO_POSTGRES.md pointer on every run. POSTGRES_PASSWORD is still generated so the file renders; the postgres container runs idle (~45 MiB measured on an empty init). An existing DATABASE_URL is never rewritten.
  • Compose-only default: - with no colon. Unset → bundled PostgreSQL (compose-only consumers get Postgres); set-but-empty → SQLite. A manual update that skips start.sh has no POSTGRES_PASSWORD and fails to render before it can switch the database. feat: community one-click paths — "Deploy on Hostinger" button + Dokploy template (Coolify queued at 1,000 stars) #2283 (compose-only channels) is still open, so no compose-only SQLite installs exist yet.
  • Password safety: if the postgres-data volume exists and .env has no POSTGRES_PASSWORD, start.sh refuses (the image applies the password only at init).
  • Backups (bug: shipped database backup tooling is never invoked — no scheduled backups, no recovery point #2216): backend image ships postgresql-client-17; pg_dump 17 dumps a 16 server. A test pins client major ≥ hosted server major.
  • prod compose unchanged: it keeps the operator-managed database.

Test plan

  • pytest tests/unit/test_3159_hosted_postgres.py tests/unit/test_2280_hosted_compose_parity.py tests/unit/test_2528_compose_file_sets.py tests/unit/test_ent580_marketplace_admin_claim.py: 91 passed
  • Every test grepping start.sh / hosted compose / packer (grep -rlE "start\.sh|docker-compose.hosted|01-provision|firstboot" tests/unit) + new file: all pass except test_2582_portal_uploads.py::test_read_inbox_populates_mime_from_the_extension, which fails identically on origin/dev (local mimetypes).
  • Full tests/unit: 20159 passed; the remaining failures (IPv6/SSRF suites, route census, error-code header, 2582 mime: 24 failed, 2 errors) reproduce identically on a clean origin/dev checkout with local Python 3.11.
  • bash -n on start.sh and 01-provision.sh.
  • docker compose --env-file /dev/null -f docker-compose.hosted.yml config (Compose v2.39.4): without POSTGRES_PASSWORD → required variable POSTGRES_PASSWORD is missing a value; with it and DATABASE_URL unset → DATABASE_URL: postgresql://trinity:…@postgres:5432/trinity on backend + scheduler; with .env DATABASE_URL= → DATABASE_URL: ""; postgres networks ['trinity-platform']; hosted + override renders.
  • postgres:16-alpine starts under no-new-privileges:true and answers over TCP.

Unverified here (live ACs, stay on #3159)

Fixes #3159
Refs #3004

🤖 Generated with Claude Code

obasilakis and others added 2 commits October 1, 2026 15:45
Throwaway pre-release so the AWS Marketplace AMI (#3004) can be built from
published images. A later 1.0.0 candidate supersedes it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
SQLite reached end-of-support on 2026-09-01. Every one-click channel runs
docker-compose.hosted.yml through start.sh --hosted (or the compose file
alone), so the default changes there.

- docker-compose.hosted.yml: `postgres` service (postgres:16-alpine,
  postgres-data volume, pg_isready healthcheck, *default-logging,
  no-new-privileges, platform network only). Backend and scheduler wait
  for it healthy. POSTGRES_PASSWORD is required to render.
  DATABASE_URL=${DATABASE_URL-<bundled url>}: unset uses the bundled
  server, set-but-empty keeps SQLite.
- start.sh ensure_hosted_database: generates POSTGRES_PASSWORD (refuses if
  the postgres-data volume exists without one); with no DATABASE_URL in
  the shell or .env, writes the bundled URL on a fresh install and
  `DATABASE_URL=` when trinity.db exists, then prints the
  SQLITE_TO_POSTGRES.md pointer while the install stays on SQLite. Runs
  after the data-switch guard and before compose pull.
- Packer provision pre-pulls postgres:16-alpine (DO and AWS).
- Parity test allowlists the hosted-only service, volume, depends_on and
  DATABASE_URL lines; CI compose render exports POSTGRES_PASSWORD.
- Docs: HOST-022, SQLITE_TO_POSTGRES.md hosted section, DEPLOYMENT.md,
  .env.example, DO and AWS listings, DO deploy guide, topology table.

Live ACs (droplet boot, 4 GB RSS, nightly .dump on a droplet, mp-submit)
remain on the issue.

Refs #3159

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@obasilakis
obasilakis force-pushed the chore/release-1.0.0-aws.1 branch from c20e88c to 3d79e01 Compare October 1, 2026 14:29
@obasilakis obasilakis changed the title chore: set version to 1.0.0-aws.1 fix(hosting): bundled PostgreSQL for one-click installs (#3159); version 1.0.0-aws.1 Oct 1, 2026
@vybe vybe added the ui PR touches the frontend UI — triggers Playwright e2e tests label Oct 1, 2026
@vybe

vybe commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

merge-train: on this train. I made two mechanical changes:

Recorded, not blocking:

  • On an existing SQLite install, the backend and scheduler still depends_on an idle Postgres becoming healthy.
  • The droplet, 4 GB memory and nightly .dump checks are still unverified, as the body says.
  • docker compose -f docker-compose.hosted.yml ps/logs fails between git checkout <tag> and start.sh --hosted on old installs. That's worth one line in the upgrade docs.

@vybe vybe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge-train: batch validated on train #3172

@vybe
vybe merged commit 77d5184 into dev Oct 1, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ui PR touches the frontend UI — triggers Playwright e2e tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants