feat(xui): add 3x-ui VPN panel behind cloudflared tunnel

VLESS+WS inbound (port 10000) via Traefik IngressRoute, panel on internal domains only with public route commented out. gitignore now covers nested k8s secrets and local-only grafana values.
This commit is contained in:
forust committed 2026-09-19 19:06:37 +02:00
1 parent 86ac43567d
commit 4e3ad00202
6 files changed
+174

No files matched your search

+4
View File
@@ -104,6 +104,10 @@ temp/*
# kubernetes
*/k8s/*secret*
!*/k8s/*secret*.example
**/k8s/*secret*
!**/k8s/*secret*.example
# Local-only tweaks, not for upstream
prometheus-stack/k8s/grafana-values.yaml
traefik/k8s/local-tls.yaml
converters/k8s/config.yaml
convertx/k8s/config.yaml
View File
Whitespace-only changes.
+11
View File
@@ -0,0 +1,11 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: xui-config
namespace: xui
data:
XUI_DB_FOLDER: "/etc/x-ui"
XUI_ENABLE_FAIL2BAN: "false"
XUI_INIT_WEB_BASE_PATH: "/"
XUI_LOG_LEVEL: "warning"
XUI_PORT: "30379"
+81
View File
@@ -0,0 +1,81 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: xui-local
namespace: xui
spec:
entryPoints:
- websecure
routes:
- match: Host(`xui.workstation.internal`) || Host(`xui.gigaforust.internal`)
kind: Rule
services:
- name: xui-service
port: 30379
---
# Public panel access (optional).
# Realistic, but intentionally disabled: the panel has its own login,
# security-chain adds Authentik in front of it.
# To enable: uncomment and add Public Hostname `xui.forust.xyz`
# in the Cloudflare tunnel (same as other *.forust.xyz hosts).
# ---
# apiVersion: traefik.io/v1alpha1
# kind: IngressRoute
# metadata:
# name: xui-prod
# namespace: xui
# spec:
# entryPoints:
# - websecure
# routes:
# - match: Host(`xui.forust.xyz`)
# kind: Rule
# middlewares:
# - name: security-chain@file
# services:
# - name: xui-service
# port: 30379
# tls:
# certResolver: letsencrypt
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: xray-prod
namespace: xui
spec:
entryPoints:
- websecure
routes:
- match: Host(`xray.forust.xyz`) && PathPrefix(`/pzzfpz6oi281f0u8`)
kind: Rule
services:
- name: xui-service
port: 2096
- match: Host(`xray.forust.xyz`)
kind: Rule
services:
- name: xui-service
port: 10000
tls:
certResolver: letsencrypt
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: xray-local
namespace: xui
spec:
entryPoints:
- websecure
routes:
- match: (Host(`xray.workstation.internal`) || Host(`xray.gigaforust.internal`)) && PathPrefix(`/pzzfpz6oi281f0u8`)
kind: Rule
services:
- name: xui-service
port: 2096
- match: Host(`xray.workstation.internal`) || Host(`xray.gigaforust.internal`)
kind: Rule
services:
- name: xui-service
port: 10000
+4
View File
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: xui
+74
View File
@@ -0,0 +1,74 @@
apiVersion: v1
kind: Service
metadata:
name: xui-service
namespace: xui
spec:
selector:
app: xui
ports:
- port: 30379
name: panel
targetPort: 30379
- port: 10000
name: xray
targetPort: 10000
- port: 2096
name: sub
targetPort: 2096
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: xui-deployment
namespace: xui
spec:
replicas: 1
selector:
matchLabels:
app: xui
template:
metadata:
labels:
app: xui
spec:
containers:
- name: xui
image: ghcr.io/mhsanaei/3x-ui:v3.8.5
envFrom:
- configMapRef:
name: xui-config
tty: true
ports:
- containerPort: 30379
name: panel
- containerPort: 10000
name: xray
- containerPort: 2096
name: sub
volumeMounts:
- name: x-ui-db
mountPath: /etc/x-ui
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "1Gi"
cpu: "1000m"
volumes:
- name: x-ui-db
persistentVolumeClaim:
claimName: xui-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: xui-pvc
namespace: xui
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi