import { useTranslations } from "next-intl"; import CopyTextBox from "./CopyTextBox"; import { SettingsSection, SettingsSectionBody, SettingsSectionDescription, SettingsSectionHeader, SettingsSectionTitle } from "./Settings"; import { CheckboxWithLabel } from "./ui/checkbox"; import { OptionSelect, type OptionSelectOption } from "./OptionSelect"; import { useState } from "react"; import { FaApple, FaCubes, FaDocker, FaLinux, FaWindows } from "react-icons/fa"; import { SiKubernetes, SiNixos } from "react-icons/si"; export type CommandItem = string | { title: string; command: string }; const PLATFORMS = [ "linux", "macos", "docker", "kubernetes", "podman", "nixos", "windows" ] as const; type Platform = (typeof PLATFORMS)[number]; export type NewtSiteInstallCommandsProps = { id: string; secret: string; endpoint: string; version?: string; }; export function NewtSiteInstallCommands({ id, secret, endpoint, version = "latest" }: NewtSiteInstallCommandsProps) { const t = useTranslations(); const [acceptClients, setAcceptClients] = useState(true); const [platform, setPlatform] = useState("linux"); const [architecture, setArchitecture] = useState( () => getArchitectures(platform)[0] ); const acceptClientsFlag = !acceptClients ? " --disable-clients" : ""; const acceptClientsEnv = !acceptClients ? "\n - DISABLE_CLIENTS=true" : ""; const commandList: Record> = { linux: { Run: [ { title: t("install"), command: `curl -fsSL https://static.pangolin.net/get-newt.sh | bash` }, { title: t("run"), command: `newt --id ${id} --secret ${secret} --endpoint ${endpoint}${acceptClientsFlag}` } ], "Systemd Service": [ { title: t("install"), command: `curl -fsSL https://static.pangolin.net/get-newt.sh | bash` }, { title: t("envFile"), command: `# Create the directory and environment file sudo install -d -m 0755 /etc/newt sudo tee /etc/newt/newt.env > /dev/null << 'EOF' NEWT_ID=${id} NEWT_SECRET=${secret} PANGOLIN_ENDPOINT=${endpoint}${!acceptClients ? ` DISABLE_CLIENTS=true` : ""} EOF sudo chmod 600 /etc/newt/newt.env` }, { title: t("serviceFile"), command: `sudo tee /etc/systemd/system/newt.service > /dev/null << 'EOF' [Unit] Description=Newt Wants=network-online.target After=network-online.target [Service] Type=simple User=root Group=root EnvironmentFile=/etc/newt/newt.env ExecStart=/usr/local/bin/newt Restart=always RestartSec=2 UMask=0077 NoNewPrivileges=true PrivateTmp=true [Install] WantedBy=multi-user.target EOF` }, { title: t("enableAndStart"), command: `sudo systemctl daemon-reload sudo systemctl enable --now newt` } ] }, macos: { Run: [ { title: t("install"), command: `curl -fsSL https://static.pangolin.net/get-newt.sh | bash` }, { title: t("run"), command: `newt --id ${id} --secret ${secret} --endpoint ${endpoint}${acceptClientsFlag}` } ] }, windows: { x64: [ { title: t("install"), command: `curl -o newt.exe -L "https://github.com/fosrl/newt/releases/download/${version}/newt_windows_amd64.exe"` }, { title: t("run"), command: `newt.exe --id ${id} --secret ${secret} --endpoint ${endpoint}${acceptClientsFlag}` } ] }, docker: { "Docker Compose": [ `services: newt: image: fosrl/newt container_name: newt restart: unless-stopped environment: - PANGOLIN_ENDPOINT=${endpoint} - NEWT_ID=${id} - NEWT_SECRET=${secret}${acceptClientsEnv}` ], "Docker Run": [ `docker run -dit --network host fosrl/newt --id ${id} --secret ${secret} --endpoint ${endpoint}${acceptClientsFlag}` ] }, kubernetes: { "Helm Chart": [ `helm repo add fossorial https://charts.fossorial.io`, `helm repo update fossorial`, `helm install newt fossorial/newt \\ --create-namespace \\ --set newtInstances[0].name="main-tunnel" \\ --set newtInstances[0].enabled=true \\ --set-string newtInstances[0].auth.keys.endpointKey="${endpoint}" \\ --set-string newtInstances[0].auth.keys.idKey="${id}" \\ --set-string newtInstances[0].auth.keys.secretKey="${secret}"` ] }, podman: { "Podman Quadlet": [ `[Unit] Description=Newt container [Container] ContainerName=newt Image=docker.io/fosrl/newt Environment=PANGOLIN_ENDPOINT=${endpoint} Environment=NEWT_ID=${id} Environment=NEWT_SECRET=${secret}${!acceptClients ? "\nEnvironment=DISABLE_CLIENTS=true" : ""} # Secret=newt-secret,type=env,target=NEWT_SECRET [Service] Restart=always [Install] WantedBy=default.target` ], "Podman Run": [ `podman run -dit docker.io/fosrl/newt --id ${id} --secret ${secret} --endpoint ${endpoint}${acceptClientsFlag}` ] }, nixos: { Flake: [ `nix run 'nixpkgs#fosrl-newt' -- --id ${id} --secret ${secret} --endpoint ${endpoint}${acceptClientsFlag}` ] } }; const commands = commandList[platform][architecture]; const platformOptions: OptionSelectOption[] = PLATFORMS.map( (os) => ({ value: os, label: getPlatformName(os), icon: getPlatformIcon(os) }) ); return ( {t("siteInstallNewt")} {t("siteInstallNewtDescription")} label={t("operatingSystem")} options={platformOptions} value={platform} onChange={(os) => { setPlatform(os); const architectures = getArchitectures(os); setArchitecture(architectures[0]); }} cols={5} /> label={ platform === "windows" ? t("architecture") : t("method") } options={getArchitectures(platform).map((arch) => ({ value: arch, label: arch }))} value={architecture} onChange={setArchitecture} cols={5} className="mt-4" />

{t("siteConfiguration")}

{ const value = checked as boolean; setAcceptClients(value); }} label={t("siteAcceptClientConnections")} />

{t("siteAcceptClientConnectionsDescription")}

{t("commands")}

{platform === "kubernetes" && (

For more and up to date Kubernetes installation information, see{" "} docs.pangolin.net/manage/sites/install-kubernetes .

)}
{commands.map((item, index) => { const commandText = typeof item === "string" ? item : item.command; const title = typeof item === "string" ? undefined : item.title; const key = `${title ?? ""}::${commandText}`; return (
{title && (

{title}

)}
); })}
); } function getPlatformIcon(platformName: Platform) { switch (platformName) { case "windows": return ; case "linux": return ; case "macos": return ; case "docker": return ; case "kubernetes": return ; case "podman": return ; case "nixos": return ; default: return ; } } function getPlatformName(platformName: Platform) { switch (platformName) { case "windows": return "Windows"; case "linux": return "Linux"; case "macos": return "macOS"; case "docker": return "Docker"; case "kubernetes": return "Kubernetes"; case "podman": return "Podman"; case "nixos": return "NixOS"; default: return "Linux"; } } function getArchitectures(platform: Platform) { switch (platform) { case "linux": return ["Run", "Systemd Service"]; case "macos": return ["Run"]; case "windows": return ["x64"]; case "docker": return ["Docker Compose", "Docker Run"]; case "kubernetes": return ["Helm Chart"]; case "podman": return ["Podman Quadlet", "Podman Run"]; case "nixos": return ["Flake"]; default: return ["Run"]; } }