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 ($geoip2_city_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