Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"dbHealthTimeoutSeconds": 120,
"majorVersion": 17,
"orioledbVersion": null,
"postgresConfigImage": "supabase/postgres:17.11.0.005",
"postgresImage": "supabase/postgres:17.11.0.005",
"postgresConfigImage": "supabase/postgres:17.11.0.006",
"postgresImage": "supabase/postgres:17.11.0.006",
"realtimeEnabledForSetup": true,
"realtimeIpVersion": "IPv4",
"realtimeMaxHeaderLength": 4096,
Expand All @@ -32,7 +32,7 @@
"experimental": false,
"networkId": "supabase_network_shell-project-id",
"postgresSpecBase": {
"configImage": "supabase/postgres:17.11.0.005",
"configImage": "supabase/postgres:17.11.0.006",
"db": {
"health_timeout": "2m",
"major_version": 17,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"dbHealthTimeoutSeconds": 120,
"majorVersion": 17,
"orioledbVersion": null,
"postgresConfigImage": "supabase/postgres:17.11.0.005",
"postgresImage": "supabase/postgres:17.11.0.005",
"postgresConfigImage": "supabase/postgres:17.11.0.006",
"postgresImage": "supabase/postgres:17.11.0.006",
"realtimeEnabledForSetup": false,
"realtimeIpVersion": "IPv4",
"realtimeMaxHeaderLength": 4096,
Expand All @@ -32,7 +32,7 @@
"experimental": false,
"networkId": "supabase_network_abcdefghijklmnopqrst",
"postgresSpecBase": {
"configImage": "supabase/postgres:17.11.0.005",
"configImage": "supabase/postgres:17.11.0.006",
"db": {
"health_timeout": "2m",
"major_version": 17,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"dbHealthTimeoutSeconds": 120,
"majorVersion": 17,
"orioledbVersion": null,
"postgresConfigImage": "supabase/postgres:17.11.0.005",
"postgresImage": "supabase/postgres:17.11.0.005",
"postgresConfigImage": "supabase/postgres:17.11.0.006",
"postgresImage": "supabase/postgres:17.11.0.006",
"realtimeEnabledForSetup": true,
"realtimeIpVersion": "IPv4",
"realtimeMaxHeaderLength": 4096,
Expand All @@ -32,7 +32,7 @@
"experimental": false,
"networkId": "supabase_network_abcdefghijklmnopqrst",
"postgresSpecBase": {
"configImage": "supabase/postgres:17.11.0.005",
"configImage": "supabase/postgres:17.11.0.006",
"db": {
"health_timeout": "2m",
"major_version": 17,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"dbHealthTimeoutSeconds": 120,
"majorVersion": 17,
"orioledbVersion": null,
"postgresConfigImage": "supabase/postgres:17.11.0.005",
"postgresImage": "supabase/postgres:17.11.0.005",
"postgresConfigImage": "supabase/postgres:17.11.0.006",
"postgresImage": "supabase/postgres:17.11.0.006",
"realtimeEnabledForSetup": true,
"realtimeIpVersion": "IPv4",
"realtimeMaxHeaderLength": 4096,
Expand All @@ -32,7 +32,7 @@
"experimental": false,
"networkId": "supabase_network_golden-shadow",
"postgresSpecBase": {
"configImage": "supabase/postgres:17.11.0.005",
"configImage": "supabase/postgres:17.11.0.006",
"db": {
"health_timeout": "2m",
"major_version": 17,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"dbHealthTimeoutSeconds": 120,
"majorVersion": 17,
"orioledbVersion": null,
"postgresConfigImage": "supabase/postgres:17.11.0.005",
"postgresImage": "supabase/postgres:17.11.0.005",
"postgresConfigImage": "supabase/postgres:17.11.0.006",
"postgresImage": "supabase/postgres:17.11.0.006",
"realtimeEnabledForSetup": false,
"realtimeIpVersion": "IPv4",
"realtimeMaxHeaderLength": 4096,
Expand All @@ -32,7 +32,7 @@
"experimental": false,
"networkId": "supabase_network_golden-shadow",
"postgresSpecBase": {
"configImage": "supabase/postgres:17.11.0.005",
"configImage": "supabase/postgres:17.11.0.006",
"db": {
"health_timeout": "2m",
"major_version": 17,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"dbHealthTimeoutSeconds": 120,
"majorVersion": 17,
"orioledbVersion": null,
"postgresConfigImage": "supabase/postgres:17.11.0.005",
"postgresImage": "supabase/postgres:17.11.0.005",
"postgresConfigImage": "supabase/postgres:17.11.0.006",
"postgresImage": "supabase/postgres:17.11.0.006",
"realtimeEnabledForSetup": false,
"realtimeIpVersion": "IPv4",
"realtimeMaxHeaderLength": 4096,
Expand All @@ -32,7 +32,7 @@
"experimental": false,
"networkId": "supabase_network_golden-shadow",
"postgresSpecBase": {
"configImage": "supabase/postgres:17.11.0.005",
"configImage": "supabase/postgres:17.11.0.006",
"db": {
"health_timeout": "2m",
"major_version": 17,
Expand Down
4 changes: 2 additions & 2 deletions apps/cli/src/shared/services/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
# a catalog update. Everything else in this file (this comment, kong, pg14, the one-shot job
# images) is hand- or Dependabot-managed. Keep a line between image lines: git conflicts on edits to
# adjacent lines, and catalog PRs for neighbouring aliases are often open at the same time.
FROM supabase/postgres:17.11.0.005 AS pg
FROM supabase/postgres:17.11.0.006 AS pg

FROM supabase/postgres:15.19.0.005 AS pg15
FROM supabase/postgres:15.19.0.006 AS pg15
# Postgres 14 has no slim build; bumped by hand (Dependabot ignores supabase/postgres).
FROM supabase/postgres:14.1.0.89 AS pg14
# New always-on service alias: extend SERVICE_IMAGE_ALIASES in
Expand Down
59 changes: 40 additions & 19 deletions packages/stack/src/Artifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,23 +114,23 @@ const definitions: Readonly<Record<ArtifactKind, ArtifactDefinition>> = {
database: definition(
"postgres",
{
upstreamVersion: "17.11.0.005",
upstreamVersion: "17.11.0.006",
revision: 0,
image:
"ghcr.io/supabase/cli/postgres:17.11.0.005-r0@sha256:7929054d92a7a0682f853af321bb65d7ffcf49123ac5578b4d276f05088211a8",
upstreamImage: "supabase/postgres:17.11.0.005",
"ghcr.io/supabase/cli/postgres:17.11.0.006-r0@sha256:ee0f2d9747fb9d3c0a29703684ec718f070384ad05bf0d92823ed02cabde8e5a",
upstreamImage: "supabase/postgres:17.11.0.006",
natives: {
"darwin-arm64": {
archive: "6dcc013929e31cfefc716af250409f10be09473e66d8db4a190dc34baefb032f",
manifest: "d2fbc88c26a5745ab7f39e4fd425e6eb0bd4ce8837635ecb896dac20b701c7d0",
archive: "fb7594525d712ab85b6da00d4d4854f8d0c9ba26b49b781a5fede0119362e917",
manifest: "b499127a253b15f362fa217301d490f5d61f4b201d1b6501de06a11c6347e192",
},
"linux-amd64": {
archive: "c449f17e25f9b16f3d79636efba88a08379ea7e9d915f39c46d0db52a225c1a8",
manifest: "b7bca7e7e858bb3970319f50c9b9d43f6156d323d10144a73e5cc0ae1b7ef3ca",
archive: "f3a4389c92c550597cacf8c71c74af025b8e75259753c4e78bb5014e6f29e6f2",
manifest: "457949debc6c8b1d17dfaedcdef4883af3ff1ef7a15998f74d9511294be9a2fa",
},
"linux-arm64": {
archive: "478258bb3e738a023a913aecc904c9837250c0f53b382ab9208394ab82f66470",
manifest: "608ea63e0a1735fdbd5fe68c3f8fcc6d5b1279cca96b59a407947356bfbf7138",
archive: "443bb6be464b78fcc9a1e07d94cc4e8a5f0f9cba3d4ca3d5d8a8563fa962fddb",
manifest: "fd0f71d0f42898657a69962475164f4446f8f732edfac248708593b36eec4fcf",
},
},
},
Expand All @@ -144,24 +144,24 @@ const definitions: Readonly<Record<ArtifactKind, ArtifactDefinition>> = {
"bin/psql",
],
{
"15.19.0.005": {
upstreamVersion: "15.19.0.005",
"15.19.0.006": {
upstreamVersion: "15.19.0.006",
revision: 0,
image:
"ghcr.io/supabase/cli/postgres:15.19.0.005-r0@sha256:8c99be31392a22ba25f6a0fe03e772ff9e1141a76044bd28578bf245f6e93d44",
upstreamImage: "supabase/postgres:15.19.0.005",
"ghcr.io/supabase/cli/postgres:15.19.0.006-r0@sha256:dd5d757785930d2daf216ccc2ea871e2337657d11c42f7cc709309774fa663f1",
upstreamImage: "supabase/postgres:15.19.0.006",
natives: {
"darwin-arm64": {
archive: "f308f7727280b40641da4266cf93b4dfcc8f351ff5c085fdbf0316d6e628f7c3",
manifest: "d36777085898fe0ee4fbdd1b54dc971ed58ab314367493f5b74e4e5e7bd702d8",
archive: "0350c9ff12f84061f1a35de8218400fb8e6059dedd36d037bd01e9b7adde3e4b",
manifest: "a2d941b715b0fa09918353164f13fac47751973ab5ae4ceca978bb8263c41f62",
},
"linux-amd64": {
archive: "c8734fe7c013712909de297abe1dfb28ccb74a2f6d71f0af187c074c242d5cce",
manifest: "569a9ec7f820c55a05ea84b9c09891a83b0d28f2e630a950e385ca59e34dd6ad",
archive: "3e0126f154c174a88c45a9fa496441e1a15e2f328e4ad3b61fcc02c9caead69c",
manifest: "af86fad4f63a9bafbc853e8291275d95762da609e9775129f7debbdcdd35c1bb",
},
"linux-arm64": {
archive: "5839443e6674ce706e388a928878cd4e44c91943d44aa3417a3082495200c42c",
manifest: "e19dbcab90d4033452bca4de0916c83f6851162c09fb1a10233ad86ad7ef35d1",
archive: "ec1f08c01a110aa267c646a7ab69dc63e2e544c5d9d0c0536cfb974423280b3a",
manifest: "7527e460894f9ef76c57ec03359db5e8cc4d8fdb7043f727f4213344d9f3e76c",
},
},
},
Expand Down Expand Up @@ -207,6 +207,27 @@ const definitions: Readonly<Record<ArtifactKind, ArtifactDefinition>> = {
},
},
},
"17.11.0.006-orioledb": {
upstreamVersion: "17.11.0.006-orioledb",
revision: 0,
image:
"ghcr.io/supabase/cli/postgres:17.11.0.006-orioledb-r0@sha256:d1b3cb9421c5448dd1d226856344ef7abdd828a6d27722a1de11b3c0f5c46fc7",
upstreamImage: "supabase/postgres:17.11.0.006-orioledb",
natives: {
"darwin-arm64": {
archive: "6e6a90857cf3f6637b22e182856b18425fe6c12af80ef065b6dce736ce5a914c",
manifest: "5433b222cc40036069ab60fdfdf1e468c2ca1268a01f505b6a835c62f770abb8",
},
"linux-amd64": {
archive: "b7ea7bcd9953e4dec1af75d26e2a96cd753d8ebafb12f01c91d0baf0d2fbe6e2",
manifest: "280b0d449ae5ca09631cf362bd8c228abff638bafc832f39849a13828e66fc88",
},
"linux-arm64": {
archive: "b5bd6e730b89c3c150107740e1489b0bc1ce2ea3e8f802470e4c2bd7f88570e2",
manifest: "0cde8aff915fb425db9dadffbd3c0307b420f4e1c2b1b3a1c0dc1849ef296c47",
},
},
},
},
),
rest: definition(
Expand Down
10 changes: 6 additions & 4 deletions packages/stack/src/services/ProcessRecipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ export interface ProcessRecipeSpec<C extends RecipeCreation<ServiceKind, unknown
readonly executable: string;
readonly ports: Readonly<Record<string, number>>;
readonly healthPath: string;
/** The `ports` entry `healthPath` is probed on; defaults to `http`. */
readonly healthPort?: string;
readonly args: (
creation: C,
endpoints: ReadonlyMap<string, ServiceEndpoint>,
Expand Down Expand Up @@ -626,12 +628,12 @@ export const makeProcessRecipe = <C extends RecipeCreation<ServiceKind, unknown>
type NativeAttempt = Effect.Success<ReturnType<typeof spawnAttempt>>;

const readyCondition = (attempt: NativeAttempt, timeout: Duration.Input) => {
const http = attempt.selected.get("http");
if (http === undefined)
const ready = attempt.selected.get(spec.healthPort ?? "http");
if (ready === undefined)
return Effect.fail(serviceError("health", "Recipe has no HTTP readiness endpoint"));
return Effect.all(
[
readiness(deps.client, http, spec.healthPath, timeout),
readiness(deps.client, ready, spec.healthPath, timeout),
spec.nativeReadinessOutput === undefined
? Effect.void
: Deferred.await(attempt.output.bindReady),
Expand Down Expand Up @@ -890,7 +892,7 @@ export const makeProcessRecipe = <C extends RecipeCreation<ServiceKind, unknown>
yield* Ref.set(endpoints, selected);
yield* publishProcessLogs(launched, yield* output.part, context.scope);
const runtime = runtimeFromContainer(launched);
const ready = selected.get("http");
const ready = selected.get(spec.healthPort ?? "http");
const noReadinessEndpoint = Effect.fail(
serviceError("health", "Recipe has no HTTP readiness endpoint"),
);
Expand Down
22 changes: 19 additions & 3 deletions packages/stack/src/services/Rest.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,18 @@ describe("service catalog", () => {
yield* sql.unsafe(
"INSERT INTO public.catalog_native_probe (id, value) VALUES (1, 'catalog-native');",
);
yield* sql.unsafe(`CREATE OR REPLACE FUNCTION public.catalog_native_hook() RETURNS void
LANGUAGE plpgsql AS $$
BEGIN
IF current_setting('request.headers', true)::json->>'x-app-secret' IS DISTINCT FROM 'expected' THEN
RAISE SQLSTATE 'PGRST' USING MESSAGE = '{"code":"APP_403","message":"Unauthorized."}',
DETAIL = '{"status":403,"headers":{}}';
END IF;
END $$;`);
yield* sql.unsafe("GRANT EXECUTE ON FUNCTION public.catalog_native_hook() TO anon;");
yield* sql.unsafe(
"ALTER ROLE supabase_admin SET pgrst.db_pre_request = 'public.catalog_native_hook';",
);
const restRecipe = yield* makeServiceRecipe(
{
service: "rest",
Expand All @@ -271,6 +283,9 @@ describe("service catalog", () => {
yield* rest.start;
yield* rest.ready;
const endpoint = yield* restRecipe.endpoint("http");
const base = "http://" + httpHost(endpoint) + ":" + endpoint.port;
const rejected = yield* client.execute(HttpClientRequest.get(base + "/"));
expect(rejected.status).toBe(403);
const token = yield* Effect.tryPromise(() =>
new SignJWT({ role: "anon" })
.setProtectedHeader({ alg: "HS256", typ: "JWT" })
Expand All @@ -279,9 +294,10 @@ describe("service catalog", () => {
.sign(new TextEncoder().encode(secret)),
);
const response = yield* client.execute(
HttpClientRequest.get(
"http://" + httpHost(endpoint) + ":" + endpoint.port + "/catalog_native_probe",
).pipe(HttpClientRequest.setHeader("Authorization", "Bearer " + token)),
HttpClientRequest.get(base + "/catalog_native_probe").pipe(
HttpClientRequest.setHeader("Authorization", "Bearer " + token),
HttpClientRequest.setHeader("x-app-secret", "expected"),
),
);
const responseBody = yield* response.text;
expect(response.status).toBe(200);
Expand Down
7 changes: 5 additions & 2 deletions packages/stack/src/services/Rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,21 @@ export interface Creation extends Schema.Schema.Type<typeof Creation> {}
export const makeSpec = (): ProcessRecipeSpec<Creation> => ({
service: "rest",
executable: "bin/postgrest",
ports: { http: 3000 },
healthPath: "/",
ports: { http: 3000, admin: 3001 },
healthPort: "admin",
healthPath: "/ready",
env: (creation, endpoints, container) =>
Effect.gen(function* () {
const databaseUrl = yield* requiredInput("rest", "databaseUrl", creation.config.databaseUrl);
const http = endpoints.get("http");
const admin = endpoints.get("admin");
const jwtSecret = creation.config.jwks ?? creation.config.jwtSecret;
return {
DATABASE_URL: databaseUrl,
PGRST_DB_URI: databaseUrl,
PGRST_SERVER_HOST: container ? "0.0.0.0" : "127.0.0.1",
...(http === undefined ? {} : { PGRST_SERVER_PORT: String(http.port) }),
...(admin === undefined ? {} : { PGRST_ADMIN_SERVER_PORT: String(admin.port) }),
PGRST_DB_SCHEMAS: creation.config.schemas ?? "public,graphql_public",
...(creation.config.extraSearchPath === undefined
? {}
Expand Down
21 changes: 21 additions & 0 deletions packages/stack/src/services/ServiceIdentity.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { expect, it } from "@effect/vitest";
import { Effect, Schema } from "effect";
import * as Realtime from "./Realtime.ts";
import type { ServiceEndpoint } from "./Recipe.ts";
import * as Rest from "./Rest.ts";
import * as Storage from "./Storage.ts";
import * as Studio from "./Studio.ts";
Expand Down Expand Up @@ -30,6 +31,26 @@ it("forwards a PostgREST HMAC secret when JWKS is omitted", () => {
expect(env.PGRST_JWT_SECRET).toBe("active-hmac-secret");
});

it.effect("probes PostgREST readiness on its admin server port", () =>
Effect.gen(function* () {
const spec = Rest.makeSpec();
const creation = yield* Schema.decodeEffect(Rest.Creation)({
service: "rest",
config: { databaseUrl: "postgresql://localhost/postgres", jwtSecret: "active-hmac-secret" },
});
const endpoints: ReadonlyMap<string, ServiceEndpoint> = new Map([
["http", { kind: "tcp" as const, host: "127.0.0.1", port: 54321 }],
["admin", { kind: "tcp" as const, host: "127.0.0.1", port: 54322 }],
]);
const env = yield* spec.env(creation, endpoints, false);

expect(spec.healthPort).toBe("admin");
expect(spec.healthPath).toBe("/ready");
expect(env.PGRST_SERVER_PORT).toBe("54321");
expect(env.PGRST_ADMIN_SERVER_PORT).toBe("54322");
}),
);

it("forwards Realtime JWKS while retaining its default JWT secret", () => {
const creation = Schema.decodeSync(Realtime.Creation)({
service: "realtime",
Expand Down
Loading