Deep-link Dozzle logs button to specific container
The discover API now fetches container names from Docker via the Python API on port 9876 and matches them to services by UUID. The Dozzle logs button builds a proper deep link using the Dozzle host ID and container name, opening directly to that container's log stream. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,9 +56,28 @@ function buildUrl(fqdn: string | null, port: number): string {
|
||||
return `http://${nucHost}`;
|
||||
}
|
||||
|
||||
async function fetchContainerNames(): Promise<string[]> {
|
||||
try {
|
||||
const res = await fetch(`http://${nucHost}:9876/containers`, {
|
||||
signal: AbortSignal.timeout(5000),
|
||||
});
|
||||
if (!res.ok) return [];
|
||||
return await res.json() as string[];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function findContainerName(uuid: string, containers: string[]): string | undefined {
|
||||
return containers.find(c => c.includes(uuid));
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const resources = await fetchResources();
|
||||
const [resources, containerNames] = await Promise.all([
|
||||
fetchResources(),
|
||||
fetchContainerNames(),
|
||||
]);
|
||||
|
||||
if (!resources) {
|
||||
return NextResponse.json(
|
||||
@@ -88,6 +107,7 @@ export async function GET() {
|
||||
resourceType: 'application',
|
||||
uuid: resource.uuid,
|
||||
coolifyStatus: resource.status,
|
||||
container: findContainerName(resource.uuid, containerNames),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -121,6 +141,7 @@ export async function GET() {
|
||||
resourceType: 'service',
|
||||
uuid: resource.uuid,
|
||||
coolifyStatus: resource.status,
|
||||
container: findContainerName(resource.uuid, containerNames),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -137,6 +158,7 @@ export async function GET() {
|
||||
resourceType: 'database',
|
||||
uuid: resource.uuid,
|
||||
coolifyStatus: resource.status,
|
||||
container: findContainerName(resource.uuid, containerNames),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
import { useState, useCallback } from 'react';
|
||||
import { Service, DiscoveredService, getCoolifyUrl, getDozzleUrl } from '@/lib/services';
|
||||
|
||||
const dozzleUrl = getDozzleUrl();
|
||||
import { HealthStatus } from '@/lib/PortalContext';
|
||||
import { Icon } from './Icons';
|
||||
|
||||
@@ -175,7 +173,7 @@ export function ServiceCard({ service, status }: ServiceCardProps) {
|
||||
{/* View logs in Dozzle */}
|
||||
{discovered && (
|
||||
<a
|
||||
href={dozzleUrl}
|
||||
href={getDozzleUrl(service as DiscoveredService)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="View logs"
|
||||
|
||||
@@ -18,4 +18,5 @@ export const clientConfig = {
|
||||
coolifyEnvUuid: process.env.NEXT_PUBLIC_COOLIFY_ENV_UUID || 'dckc0w4ko8s888c4gk84skoo',
|
||||
grafanaUrl: process.env.NEXT_PUBLIC_GRAFANA_URL || 'http://192.168.1.3:3333',
|
||||
dozzleUrl: process.env.NEXT_PUBLIC_DOZZLE_URL || 'http://192.168.1.3:9999',
|
||||
dozzleHostId: process.env.NEXT_PUBLIC_DOZZLE_HOST_ID || '6c1738d9-6f12-4ed7-9293-70a91f407347',
|
||||
};
|
||||
|
||||
@@ -26,8 +26,13 @@ export function getCoolifyUrl(service: DiscoveredService): string {
|
||||
return `${base}/project/${project}/environment/${env}/${service.resourceType}/${service.uuid}`;
|
||||
}
|
||||
|
||||
export function getDozzleUrl(): string {
|
||||
return process.env.NEXT_PUBLIC_DOZZLE_URL || 'http://192.168.1.3:9999';
|
||||
export function getDozzleUrl(service?: DiscoveredService): string {
|
||||
const base = process.env.NEXT_PUBLIC_DOZZLE_URL || 'http://192.168.1.3:9999';
|
||||
const hostId = process.env.NEXT_PUBLIC_DOZZLE_HOST_ID || '6c1738d9-6f12-4ed7-9293-70a91f407347';
|
||||
if (service?.container) {
|
||||
return `${base}/container/${hostId}~${service.container}`;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
export interface Bookmark {
|
||||
|
||||
Reference in New Issue
Block a user