1// Probe server for container → SQL DATABASE_URL reachability. Plain node,
2// no deps. `/env` reports the URL the process received (and duplicate-key
3// count from the raw environ — glibc getenv is first-match). `/probe`
4// TCP-connects to that URL from inside the container.
5//
6// NOTE: this file is force-added past the repo's `*.js` ignore rule.
7const fs = require("node:fs");
8const http = require("node:http");
9const net = require("node:net");
10
11const countEnv = (name) => {
12 try {
13 return fs
14 .readFileSync("/proc/self/environ", "utf8")
15 .split("\0")
16 .filter((entry) => entry.startsWith(`${name}=`)).length;
17 } catch {
18 return undefined;
19 }
20};
21
22const defaultPort = (url) => {
23 if (url.port) return Number(url.port);
24 if (url.protocol.startsWith("mysql")) return 3306;
25 return 5432;
26};
27
28const tcpProbe = (hostname, port) =>
29 new Promise((resolve) => {
30 const socket = net.connect({ host: hostname, port }, () => {
31 socket.end();
32 resolve({ ok: true, host: hostname, port });
33 });
34 socket.setTimeout(8000, () => {
35 socket.destroy();
36 resolve({ ok: false, host: hostname, port, error: "timeout" });
37 });
38 socket.on("error", (error) =>
39 resolve({ ok: false, host: hostname, port, error: String(error) }),
40 );
41 });
42
43const server = http.createServer(async (req, res) => {
44 res.setHeader("content-type", "application/json");
45 if (req.url === "/env") {
46 res.end(
47 JSON.stringify({
48 DATABASE_URL: process.env.DATABASE_URL,
49 databaseUrlCount: countEnv("DATABASE_URL"),
50 }),
51 );
52 return;
53 }
54 if (req.url === "/probe") {
55 const value = process.env.DATABASE_URL;
56 if (!value) {
57 res.end(JSON.stringify({ error: "missing DATABASE_URL" }));
58 return;
59 }
60 try {
61 const url = new URL(value);
62 res.end(JSON.stringify(await tcpProbe(url.hostname, defaultPort(url))));
63 } catch (error) {
64 res.end(JSON.stringify({ error: String(error) }));
65 }
66 return;
67 }
68 res.end(JSON.stringify({ ok: true }));
69});
70
71server.listen(8080, () => {
72 console.log("sqlreach probe server listening on 8080");
73});