Skip to content
Open
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
24 changes: 18 additions & 6 deletions packages/server/src/setup/traefik-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const TRAEFIK_PORT =
export const TRAEFIK_HTTP3_PORT =
Number.parseInt(process.env.TRAEFIK_HTTP3_PORT!, 10) || 443;
export const TRAEFIK_VERSION = process.env.TRAEFIK_VERSION || "3.6.7";
export const TRAEFIK_BIND_IP = process.env.TRAEFIK_BIND_IP || "0.0.0.0";
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.

P2 No validation of TRAEFIK_BIND_IP

TRAEFIK_BIND_IP is passed directly from the environment into Docker's port binding HostIp field with no format validation. An invalid value (e.g. a hostname, a CIDR range, or a typo like 0.0.0.) will cause docker.createContainer() to throw a cryptic error rather than a user-friendly message.

Consider adding a basic sanity check or at least logging the resolved value at startup so operators can confirm the setting is applied as expected:

Suggested change
export const TRAEFIK_BIND_IP = process.env.TRAEFIK_BIND_IP || "0.0.0.0";
export const TRAEFIK_BIND_IP = process.env.TRAEFIK_BIND_IP || "0.0.0.0";
// Basic guard so a misconfigured value surfaces early with a clear message.
if (!/^(\d{1,3}\.){3}\d{1,3}$|^::$|^::1$/.test(TRAEFIK_BIND_IP)) {
console.warn(
`TRAEFIK_BIND_IP "${TRAEFIK_BIND_IP}" does not look like a valid IP address – falling back to 0.0.0.0`,
);
}

This is consistent with how operators discover misconfigured TRAEFIK_PORT / TRAEFIK_SSL_PORT values today (the pattern is not validated there either), so this is purely a hardening suggestion.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


export interface TraefikOptions {
env?: string[];
Expand All @@ -47,11 +48,18 @@ export const initializeStandaloneTraefik = async ({
[`${TRAEFIK_HTTP3_PORT}/udp`]: {},
};

const portBindings: Record<string, Array<{ HostPort: string }>> = {
[`${TRAEFIK_PORT}/tcp`]: [{ HostPort: TRAEFIK_PORT.toString() }],
[`${TRAEFIK_SSL_PORT}/tcp`]: [{ HostPort: TRAEFIK_SSL_PORT.toString() }],
const portBindings: Record<
string,
Array<{ HostPort: string; HostIp: string }>
> = {
[`${TRAEFIK_PORT}/tcp`]: [
{ HostPort: TRAEFIK_PORT.toString(), HostIp: TRAEFIK_BIND_IP },
],
[`${TRAEFIK_SSL_PORT}/tcp`]: [
{ HostPort: TRAEFIK_SSL_PORT.toString(), HostIp: TRAEFIK_BIND_IP },
],
[`${TRAEFIK_HTTP3_PORT}/udp`]: [
{ HostPort: TRAEFIK_HTTP3_PORT.toString() },
{ HostPort: TRAEFIK_HTTP3_PORT.toString(), HostIp: TRAEFIK_BIND_IP },
],
};

Expand All @@ -61,13 +69,17 @@ export const initializeStandaloneTraefik = async ({

if (enableDashboard) {
exposedPorts["8080/tcp"] = {};
portBindings["8080/tcp"] = [{ HostPort: "8080" }];
portBindings["8080/tcp"] = [
{ HostPort: "8080", HostIp: TRAEFIK_BIND_IP },
];
}

for (const port of additionalPorts) {
const portKey = `${port.targetPort}/${port.protocol ?? "tcp"}`;
exposedPorts[portKey] = {};
portBindings[portKey] = [{ HostPort: port.publishedPort.toString() }];
portBindings[portKey] = [
{ HostPort: port.publishedPort.toString(), HostIp: TRAEFIK_BIND_IP },
];
}

const settings: ContainerCreateOptions = {
Expand Down