Skip to content

fix(cli): exec start wrappers and bump postgres-meta so docker stop is not 10s (CLI-2192) - #6203

Open
avallete wants to merge 5 commits into
avallete/shadow-db-perf-6ad622from
avallete/fast-stop-exec-wrappers
Open

fix(cli): exec start wrappers and bump postgres-meta so docker stop is not 10s (CLI-2192)#6203
avallete wants to merge 5 commits into
avallete/shadow-db-perf-6ad622from
avallete/fast-stop-exec-wrappers

Conversation

@avallete

@avallete avallete commented Aug 14, 2026

Copy link
Copy Markdown
Member

Full-stack supabase stop --no-backup was gated by Docker's 10s SIGTERM grace period: six long-running containers either kept sh as PID 1 (signal never forwarded) or hung in their own shutdown handler, and stops run in parallel, so wall time = slowest container + prune.

What changed

exec in every CLI-authored wrapper — the real process replaces sh as PID 1 (deliberate divergence from Go's scripts; stop timing is outside the Go-parity surface, ADR 0016). Command paths, output, exit codes, telemetry, and documented side effects unchanged; no -t, no docker rm -f, no grace-period env:

Logflare: trap-and-escalate supervisor — measured with beam.smp as PID 1 (a plain exec chain), docker stop still burned the full grace period: Logflare's own SIGTERM shutdown hangs upstream, the same class of problem postgres-meta#1103 fixed for pg-meta. So run.sh's shell stays PID 1 deliberately with a real handler: forward SIGTERM to the BEAM, give its graceful shutdown 3s, then SIGKILL. Today's post-timeout outcome is already SIGKILL, so this is the identical end state ~7s sooner — and the graceful window wins first if upstream fixes its handler. Exit codes are preserved via the interrupted-wait idiom (validated in isolation: hung child stops in ~3.4s with exit 137; a clean child's exit code propagates untouched). migrate && start sequencing unchanged (#6088).

postgres-meta v0.98.0 — released 2026-08-14, tag verified identical to the postgres-meta#1103 merge commit (fixes the circular onClose hang that made v0.97.0 ride close-with-grace's 10s timeout). Dockerfile pin bumped + versions synced.

Measured (real full stack, analytics enabled, Docker 29/OrbStack, CLI run from source)

Per-container docker stop -t 10, develop → this branch:

Container PID 1 before → after Stop before Stop after
pg_meta node (v0.97.0 hang) → node (v0.98.0) ~11.7s 0.24s
kong sh -cnginx ~11.1s 0.34s
vector sh -cvector ~10.8s 0.42s
edge_runtime sh -cedge-runtime ~10.7s 0.53s
analytics (logflare) sh -c → supervised sh run.sh ~11.2s ~3s (TERM → 3s grace → KILL)
db sh -cpostgres ~10.5s ~4s (Postgres's own fast shutdown)

Full stop --no-backup wall: 15.8s → 6.58s (analytics on; a default stack with analytics off is gated by Postgres alone). Remaining upstream nicety: a Logflare image whose SIGTERM handler actually completes would let the supervisor's graceful window win and shave the last ~3s — tracked in CLI-2192.

🤖 Generated with Claude Code

@avallete
avallete requested a review from a team as a code owner August 14, 2026 18:11
@avallete avallete changed the title fix(cli): exec start wrappers and bump postgres-meta so docker stop is not 10s fix(cli): exec start wrappers and bump postgres-meta so docker stop is not 10s (CLI-2192) Aug 14, 2026
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Supabase CLI preview

npx --yes https://pkg.pr.new/supabase/cli/supabase@2c0c7906c9896cc5541ee36ffbbd6e8ea5cc4bf0

Preview package for commit 2c0c790.

@avallete
avallete force-pushed the avallete/fast-stop-exec-wrappers branch from 2383507 to 6c58a71 Compare August 15, 2026 08:26
code: LEGACY_PG_DELTA_NEXT_SKIPPED_STATEMENT_CODE,
severity: "warning",
subject: entry.file,
message: `pg-delta could not load a declarative schema statement from ${entry.file}: ${entry.stmt}`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Severity: MEDIUM

planSchemaFiles' skipped statement is copied verbatim into the diagnostic message, so declarative CREATE ROLE ... PASSWORD 'secret' SQL reaches debug logging with PGDELTA_DEBUG and terminal output with --strict-coverage. This exposes credential-bearing project SQL in CI or shell logs, despite raw statements being intended as detail-only.
Helpful? Add 👍 / 👎

💡 Fix Suggestion

Suggestion: Remove ${entry.stmt} from the message template string. The raw SQL statement is already captured safely in context.statement (intended as detail-only), which aligns with the JSDoc comment that explicitly states 'The raw statement stays in context/detail rather than the aggregate warning, since a skipped CREATE ROLE can carry a password.' The message field should only reference the file name to avoid exposing credential-bearing SQL (e.g., CREATE ROLE ... PASSWORD 'secret') in debug logs and terminal output.

⚠️ Experimental Feature: This code suggestion is automatically generated. Please review carefully.

Suggested change
message: `pg-delta could not load a declarative schema statement from ${entry.file}: ${entry.stmt}`,
message: `pg-delta could not load a declarative schema statement from ${entry.file}`,

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6c58a710cf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

code: LEGACY_PG_DELTA_NEXT_SKIPPED_STATEMENT_CODE,
severity: "warning",
subject: entry.file,
message: `pg-delta could not load a declarative schema statement from ${entry.file}: ${entry.stmt}`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep skipped SQL out of user-facing diagnostics

When a skipped declarative statement contains a secret, such as CREATE ROLE ... PASSWORD ..., this embeds the complete SQL in the diagnostic message. legacyReportPgDeltaNextDiagnostics emits that message to stderr whenever --strict-coverage or debug diagnostics are enabled, despite the adjacent comment saying raw SQL should remain only in diagnostic context, so credentials can be exposed in terminals and captured logs. Keep the message limited to the filename and store the statement only in the non-rendered context.

Useful? React with 👍 / 👎.

Comment on lines +201 to +203
const targetPath = path.join(declarativeDir, file.name);
yield* fs.makeDirectory(path.dirname(targetPath), { recursive: true });
yield* fs.writeFileString(targetPath, file.sql);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject symlinked export destinations before writing

When the declarative directory comes from an untrusted checkout and an exported filename already exists as a symlink, this write follows the link and overwrites its target outside the declarative tree. readManagedDeclarativeSqlFiles deliberately skips symlinks, but that makes the destination appear newly created and does not remove or reject the link before writeFileString; nested symlinked directories have the same problem. Verify every destination component without following links or replace symlinks safely before writing.

Useful? React with 👍 / 👎.

Comment on lines +335 to +339
const result = yield* pgDelta.diffExplicit({
context: explicitCtx,
toml: cfg,
source,
desired,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve the config snapshot for migrations endpoints

For db diff --from migrations --to linked, source is captured before the linked target is resolved, but it no longer captures the current cfg; resolving desired then replaces cfg with the linked project's remote-merged config, and this final value is passed to both endpoints. Consequently the migrations shadow/catalog can be built with remote overrides that occur later in argument resolution, unlike the previous implementation that provisioned it immediately from the base config, producing a diff against the wrong PostgreSQL image or platform baseline. Store the TOML/context with each migrations endpoint when it is resolved rather than passing one final cfg.

AGENTS.md reference: apps/cli/AGENTS.md:L53-L56

Useful? React with 👍 / 👎.

Comment on lines +18 to +23
output: Flag.string("output").pipe(
Flag.withAlias("o"),
Flag.withDescription(
"Write the generated declarative schema to this directory without changing the configured declarative schema path.",
),
Flag.optional,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Record the new output flag as a Go divergence

This adds the TS-only db schema declarative generate --output flag, but the accompanying docs/go-cli-divergences.md update records only --strict-coverage. Add --output to the flag-divergence section so the documented parity surface remains complete as required for every new legacy-shell flag with no Go equivalent.

AGENTS.md reference: apps/cli/AGENTS.md:L540-L544

Useful? React with 👍 / 👎.

* like an unmodeled object kind. Silently dropping these would let a statement the
* user wrote in a declarative file vanish from the plan with no signal at all.
*/
export const LEGACY_PG_DELTA_NEXT_SKIPPED_STATEMENT_CODE = "skipped_statement";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Rename the new uppercase legacy exports

The newly exported LEGACY_PG_DELTA_NEXT_SKIPPED_STATEMENT_CODE does not use the mandatory Legacy or legacy prefix convention; LEGACY_ENABLE_LOCAL_WEBHOOKS_SUGGESTION introduced in the same commit has the same issue. Rename both exports and their imports so legacy-only symbols do not pollute completion and the namespace remains unambiguous.

AGENTS.md reference: apps/cli/AGENTS.md:L235-L249

Useful? React with 👍 / 👎.

const migrationEntries = yield* fs.readDirectory(migrationsDir).pipe(
Effect.catchTag("PlatformError", (error) =>
error.reason._tag === "NotFound"
? Effect.succeed([] as ReadonlyArray<string>)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Remove the production type assertion

The [] as ReadonlyArray<string> assertion papers over the differing success types in this Effect branch, contrary to the workspace requirement to resolve Effect typing without as casts. Give Effect.succeed an explicit result type or restructure the branch so inference produces the intended readonly array without an assertion.

AGENTS.md reference: apps/cli/AGENTS.md:L99-L99

Useful? React with 👍 / 👎.

@avallete
avallete force-pushed the avallete/fast-stop-exec-wrappers branch from 6c58a71 to 4d6fac4 Compare August 15, 2026 09:06
@avallete
avallete changed the base branch from develop to avallete/shadow-db-perf-6ad622 August 15, 2026 09:08
@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

yield* fs.writeFileString(path.join(debugDir, name), contents);

P2 Badge Restrict pg-delta debug artifacts to the current user

When PGDELTA_DEBUG is enabled, diagnostics.json includes each skipped statement from context.statement, including possible CREATE ROLE ... PASSWORD ... SQL, but these writes use the default mode (typically 0644 under umask 022). On a shared machine, another local user can therefore read credentials from the persistent debug bundle even if the separately flagged stderr rendering is removed. Create the directory as 0700 or write every artifact as 0600, as the PGDATA snapshot path already does.


// Same policy as `legacyWaitForHealthyServices` (Go's
// `NewBackoffPolicy(ctx, timeout)`): a 1-second constant delay, capped at
// `timeoutSeconds` retries after the initial attempt.
const schedule = Schedule.max([Schedule.spaced("1 seconds"), Schedule.recurs(timeoutSeconds)]);

P2 Badge Enforce the configured readiness deadline

When a Postgres connection attempt consumes its new 2-second connect timeout—for example, while Docker Desktop routing is black-holed—this schedule still performs timeoutSeconds retries and sleeps another second between them. Thus the default nominal 30-second readiness budget can take roughly 90 seconds before failing, unlike the previous fast Docker-inspect probes and contrary to this function's timeout contract. Apply a wall-clock timeout to the whole retry effect or derive the remaining deadline before each attempt.


dbSettings: input.db.settings,
storageTargetMigration: input.setup.storageTargetMigration,
autoExposeNewTables: input.setup.apiAutoExposeNewTables,
rolesSql,
vault: input.setup.vault,
jwks,
services: {

P1 Badge Key cached shadows by the effective webhooks baseline

When [experimental.webhooks].enabled changes, or a project with Webhooks disabled switches between migra/legacy pg-delta and pg-delta next, this key remains unchanged even though legacyMigrateShadowDatabase force-installs pg_net while legacyMigrateNextShadowDatabase follows the config value. A warm restore can therefore give the next engine a source baseline containing pg_net when it should not (or omit it for a legacy engine), producing a spurious extension drop/add in the generated migration. Include the effective Webhooks/baseline mode in the cache key so snapshots are never shared across these distinct baselines.

AGENTS.md reference: apps/cli/AGENTS.md:L387-L394


function maskSqlNonCode(sql: string): string {
return sql.replaceAll(
/--[^\r\n]*|\/\*[\s\S]*?\*\/|'(?:''|[^'])*'|\$(?:[a-zA-Z_][\w$]*)?\$[\s\S]*?\$(?:[a-zA-Z_][\w$]*)?\$/g,
(matched) => matched.replaceAll(/[^\r\n]/g, " "),

P2 Badge Match dollar-quote closing tags before masking SQL

When a declarative function uses a tagged outer body and a differently tagged inner string, such as $function$ ... $sql$CREATE EXTENSION pgcrypto$sql$ ... $function$, this regex closes the outer match at the first $sql$ because it does not require the closing tag to equal the opening tag. The inner CREATE EXTENSION is then treated as top-level code, so legacyDeclaredExtensions incorrectly considers the extension declared and suppresses the compatibility repair even though loading the file never executes that dynamic SQL. Use a backreference-aware scanner so each dollar-quoted region closes only on its own tag.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@avallete
avallete force-pushed the avallete/fast-stop-exec-wrappers branch from 4d6fac4 to 7e0315c Compare August 15, 2026 09:58

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7e0315c7be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"./logflare eval Logflare.Release.migrate || exit $?\n" +
"./logflare start --sname logflare &\n" +
"BEAM_PID=$!\n" +
'trap \'kill -TERM "$BEAM_PID" 2>/dev/null; n=0; while [ "$n" -lt 3 ] && kill -0 "$BEAM_PID" 2>/dev/null; do n=$((n+1)); sleep 1; done; kill -KILL "$BEAM_PID" 2>/dev/null\' TERM\n' +

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Cover the new shutdown supervisor with a live test

When analytics is enabled, this supervisor's correctness depends on real PID-1 signal delivery and the Logflare image's shutdown behavior, but the added unit test only compares the generated shell string. I checked the existing start.live.test.ts and stop.live.test.ts: neither starts analytics/Logflare and measures its shutdown, so CI cannot detect this trap failing and restoring Docker's 10-second timeout. Add or extend a real-Docker live scenario that enables analytics and verifies the bounded stop behavior.

AGENTS.md reference: apps/cli/AGENTS.md:L520-L523

Useful? React with 👍 / 👎.

avallete and others added 3 commits August 15, 2026 14:44
…s not 10s

Full-stack `supabase stop --no-backup` is gated by a 10s Docker SIGTERM
grace period: five long-running containers keep `sh` (or a hung Node
shutdown) as PID 1, so SIGTERM never reaches the real process and every
`docker stop` burns the full timeout before SIGKILL. Stops run in
parallel, so wall time = slowest container.

Workstream A — `exec` the real process in every CLI-authored wrapper,
the same deliberate divergence from Go's scripts as the Postgres
entrypoint (timing is outside the Go-parity surface, ADR 0016):

- Kong: `exec ./docker-entrypoint.sh kong docker-start …`
- Vector: `exec vector --config …` (the Logflare wget wait-loop still
  runs in the wrapper shell before the exec)
- Logflare: `exec sh run.sh` outer + `exec ./logflare start` inside
  run.sh (the migrate && start sequencing is unchanged — #6088)
- Edge runtime: `exec edge-runtime start …` in the long-lived serve/
  start container, and in the ephemeral script-runner for cancellation
  latency

Workstream B — postgres-meta v0.98.0 (released today, contains
postgres-meta#1103, which fixes the circular onClose hang that made
v0.97.0 ride the close-with-grace 10s timeout; the canary measured
~230-320ms). Dockerfile pin bumped + versions synced.

Command paths, stdout/stderr text, exit codes, telemetry, and
documented side effects are unchanged; no `-t`, no `docker rm -f`, no
grace-period env.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Measured on a real stack: with beam.smp as PID 1 (both execs in place),
docker stop -t 10 on the logflare container still burns the full grace
period (~10.5s) — Logflare's own SIGTERM shutdown hangs upstream, the
same class of problem postgres-meta#1103 fixed for pg-meta. The execs
stay (necessary, one less layer, load-bearing once upstream fixes its
handler); the comment no longer claims they alone fix stop time.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… stop finishes in seconds

Two additions to the fast-stop work:

- The three postgres entrypoint variants exec docker-entrypoint.sh, so
  Postgres is PID 1 and docker stop's SIGTERM triggers its own fast
  shutdown (~4s) instead of burning the 10s grace period. Same change
  #6184 carries for the shadow's benefit; included here so stop is fast
  without waiting on that PR.
- Logflare gets a trap-and-escalate supervisor instead of a bare exec:
  measured with beam.smp as PID 1, docker stop STILL burned the full
  grace period (Logflare's SIGTERM shutdown hangs upstream, the class
  of problem postgres-meta#1103 fixed for pg-meta). run.sh's shell now
  stays PID 1 deliberately, forwards SIGTERM to the BEAM, waits up to
  3s for a graceful exit, then SIGKILLs — the same end state as today's
  post-timeout kill, ~7s sooner, and the graceful path wins first if
  upstream ever fixes its handler. Exit codes are preserved via the
  interrupted-wait idiom (validated: hung child stops in ~3.4s exit
  137; clean child exit code propagates).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@avallete
avallete force-pushed the avallete/fast-stop-exec-wrappers branch from 7e0315c to 787493f Compare August 15, 2026 12:58

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 787493f3bd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// without it every stop burns the full 10s grace period. The wget wait-loop above still runs
// in the wrapper shell BEFORE the exec, unchanged. Stop timing is outside the Go-parity
// surface (ADR 0016).
":4000/health 2>/dev/null; do sleep 2; done\nexec vector --config /etc/vector/vector.yaml\n"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle SIGTERM while Vector is polling

When Vector restarts while Logflare is unhealthy, this loop can run indefinitely and execution never reaches the new exec. The shell therefore remains PID 1 and does not forward Docker's stop signal to the active wget/sleep; Docker then waits for its grace timeout before killing the container, so the latency regression this change addresses remains in this failure state. Install a TERM handler around the polling phase (then reset it before exec) and exercise the unhealthy-Logflare path in the required real-Docker live test. Docker documents that stop signals the container's main process and force-kills it after the timeout.

AGENTS.md reference: apps/cli/AGENTS.md:L520-L523

Useful? React with 👍 / 👎.

const LEGACY_LOGFLARE_ENTRYPOINT_SCRIPT =
"cat <<'EOF' > run.sh && sh run.sh\n./logflare eval Logflare.Release.migrate &&\n./logflare start --sname logflare\nEOF\n";
"cat <<'EOF' > run.sh && exec sh run.sh\n" +
"./logflare eval Logflare.Release.migrate || exit $?\n" +

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Install the Logflare TERM trap before migration

When supabase stop or startup rollback runs while Logflare.Release.migrate is still executing, run.sh is already PID 1 but the TERM trap has not yet been installed. Docker signals only that main shell process; it does not signal the foreground migration child, and PID 1's unhandled terminating signal is ignored, so the stop still reaches Docker's grace timeout and ends in SIGKILL. Install the handler before starting the migration (and make it terminate the migration phase as well) so shutdown is bounded throughout container startup, not only after the BEAM has launched.

Useful? React with 👍 / 👎.

Comment on lines 180 to +181
"cat <<'EOF' > /home/kong/custom_nginx.template && \\\n" +
"./docker-entrypoint.sh kong docker-start --nginx-conf /home/kong/custom_nginx.template\n";
"exec ./docker-entrypoint.sh kong docker-start --nginx-conf /home/kong/custom_nginx.template\n";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Record the PID-1 changes in the Go divergence ledger

This intentionally changes legacy Docker behavior relative to the Go reference for Kong, Vector, Logflare, Edge Runtime, and functions serve, but docs/go-cli-divergences.md contains no entry for the new PID-1/signal-handling behavior. Add one behavioral-divergence entry covering these wrappers so support and future parity work do not mistake the changed shutdown semantics for accidental drift.

AGENTS.md reference: apps/cli/AGENTS.md:L540-L544

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4d61ad81e9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

name: "realtime",
configKey: "realtime",
defaultVersion: "2.123.1",
defaultVersion: "2.124.4",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Sync all stack defaults to the Dockerfile manifest

When a consumer relies on @supabase/stack defaults, this partial update still selects Realtime 2.124.4 and Storage 1.69.0 even though apps/cli-go/pkg/config/templates/Dockerfile:14-15 pins 2.128.0 and 1.69.9. The package's sync:versions --check logic derives every catalog entry from that manifest, so the catalog remains out of sync and programmatic stacks run a different service set than supabase start; regenerate both changed entries from the current Dockerfile.

Useful? React with 👍 / 👎.

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