Dont do socket on non-newt sites

This commit is contained in:
Owen 2025-06-04 16:02:45 -04:00
parent 58a2a9dcc9
commit df4da75c57
No known key found for this signature in database
GPG key ID: 8271FDFFD9E0CCBD
6 changed files with 45 additions and 66 deletions

View file

@ -141,6 +141,7 @@ export async function createSite(
niceId, niceId,
subnet, subnet,
type, type,
dockerSocketEnabled: type == "newt",
...(pubKey && type == "wireguard" && { pubKey }) ...(pubKey && type == "wireguard" && { pubKey })
}) })
.returning(); .returning();
@ -154,6 +155,7 @@ export async function createSite(
name, name,
niceId, niceId,
type, type,
dockerSocketEnabled: type == "newt",
subnet: "0.0.0.0/0" subnet: "0.0.0.0/0"
}) })
.returning(); .returning();

View file

@ -20,7 +20,7 @@ export default function ResourceInfoBox({}: ResourceInfoBoxType) {
const { resource, authInfo, site } = useResourceContext(); const { resource, authInfo, site } = useResourceContext();
const api = createApiClient(useEnvContext()); const api = createApiClient(useEnvContext());
const { isEnabled, isAvailable } = useDockerSocket(resource.siteId); const { isEnabled, isAvailable } = useDockerSocket(site!);
let fullUrl = `${resource.ssl ? "https" : "http"}://${resource.fullDomain}`; let fullUrl = `${resource.ssl ? "https" : "http"}://${resource.fullDomain}`;

View file

@ -776,7 +776,7 @@ export default function ReverseProxyTargets(props: {
<Input id="ip" {...field} /> <Input id="ip" {...field} />
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
{site && ( {site && site.type == 'newt' && (
<ContainersSelector <ContainersSelector
site={site} site={site}
onContainerSelect={( onContainerSelect={(

View file

@ -129,31 +129,35 @@ export default function GeneralPage() {
</FormItem> </FormItem>
)} )}
/> />
<FormField {site && site.type === "newt" && (
control={form.control} <FormField
name="dockerSocketEnabled" control={form.control}
render={({ field }) => ( name="dockerSocketEnabled"
<FormItem> render={({ field }) => (
<FormControl> <FormItem>
<SwitchInput <FormControl>
id="docker-socket-enabled" <SwitchInput
label="Enable Docker Socket" id="docker-socket-enabled"
defaultChecked={field.value} label="Enable Docker Socket"
onCheckedChange={ defaultChecked={
field.onChange field.value
} }
/> onCheckedChange={
</FormControl> field.onChange
<FormMessage /> }
<FormDescription> />
Enable Docker Socket discovery </FormControl>
for populating container <FormMessage />
information, useful in resource <FormDescription>
targets. Enable Docker Socket
</FormDescription> discovery for populating
</FormItem> container information,
)} useful in resource targets.
/> </FormDescription>
</FormItem>
)}
/>
)}
</form> </form>
</Form> </Form>
</SettingsSectionForm> </SettingsSectionForm>

View file

@ -68,8 +68,9 @@ export const ContainersSelector: FC<ContainerSelectorProps> = ({
}) => { }) => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const isDesktop = useMediaQuery("(min-width: 768px)"); const isDesktop = useMediaQuery("(min-width: 768px)");
const { isAvailable, containers, fetchContainers } = useDockerSocket( const { isAvailable, containers, fetchContainers } = useDockerSocket(
site.siteId site
); );
useEffect(() => { useEffect(() => {

View file

@ -10,15 +10,13 @@ import {
} from "@server/routers/site"; } from "@server/routers/site";
import { AxiosResponse } from "axios"; import { AxiosResponse } from "axios";
import { toast } from "./useToast"; import { toast } from "./useToast";
import { Site } from "@server/db";
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
export function useDockerSocket(siteId: number) { export function useDockerSocket(site: Site) {
if (!siteId) { console.log(`useDockerSocket initialized for site ID: ${site.siteId}`);
throw new Error("Site ID is required to use Docker Socket");
}
const [site, setSite] = useState<GetSiteResponse>();
const [dockerSocket, setDockerSocket] = useState<GetDockerStatusResponse>(); const [dockerSocket, setDockerSocket] = useState<GetDockerStatusResponse>();
const [containers, setContainers] = useState<Container[]>([]); const [containers, setContainers] = useState<Container[]>([]);
@ -27,40 +25,18 @@ export function useDockerSocket(siteId: number) {
const { dockerSocketEnabled: isEnabled = true } = site || {}; const { dockerSocketEnabled: isEnabled = true } = site || {};
const { isAvailable = false, socketPath } = dockerSocket || {}; const { isAvailable = false, socketPath } = dockerSocket || {};
const fetchSite = useCallback(async () => {
try {
const res = await api.get<AxiosResponse<GetSiteResponse>>(
`/site/${siteId}`
);
if (res.status === 200) {
setSite(res.data.data);
}
} catch (err) {
console.error(err);
toast({
variant: "destructive",
title: "Failed to fetch resource",
description: formatAxiosError(
err,
"An error occurred while fetching resource"
)
});
}
}, [api, siteId]);
const checkDockerSocket = useCallback(async () => { const checkDockerSocket = useCallback(async () => {
if (!isEnabled) { if (!isEnabled) {
console.warn("Docker socket is not enabled for this site."); console.warn("Docker socket is not enabled for this site.");
return; return;
} }
try { try {
const res = await api.post(`/site/${siteId}/docker/check`); const res = await api.post(`/site/${site.siteId}/docker/check`);
console.log("Docker socket check response:", res); console.log("Docker socket check response:", res);
} catch (error) { } catch (error) {
console.error("Failed to check Docker socket:", error); console.error("Failed to check Docker socket:", error);
} }
}, [api, siteId, isEnabled]); }, [api, site.siteId, isEnabled]);
const getDockerSocketStatus = useCallback(async () => { const getDockerSocketStatus = useCallback(async () => {
if (!isEnabled) { if (!isEnabled) {
@ -70,7 +46,7 @@ export function useDockerSocket(siteId: number) {
try { try {
const res = await api.get<AxiosResponse<GetDockerStatusResponse>>( const res = await api.get<AxiosResponse<GetDockerStatusResponse>>(
`/site/${siteId}/docker/status` `/site/${site.siteId}/docker/status`
); );
if (res.status === 200) { if (res.status === 200) {
@ -92,7 +68,7 @@ export function useDockerSocket(siteId: number) {
description: "An error occurred while fetching Docker status." description: "An error occurred while fetching Docker status."
}); });
} }
}, [api, siteId, isEnabled]); }, [api, site.siteId, isEnabled]);
const getContainers = useCallback( const getContainers = useCallback(
async (maxRetries: number = 3) => { async (maxRetries: number = 3) => {
@ -111,7 +87,7 @@ export function useDockerSocket(siteId: number) {
try { try {
const res = await api.get< const res = await api.get<
AxiosResponse<ListContainersResponse> AxiosResponse<ListContainersResponse>
>(`/site/${siteId}/docker/containers`); >(`/site/${site.siteId}/docker/containers`);
setContainers(res.data.data); setContainers(res.data.data);
return; return;
} catch (error: any) { } catch (error: any) {
@ -160,7 +136,7 @@ export function useDockerSocket(siteId: number) {
try { try {
const res = await api.post<AxiosResponse<TriggerFetchResponse>>( const res = await api.post<AxiosResponse<TriggerFetchResponse>>(
`/site/${siteId}/docker/trigger` `/site/${site.siteId}/docker/trigger`
); );
// TODO: identify a way to poll the server for latest container list periodically? // TODO: identify a way to poll the server for latest container list periodically?
await fetchContainerList(); await fetchContainerList();
@ -169,13 +145,9 @@ export function useDockerSocket(siteId: number) {
console.error("Failed to trigger Docker containers:", error); console.error("Failed to trigger Docker containers:", error);
} }
}, },
[api, siteId, isEnabled, isAvailable] [api, site.siteId, isEnabled, isAvailable]
); );
useEffect(() => {
fetchSite();
}, [fetchSite]);
// 2. Docker socket status monitoring // 2. Docker socket status monitoring
useEffect(() => { useEffect(() => {
if (!isEnabled || isAvailable) { if (!isEnabled || isAvailable) {