Deployment port configuration and log fix

This commit is contained in:
2026-01-03 22:16:32 +01:00
parent 8f2ebaeab7
commit 21f9f1bb56
8 changed files with 158 additions and 38 deletions
+18 -5
View File
@@ -1,7 +1,7 @@
"use server";
import Docker from "dockerode";
import { Application, Deployment } from "@/lib/types";
import { Application, Deployment, Port } from "@/lib/types";
import { CPUusage } from "@/lib/server/calc";
import path from "path";
import fs from "fs";
@@ -20,6 +20,20 @@ function sanitizeString(str: string): string {
);
}
function formatPorts(ports: Port[]) {
const dockerPorts: Record<string, { HostPort: string }[]> = {};
ports.forEach(({ containerPort, hostPort, protocol }) => {
const key = `${containerPort}/${protocol}`;
if (!dockerPorts[key]) {
dockerPorts[key] = [];
}
dockerPorts[key].push({ HostPort: hostPort });
});
return dockerPorts;
}
export async function getDeployments(
apps: Application[]
): Promise<Deployment[]> {
@@ -96,7 +110,8 @@ export async function getDeployments(
export async function deployApp(
name: string,
app: Application
app: Application,
ports: Port[]
): Promise<string | undefined> {
const deployId = randomUUID();
const deployPath = path.join("data", "deploys", deployId);
@@ -134,9 +149,7 @@ export async function deployApp(
Tty: true,
HostConfig: {
RestartPolicy: { Name: "unless-stopped" },
PortBindings: {
"3000/tcp": [{ HostPort: "3800" }],
},
PortBindings: formatPorts(ports),
},
Env: Object.entries(app.env).map(
([key, { value }]) => `${key}="${value.replaceAll('"', '\\"')}"`
+37 -21
View File
@@ -67,36 +67,52 @@ function demuxLogs(buffer: Buffer): string {
return output;
}
async function getContainerLogs(
containerId: string,
name: string
): Promise<Log[]> {
const container = docker.getContainer(containerId);
const raw = await container.logs({
stdout: true,
stderr: true,
timestamps: true,
});
// Inspect the container to check the logging driver
const info = await container.inspect();
const driver = info.HostConfig.LogConfig?.Type;
const text = demuxLogs(raw);
if (driver !== "json-file" && driver !== "journald") {
// Skip containers with unsupported logging drivers
return [];
}
return text
.split("\n")
.filter(Boolean)
.map((line) => {
const firstSpace = line.indexOf(" ");
const timestamp = line.slice(0, firstSpace);
const message = line.slice(firstSpace + 1);
return {
timestamp,
level: inferLevel(message),
source: name,
message,
} satisfies Log;
try {
const raw = await container.logs({
stdout: true,
stderr: true,
timestamps: true,
});
const text = demuxLogs(raw);
return text
.split("\n")
.filter(Boolean)
.map((line) => {
const firstSpace = line.indexOf(" ");
const timestamp = line.slice(0, firstSpace);
const message = line.slice(firstSpace + 1);
return {
timestamp,
level: inferLevel(message),
source: name,
message,
} satisfies Log;
});
} catch (err: any) {
if (err.statusCode === 501) {
// Logging driver does not support reading
return [];
}
throw err; // rethrow any other error
}
}
export async function getAllContainerLogs(): Promise<Log[]> {