mirror of
https://github.com/fosrl/pangolin.git
synced 2025-08-24 11:15:31 +02:00
change target form verbiage and update readme
This commit is contained in:
parent
c3d19454f7
commit
7b20329743
7 changed files with 54 additions and 15 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -30,3 +30,4 @@ dist
|
||||||
.dist
|
.dist
|
||||||
installer
|
installer
|
||||||
*.tar
|
*.tar
|
||||||
|
bin
|
||||||
|
|
5
Makefile
5
Makefile
|
@ -1,4 +1,4 @@
|
||||||
build-all:
|
build-release:
|
||||||
@if [ -z "$(tag)" ]; then \
|
@if [ -z "$(tag)" ]; then \
|
||||||
echo "Error: tag is required. Usage: make build-all tag=<tag>"; \
|
echo "Error: tag is required. Usage: make build-all tag=<tag>"; \
|
||||||
exit 1; \
|
exit 1; \
|
||||||
|
@ -12,6 +12,9 @@ build-arm:
|
||||||
build-x86:
|
build-x86:
|
||||||
docker buildx build --platform linux/amd64 -t fosrl/pangolin:latest .
|
docker buildx build --platform linux/amd64 -t fosrl/pangolin:latest .
|
||||||
|
|
||||||
|
build-x86-ecr:
|
||||||
|
docker buildx build --platform linux/amd64 -t 216989133116.dkr.ecr.us-east-1.amazonaws.com/pangolin:latest --push .
|
||||||
|
|
||||||
build:
|
build:
|
||||||
docker build -t fosrl/pangolin:latest .
|
docker build -t fosrl/pangolin:latest .
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
# Pangolin
|
# Pangolin
|
||||||
|
|
||||||
|
[](https://docs.fossorial.io/)
|
||||||
|
[](https://hub.docker.com/r/fosrl/pangolin)
|
||||||
|

|
||||||
|
[](https://discord.gg/HCJR8Xhme4)
|
||||||
|
[](https://www.youtube.com/@fossorial-app)
|
||||||
|
|
||||||
Pangolin is a self-hosted tunneled reverse proxy management server with identity and access management, designed to securely expose private resources through use with the Traefik reverse proxy and WireGuard tunnel clients like Newt. With Pangolin, you retain full control over your infrastructure while providing a user-friendly and feature-rich solution for managing proxies, authentication, and access, and simplifying complex network setups, all with a clean and simple UI.
|
Pangolin is a self-hosted tunneled reverse proxy management server with identity and access management, designed to securely expose private resources through use with the Traefik reverse proxy and WireGuard tunnel clients like Newt. With Pangolin, you retain full control over your infrastructure while providing a user-friendly and feature-rich solution for managing proxies, authentication, and access, and simplifying complex network setups, all with a clean and simple UI.
|
||||||
|
|
||||||
### Installation and Documentation
|
### Installation and Documentation
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
|
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
build:
|
build:
|
||||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o installer
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o installer
|
||||||
|
|
||||||
|
build-release:
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/installer_linux_amd64
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o bin/installer_linux_arm64
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm installer
|
rm installer
|
||||||
|
|
|
@ -62,6 +62,7 @@ import {
|
||||||
SettingsSectionFooter
|
SettingsSectionFooter
|
||||||
} from "@app/components/Settings";
|
} from "@app/components/Settings";
|
||||||
import { SwitchInput } from "@app/components/SwitchInput";
|
import { SwitchInput } from "@app/components/SwitchInput";
|
||||||
|
import { useSiteContext } from "@app/hooks/useSiteContext";
|
||||||
|
|
||||||
// Regular expressions for validation
|
// Regular expressions for validation
|
||||||
const DOMAIN_REGEX =
|
const DOMAIN_REGEX =
|
||||||
|
@ -528,11 +529,23 @@ export default function ReverseProxyTargets(props: {
|
||||||
name="ip"
|
name="ip"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>IP Address</FormLabel>
|
<FormLabel>IP / Hostname</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input id="ip" {...field} />
|
<Input id="ip" {...field} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
|
{site?.type === "newt" ? (
|
||||||
|
<FormDescription>
|
||||||
|
This is the IP or hostname
|
||||||
|
of the target service on
|
||||||
|
your network.
|
||||||
|
</FormDescription>
|
||||||
|
) : site?.type === "wireguard" ? (
|
||||||
|
<FormDescription>
|
||||||
|
This is the IP of the
|
||||||
|
WireGuard peer.
|
||||||
|
</FormDescription>
|
||||||
|
) : null}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -551,6 +564,19 @@ export default function ReverseProxyTargets(props: {
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
|
{site?.type === "newt" ? (
|
||||||
|
<FormDescription>
|
||||||
|
This is the port of the
|
||||||
|
target service on your
|
||||||
|
network.
|
||||||
|
</FormDescription>
|
||||||
|
) : site?.type === "wireguard" ? (
|
||||||
|
<FormDescription>
|
||||||
|
This is the port exposed on
|
||||||
|
an address on the WireGuard
|
||||||
|
network.
|
||||||
|
</FormDescription>
|
||||||
|
) : null}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -2,13 +2,12 @@ import ResourceProvider from "@app/providers/ResourceProvider";
|
||||||
import { internal } from "@app/lib/api";
|
import { internal } from "@app/lib/api";
|
||||||
import {
|
import {
|
||||||
GetResourceAuthInfoResponse,
|
GetResourceAuthInfoResponse,
|
||||||
GetResourceResponse,
|
GetResourceResponse
|
||||||
} from "@server/routers/resource";
|
} from "@server/routers/resource";
|
||||||
import { AxiosResponse } from "axios";
|
import { AxiosResponse } from "axios";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
import { authCookieHeader } from "@app/lib/api/cookies";
|
import { authCookieHeader } from "@app/lib/api/cookies";
|
||||||
import { SidebarSettings } from "@app/components/SidebarSettings";
|
import { SidebarSettings } from "@app/components/SidebarSettings";
|
||||||
import { Cloud, Settings, Shield } from "lucide-react";
|
|
||||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||||
import { GetOrgResponse } from "@server/routers/org";
|
import { GetOrgResponse } from "@server/routers/org";
|
||||||
import OrgProvider from "@app/providers/OrgProvider";
|
import OrgProvider from "@app/providers/OrgProvider";
|
||||||
|
@ -20,7 +19,7 @@ import {
|
||||||
BreadcrumbLink,
|
BreadcrumbLink,
|
||||||
BreadcrumbList,
|
BreadcrumbList,
|
||||||
BreadcrumbPage,
|
BreadcrumbPage,
|
||||||
BreadcrumbSeparator,
|
BreadcrumbSeparator
|
||||||
} from "@app/components/ui/breadcrumb";
|
} from "@app/components/ui/breadcrumb";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ export default async function ResourceLayout(props: ResourceLayoutProps) {
|
||||||
try {
|
try {
|
||||||
const res = await internal.get<AxiosResponse<GetResourceResponse>>(
|
const res = await internal.get<AxiosResponse<GetResourceResponse>>(
|
||||||
`/resource/${params.resourceId}`,
|
`/resource/${params.resourceId}`,
|
||||||
await authCookieHeader(),
|
await authCookieHeader()
|
||||||
);
|
);
|
||||||
resource = res.data.data;
|
resource = res.data.data;
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -68,8 +67,8 @@ export default async function ResourceLayout(props: ResourceLayoutProps) {
|
||||||
const getOrg = cache(async () =>
|
const getOrg = cache(async () =>
|
||||||
internal.get<AxiosResponse<GetOrgResponse>>(
|
internal.get<AxiosResponse<GetOrgResponse>>(
|
||||||
`/org/${params.orgId}`,
|
`/org/${params.orgId}`,
|
||||||
await authCookieHeader(),
|
await authCookieHeader()
|
||||||
),
|
)
|
||||||
);
|
);
|
||||||
const res = await getOrg();
|
const res = await getOrg();
|
||||||
org = res.data.data;
|
org = res.data.data;
|
||||||
|
@ -84,19 +83,19 @@ export default async function ResourceLayout(props: ResourceLayoutProps) {
|
||||||
const sidebarNavItems = [
|
const sidebarNavItems = [
|
||||||
{
|
{
|
||||||
title: "General",
|
title: "General",
|
||||||
href: `/{orgId}/settings/resources/{resourceId}/general`,
|
href: `/{orgId}/settings/resources/{resourceId}/general`
|
||||||
// icon: <Settings className="w-4 h-4" />,
|
// icon: <Settings className="w-4 h-4" />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Connectivity",
|
title: "Connectivity",
|
||||||
href: `/{orgId}/settings/resources/{resourceId}/connectivity`,
|
href: `/{orgId}/settings/resources/{resourceId}/connectivity`
|
||||||
// icon: <Cloud className="w-4 h-4" />,
|
// icon: <Cloud className="w-4 h-4" />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Authentication",
|
title: "Authentication",
|
||||||
href: `/{orgId}/settings/resources/{resourceId}/authentication`,
|
href: `/{orgId}/settings/resources/{resourceId}/authentication`
|
||||||
// icon: <Shield className="w-4 h-4" />,
|
// icon: <Shield className="w-4 h-4" />,
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default async function RootLayout({
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<footer className="w-full mt-12 py-3 mb-6 px-4">
|
<footer className="w-full mt-12 py-3 mb-6 px-4">
|
||||||
<div className="container mx-auto flex flex-wrap justify-center items-center h-3 space-x-4 text-sm text-neutral-600 select-none">
|
<div className="container mx-auto flex flex-wrap justify-center items-center h-3 space-x-4 text-sm text-neutral-400 dark:text-neutral-600 select-none">
|
||||||
<div className="flex items-center space-x-2 whitespace-nowrap">
|
<div className="flex items-center space-x-2 whitespace-nowrap">
|
||||||
<span>Pangolin</span>
|
<span>Pangolin</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue