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
17 changes: 6 additions & 11 deletions apps/api/src/api/projects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
listProjects,
getProjectById,
updateProject,
deleteProject,
deleteProjectCascade,
listDomains,
} from "../../db/repo";
import { tryRun, reloadCaddy } from "../../orchestrator/runtime";
Expand Down Expand Up @@ -79,7 +79,6 @@ export const projectsRoutes = new Elysia()
return { error: "Project not found" };
}

// Docker containers cleanup
for (const name of info.deploymentContainerNames) {
await tryRun(dockerBin, ['stop', '-t', '5', name]);
await tryRun(dockerBin, ['rm', '-f', name]);
Expand All @@ -89,22 +88,18 @@ export const projectsRoutes = new Elysia()
await tryRun(dockerBin, ['rm', '-f', name]);
}

// Docker volumes cleanup
for (const name of [...info.databaseVolumeNames, ...info.volumeDockerNames]) {
await tryRun(dockerBin, ['volume', 'rm', '-f', name]);
}

// Docker images cleanup
for (const tag of info.deploymentImageTags) {
if (tag) await tryRun(dockerBin, ['rmi', '-f', tag]);
}

// Remove domains from Caddy route file
for (const { domain, projectName } of info.domains) {
await removeFromCaddyRoute(domain, id, projectName);
}

// Delete the Caddy route file for this project's slug
const caddyFilePath = join(config.caddyRoutesDir, `${info.slug}.caddy`);
await unlink(caddyFilePath).catch(() => {});
await reloadCaddy().catch(() => {});
Expand Down Expand Up @@ -206,14 +201,14 @@ export const projectsRoutes = new Elysia()
}

const regexEscaped = domains.map(d => d.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\\\$&')).join('|');

// Loki metric query for request rate
const query = `sum(count_over_time({container="dequel-caddy-1"} | json | request_host =~ "^(${regexEscaped})$" [5m]))`;

const end = Math.floor(Date.now() / 1000);
const start = end - (6 * 60 * 60); // 6 hours ago
const step = "60s"; // 1 min resolution

try {
const response = await fetch(
`http://loki:3100/loki/api/v1/query_range?query=${encodeURIComponent(query)}&start=${start}&end=${end}&step=${step}`
Expand Down Expand Up @@ -304,8 +299,8 @@ export const projectsRoutes = new Elysia()
ws.onmessage = (event) => {
if (closed) return;
try {
const dataStr = typeof event.data === "string"
? event.data
const dataStr = typeof event.data === "string"
? event.data
: new TextDecoder().decode(event.data as any);
const data = JSON.parse(dataStr) as any;
if (data.streams) {
Expand Down
3 changes: 2 additions & 1 deletion apps/api/src/db/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ const addClearCacheColumn = async (db: ReturnType<typeof getDrizzle>) => {
db.run(sql`ALTER TABLE deployments ADD COLUMN clear_cache integer NOT NULL DEFAULT 0`);
console.log("[Migrate] Added clear_cache column to deployments table");
} catch (err) {
if (err instanceof Error && err.message.includes("duplicate column name")) return;
const cause = err instanceof Error && "cause" in err ? err.cause : err;
if (cause instanceof Error && cause.message.includes("duplicate column name")) return;
console.error("[Migrate] Failed to add clear_cache column:", err);
throw err;
}
Expand Down
1 change: 1 addition & 0 deletions apps/api/src/orchestrator/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,7 @@ export class PipelineOrchestrator {
.slice(0, 63);
const containerRegex = `${dashSlug}-.*`;
ensureProjectDashboard(
deployment.projectId!,
projectName,
containerRegex,
).catch((e) =>
Expand Down
Loading
Loading