Skip to content

Commit 34e9d74

Browse files
committed
chore: better env handling
1 parent 36e7723 commit 34e9d74

8 files changed

Lines changed: 37 additions & 22 deletions

File tree

Dockerfile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ WORKDIR /app
44
COPY deno.json deno.lock .
55
RUN deno install --frozen
66
COPY . .
7-
RUN deno compile --allow-env --allow-run --allow-net --allow-read --deny-sys -o sync main.ts
7+
RUN deno compile \
8+
--allow-env \
9+
--allow-net \
10+
--allow-read=/usr/bin/pg_dump \
11+
--allow-run \
12+
--deny-sys \
13+
-o sync main.ts
814

915
FROM denoland/deno:alpine AS runner
1016

@@ -14,7 +20,9 @@ WORKDIR /app
1420
RUN apk add --no-cache postgresql-client
1521

1622
ENV PG_DUMP_BINARY=/usr/bin/pg_dump
17-
COPY bin ./bin
23+
# bind to all interfaces
24+
ENV HOST=0.0.0.0
25+
# COPY bin ./bin
1826
COPY --from=builder /app/sync /app/sync
1927

2028
USER deno

deno.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
"sloppy-imports"
77
],
88
"tasks": {
9-
"dev": "deno run --watch main.ts"
9+
"dev": "deno run --allow-env=HOST,PORT,HOSTED,PG_DUMP_BINARY,PGPASSWORD,PGSSL,PGIDLE_TIMEOUT,PGMAX_LIFETIME,PGMAX_PIPELINE,PGBACKOFF,PGKEEP_ALIVE,PGPREPARE,PGDEBUG,PGFETCH_TYPES,PGPUBLICATIONS,PGTARGET_SESSION_ATTRS,PGAPPNAME,PGCONNECT_TIMEOUT,PGTARGETSESSIONATTRS,PGPORT,PGMAX --allow-run --allow-net --allow-read=./bin --deny-sys --watch main.ts"
1010
},
1111
"imports": {
1212
"@opentelemetry/api": "jsr:@opentelemetry/api@^1.9.0",
1313
"@rabbit-company/rate-limiter": "jsr:@rabbit-company/rate-limiter@^3.0.0",
1414
"@std/assert": "jsr:@std/assert@^1.0.13",
15+
"@std/collections": "jsr:@std/collections@^1.1.1",
1516
"postgres": "https://deno.land/x/postgresjs@v3.4.7/mod.js",
1617
"zod": "npm:zod@^3.25.67"
1718
},

deno.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

main.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import { createServer } from "./src/server/http.ts";
22
import { log } from "./src/log.ts";
33
import { shutdown } from "./src/shutdown.ts";
4-
5-
const DEFAULT_PORT = 2345;
4+
import { env } from "./src/env.ts";
65

76
// Learn more at https://docs.deno.com/runtime/manual/examples/module_metadata#concepts
87
if (import.meta.main) {
98
const os = Deno.build.os;
109
const arch = Deno.build.arch;
11-
const port = Deno.env.get("PORT") || DEFAULT_PORT;
12-
log.info(`Starting server (${os}-${arch}) on port ${port}`, "main");
13-
createServer(Number(port));
10+
log.info(
11+
`Starting server (${os}-${arch}) on ${env.HOST}:${env.PORT}`,
12+
"main"
13+
);
14+
createServer(env.HOST, env.PORT);
1415

1516
Deno.addSignalListener("SIGTERM", shutdown);
1617
Deno.addSignalListener("SIGINT", shutdown);

src/env.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
import { z } from "zod";
2+
import { mapValues } from "@std/collections";
23

34
const envSchema = z.object({
5+
PG_DUMP_BINARY: z.string().optional(),
46
HOSTED: z.coerce.boolean().default(false),
5-
PORT: z.coerce.number().min(1024).max(65535).default(3000),
7+
HOST: z.string().default("127.0.0.1"),
8+
PORT: z.coerce.number().min(1024).max(65535).default(2345),
69
});
710

8-
export const env = envSchema.parse(Deno.env.toObject());
11+
// we want to avoid asking for ALL env permissions if possible
12+
export const env = envSchema.parse(
13+
mapValues(envSchema._def.shape(), (_, key) => Deno.env.get(key))
14+
);

src/server/http.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ async function onSync(req: Request) {
144144
return Response.json(result, { status: 200 });
145145
}
146146

147-
export function createServer(port: number) {
147+
export function createServer(hostname: string, port: number) {
148148
return Deno.serve(
149-
{ port, signal: shutdownController.signal },
149+
{ hostname, port, signal: shutdownController.signal },
150150
async (req, info) => {
151151
const url = new URL(req.url);
152152
log.http(req);

src/sync/schema.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { SpanStatusCode, trace } from "@opentelemetry/api";
22
import { log } from "../log.ts";
33
import { shutdownController } from "../shutdown.ts";
4+
import { env } from "../env.ts";
45

56
export type TableStats = {
67
name: string;
@@ -14,15 +15,7 @@ export class PostgresSchemaLink {
1415
}
1516

1617
findPgDumpBinary(): string {
17-
let forcePath: string | undefined;
18-
try {
19-
forcePath = Deno.env.get("PG_DUMP_BINARY");
20-
} catch (_err) {
21-
log.warn(
22-
"Permission denied to read PG_DUMP_BINARY from env, falling back to built-in binary",
23-
"schema:setup"
24-
);
25-
}
18+
const forcePath = env.PG_DUMP_BINARY;
2619
if (forcePath) {
2720
log.info(
2821
`Using pg_dump binary from env(PG_DUMP_BINARY): ${forcePath}`,

src/sync/syncer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import { PostgresSchemaLink } from "./schema.ts";
1414
import { withSpan } from "../otel.ts";
1515
import { SpanStatusCode } from "@opentelemetry/api";
16+
import { env } from "../env.ts";
1617

1718
type SyncOptions = DependencyAnalyzerOptions;
1819

@@ -84,7 +85,7 @@ export class PostgresSyncer {
8485
/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(url.hostname) ||
8586
// ipv6 localhost
8687
url.hostname === "[::1]";
87-
if (isLocalhost && Deno.env.get("DISALLOW_LOCAL_SYNC") === "true") {
88+
if (isLocalhost && env.HOSTED) {
8889
return {
8990
kind: "error",
9091
type: "postgres_connection_error",

0 commit comments

Comments
 (0)