Caddy previously ran as a host binary in /opt/caddy with a wgui-caddy systemd/OpenRC unit. Only Caddy is containerized; the app still runs on the host as root because it shells out to wg, ip and iptables. - Add caddy-container-commands.ts as the single source of truth for the run/exec/validate/inspect argument arrays. Every value stays a separate argv element, the image is pinned to caddy:2.11.4-alpine, and the entrypoint is set explicitly because some mirrors publish the image with a null Entrypoint (which made Docker exec "run" as a binary). - Rewrite install-caddy.sh: require_docker with distro-specific hints, pull + recreate the container, assert it is running and echo the daemon error instead of discarding it, normalize the admin socket path in existing Caddyfiles, and clean up a legacy native install only after the container is up so the ingress port is never unbound. Add --purge-legacy / --purge for hosts that want to drop the old install without installing the container. - Move the admin socket to /var/lib/wgui/caddy/admin.sock so it lives inside the mounted Caddy dir and reloads work over docker exec. - Validate candidate configs in a throwaway container, mounting the TLS dir read-only as well: provisioning the tls app loads every certificate referenced by a tls directive, so without that mount a route with a certificate failed validation and its Caddyfile was never committed. - Report docker-based installed/version/service_active, skip validate/reload with a warning when the image is absent, and update the system setup tool check to look for docker. - Issue certificates with a docker exec reload command and chown files to root:root, since the container reads them through a read-only mount. - Update the Setup UI copy and docs (README, AGENTS.md). Also drops the unused EmptyContent import and a stray debug log in the client route form, and stops passing the unsupported cancel_href prop to ClientRouteForm from the route add/edit pages.
84 lines
3.1 KiB
TypeScript
84 lines
3.1 KiB
TypeScript
import { RotateCcw, Wrench } from "lucide-react";
|
|
import fetchApi from "@/src/components/twui/utils/fetch/fetchApi";
|
|
import Panel from "@/src/components/general/panel";
|
|
import type { ApiReqParams } from "@/src/types";
|
|
import type { APIResponseObject } from "@moduletrace/bunext/types";
|
|
import type useSystemSetupStatus from "../(hooks)/use-system-setup-status";
|
|
import SetupActionRow from "../(partials)/setup-action-row";
|
|
import SetupCaddyAction from "../(partials)/setup-caddy-action";
|
|
import SetupUpdateWgUiAction from "../(partials)/setup-update-wg-ui-action";
|
|
|
|
type Props = {
|
|
setup: ReturnType<typeof useSystemSetupStatus>;
|
|
};
|
|
|
|
const WG_TOOL_COMMANDS = [`wg`, `wg-quick`, `ip`, `curl`];
|
|
|
|
export default function SetupActionsSection({ setup }: Props) {
|
|
const setup_status = setup.setup_status;
|
|
|
|
if (!setup_status) {
|
|
return null;
|
|
}
|
|
|
|
const have_wg_tools = setup_status.tools
|
|
.filter((tool) => WG_TOOL_COMMANDS.includes(tool.command))
|
|
.every((tool) => tool.installed);
|
|
|
|
const have_caddy = Boolean(
|
|
setup_status.tools.find((tool) => tool.name.startsWith("caddy"))
|
|
?.installed,
|
|
);
|
|
|
|
const show_restart = !setup_status.is_dev && setup_status.init_system !== "unknown";
|
|
|
|
return (
|
|
<Panel flush>
|
|
<SetupActionRow
|
|
title="WireGuard tools"
|
|
description="Installs or updates wg, wg-quick and iproute2 with your distro's package manager. Safe to re-run."
|
|
icon={<Wrench size={15} />}
|
|
button_title={have_wg_tools ? "Update tools" : "Install tools"}
|
|
on_run={async () => {
|
|
const res = await fetchApi<ApiReqParams, APIResponseObject>(
|
|
`/api/admin/setup-wireguard-tools`,
|
|
{ method: "POST" },
|
|
);
|
|
setup.refresh();
|
|
return res;
|
|
}}
|
|
/>
|
|
|
|
<SetupCaddyAction
|
|
installed={have_caddy}
|
|
on_done={() => setup.refresh()}
|
|
/>
|
|
|
|
<SetupUpdateWgUiAction setup={setup} />
|
|
|
|
{show_restart ? (
|
|
<SetupActionRow
|
|
title="Restart service"
|
|
description={`Restarts the ${setup_status.service_name} system service. Use after manual changes.`}
|
|
icon={<RotateCcw size={15} />}
|
|
button_title="Restart"
|
|
confirm_params={{
|
|
title: "Restart wg-ui?",
|
|
message: `The ${setup_status.service_name} service restarts and this dashboard goes briefly offline.`,
|
|
confirm_label: "Restart service",
|
|
tone: "danger",
|
|
}}
|
|
on_run={async () => {
|
|
const res = await fetchApi<ApiReqParams, APIResponseObject>(
|
|
`/api/admin/restart-wg-ui-service`,
|
|
{ method: "POST" },
|
|
);
|
|
setup.refresh();
|
|
return res;
|
|
}}
|
|
/>
|
|
) : null}
|
|
</Panel>
|
|
);
|
|
}
|