added webserver
This commit is contained in:
@@ -877,4 +877,26 @@ spec:
|
|||||||
syncOptions:
|
syncOptions:
|
||||||
- CreateNamespace=true
|
- CreateNamespace=true
|
||||||
- PruneLast=true
|
- PruneLast=true
|
||||||
|
---
|
||||||
|
# Webserver
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: webserver
|
||||||
|
namespace: argocd
|
||||||
|
finalizers:
|
||||||
|
- resources-finalizer.argocd.argoproj.io
|
||||||
|
spec:
|
||||||
|
project: homelab
|
||||||
|
source:
|
||||||
|
repoURL: https://gitea.dooplex.hu/admin/homelab-manifests.git
|
||||||
|
targetRevision: main
|
||||||
|
path: web-system
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: web-system
|
||||||
|
syncPolicy:
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
|
- PruneLast=true
|
||||||
---
|
---
|
||||||
@@ -0,0 +1,495 @@
|
|||||||
|
---
|
||||||
|
# FileBrowser - Web-based file manager
|
||||||
|
# https://filebrowser.org/
|
||||||
|
#
|
||||||
|
# Features:
|
||||||
|
# - Web-based file browser and manager
|
||||||
|
# - File upload/download via web UI
|
||||||
|
# - File preview (images, text, markdown, video)
|
||||||
|
# - Built-in text editor
|
||||||
|
# - Share links for files
|
||||||
|
# - Very lightweight (~15MB RAM)
|
||||||
|
# - Authentik SSO integration (proxy auth)
|
||||||
|
#
|
||||||
|
# Authentication: Via Authentik (no double login!)
|
||||||
|
# FileBrowser trusts the X-authentik-username header from the proxy.
|
||||||
|
#
|
||||||
|
# Authentik Setup:
|
||||||
|
# 1. Create a Proxy Provider in Authentik:
|
||||||
|
# - Name: FileBrowser
|
||||||
|
# - Authorization flow: default-provider-authorization-implicit-consent
|
||||||
|
# - Type: Forward auth (single application)
|
||||||
|
# - External host: https://webadmin.dooplex.hu
|
||||||
|
#
|
||||||
|
# 2. Create an Application:
|
||||||
|
# - Name: FileBrowser
|
||||||
|
# - Slug: filebrowser
|
||||||
|
# - Provider: FileBrowser (the one you just created)
|
||||||
|
#
|
||||||
|
# 3. Create an Outpost (or add to existing):
|
||||||
|
# - Name: filebrowser-outpost
|
||||||
|
# - Type: Proxy
|
||||||
|
# - Integration: Kubernetes (auth-system namespace)
|
||||||
|
# - Applications: FileBrowser
|
||||||
|
#
|
||||||
|
# 4. Authentik will auto-create:
|
||||||
|
# - Deployment: ak-outpost-filebrowser-outpost in auth-system
|
||||||
|
# - Service: ak-outpost-filebrowser-outpost in auth-system
|
||||||
|
# - Ingress for /outpost.goauthentik.io path on webadmin.dooplex.hu
|
||||||
|
#
|
||||||
|
# Note: The outpost service name in auth-url must match!
|
||||||
|
# If you name outpost differently, update the annotation:
|
||||||
|
# http://ak-outpost-<your-outpost-name>.auth-system.svc.cluster.local:9000/...
|
||||||
|
#
|
||||||
|
# Access:
|
||||||
|
# - Admin UI: https://webadmin.dooplex.hu (Authentik login)
|
||||||
|
# - Public files: https://web.dooplex.hu (direct file access, no auth)
|
||||||
|
#
|
||||||
|
# Usage for static HTML hosting:
|
||||||
|
# 1. Login to webadmin.dooplex.hu (via Authentik)
|
||||||
|
# 2. Upload HTML files and assets to /public folder
|
||||||
|
# 3. Access directly via web.dooplex.hu/filename or web.dooplex.hu/folder
|
||||||
|
#
|
||||||
|
# Clean URL examples:
|
||||||
|
# - /public/fizetes.html → web.dooplex.hu/fizetes
|
||||||
|
# - /public/fizetes/index.html → web.dooplex.hu/fizetes
|
||||||
|
# - /public/about/index.html → web.dooplex.hu/about
|
||||||
|
#
|
||||||
|
# Note: First user to login via Authentik becomes admin in FileBrowser.
|
||||||
|
# Additional users logging in will be created automatically.
|
||||||
|
#
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: web-system
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: web-system
|
||||||
|
---
|
||||||
|
# PVC for files
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: filebrowser-data
|
||||||
|
namespace: web-system
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: filebrowser
|
||||||
|
app.kubernetes.io/name: filebrowser
|
||||||
|
recurring-job-group.longhorn.io/backup: enabled
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
storageClassName: longhorn
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
---
|
||||||
|
# PVC for database and config
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: filebrowser-config
|
||||||
|
namespace: web-system
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: filebrowser
|
||||||
|
app.kubernetes.io/name: filebrowser
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
storageClassName: longhorn
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 100Mi
|
||||||
|
---
|
||||||
|
# ConfigMap for FileBrowser settings
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: filebrowser-config
|
||||||
|
namespace: web-system
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: filebrowser
|
||||||
|
app.kubernetes.io/name: filebrowser
|
||||||
|
data:
|
||||||
|
.filebrowser.json: |
|
||||||
|
{
|
||||||
|
"port": 80,
|
||||||
|
"baseURL": "",
|
||||||
|
"address": "",
|
||||||
|
"log": "stdout",
|
||||||
|
"database": "/config/filebrowser.db",
|
||||||
|
"root": "/srv",
|
||||||
|
"auth": {
|
||||||
|
"method": "proxy",
|
||||||
|
"header": "X-authentik-username"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
---
|
||||||
|
# FileBrowser Deployment
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: filebrowser
|
||||||
|
namespace: web-system
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: filebrowser
|
||||||
|
app.kubernetes.io/name: filebrowser
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/instance: filebrowser
|
||||||
|
app.kubernetes.io/name: filebrowser
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: filebrowser
|
||||||
|
app.kubernetes.io/name: filebrowser
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 1000
|
||||||
|
runAsGroup: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
containers:
|
||||||
|
- name: filebrowser
|
||||||
|
image: filebrowser/filebrowser:v2.53.1
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
name: http
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: TZ
|
||||||
|
value: "Europe/Budapest"
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /srv
|
||||||
|
- name: config
|
||||||
|
mountPath: /config
|
||||||
|
- name: settings
|
||||||
|
mountPath: /.filebrowser.json
|
||||||
|
subPath: .filebrowser.json
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 128Mi
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 30
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: filebrowser-data
|
||||||
|
- name: config
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: filebrowser-config
|
||||||
|
- name: settings
|
||||||
|
configMap:
|
||||||
|
name: filebrowser-config
|
||||||
|
---
|
||||||
|
# Service for FileBrowser
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: filebrowser
|
||||||
|
namespace: web-system
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: filebrowser
|
||||||
|
app.kubernetes.io/name: filebrowser
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/instance: filebrowser
|
||||||
|
app.kubernetes.io/name: filebrowser
|
||||||
|
---
|
||||||
|
# Ingress for FileBrowser admin UI (Authentik protected)
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: filebrowser
|
||||||
|
namespace: web-system
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: filebrowser
|
||||||
|
app.kubernetes.io/name: filebrowser
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
external-dns.alpha.kubernetes.io/hostname: webadmin.dooplex.hu
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: "1024m"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||||
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||||
|
# Authentik forward auth - update outpost name after creating in Authentik!
|
||||||
|
nginx.ingress.kubernetes.io/auth-url: http://ak-outpost-filebrowser-outpost.auth-system.svc.cluster.local:9000/outpost.goauthentik.io/auth/nginx
|
||||||
|
nginx.ingress.kubernetes.io/auth-signin: https://webadmin.dooplex.hu/outpost.goauthentik.io/start?rd=$escaped_request_uri
|
||||||
|
nginx.ingress.kubernetes.io/auth-response-headers: X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid
|
||||||
|
nginx.ingress.kubernetes.io/auth-snippet: |
|
||||||
|
proxy_set_header X-Forwarded-Host $http_host;
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx-internal
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- webadmin.dooplex.hu
|
||||||
|
secretName: filebrowser-tls
|
||||||
|
rules:
|
||||||
|
- host: webadmin.dooplex.hu
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: filebrowser
|
||||||
|
port:
|
||||||
|
name: http
|
||||||
|
- host: webadmin.home
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: filebrowser
|
||||||
|
port:
|
||||||
|
name: http
|
||||||
|
---
|
||||||
|
# ============================================
|
||||||
|
# NGINX Static File Server (Public Access)
|
||||||
|
# ============================================
|
||||||
|
# This serves files from /public folder without authentication
|
||||||
|
# Access: https://web.dooplex.hu/filename or https://web.dooplex.hu/folder
|
||||||
|
#
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: static-server
|
||||||
|
namespace: web-system
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: static-server
|
||||||
|
app.kubernetes.io/name: static-server
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/instance: static-server
|
||||||
|
app.kubernetes.io/name: static-server
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: static-server
|
||||||
|
app.kubernetes.io/name: static-server
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 1000
|
||||||
|
runAsGroup: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
initContainers:
|
||||||
|
# Create public directory if it doesn't exist
|
||||||
|
- name: init-public-dir
|
||||||
|
image: busybox:1.36
|
||||||
|
command: ['sh', '-c', 'mkdir -p /srv/public && chmod 755 /srv/public']
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /srv
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 0
|
||||||
|
containers:
|
||||||
|
- name: nginx
|
||||||
|
image: nginx:1.27-alpine
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
name: http
|
||||||
|
protocol: TCP
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /usr/share/nginx/html
|
||||||
|
subPath: public
|
||||||
|
readOnly: true
|
||||||
|
- name: nginx-config
|
||||||
|
mountPath: /etc/nginx/nginx.conf
|
||||||
|
subPath: nginx.conf
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 5m
|
||||||
|
memory: 16Mi
|
||||||
|
limits:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 64Mi
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 30
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 3
|
||||||
|
periodSeconds: 10
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: filebrowser-data
|
||||||
|
- name: nginx-config
|
||||||
|
configMap:
|
||||||
|
name: static-server-config
|
||||||
|
---
|
||||||
|
# ConfigMap for nginx static server
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: static-server-config
|
||||||
|
namespace: web-system
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: static-server
|
||||||
|
app.kubernetes.io/name: static-server
|
||||||
|
data:
|
||||||
|
nginx.conf: |
|
||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
pid /tmp/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
# Temp paths for non-root user
|
||||||
|
client_body_temp_path /tmp/client_temp;
|
||||||
|
proxy_temp_path /tmp/proxy_temp;
|
||||||
|
fastcgi_temp_path /tmp/fastcgi_temp;
|
||||||
|
uwsgi_temp_path /tmp/uwsgi_temp;
|
||||||
|
scgi_temp_path /tmp/scgi_temp;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 8080;
|
||||||
|
server_name _;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "OK\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Serve static files
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ $uri.html =404;
|
||||||
|
|
||||||
|
# Directory listing disabled for security
|
||||||
|
# Uncomment below if you want to browse directories
|
||||||
|
# autoindex on;
|
||||||
|
# autoindex_exact_size off;
|
||||||
|
# autoindex_localtime on;
|
||||||
|
|
||||||
|
# Cache static assets
|
||||||
|
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2)$ {
|
||||||
|
expires 7d;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
add_header X-Frame-Options SAMEORIGIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
---
|
||||||
|
# Service for static server
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: static-server
|
||||||
|
namespace: web-system
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: static-server
|
||||||
|
app.kubernetes.io/name: static-server
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/instance: static-server
|
||||||
|
app.kubernetes.io/name: static-server
|
||||||
|
---
|
||||||
|
# Ingress for public static files
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: static-server
|
||||||
|
namespace: web-system
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/instance: static-server
|
||||||
|
app.kubernetes.io/name: static-server
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
external-dns.alpha.kubernetes.io/hostname: web.dooplex.hu
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx-internal
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- web.dooplex.hu
|
||||||
|
secretName: static-server-tls
|
||||||
|
rules:
|
||||||
|
- host: web.dooplex.hu
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: static-server
|
||||||
|
port:
|
||||||
|
name: http
|
||||||
|
- host: web.home
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: static-server
|
||||||
|
port:
|
||||||
|
name: http
|
||||||
Reference in New Issue
Block a user