249 lines
6.2 KiB
YAML
249 lines
6.2 KiB
YAML
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: opengist-system
|
|
labels:
|
|
app.kubernetes.io/name: opengist
|
|
---
|
|
# 2. PVC
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: opengist-data
|
|
namespace: opengist-system
|
|
labels:
|
|
app.kubernetes.io/name: opengist
|
|
recurring-job-group.longhorn.io/needbackup: enabled
|
|
recurring-job.longhorn.io/source: enabled
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
storageClassName: longhorn
|
|
resources:
|
|
requests:
|
|
storage: 5Gi
|
|
|
|
---
|
|
# 3. CONFIGMAP (UPDATED: Security settings moved here)
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: opengist-config
|
|
namespace: opengist-system
|
|
labels:
|
|
app.kubernetes.io/name: opengist
|
|
data:
|
|
config.yaml: |
|
|
log-level: info
|
|
external-url: https://paste.dooplex.hu
|
|
|
|
# Branding
|
|
custom.name: Dooplex Paste
|
|
|
|
# Security Features
|
|
# We set these here to ensure they override defaults
|
|
disable-signup: true
|
|
disable-login-form: true
|
|
require-login: false
|
|
disable-gravatar: false
|
|
|
|
---
|
|
# 4. DEPLOYMENT
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: opengist
|
|
namespace: opengist-system
|
|
labels:
|
|
app.kubernetes.io/name: opengist
|
|
app.kubernetes.io/instance: opengist
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: opengist
|
|
app.kubernetes.io/instance: opengist
|
|
strategy:
|
|
type: Recreate
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/name: opengist
|
|
app.kubernetes.io/instance: opengist
|
|
spec:
|
|
containers:
|
|
- name: opengist
|
|
image: ghcr.io/thomiceli/opengist:1.11.1
|
|
args: ["--config", "/config/config.yaml"]
|
|
env:
|
|
# --- OIDC CONFIGURATION ---
|
|
- name: OG_OIDC_CLIENT_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: opengist-oidc
|
|
key: client-id
|
|
- name: OG_OIDC_SECRET
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: opengist-oidc
|
|
key: client-secret
|
|
- name: OG_OIDC_DISCOVERY_URL
|
|
value: "https://authentik.dooplex.hu/application/o/opengist/.well-known/openid-configuration"
|
|
ports:
|
|
- containerPort: 6157
|
|
name: http
|
|
- containerPort: 2222
|
|
name: ssh
|
|
resources:
|
|
requests:
|
|
cpu: 50m
|
|
memory: 64Mi
|
|
limits:
|
|
cpu: 500m
|
|
memory: 256Mi
|
|
volumeMounts:
|
|
- name: data
|
|
mountPath: /opengist
|
|
- name: config
|
|
mountPath: /config
|
|
readOnly: true
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthcheck
|
|
port: http
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 30
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /healthcheck
|
|
port: http
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
volumes:
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: opengist-data
|
|
- name: config
|
|
configMap:
|
|
name: opengist-config
|
|
|
|
---
|
|
# 5. SERVICE
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: opengist
|
|
namespace: opengist-system
|
|
labels:
|
|
app.kubernetes.io/name: opengist
|
|
app.kubernetes.io/instance: opengist
|
|
spec:
|
|
type: ClusterIP
|
|
ports:
|
|
- name: http
|
|
port: 80
|
|
targetPort: http
|
|
- name: ssh
|
|
port: 2222
|
|
targetPort: ssh
|
|
selector:
|
|
app.kubernetes.io/name: opengist
|
|
app.kubernetes.io/instance: opengist
|
|
|
|
---
|
|
# 6. INGRESS
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata:
|
|
name: opengist
|
|
namespace: opengist-system
|
|
labels:
|
|
app.kubernetes.io/name: opengist
|
|
app.kubernetes.io/instance: opengist
|
|
annotations:
|
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
external-dns.alpha.kubernetes.io/hostname: paste.dooplex.hu,paste.home
|
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
|
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
|
|
# GeoIP-based access control
|
|
nginx.ingress.kubernetes.io/configuration-snippet: |
|
|
# GeoIP-based access control for OpenGist
|
|
# Allows Hungarian traffic everywhere, worldwide only for paste viewing
|
|
|
|
set $geo_allowed 0;
|
|
|
|
# Allow all Hungarian traffic
|
|
if ($remote_addr ~ "^192\.168\.") { set $geo_allowed 1; }
|
|
if ($remote_addr ~ "^10\.") { set $geo_allowed 1; }
|
|
if ($geoip2_country_code = "HU") {
|
|
set $geo_allowed 1;
|
|
}
|
|
|
|
# Allow public gist viewing: /{username}/{32-lowercase-hex-chars}
|
|
if ($request_uri ~* "^/[a-zA-Z0-9_-]+/[a-f0-9]{32}$") {
|
|
set $geo_allowed 1;
|
|
}
|
|
|
|
# Allow raw view: /{username}/{32-hex}/raw/{filename}
|
|
if ($request_uri ~* "^/[a-zA-Z0-9_-]+/[a-f0-9]{32}/raw/") {
|
|
set $geo_allowed 1;
|
|
}
|
|
|
|
# Allow download: /{username}/{32-hex}/download
|
|
if ($request_uri ~* "^/[a-zA-Z0-9_-]+/[a-f0-9]{32}/download") {
|
|
set $geo_allowed 1;
|
|
}
|
|
|
|
# Allow revision viewing: /{username}/{32-hex}/rev/{revision}
|
|
if ($request_uri ~* "^/[a-zA-Z0-9_-]+/[a-f0-9]{32}/rev/[a-f0-9]+") {
|
|
set $geo_allowed 1;
|
|
}
|
|
|
|
# Allow embed view
|
|
if ($request_uri ~* "^/[a-zA-Z0-9_-]+/[a-f0-9]{32}/embed") {
|
|
set $geo_allowed 1;
|
|
}
|
|
|
|
# Allow static assets
|
|
if ($request_uri ~* "^/assets/") {
|
|
set $geo_allowed 1;
|
|
}
|
|
if ($request_uri ~* "^/favicon") {
|
|
set $geo_allowed 1;
|
|
}
|
|
if ($request_uri ~* "\.(css|js|woff2?|ttf|svg|png|ico)$") {
|
|
set $geo_allowed 1;
|
|
}
|
|
|
|
# Block non-allowed requests
|
|
if ($geo_allowed = 0) {
|
|
return 403 "Access restricted to Hungary";
|
|
}
|
|
spec:
|
|
ingressClassName: nginx-internal
|
|
rules:
|
|
- host: paste.dooplex.hu
|
|
http:
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
backend:
|
|
service:
|
|
name: opengist
|
|
port:
|
|
number: 80
|
|
- host: paste.home
|
|
http:
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
backend:
|
|
service:
|
|
name: opengist
|
|
port:
|
|
number: 80
|
|
tls:
|
|
- hosts:
|
|
- paste.dooplex.hu
|
|
secretName: opengist-tls
|