├── README.md ├── adguard-home ├── adguard-configmap.yml ├── adguard-deployment.yml ├── adguard-namespace.yml ├── adguard-pvc.yml ├── adguard-secret.yml └── adguard-service.yml ├── changedetection ├── changedetection-deployment.yml ├── changedetection-ingress.yml ├── changedetection-namespace.yml ├── changedetection-pvc.yml ├── changedetection-secret.yml └── changedetection-svc.yml ├── firefox ├── firefox-deployment.yml ├── firefox-ingress.yml ├── firefox-namespace.yml ├── firefox-pvc.yml └── firefox-service.yml ├── flame-dashboard ├── flame-claim0-persistentvolumeclaim.yaml ├── flame-deployment.yaml ├── flame-ingressroute.yml ├── flame-namespace.yml ├── flame-secret.yml └── flame-service.yaml ├── ghost-blog ├── ghost-deployment.yml ├── ghost-ingressroute.yml ├── ghost-namespace.yml ├── ghost-pvc.yml └── ghost-service.yml ├── homarr ├── homarr-deployment.yml ├── homarr-ingress.yml ├── homarr-namespace.yml ├── homarr-pvc.yml └── homarr-svc.yml ├── littlelink ├── littlelink-deployment.yml ├── littlelink-ingress.yml ├── littlelink-namespace.yml └── littlelink-svc.yml ├── mysql-workbench ├── mysql-workbench-auth.yml ├── mysql-workbench-deployment.yml ├── mysql-workbench-ingress.yml ├── mysql-workbench-middleware.yml ├── mysql-workbench-namespace.yml ├── mysql-workbench-pvc.yml └── mysql-workbench-services.yml ├── mysql ├── mysql-deployment.yml ├── mysql-namespace.yml ├── mysql-pvc.yml ├── mysql-secret.yml └── mysql-svc.yml ├── nextcloud ├── app-deployment.yaml ├── app-service.yaml ├── configmaps.yaml ├── db-deployment.yaml ├── db-service.yaml ├── ingressroute.yaml ├── namespace.yaml ├── pvc.yaml └── secrets.yaml ├── pihole ├── pihole-configmap.yml ├── pihole-deployment.yml ├── pihole-ingress.yml ├── pihole-namespace.yml ├── pihole-pvc.yml ├── pihole-secret.yml └── pihole-svc.yml ├── smokeping ├── smokeping-configmap.yml ├── smokeping-deployment.yml ├── smokeping-ingress.yml ├── smokeping-namespace.yml ├── smokeping-netpolicy.yml ├── smokeping-pvc.yml └── smokeping-svc.yml ├── speedtest-tracker ├── speedtest-tracker-db-creds.yml ├── speedtest-tracker-db-pvc.yml ├── speedtest-tracker-db-svc.yml ├── speedtest-tracker-db.yml ├── speedtest-tracker-ingress.yml ├── speedtest-tracker-namespace.yml ├── speedtest-tracker-netpolicy.yml ├── speedtest-tracker-pvc.yml ├── speedtest-tracker-svc.yml └── speedtest-tracker.yml ├── traefik ├── default-headers.yml ├── demo-ingress-route-with-cert.yml ├── demo-ingress-route.yml ├── traefik-dashboard-auth.yml ├── traefik-dashboard-basicauth-middleware.yml ├── traefik-dashboard-ingress-route-with-auth.yml └── values.yml └── uptime ├── uptime-ingress.yml ├── uptime-kuma-deployment.yml ├── uptime-kuma-svc.yml ├── uptime-namespace.yml ├── uptime-netpolicy.yml └── uptime-pvc.yml /README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes Application Manifests 2 | 3 | This repository contains a collection of Kubernetes manifests for deploying self-hosted applications in a homelab or production environment. Each application is configured with security best practices, proper resource management, and modern deployment patterns. 4 | 5 | ## Table of Contents 6 | 7 | - [Applications](#applications) 8 | - [Prerequisites](#prerequisites) 9 | - [Architecture](#architecture) 10 | - [Installation](#installation) 11 | - [Application Details](#application-details) 12 | - [Security Considerations](#security-considerations) 13 | - [Customization](#customization) 14 | - [Troubleshooting](#troubleshooting) 15 | - [Contributing](#contributing) 16 | - [License](#license) 17 | 18 | ## Applications 19 | 20 | This repository includes manifests for the following applications: 21 | 22 | ### Networking & Infrastructure 23 | - **Traefik**: Modern edge router and reverse proxy with automatic HTTPS 24 | - **Pi-hole**: Network-wide ad blocking and DNS resolution 25 | - **AdGuard Home**: Alternative DNS-based ad and tracker blocker 26 | 27 | ### Monitoring & Observability 28 | - **Uptime Kuma**: Simple uptime monitoring and alerting 29 | - **SmokePing**: Network latency monitoring and visualization 30 | - **Speedtest Tracker**: Automated internet speed monitoring 31 | 32 | ### Productivity & Web Services 33 | - **Nextcloud**: Self-hosted productivity platform with file sharing 34 | - **Ghost Blog**: Modern publishing platform 35 | - **MySQL & MySQL Workbench**: Database and management tools 36 | - **Firefox**: Containerized browser for self-hosted applications 37 | 38 | ### Dashboards & Home Pages 39 | - **Flame Dashboard**: Minimalist application dashboard 40 | - **Homarr**: Customizable homepage for self-hosted services 41 | - **LittleLink**: Simple homepage with social media links 42 | 43 | ### Utilities 44 | - **ChangeDetection.io**: Monitor website changes and get notifications 45 | 46 | ## Prerequisites 47 | 48 | - A functioning Kubernetes cluster (single or multi-node) 49 | - kubectl configured to access your cluster 50 | - Helm installed (for Traefik and other chart-based deployments) 51 | - Persistent storage provider (Longhorn recommended) 52 | - Basic understanding of Kubernetes concepts 53 | 54 | ## Architecture 55 | 56 | This repository follows a consistent pattern for each application: 57 | 58 | - **Namespace**: Dedicated namespace per application 59 | - **Security Contexts**: Non-root users, restricted capabilities 60 | - **Network Policies**: Proper network isolation 61 | - **Resource Limits**: CPU and memory specifications 62 | - **Persistent Storage**: Based on Longhorn storage class 63 | - **Traefik Integration**: Modern IngressRoute objects with TLS 64 | 65 | ### Directory Structure 66 | 67 | Each application has its own directory containing: 68 | ``` 69 | application-name/ 70 | ├── application-namespace.yml # Dedicated namespace 71 | ├── application-deployment.yml # Main application deployment 72 | ├── application-pvc.yml # Persistent volume claims 73 | ├── application-svc.yml # Service definitions 74 | ├── application-ingress.yml # IngressRoute configuration 75 | ├── application-configmap.yml # Configuration files 76 | ├── application-secret.yml # Sensitive data (credentials) 77 | └── application-netpolicy.yml # Network policies 78 | ``` 79 | 80 | ## Installation 81 | 82 | ### 1. Clone the Repository 83 | ```bash 84 | git clone https://github.com/your-username/kubernetes.git 85 | cd kubernetes 86 | ``` 87 | 88 | ### 2. Set Up Traefik First 89 | Traefik serves as the ingress controller for all applications: 90 | 91 | ```bash 92 | kubectl create namespace traefik 93 | kubectl apply -f traefik/traefik-dashboard-auth.yml 94 | kubectl apply -f traefik/traefik-dashboard-basicauth-middleware.yml 95 | kubectl apply -f traefik/default-headers.yml 96 | 97 | # Install Traefik using Helm 98 | helm repo add traefik https://traefik.github.io/charts 99 | helm repo update 100 | helm install traefik traefik/traefik --namespace traefik -f traefik/values.yml 101 | 102 | # Apply Traefik dashboard IngressRoute 103 | kubectl apply -f traefik/traefik-dashboard-ingress-route-with-auth.yml 104 | ``` 105 | 106 | ### 3. Deploy Applications 107 | Deploy applications in their dependency order: 108 | 109 | ```bash 110 | # Deploy database first if needed 111 | kubectl apply -f mysql/ 112 | 113 | # Then deploy applications 114 | kubectl apply -f application-name/ 115 | ``` 116 | 117 | Before deploying, customize the following in each application: 118 | - Domain names in IngressRoute objects 119 | - Storage sizes in PVC objects 120 | - Credentials in Secret objects 121 | 122 | ## Application Details 123 | 124 | ### Traefik 125 | - **Features**: Automatic HTTPS with Let's Encrypt, metrics, access logs 126 | - **Security**: Non-root execution, secure headers, TLS enforcement 127 | - **Dashboard**: Available at `traefik.yourdomain.com` with authentication 128 | 129 | ### Nextcloud 130 | - **Purpose**: Self-hosted file storage and collaboration 131 | - **Components**: Web app, database, Redis cache 132 | - **Volumes**: Separate volumes for app data and database 133 | 134 | ### Pi-hole 135 | - **Purpose**: Network-wide ad blocking 136 | - **Features**: DNS server, DHCP capabilities, statistics dashboard 137 | - **Configuration**: Uses ConfigMap for customization 138 | 139 | ### Speedtest Tracker 140 | - **Purpose**: Monitor your internet connection speed 141 | - **Components**: Web app and PostgreSQL database 142 | - **Scheduling**: Configurable speed tests on a regular schedule 143 | 144 | ### Uptime Kuma 145 | - **Purpose**: Simple uptime monitoring and alerting 146 | - **Features**: Status pages, notification integrations 147 | - **Storage**: Persistent storage for monitoring history 148 | 149 | ### SmokePing 150 | - **Purpose**: Network latency monitoring and visualization 151 | - **Features**: Ping statistics, visual charts, historical data 152 | - **Configuration**: Customizable targets via ConfigMap 153 | 154 | ## Security Considerations 155 | 156 | This repository implements several security best practices: 157 | 158 | 1. **Pod Security**: 159 | - Non-root user execution 160 | - Restricted capabilities 161 | - Read-only root filesystem where possible 162 | - Proper seccomp profiles 163 | 164 | 2. **Network Security**: 165 | - Network policies to restrict communication 166 | - HTTPS everywhere with proper TLS configuration 167 | - Secure headers for all web applications 168 | 169 | 3. **Secret Management**: 170 | - Kubernetes Secrets for credentials 171 | - No hardcoded passwords 172 | - Base64 encoding (consider a proper secret management solution for production) 173 | 174 | 4. **Resource Control**: 175 | - CPU and memory limits for all containers 176 | - Prevent resource exhaustion 177 | 178 | ## Customization 179 | 180 | ### Domain Names 181 | Replace `yourdomain.com` in all IngressRoute objects with your actual domain: 182 | 183 | ```yaml 184 | routes: 185 | - match: Host(`app.yourdomain.com`) 186 | ``` 187 | 188 | ### Storage Sizes 189 | Adjust PVC storage sizes based on your needs: 190 | 191 | ```yaml 192 | resources: 193 | requests: 194 | storage: 10Gi # Change based on requirements 195 | ``` 196 | 197 | ### Application Versions 198 | Update container image versions in deployments: 199 | 200 | ```yaml 201 | containers: 202 | - name: application 203 | image: application/image:version # Update to specific version 204 | ``` 205 | 206 | ## Troubleshooting 207 | 208 | ### Check Application Status 209 | ```bash 210 | kubectl get pods -n application-namespace 211 | kubectl describe pod pod-name -n application-namespace 212 | kubectl logs pod-name -n application-namespace 213 | ``` 214 | 215 | ### Verify Ingress Routes 216 | ```bash 217 | kubectl get ingressroutes -A 218 | kubectl describe ingressroute ingressroute-name -n application-namespace 219 | ``` 220 | 221 | ### Storage Issues 222 | ```bash 223 | kubectl get pvc -n application-namespace 224 | kubectl describe pvc pvc-name -n application-namespace 225 | ``` 226 | 227 | ## Contributing 228 | 229 | 1. Fork the repository 230 | 2. Create a feature branch: `git checkout -b feature/new-app` 231 | 3. Commit your changes: `git commit -am 'Add new application'` 232 | 4. Push to the branch: `git push origin feature/new-app` 233 | 5. Submit a pull request -------------------------------------------------------------------------------- /adguard-home/adguard-configmap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: adguard-config 5 | namespace: adguard 6 | labels: 7 | app: adguard-home 8 | app.kubernetes.io/name: adguard 9 | app.kubernetes.io/instance: adguard 10 | data: 11 | AdGuardHome.yaml: | 12 | bind_host: 0.0.0.0 13 | bind_port: 3000 14 | beta_bind_port: 0 15 | users: [] # Move users to secret 16 | language: "en" 17 | theme: "auto" 18 | dns: 19 | bind_host: 0.0.0.0 20 | port: 53 21 | protection_enabled: true 22 | filtering_enabled: true 23 | safebrowsing_enabled: true 24 | safesearch_enabled: true 25 | querylog_enabled: true 26 | ratelimit: 20 27 | blocked_response_ttl: 10 28 | bootstrap_dns: 29 | - 1.1.1.1 30 | - 8.8.8.8 31 | tls: 32 | enabled: false 33 | log: 34 | file: "" 35 | max_backups: 0 36 | max_size: 100 37 | max_age: 3 38 | compress: false 39 | local_time: false 40 | security: 41 | protection_enabled: true -------------------------------------------------------------------------------- /adguard-home/adguard-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: adguard-deployment 5 | namespace: adguard 6 | labels: 7 | app: adguard-home 8 | app.kubernetes.io/name: adguard 9 | app.kubernetes.io/instance: adguard 10 | spec: 11 | replicas: 1 12 | strategy: 13 | type: Recreate 14 | selector: 15 | matchLabels: 16 | app: adguard-home 17 | template: 18 | metadata: 19 | labels: 20 | app: adguard-home 21 | spec: 22 | securityContext: 23 | fsGroup: 1000 24 | containers: 25 | - name: adguard-home 26 | image: adguard/adguardhome:v0.107.41 27 | imagePullPolicy: IfNotPresent 28 | env: 29 | - name: AGH_CONFIG 30 | valueFrom: 31 | configMapKeyRef: 32 | name: adguard-config 33 | key: AdGuardHome.yaml 34 | ports: 35 | - containerPort: 53 36 | name: dns-udp 37 | protocol: UDP 38 | - containerPort: 53 39 | name: dns-tcp 40 | protocol: TCP 41 | - containerPort: 3000 42 | name: http-initial 43 | protocol: TCP 44 | - containerPort: 80 45 | name: http 46 | protocol: TCP 47 | resources: 48 | requests: 49 | cpu: "100m" 50 | memory: "128Mi" 51 | limits: 52 | cpu: "300m" 53 | memory: "256Mi" 54 | securityContext: 55 | readOnlyRootFilesystem: true 56 | runAsNonRoot: true 57 | runAsUser: 1000 58 | allowPrivilegeEscalation: false 59 | livenessProbe: 60 | httpGet: 61 | path: / 62 | port: 3000 63 | initialDelaySeconds: 60 64 | periodSeconds: 10 65 | readinessProbe: 66 | httpGet: 67 | path: / 68 | port: 3000 69 | initialDelaySeconds: 30 70 | periodSeconds: 5 71 | volumeMounts: 72 | - name: adguard-data 73 | mountPath: /opt/adguardhome/work 74 | - name: adguard-config 75 | mountPath: /opt/adguardhome/conf 76 | volumes: 77 | - name: adguard-data 78 | persistentVolumeClaim: 79 | claimName: adguard-pvc 80 | - name: adguard-config 81 | configMap: 82 | name: adguard-config -------------------------------------------------------------------------------- /adguard-home/adguard-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: adguard 5 | labels: 6 | name: adguard -------------------------------------------------------------------------------- /adguard-home/adguard-pvc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: adguard-pvc 5 | namespace: adguard 6 | labels: 7 | app: adguard-home 8 | app.kubernetes.io/name: adguard 9 | app.kubernetes.io/instance: adguard 10 | annotations: 11 | description: "PVC for AdGuard Home configuration and data" 12 | spec: 13 | accessModes: 14 | - ReadWriteOnce 15 | storageClassName: longhorn 16 | resources: 17 | requests: 18 | storage: 1Gi 19 | selector: 20 | matchLabels: 21 | app: adguard -------------------------------------------------------------------------------- /adguard-home/adguard-secret.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: adguard-secret 5 | namespace: adguard 6 | labels: 7 | app: adguard-home 8 | app.kubernetes.io/name: adguard 9 | app.kubernetes.io/instance: adguard 10 | type: Opaque 11 | data: 12 | users.yaml: dXNlcnM6CiAgLSBuYW1lOiBhZG1pbgogICAgcGFzc3dvcmQ6ICQyYSQxMCRnTG1QVXIzRTJqM0c2TDBRMmRVTnAuVWY1VlFhUjhMVy5PVVVKN2xJc0xSYTZCSnljblRtVwogICAgZW5hYmxlZDogdHJ1ZQ== -------------------------------------------------------------------------------- /adguard-home/adguard-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: adguard-home 5 | namespace: adguard 6 | labels: 7 | app: adguard-home 8 | annotations: 9 | prometheus.io/scrape: "true" 10 | prometheus.io/port: "3000" 11 | spec: 12 | selector: 13 | app: adguard-home 14 | ports: 15 | - name: web-admin 16 | protocol: TCP 17 | port: 3000 18 | targetPort: 3000 19 | - name: web-interface 20 | protocol: TCP 21 | port: 80 22 | targetPort: 80 23 | - name: dns-udp 24 | protocol: UDP 25 | port: 53 26 | targetPort: 53 27 | - name: dns-tcp 28 | protocol: TCP 29 | port: 53 30 | targetPort: 53 31 | type: LoadBalancer 32 | externalTrafficPolicy: Local -------------------------------------------------------------------------------- /changedetection/changedetection-deployment.yml: -------------------------------------------------------------------------------- 1 | # changedetection-deployment.yml 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: changedetection 6 | namespace: changedetection 7 | labels: 8 | app: changedetection 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | app: changedetection 14 | template: 15 | metadata: 16 | labels: 17 | app: changedetection 18 | spec: 19 | securityContext: 20 | fsGroup: 1000 21 | containers: 22 | - name: changedetection 23 | image: dgtlmoon/changedetection.io:0.45.6 24 | securityContext: 25 | runAsUser: 1000 26 | runAsNonRoot: true 27 | readOnlyRootFilesystem: true 28 | allowPrivilegeEscalation: false 29 | capabilities: 30 | drop: 31 | - ALL 32 | env: 33 | - name: API_KEY 34 | valueFrom: 35 | secretKeyRef: 36 | name: changedetection-secret 37 | key: API_KEY 38 | - name: NOTIFICATION_TOKEN 39 | valueFrom: 40 | secretKeyRef: 41 | name: changedetection-secret 42 | key: NOTIFICATION_TOKEN 43 | ports: 44 | - containerPort: 5000 45 | name: http 46 | resources: 47 | requests: 48 | cpu: "100m" 49 | memory: "128Mi" 50 | limits: 51 | cpu: "500m" 52 | memory: "512Mi" 53 | livenessProbe: 54 | httpGet: 55 | path: / 56 | port: http 57 | initialDelaySeconds: 30 58 | periodSeconds: 10 59 | readinessProbe: 60 | httpGet: 61 | path: / 62 | port: http 63 | initialDelaySeconds: 15 64 | periodSeconds: 5 65 | volumeMounts: 66 | - name: data 67 | mountPath: /datastore 68 | - name: tmp 69 | mountPath: /tmp 70 | volumes: 71 | - name: data 72 | persistentVolumeClaim: 73 | claimName: changedetection-data 74 | - name: tmp 75 | emptyDir: {} -------------------------------------------------------------------------------- /changedetection/changedetection-ingress.yml: -------------------------------------------------------------------------------- 1 | # changedetection-ingress.yml 2 | apiVersion: traefik.io/v1alpha1 3 | kind: IngressRoute 4 | metadata: 5 | name: changedetection 6 | namespace: changedetection 7 | spec: 8 | entryPoints: 9 | - websecure 10 | routes: 11 | - match: Host(`changes.yourdomain.com`) 12 | kind: Rule 13 | services: 14 | - name: changedetection 15 | port: 80 16 | tls: 17 | certResolver: le -------------------------------------------------------------------------------- /changedetection/changedetection-namespace.yml: -------------------------------------------------------------------------------- 1 | # changedetection-namespace.yml 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: changedetection 6 | labels: 7 | name: changedetection -------------------------------------------------------------------------------- /changedetection/changedetection-pvc.yml: -------------------------------------------------------------------------------- 1 | # changedetection-pvc.yml 2 | apiVersion: v1 3 | kind: PersistentVolumeClaim 4 | metadata: 5 | name: changedetection-data 6 | namespace: changedetection 7 | labels: 8 | app: changedetection 9 | spec: 10 | accessModes: 11 | - ReadWriteOnce 12 | resources: 13 | requests: 14 | storage: 1Gi 15 | storageClassName: longhorn -------------------------------------------------------------------------------- /changedetection/changedetection-secret.yml: -------------------------------------------------------------------------------- 1 | # changedetection-secret.yml 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: changedetection-secret 6 | namespace: changedetection 7 | labels: 8 | app: changedetection 9 | type: Opaque 10 | data: 11 | API_KEY: Y2hhbmdlZGV0ZWN0aW9uLWFwaS1rZXk= 12 | NOTIFICATION_TOKEN: Y2hhbmdlZGV0ZWN0aW9uLW5vdGlmaWNhdGlvbi10b2tlbg== -------------------------------------------------------------------------------- /changedetection/changedetection-svc.yml: -------------------------------------------------------------------------------- 1 | # changedetection-service.yml 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: changedetection 6 | namespace: changedetection 7 | labels: 8 | app: changedetection 9 | spec: 10 | ports: 11 | - port: 80 12 | targetPort: 5000 13 | protocol: TCP 14 | name: http 15 | selector: 16 | app: changedetection -------------------------------------------------------------------------------- /firefox/firefox-deployment.yml: -------------------------------------------------------------------------------- 1 | # firefox-deployment.yml 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: firefox 6 | namespace: firefox 7 | labels: 8 | app: firefox 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | app: firefox 14 | template: 15 | metadata: 16 | labels: 17 | app: firefox 18 | spec: 19 | securityContext: 20 | fsGroup: 1000 21 | containers: 22 | - name: firefox 23 | image: jlesage/firefox:v1.19.1 24 | securityContext: 25 | runAsUser: 1000 26 | runAsNonRoot: true 27 | allowPrivilegeEscalation: false 28 | ports: 29 | - containerPort: 5800 30 | name: http 31 | - containerPort: 5900 32 | name: vnc 33 | env: 34 | - name: TZ 35 | value: "America/New_York" 36 | - name: DISPLAY_WIDTH 37 | value: "1920" 38 | - name: DISPLAY_HEIGHT 39 | value: "1080" 40 | resources: 41 | requests: 42 | cpu: "500m" 43 | memory: "512Mi" 44 | limits: 45 | cpu: "2000m" 46 | memory: "2Gi" 47 | livenessProbe: 48 | tcpSocket: 49 | port: 5800 50 | initialDelaySeconds: 30 51 | periodSeconds: 10 52 | timeoutSeconds: 5 53 | readinessProbe: 54 | tcpSocket: 55 | port: 5800 56 | initialDelaySeconds: 15 57 | periodSeconds: 5 58 | volumeMounts: 59 | - name: firefox-config 60 | mountPath: /config 61 | volumes: 62 | - name: firefox-config 63 | persistentVolumeClaim: 64 | claimName: firefox-config-pvc -------------------------------------------------------------------------------- /firefox/firefox-ingress.yml: -------------------------------------------------------------------------------- 1 | # firefox-ingress.yml 2 | apiVersion: traefik.io/v1alpha1 3 | kind: IngressRoute 4 | metadata: 5 | name: firefox 6 | namespace: firefox 7 | spec: 8 | entryPoints: 9 | - websecure 10 | routes: 11 | - match: Host(`firefox.yourdomain.com`) 12 | kind: Rule 13 | services: 14 | - name: firefox 15 | port: 80 16 | tls: 17 | certResolver: le -------------------------------------------------------------------------------- /firefox/firefox-namespace.yml: -------------------------------------------------------------------------------- 1 | # firefox-namespace.yml 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: firefox 6 | labels: 7 | name: firefox -------------------------------------------------------------------------------- /firefox/firefox-pvc.yml: -------------------------------------------------------------------------------- 1 | # firefox-pvc.yml 2 | apiVersion: v1 3 | kind: PersistentVolumeClaim 4 | metadata: 5 | name: firefox-config-pvc 6 | namespace: firefox 7 | labels: 8 | app: firefox 9 | spec: 10 | accessModes: 11 | - ReadWriteOnce 12 | resources: 13 | requests: 14 | storage: 2Gi 15 | storageClassName: longhorn -------------------------------------------------------------------------------- /firefox/firefox-service.yml: -------------------------------------------------------------------------------- 1 | # firefox-service.yml 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: firefox 6 | namespace: firefox 7 | labels: 8 | app: firefox 9 | spec: 10 | type: ClusterIP 11 | ports: 12 | - port: 80 13 | targetPort: 5800 14 | protocol: TCP 15 | name: http 16 | - port: 5900 17 | targetPort: 5900 18 | protocol: TCP 19 | name: vnc 20 | selector: 21 | app: firefox -------------------------------------------------------------------------------- /flame-dashboard/flame-claim0-persistentvolumeclaim.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | labels: 5 | app: flame 6 | name: flame-claim0 7 | namespace: flame 8 | spec: 9 | accessModes: 10 | - ReadWriteOnce 11 | storageClassName: longhorn 12 | resources: 13 | requests: 14 | storage: 100Mi -------------------------------------------------------------------------------- /flame-dashboard/flame-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: flame 5 | namespace: flame 6 | labels: 7 | app: flame 8 | spec: 9 | selector: 10 | matchLabels: 11 | app: flame 12 | replicas: 1 13 | strategy: 14 | type: Recreate 15 | template: 16 | metadata: 17 | labels: 18 | app: flame 19 | spec: 20 | securityContext: 21 | fsGroup: 1000 22 | containers: 23 | - name: flame 24 | image: pawelmalak/flame:2.3.1 25 | securityContext: 26 | runAsUser: 1000 27 | runAsNonRoot: true 28 | allowPrivilegeEscalation: false 29 | env: 30 | - name: PASSWORD 31 | valueFrom: 32 | secretKeyRef: 33 | name: flame-secret 34 | key: password 35 | ports: 36 | - containerPort: 5005 37 | name: http 38 | resources: 39 | requests: 40 | cpu: "50m" 41 | memory: "128Mi" 42 | limits: 43 | cpu: "200m" 44 | memory: "256Mi" 45 | livenessProbe: 46 | httpGet: 47 | path: / 48 | port: http 49 | initialDelaySeconds: 30 50 | periodSeconds: 10 51 | timeoutSeconds: 5 52 | readinessProbe: 53 | httpGet: 54 | path: / 55 | port: http 56 | initialDelaySeconds: 15 57 | periodSeconds: 5 58 | volumeMounts: 59 | - mountPath: /app/data 60 | name: flame-data 61 | volumes: 62 | - name: flame-data 63 | persistentVolumeClaim: 64 | claimName: flame-claim0 65 | restartPolicy: Always -------------------------------------------------------------------------------- /flame-dashboard/flame-ingressroute.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: flame 5 | namespace: flame 6 | labels: 7 | app: flame 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`flame.yourdomain.com`) 13 | kind: Rule 14 | services: 15 | - name: flame 16 | port: 5005 17 | tls: 18 | certResolver: le -------------------------------------------------------------------------------- /flame-dashboard/flame-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: flame 5 | labels: 6 | name: flame -------------------------------------------------------------------------------- /flame-dashboard/flame-secret.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: flame-secret 5 | namespace: flame 6 | labels: 7 | app: flame 8 | type: Opaque 9 | data: 10 | # Base64 encoded "flamepassword123" 11 | password: ZmxhbWVwYXNzd29yZDEyMw== -------------------------------------------------------------------------------- /flame-dashboard/flame-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: flame 5 | namespace: flame 6 | labels: 7 | app: flame 8 | spec: 9 | type: ClusterIP 10 | ports: 11 | - name: flame 12 | port: 5005 13 | targetPort: 5005 14 | selector: 15 | app: flame -------------------------------------------------------------------------------- /ghost-blog/ghost-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: ghost 5 | namespace: ghost 6 | labels: 7 | app: ghost 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: ghost 13 | template: 14 | metadata: 15 | labels: 16 | app: ghost 17 | spec: 18 | securityContext: 19 | fsGroup: 1000 20 | runAsUser: 1000 21 | runAsNonRoot: true 22 | containers: 23 | - name: ghost 24 | image: ghost:5.109.0-alpine 25 | securityContext: 26 | allowPrivilegeEscalation: false 27 | capabilities: 28 | drop: 29 | - ALL 30 | env: 31 | - name: url 32 | value: https://blog.yourdomain.com 33 | - name: database__client 34 | value: sqlite3 35 | - name: database__connection__filename 36 | value: /var/lib/ghost/content/data/ghost.db 37 | ports: 38 | - containerPort: 2368 39 | name: http 40 | resources: 41 | requests: 42 | cpu: "100m" 43 | memory: "256Mi" 44 | limits: 45 | cpu: "500m" 46 | memory: "512Mi" 47 | livenessProbe: 48 | httpGet: 49 | path: / 50 | port: http 51 | initialDelaySeconds: 60 52 | periodSeconds: 10 53 | timeoutSeconds: 5 54 | readinessProbe: 55 | httpGet: 56 | path: / 57 | port: http 58 | initialDelaySeconds: 30 59 | periodSeconds: 10 60 | volumeMounts: 61 | - name: ghost-data 62 | mountPath: /var/lib/ghost/content 63 | volumes: 64 | - name: ghost-data 65 | persistentVolumeClaim: 66 | claimName: ghost-pvc 67 | -------------------------------------------------------------------------------- /ghost-blog/ghost-ingressroute.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: ghost-ingress 5 | namespace: ghost 6 | labels: 7 | app: ghost 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`blog.yourdomain.com`) 13 | kind: Rule 14 | services: 15 | - name: ghost-svc 16 | port: 2368 17 | tls: 18 | certResolver: le -------------------------------------------------------------------------------- /ghost-blog/ghost-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: ghost 5 | labels: 6 | name: ghost -------------------------------------------------------------------------------- /ghost-blog/ghost-pvc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | namespace: ghost 5 | name: ghost-pvc 6 | labels: 7 | app: ghost 8 | spec: 9 | storageClassName: longhorn 10 | accessModes: 11 | - ReadWriteOnce 12 | resources: 13 | requests: 14 | storage: "5Gi" -------------------------------------------------------------------------------- /ghost-blog/ghost-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: ghost-svc 5 | namespace: ghost 6 | labels: 7 | app: ghost 8 | spec: 9 | type: ClusterIP 10 | ports: 11 | - name: web 12 | port: 2368 13 | targetPort: 2368 14 | selector: 15 | app: ghost -------------------------------------------------------------------------------- /homarr/homarr-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: homarr 5 | namespace: homarr 6 | labels: 7 | app: homarr 8 | spec: 9 | selector: 10 | matchLabels: 11 | app: homarr 12 | replicas: 1 13 | strategy: 14 | type: Recreate 15 | template: 16 | metadata: 17 | labels: 18 | app: homarr 19 | spec: 20 | securityContext: 21 | fsGroup: 1000 22 | containers: 23 | - name: homarr 24 | image: ghcr.io/ajnart/homarr:0.15.10 25 | securityContext: 26 | runAsUser: 1000 27 | runAsNonRoot: true 28 | allowPrivilegeEscalation: false 29 | capabilities: 30 | drop: 31 | - ALL 32 | ports: 33 | - containerPort: 7575 34 | name: homarr 35 | resources: 36 | requests: 37 | cpu: "100m" 38 | memory: "128Mi" 39 | limits: 40 | cpu: "300m" 41 | memory: "256Mi" 42 | livenessProbe: 43 | httpGet: 44 | path: / 45 | port: homarr 46 | initialDelaySeconds: 30 47 | periodSeconds: 10 48 | timeoutSeconds: 5 49 | readinessProbe: 50 | httpGet: 51 | path: / 52 | port: homarr 53 | initialDelaySeconds: 15 54 | periodSeconds: 5 55 | volumeMounts: 56 | - name: homarr-data 57 | mountPath: /app/data/configs 58 | volumes: 59 | - name: homarr-data 60 | persistentVolumeClaim: 61 | claimName: homarr-claim0 62 | restartPolicy: Always -------------------------------------------------------------------------------- /homarr/homarr-ingress.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: homarr 5 | namespace: homarr 6 | labels: 7 | app: homarr 8 | annotations: 9 | kubernetes.io/ingress.class: traefik-external 10 | spec: 11 | entryPoints: 12 | - websecure 13 | routes: 14 | - match: Host(`dashboard.yourdomain.com`) 15 | kind: Rule 16 | services: 17 | - name: homarr 18 | port: 80 19 | tls: 20 | certResolver: le -------------------------------------------------------------------------------- /homarr/homarr-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: homarr 5 | labels: 6 | name: homarr -------------------------------------------------------------------------------- /homarr/homarr-pvc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: homarr-claim0 5 | namespace: homarr 6 | labels: 7 | app: homarr 8 | spec: 9 | storageClassName: longhorn 10 | accessModes: 11 | - ReadWriteOnce 12 | resources: 13 | requests: 14 | storage: 100Mi -------------------------------------------------------------------------------- /homarr/homarr-svc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: homarr 5 | namespace: homarr 6 | labels: 7 | app: homarr 8 | spec: 9 | type: ClusterIP 10 | ports: 11 | - name: homarr 12 | port: 80 13 | protocol: TCP 14 | targetPort: 7575 15 | selector: 16 | app: homarr -------------------------------------------------------------------------------- /littlelink/littlelink-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: littlelink 5 | namespace: littlelink 6 | labels: 7 | app: littlelink 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: littlelink 13 | template: 14 | metadata: 15 | labels: 16 | app: littlelink 17 | spec: 18 | securityContext: 19 | fsGroup: 1000 20 | containers: 21 | - env: 22 | - name: AVATAR_2X_URL 23 | value: https://something.com/200/200 24 | - name: AVATAR_ALT 25 | value: Profile picture 26 | - name: AVATAR_URL 27 | value: https://something.com/100/100 28 | - name: META_DESCRIPTION 29 | value: Links to my social profiles 30 | - name: BIO 31 | value: Find me across the web 32 | - name: BUTTON_ORDER 33 | value: YOUTUBE,GITHUB,LINKED,EMAIL 34 | - name: BUTTON_TARGET 35 | value: blank 36 | - name: CUSTOM_BUTTON_ALT_TEXT 37 | value: Visit my homepage 38 | - name: CUSTOM_BUTTON_COLOR 39 | value: '#B997FC,#B997FC' 40 | - name: CUSTOM_BUTTON_ICON 41 | value: fas link,fab youtube 42 | - name: CUSTOM_BUTTON_NAME 43 | value: HOMEPAGE 44 | - name: CUSTOM_BUTTON_TEXT 45 | value: My Homepage 46 | - name: CUSTOM_BUTTON_TEXT_COLOR 47 | value: '#ffffff,#ffffff' 48 | - name: CUSTOM_BUTTON_URL 49 | value: https://yourdomain.com 50 | - name: EMAIL 51 | value: your.email@yourdomain.com 52 | - name: EMAIL_TEXT 53 | value: Email Me 54 | - name: FAVICON_URL 55 | value: https://something.com/32/32 56 | - name: GITHUB 57 | value: https://github.com/yourusername 58 | - name: YOUTUBE 59 | value: https://youtube.com/@yourusername 60 | - name: LANG 61 | value: en 62 | - name: LINKED_IN 63 | value: https://linkedin.com/in/yourusername 64 | - name: META_AUTHOR 65 | value: Your Name 66 | - name: META_DESCRIPTION 67 | value: About Your Name 68 | - name: META_INDEX_STATUS 69 | value: all 70 | - name: META_TITLE 71 | value: Your Name - Links 72 | - name: NAME 73 | value: Your Name 74 | - name: THEME 75 | value: Dark 76 | image: ghcr.io/techno-tim/littlelink-server:v0.5.4 77 | name: littlelink-server 78 | securityContext: 79 | runAsUser: 1000 80 | runAsNonRoot: true 81 | allowPrivilegeEscalation: false 82 | capabilities: 83 | drop: 84 | - ALL 85 | resources: 86 | requests: 87 | cpu: "50m" 88 | memory: "128Mi" 89 | limits: 90 | cpu: "200m" 91 | memory: "256Mi" 92 | livenessProbe: 93 | httpGet: 94 | path: / 95 | port: 3000 96 | initialDelaySeconds: 30 97 | periodSeconds: 10 98 | readinessProbe: 99 | httpGet: 100 | path: / 101 | port: 3000 102 | initialDelaySeconds: 15 103 | periodSeconds: 5 104 | ports: 105 | - containerPort: 3000 106 | name: http 107 | restartPolicy: Always 108 | # From Techno Tim Little Link Project -------------------------------------------------------------------------------- /littlelink/littlelink-ingress.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: littlelink 5 | namespace: littlelink 6 | labels: 7 | app: littlelink 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`links.yourdomain.com`) 13 | kind: Rule 14 | services: 15 | - name: littlelink 16 | port: 8080 17 | tls: 18 | certResolver: le -------------------------------------------------------------------------------- /littlelink/littlelink-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: littlelink 5 | labels: 6 | name: littlelink -------------------------------------------------------------------------------- /littlelink/littlelink-svc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: littlelink 5 | namespace: littlelink 6 | labels: 7 | app: littlelink 8 | spec: 9 | type: ClusterIP 10 | ports: 11 | - name: littlelink 12 | port: 8080 13 | protocol: TCP 14 | targetPort: 3000 15 | selector: 16 | app: littlelink -------------------------------------------------------------------------------- /mysql-workbench/mysql-workbench-auth.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: auth 5 | namespace: mysql-workbench 6 | type: kubernetes.io/basic-auth 7 | data: 8 | # admin / secure-workbench-password base64 encoded 9 | username: YWRtaW4= 10 | password: c2VjdXJlLXdvcmtiZW5jaC1wYXNzd29yZA== -------------------------------------------------------------------------------- /mysql-workbench/mysql-workbench-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql-workbench 5 | namespace: mysql-workbench 6 | labels: 7 | app: mysql-workbench 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: mysql-workbench 13 | template: 14 | metadata: 15 | labels: 16 | app: mysql-workbench 17 | spec: 18 | securityContext: 19 | fsGroup: 1000 20 | containers: 21 | - name: mysql-workbench 22 | image: lscr.io/linuxserver/mysql-workbench:latest 23 | securityContext: 24 | runAsUser: 1000 25 | runAsGroup: 1000 26 | allowPrivilegeEscalation: false 27 | env: 28 | - name: PUID 29 | value: "1000" 30 | - name: PGID 31 | value: "1000" 32 | - name: TZ 33 | value: "America/New_York" 34 | ports: 35 | - containerPort: 3000 36 | name: workbench 37 | resources: 38 | requests: 39 | cpu: "200m" 40 | memory: "512Mi" 41 | limits: 42 | cpu: "1000m" 43 | memory: "1Gi" 44 | volumeMounts: 45 | - name: config 46 | mountPath: /config 47 | volumes: 48 | - name: config 49 | persistentVolumeClaim: 50 | claimName: mysql-workbench-pvc -------------------------------------------------------------------------------- /mysql-workbench/mysql-workbench-ingress.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: mysql-workbench 5 | namespace: mysql-workbench 6 | labels: 7 | app: mysql-workbench 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`workbench.yourdomain.com`) 13 | kind: Rule 14 | middlewares: 15 | - name: auth 16 | namespace: mysql-workbench 17 | services: 18 | - name: mysql-workbench 19 | port: 3000 20 | tls: 21 | certResolver: le -------------------------------------------------------------------------------- /mysql-workbench/mysql-workbench-middleware.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: Middleware 3 | metadata: 4 | name: auth 5 | namespace: mysql-workbench 6 | spec: 7 | basicAuth: 8 | secret: auth -------------------------------------------------------------------------------- /mysql-workbench/mysql-workbench-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: mysql-workbench 5 | labels: 6 | name: mysql-workbench -------------------------------------------------------------------------------- /mysql-workbench/mysql-workbench-pvc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: mysql-workbench-pvc 5 | namespace: mysql-workbench 6 | labels: 7 | app: mysql-workbench 8 | spec: 9 | accessModes: 10 | - ReadWriteOnce 11 | resources: 12 | requests: 13 | storage: 1Gi 14 | storageClassName: longhorn -------------------------------------------------------------------------------- /mysql-workbench/mysql-workbench-services.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql-workbench 5 | namespace: mysql-workbench 6 | labels: 7 | app: mysql-workbench 8 | spec: 9 | type: ClusterIP 10 | ports: 11 | - name: mysql-workbench 12 | port: 3000 13 | protocol: TCP 14 | targetPort: 3000 15 | selector: 16 | app: mysql-workbench -------------------------------------------------------------------------------- /mysql/mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | namespace: mysql 6 | labels: 7 | app: mysql 8 | spec: 9 | selector: 10 | matchLabels: 11 | app: mysql 12 | strategy: 13 | type: Recreate 14 | template: 15 | metadata: 16 | labels: 17 | app: mysql 18 | spec: 19 | containers: 20 | - name: mysql 21 | image: mysql:8.0.34 22 | env: 23 | - name: MYSQL_ROOT_PASSWORD 24 | valueFrom: 25 | secretKeyRef: 26 | name: mysql-password 27 | key: password 28 | ports: 29 | - containerPort: 3306 30 | name: mysql 31 | resources: 32 | requests: 33 | cpu: "200m" 34 | memory: "512Mi" 35 | limits: 36 | cpu: "1000m" 37 | memory: "1Gi" 38 | securityContext: 39 | runAsUser: 104 40 | runAsGroup: 113 41 | allowPrivilegeEscalation: false 42 | capabilities: 43 | drop: 44 | - ALL 45 | livenessProbe: 46 | exec: 47 | command: ["mysqladmin", "ping", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] 48 | initialDelaySeconds: 30 49 | periodSeconds: 10 50 | timeoutSeconds: 5 51 | readinessProbe: 52 | exec: 53 | command: ["mysqladmin", "ping", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] 54 | initialDelaySeconds: 5 55 | periodSeconds: 2 56 | timeoutSeconds: 1 57 | volumeMounts: 58 | - name: mysql-data 59 | mountPath: /var/lib/mysql 60 | securityContext: 61 | fsGroup: 113 62 | volumes: 63 | - name: mysql-data 64 | persistentVolumeClaim: 65 | claimName: mysql-pvc 66 | -------------------------------------------------------------------------------- /mysql/mysql-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: mysql 5 | labels: 6 | name: mysql -------------------------------------------------------------------------------- /mysql/mysql-pvc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: mysql-pvc 5 | namespace: mysql 6 | labels: 7 | app: mysql 8 | spec: 9 | accessModes: 10 | - ReadWriteOnce 11 | resources: 12 | requests: 13 | storage: 10Gi 14 | storageClassName: longhorn -------------------------------------------------------------------------------- /mysql/mysql-secret.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mysql-password 5 | namespace: mysql 6 | labels: 7 | app: mysql 8 | type: Opaque 9 | data: 10 | # This is "MySQLStrongPassword123!" base64 encoded 11 | # In production, use a proper secret management solution 12 | password: TXlTUUxTdHJvbmdQYXNzd29yZDEyMyE= -------------------------------------------------------------------------------- /mysql/mysql-svc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | namespace: mysql 6 | labels: 7 | app: mysql 8 | spec: 9 | type: ClusterIP 10 | selector: 11 | app: mysql 12 | ports: 13 | - name: mysql 14 | protocol: TCP 15 | port: 3306 16 | targetPort: 3306 -------------------------------------------------------------------------------- /nextcloud/app-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nextcloud 5 | namespace: nextcloud 6 | labels: 7 | app: nextcloud 8 | role: app 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | app: nextcloud 14 | role: app 15 | template: 16 | metadata: 17 | labels: 18 | app: nextcloud 19 | role: app 20 | spec: 21 | securityContext: 22 | fsGroup: 33 # www-data 23 | containers: 24 | - name: nextcloud 25 | image: nextcloud:30.0.5-apache 26 | securityContext: 27 | runAsUser: 33 28 | runAsGroup: 33 29 | allowPrivilegeEscalation: false 30 | capabilities: 31 | drop: 32 | - ALL 33 | ports: 34 | - name: http 35 | containerPort: 80 36 | env: 37 | - name: MYSQL_PASSWORD 38 | valueFrom: 39 | secretKeyRef: 40 | name: nextcloud-db-password 41 | key: password 42 | - name: MYSQL_DATABASE 43 | value: nextcloud 44 | - name: MYSQL_USER 45 | value: nextcloud 46 | - name: MYSQL_HOST 47 | value: nextcloud-db-service 48 | - name: NEXTCLOUD_TRUSTED_DOMAINS 49 | value: "cloud.yourdomain.com localhost" 50 | - name: NEXTCLOUD_ADMIN_USER 51 | valueFrom: 52 | secretKeyRef: 53 | name: nextcloud-admin-credentials 54 | key: username 55 | - name: NEXTCLOUD_ADMIN_PASSWORD 56 | valueFrom: 57 | secretKeyRef: 58 | name: nextcloud-admin-credentials 59 | key: password 60 | - name: PHP_MEMORY_LIMIT 61 | value: "512M" 62 | - name: PHP_UPLOAD_LIMIT 63 | value: "512M" 64 | resources: 65 | requests: 66 | cpu: "200m" 67 | memory: "512Mi" 68 | limits: 69 | cpu: "1000m" 70 | memory: "1Gi" 71 | livenessProbe: 72 | httpGet: 73 | path: /status.php 74 | port: http 75 | initialDelaySeconds: 120 76 | periodSeconds: 10 77 | readinessProbe: 78 | httpGet: 79 | path: /status.php 80 | port: http 81 | initialDelaySeconds: 30 82 | periodSeconds: 10 83 | volumeMounts: 84 | - name: nextcloud-data 85 | mountPath: /var/www/html/data 86 | - name: nextcloud-config 87 | mountPath: /var/www/html/config 88 | volumes: 89 | - name: nextcloud-data 90 | persistentVolumeClaim: 91 | claimName: nextcloud-data-pvc 92 | - name: nextcloud-config 93 | emptyDir: {} 94 | -------------------------------------------------------------------------------- /nextcloud/app-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nextcloud 5 | namespace: nextcloud 6 | labels: 7 | app: nextcloud 8 | role: app 9 | spec: 10 | type: ClusterIP 11 | ports: 12 | - name: http 13 | port: 80 14 | targetPort: 80 15 | selector: 16 | app: nextcloud 17 | role: app 18 | -------------------------------------------------------------------------------- /nextcloud/configmaps.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: nextcloud-config 5 | namespace: nextcloud 6 | labels: 7 | app: nextcloud 8 | data: 9 | # Configuration for Nextcloud 10 | nextcloud-config.php: | 11 | '\\OC\\Memcache\\APCu', 14 | 'datadirectory' => '/var/www/html/data', 15 | 'instanceid' => 'oc9a42455f22', 16 | 'passwordsalt' => 'YourSaltValueFromDeployment', 17 | 'secret' => 'YourSecretValueFromDeployment', 18 | 'trusted_domains' => 19 | array ( 20 | 0 => 'localhost', 21 | 1 => 'cloud.yourdomain.com', 22 | ), 23 | 'dbtype' => 'mysql', 24 | 'version' => '30.0.5', 25 | 'overwrite.cli.url' => 'https://cloud.yourdomain.com', 26 | 'dbname' => 'nextcloud', 27 | 'dbhost' => 'nextcloud-db-service', 28 | 'dbport' => '', 29 | 'dbtableprefix' => 'oc_', 30 | 'mysql.utf8mb4' => true, 31 | 'dbuser' => 'nextcloud', 32 | 'installed' => false, 33 | ); 34 | # Additional custom configuration can be added here 35 | -------------------------------------------------------------------------------- /nextcloud/db-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nextcloud-db 5 | namespace: nextcloud 6 | labels: 7 | app: nextcloud 8 | role: db 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | app: nextcloud 14 | role: db 15 | template: 16 | metadata: 17 | labels: 18 | app: nextcloud 19 | role: db 20 | spec: 21 | securityContext: 22 | fsGroup: 999 # mysql group 23 | containers: 24 | - name: nextcloud-db 25 | image: mariadb:10.5 26 | securityContext: 27 | runAsUser: 999 # mysql user 28 | runAsGroup: 999 29 | allowPrivilegeEscalation: false 30 | capabilities: 31 | drop: 32 | - ALL 33 | env: 34 | - name: MYSQL_ROOT_PASSWORD 35 | valueFrom: 36 | secretKeyRef: 37 | name: nextcloud-db-password 38 | key: root-password 39 | - name: MYSQL_PASSWORD 40 | valueFrom: 41 | secretKeyRef: 42 | name: nextcloud-db-password 43 | key: password 44 | - name: MYSQL_DATABASE 45 | value: nextcloud 46 | - name: MYSQL_USER 47 | value: nextcloud 48 | ports: 49 | - containerPort: 3306 50 | name: mysql 51 | resources: 52 | requests: 53 | cpu: "200m" 54 | memory: "512Mi" 55 | limits: 56 | cpu: "500m" 57 | memory: "1Gi" 58 | volumeMounts: 59 | - name: nextcloud-db 60 | mountPath: /var/lib/mysql 61 | volumes: 62 | - name: nextcloud-db 63 | persistentVolumeClaim: 64 | claimName: nextcloud-db-pvc 65 | -------------------------------------------------------------------------------- /nextcloud/db-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nextcloud-db-service 5 | namespace: nextcloud 6 | labels: 7 | app: nextcloud 8 | role: db 9 | spec: 10 | type: ClusterIP 11 | ports: 12 | - name: mysql 13 | port: 3306 14 | targetPort: 3306 15 | selector: 16 | app: nextcloud 17 | role: db 18 | -------------------------------------------------------------------------------- /nextcloud/ingressroute.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: nextcloud 5 | namespace: nextcloud 6 | labels: 7 | app: nextcloud 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`cloud.yourdomain.com`) 13 | kind: Rule 14 | services: 15 | - name: nextcloud 16 | port: 80 17 | middlewares: 18 | - name: nextcloud-headers 19 | tls: 20 | certResolver: le 21 | --- 22 | apiVersion: traefik.io/v1alpha1 23 | kind: Middleware 24 | metadata: 25 | name: nextcloud-headers 26 | namespace: nextcloud 27 | spec: 28 | headers: 29 | customRequestHeaders: 30 | X-Forwarded-Proto: "https" -------------------------------------------------------------------------------- /nextcloud/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: nextcloud 5 | labels: 6 | name: nextcloud -------------------------------------------------------------------------------- /nextcloud/pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: nextcloud-data-pvc 5 | namespace: nextcloud 6 | labels: 7 | app: nextcloud 8 | role: app 9 | spec: 10 | storageClassName: longhorn 11 | accessModes: 12 | - ReadWriteOnce 13 | resources: 14 | requests: 15 | storage: 50Gi 16 | --- 17 | apiVersion: v1 18 | kind: PersistentVolumeClaim 19 | metadata: 20 | name: nextcloud-db-pvc 21 | namespace: nextcloud 22 | labels: 23 | app: nextcloud 24 | role: db 25 | spec: 26 | storageClassName: longhorn 27 | accessModes: 28 | - ReadWriteOnce 29 | resources: 30 | requests: 31 | storage: 10Gi 32 | -------------------------------------------------------------------------------- /nextcloud/secrets.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: nextcloud-db-password 5 | namespace: nextcloud 6 | labels: 7 | app: nextcloud 8 | type: Opaque 9 | data: 10 | # Base64 encoded values - in production use a proper secret management system 11 | password: VzNsY29tZVRvTmV4dGNsb3VkMjAyNCE= 12 | root-password: UjAwdFBAc3N3MHJkTjN4dGNsb3VkMjAyNCE= 13 | --- 14 | apiVersion: v1 15 | kind: Secret 16 | metadata: 17 | name: nextcloud-admin-credentials 18 | namespace: nextcloud 19 | labels: 20 | app: nextcloud 21 | type: Opaque 22 | data: 23 | # Base64 encoded values - in production use a proper secret management system 24 | username: YWRtaW4= 25 | password: TmV4dGNsb3VkQGRtaW5QYXNzdzByZDIwMjQh 26 | -------------------------------------------------------------------------------- /pihole/pihole-configmap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: pihole-dnsmasq-cm 5 | namespace: pihole 6 | labels: 7 | app: pihole 8 | data: 9 | dnsmasq.conf: | 10 | # Pi-hole dnsmasq optimal configuration 11 | # Increased cache for better performance 12 | cache-size=10000 13 | 14 | # Enable DNSSEC validation 15 | dnssec 16 | dnssec-check-unsigned 17 | 18 | # Logging configuration 19 | log-queries=extra 20 | log-facility=/var/log/pihole.log 21 | 22 | # Reduce TTL for local responses for faster updates 23 | local-ttl=2 24 | 25 | # Improve DNS lookup speeds 26 | dns-forward-max=500 27 | 28 | # Prevent DNS rebinding attacks 29 | stop-dns-rebind 30 | rebind-domain-ok=/plex.direct/ 31 | # Add your custom dnsmasq configurations here 32 | # For example: 33 | # server=/example.com/192.168.1.1 34 | # address=/example.com/192.168.1.1 35 | # This is a basic configuration -------------------------------------------------------------------------------- /pihole/pihole-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: pihole-deployment 5 | namespace: pihole 6 | labels: 7 | app: pihole 8 | spec: 9 | replicas: 1 10 | strategy: 11 | type: Recreate 12 | selector: 13 | matchLabels: 14 | app: pihole 15 | template: 16 | metadata: 17 | labels: 18 | app: pihole 19 | annotations: 20 | instrumentation.opentelemetry.io/inject-sdk: "false" 21 | spec: 22 | securityContext: 23 | fsGroup: 1000 24 | containers: 25 | - name: pihole 26 | image: pihole/pihole:2024.07.0 27 | securityContext: 28 | runAsUser: 1000 29 | runAsNonRoot: true 30 | allowPrivilegeEscalation: false 31 | seccompProfile: 32 | type: RuntimeDefault 33 | capabilities: 34 | drop: 35 | - ALL 36 | env: 37 | - name: TZ 38 | value: "America/Los_Angeles" 39 | - name: ServerIP 40 | valueFrom: 41 | fieldRef: 42 | fieldPath: status.podIP 43 | - name: WEBPASSWORD 44 | valueFrom: 45 | secretKeyRef: 46 | name: pihole-webpassword 47 | key: password 48 | - name: DNS1 49 | value: "1.1.1.1" 50 | - name: DNS2 51 | value: "9.9.9.9" 52 | - name: DNSMASQ_LISTENING 53 | value: "all" 54 | - name: TEMPERATUREUNIT 55 | value: "c" 56 | - name: PIHOLE_DNS_ 57 | value: "1.1.1.1;9.9.9.9" 58 | ports: 59 | - containerPort: 80 60 | name: http 61 | - containerPort: 53 62 | protocol: UDP 63 | name: dns-udp 64 | - containerPort: 53 65 | protocol: TCP 66 | name: dns-tcp 67 | resources: 68 | requests: 69 | cpu: "100m" 70 | memory: "128Mi" 71 | limits: 72 | cpu: "500m" 73 | memory: "512Mi" 74 | livenessProbe: 75 | httpGet: 76 | path: /admin/ 77 | port: http 78 | initialDelaySeconds: 60 79 | periodSeconds: 10 80 | timeoutSeconds: 5 81 | readinessProbe: 82 | httpGet: 83 | path: /admin/ 84 | port: http 85 | initialDelaySeconds: 30 86 | periodSeconds: 10 87 | timeoutSeconds: 5 88 | volumeMounts: 89 | - name: pihole-etc 90 | mountPath: /etc/pihole/ 91 | - name: dnsmasq-etc 92 | mountPath: /etc/dnsmasq.d/ 93 | volumes: 94 | - name: pihole-etc 95 | persistentVolumeClaim: 96 | claimName: pihole-pvc 97 | - name: dnsmasq-etc 98 | configMap: 99 | name: pihole-dnsmasq-cm 100 | items: 101 | - key: dnsmasq.conf 102 | path: dnsmasq.conf -------------------------------------------------------------------------------- /pihole/pihole-ingress.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: pihole-ingressroute 5 | namespace: pihole 6 | labels: 7 | app: pihole 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`pihole.yourdomain.com`) 13 | kind: Rule 14 | services: 15 | - name: pihole-service 16 | port: 80 17 | middlewares: 18 | - name: pihole-headers 19 | tls: 20 | certResolver: le 21 | 22 | --- 23 | apiVersion: traefik.io/v1alpha1 24 | kind: Middleware 25 | metadata: 26 | name: pihole-headers 27 | namespace: pihole 28 | spec: 29 | headers: 30 | customRequestHeaders: 31 | X-Forwarded-Proto: "https" -------------------------------------------------------------------------------- /pihole/pihole-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: pihole 5 | labels: 6 | name: pihole -------------------------------------------------------------------------------- /pihole/pihole-pvc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: pihole-pvc 5 | namespace: pihole 6 | labels: 7 | app: pihole 8 | spec: 9 | accessModes: 10 | - ReadWriteOnce 11 | storageClassName: longhorn 12 | resources: 13 | requests: 14 | storage: 5Gi 15 | -------------------------------------------------------------------------------- /pihole/pihole-secret.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: pihole-webpassword 5 | namespace: pihole 6 | labels: 7 | app: pihole 8 | type: Opaque 9 | data: 10 | # This is a more complex password encoded in base64 11 | # In production, use a properly generated strong password 12 | password: U3Ryb25nUGFzc3dvcmQxMjMh -------------------------------------------------------------------------------- /pihole/pihole-svc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: pihole-service 5 | namespace: pihole 6 | labels: 7 | app: pihole 8 | role: dns 9 | spec: 10 | type: ClusterIP 11 | selector: 12 | app: pihole 13 | ports: 14 | - name: http 15 | protocol: TCP 16 | port: 80 17 | targetPort: 80 18 | - name: dns-udp 19 | protocol: UDP 20 | port: 53 21 | targetPort: 53 22 | - name: dns-tcp 23 | protocol: TCP 24 | port: 53 25 | targetPort: 53 -------------------------------------------------------------------------------- /smokeping/smokeping-configmap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: smokeping-config 5 | namespace: smokeping 6 | labels: 7 | app: smokeping 8 | data: 9 | Targets: | 10 | *** Targets *** 11 | 12 | probe = FPing 13 | 14 | menu = Top 15 | title = Network Latency Grapher 16 | remark = Welcome to the SmokePing website. Here you will learn about the latency of our network. 17 | 18 | + Local 19 | 20 | menu = Local 21 | title = Local Network 22 | remark = This section contains local network hosts 23 | 24 | ++ LocalMachine 25 | 26 | menu = Local Machine 27 | title = This host 28 | host = localhost 29 | 30 | + Internet 31 | 32 | menu = Internet 33 | title = Internet Connectivity 34 | remark = This section contains Internet targets 35 | 36 | ++ GoogleDNS 37 | 38 | menu = Google DNS 39 | title = Google DNS Servers 40 | remark = Google's public DNS servers 41 | 42 | +++ GoogleDNS1 43 | menu = Google DNS 1 44 | title = Google DNS 8.8.8.8 45 | host = 8.8.8.8 46 | 47 | +++ GoogleDNS2 48 | menu = Google DNS 2 49 | title = Google DNS 8.8.4.4 50 | host = 8.8.4.4 51 | 52 | ++ CloudflareDNS 53 | 54 | menu = Cloudflare DNS 55 | title = Cloudflare DNS Servers 56 | remark = Cloudflare's public DNS servers 57 | 58 | +++ CloudflareDNS1 59 | menu = Cloudflare DNS 1 60 | title = Cloudflare DNS 1.1.1.1 61 | host = 1.1.1.1 62 | 63 | +++ CloudflareDNS2 64 | menu = Cloudflare DNS 2 65 | title = Cloudflare DNS 1.0.0.1 66 | host = 1.0.0.1 67 | 68 | ++ Websites 69 | 70 | menu = Popular Websites 71 | title = Popular Websites 72 | 73 | +++ Google 74 | menu = Google 75 | title = Google Website 76 | host = google.com 77 | 78 | +++ GitHub 79 | menu = GitHub 80 | title = GitHub Website 81 | host = github.com -------------------------------------------------------------------------------- /smokeping/smokeping-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: smokeping 5 | namespace: smokeping 6 | labels: 7 | app: smokeping 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: smokeping 13 | template: 14 | metadata: 15 | labels: 16 | app: smokeping 17 | spec: 18 | securityContext: 19 | fsGroup: 1000 20 | containers: 21 | - name: smokeping 22 | image: linuxserver/smokeping:latest 23 | imagePullPolicy: Always 24 | securityContext: 25 | runAsUser: 1000 26 | runAsNonRoot: true 27 | allowPrivilegeEscalation: false 28 | seccompProfile: 29 | type: RuntimeDefault 30 | capabilities: 31 | drop: 32 | - ALL 33 | ports: 34 | - containerPort: 80 35 | name: http 36 | resources: 37 | requests: 38 | cpu: "100m" 39 | memory: "128Mi" 40 | limits: 41 | cpu: "300m" 42 | memory: "512Mi" 43 | livenessProbe: 44 | httpGet: 45 | path: /smokeping/smokeping.cgi 46 | port: http 47 | initialDelaySeconds: 90 48 | periodSeconds: 15 49 | timeoutSeconds: 5 50 | failureThreshold: 3 51 | readinessProbe: 52 | httpGet: 53 | path: /smokeping/smokeping.cgi 54 | port: http 55 | initialDelaySeconds: 45 56 | periodSeconds: 10 57 | timeoutSeconds: 3 58 | failureThreshold: 3 59 | env: 60 | - name: PGID 61 | value: "1000" 62 | - name: PUID 63 | value: "1000" 64 | - name: TZ 65 | value: "America/Los_Angeles" 66 | volumeMounts: 67 | - name: smokeping-pvc 68 | mountPath: /data 69 | - name: smokeping-config 70 | mountPath: /config/Targets 71 | subPath: Targets 72 | volumes: 73 | - name: smokeping-pvc 74 | persistentVolumeClaim: 75 | claimName: smokeping-pvc 76 | - name: smokeping-config 77 | configMap: 78 | name: smokeping-config -------------------------------------------------------------------------------- /smokeping/smokeping-ingress.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: smokeping-ingressroute 5 | namespace: smokeping 6 | labels: 7 | app: smokeping 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`smokeping.yourdomain.com`) 13 | kind: Rule 14 | services: 15 | - name: smokeping-svc 16 | port: 80 17 | middlewares: 18 | - name: smokeping-headers 19 | tls: 20 | certResolver: le 21 | 22 | --- 23 | apiVersion: traefik.io/v1alpha1 24 | kind: Middleware 25 | metadata: 26 | name: smokeping-headers 27 | namespace: smokeping 28 | spec: 29 | headers: 30 | customRequestHeaders: 31 | X-Forwarded-Proto: "https" -------------------------------------------------------------------------------- /smokeping/smokeping-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: smokeping 5 | labels: 6 | name: smokeping -------------------------------------------------------------------------------- /smokeping/smokeping-netpolicy.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: smokeping-network-policy 5 | namespace: smokeping 6 | labels: 7 | app: smokeping 8 | spec: 9 | podSelector: 10 | matchLabels: 11 | app: smokeping 12 | policyTypes: 13 | - Ingress 14 | - Egress 15 | ingress: 16 | - from: 17 | - namespaceSelector: 18 | matchLabels: 19 | kubernetes.io/metadata.name: traefik 20 | ports: 21 | - protocol: TCP 22 | port: 80 23 | egress: 24 | - to: 25 | - ipBlock: 26 | cidr: 0.0.0.0/0 27 | ports: 28 | - protocol: ICMP 29 | - protocol: UDP 30 | port: 53 31 | - protocol: TCP 32 | port: 53 33 | - protocol: TCP 34 | port: 80 35 | - protocol: TCP 36 | port: 443 -------------------------------------------------------------------------------- /smokeping/smokeping-pvc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: smokeping-pvc 5 | namespace: smokeping 6 | labels: 7 | app: smokeping 8 | spec: 9 | accessModes: 10 | - ReadWriteOnce 11 | storageClassName: longhorn 12 | resources: 13 | requests: 14 | storage: 5Gi -------------------------------------------------------------------------------- /smokeping/smokeping-svc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: smokeping-svc 5 | namespace: smokeping 6 | labels: 7 | app: smokeping 8 | role: monitoring 9 | spec: 10 | type: ClusterIP 11 | selector: 12 | app: smokeping 13 | ports: 14 | - name: http 15 | port: 80 16 | protocol: TCP 17 | targetPort: 80 -------------------------------------------------------------------------------- /speedtest-tracker/speedtest-tracker-db-creds.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: db-credentials 5 | namespace: speedtest-tracker 6 | labels: 7 | app: speedtest-tracker-db 8 | type: Opaque 9 | data: 10 | # This is a secure randomly generated password (base64 encoded) 11 | # In production, use a proper secret management system 12 | postgres-password: U3BlZWR0ZXN0VHJhY2tlclBhc3N3b3JkXzEyMyE= 13 | -------------------------------------------------------------------------------- /speedtest-tracker/speedtest-tracker-db-pvc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: speedtest-db 5 | namespace: speedtest-tracker 6 | labels: 7 | app: speedtest-tracker-db 8 | spec: 9 | accessModes: 10 | - ReadWriteOnce 11 | storageClassName: longhorn 12 | resources: 13 | requests: 14 | storage: 15Gi -------------------------------------------------------------------------------- /speedtest-tracker/speedtest-tracker-db-svc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: speedtest-tracker-db-svc 5 | namespace: speedtest-tracker 6 | labels: 7 | app: speedtest-tracker-db 8 | role: database 9 | spec: 10 | type: ClusterIP 11 | selector: 12 | app: speedtest-tracker-db 13 | ports: 14 | - name: postgres 15 | port: 5432 16 | protocol: TCP 17 | targetPort: 5432 -------------------------------------------------------------------------------- /speedtest-tracker/speedtest-tracker-db.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: speedtest-tracker-db 5 | namespace: speedtest-tracker 6 | labels: 7 | app: speedtest-tracker-db 8 | spec: 9 | replicas: 1 10 | strategy: 11 | type: Recreate 12 | selector: 13 | matchLabels: 14 | app: speedtest-tracker-db 15 | template: 16 | metadata: 17 | labels: 18 | app: speedtest-tracker-db 19 | spec: 20 | securityContext: 21 | fsGroup: 999 22 | initContainers: 23 | - name: clean-db-dir 24 | image: busybox:1.36.1 25 | command: ['sh', '-c', 'rm -rf /var/lib/postgresql/data/pgdata/* && rm -rf /var/lib/postgresql/data/pgdata/.* || true'] 26 | securityContext: 27 | runAsUser: 0 28 | allowPrivilegeEscalation: false 29 | seccompProfile: 30 | type: RuntimeDefault 31 | capabilities: 32 | drop: 33 | - ALL 34 | volumeMounts: 35 | - name: db-data 36 | mountPath: /var/lib/postgresql/data/pgdata 37 | containers: 38 | - name: postgres 39 | image: postgres:15.5 40 | imagePullPolicy: IfNotPresent 41 | securityContext: 42 | runAsUser: 999 43 | runAsNonRoot: true 44 | allowPrivilegeEscalation: false 45 | seccompProfile: 46 | type: RuntimeDefault 47 | capabilities: 48 | drop: 49 | - ALL 50 | ports: 51 | - containerPort: 5432 52 | name: postgres 53 | resources: 54 | requests: 55 | cpu: "200m" 56 | memory: "256Mi" 57 | limits: 58 | cpu: "500m" 59 | memory: "512Mi" 60 | livenessProbe: 61 | exec: 62 | command: ["pg_isready", "-U", "speedy"] 63 | initialDelaySeconds: 30 64 | periodSeconds: 10 65 | timeoutSeconds: 5 66 | failureThreshold: 3 67 | readinessProbe: 68 | exec: 69 | command: ["pg_isready", "-U", "speedy"] 70 | initialDelaySeconds: 5 71 | periodSeconds: 5 72 | timeoutSeconds: 3 73 | failureThreshold: 3 74 | env: 75 | - name: POSTGRES_DB 76 | value: "speedtest_tracker" 77 | - name: POSTGRES_USER 78 | value: "speedy" 79 | - name: POSTGRES_PASSWORD 80 | valueFrom: 81 | secretKeyRef: 82 | name: db-credentials 83 | key: postgres-password 84 | - name: PGDATA 85 | value: "/var/lib/postgresql/data/pgdata" 86 | volumeMounts: 87 | - mountPath: /var/lib/postgresql/data/pgdata 88 | name: db-data 89 | volumes: 90 | - name: db-data 91 | persistentVolumeClaim: 92 | claimName: speedtest-db -------------------------------------------------------------------------------- /speedtest-tracker/speedtest-tracker-ingress.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: speedtest-ingressroute 5 | namespace: speedtest-tracker 6 | labels: 7 | app: speedtest-tracker 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`speedtest.yourdomain.com`) 13 | kind: Rule 14 | services: 15 | - name: speedtest-tracker 16 | port: 80 17 | middlewares: 18 | - name: speedtest-headers 19 | tls: 20 | certResolver: le 21 | 22 | --- 23 | apiVersion: traefik.io/v1alpha1 24 | kind: Middleware 25 | metadata: 26 | name: speedtest-headers 27 | namespace: speedtest-tracker 28 | spec: 29 | headers: 30 | customRequestHeaders: 31 | X-Forwarded-Proto: "https" -------------------------------------------------------------------------------- /speedtest-tracker/speedtest-tracker-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: speedtest-tracker 5 | labels: 6 | name: speedtest-tracker -------------------------------------------------------------------------------- /speedtest-tracker/speedtest-tracker-netpolicy.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: speedtest-tracker-network-policy 5 | namespace: speedtest-tracker 6 | labels: 7 | app: speedtest-tracker 8 | spec: 9 | podSelector: 10 | matchLabels: 11 | app: speedtest-tracker 12 | policyTypes: 13 | - Ingress 14 | - Egress 15 | ingress: 16 | - from: 17 | - namespaceSelector: 18 | matchLabels: 19 | kubernetes.io/metadata.name: traefik 20 | ports: 21 | - protocol: TCP 22 | port: 80 23 | egress: 24 | - to: 25 | - podSelector: 26 | matchLabels: 27 | app: speedtest-tracker-db 28 | ports: 29 | - protocol: TCP 30 | port: 5432 31 | - to: 32 | - ipBlock: 33 | cidr: 0.0.0.0/0 34 | ports: 35 | - protocol: TCP 36 | port: 80 37 | - protocol: TCP 38 | port: 443 39 | - protocol: UDP 40 | port: 53 41 | - protocol: TCP 42 | port: 53 43 | --- 44 | apiVersion: networking.k8s.io/v1 45 | kind: NetworkPolicy 46 | metadata: 47 | name: speedtest-tracker-db-network-policy 48 | namespace: speedtest-tracker 49 | labels: 50 | app: speedtest-tracker-db 51 | spec: 52 | podSelector: 53 | matchLabels: 54 | app: speedtest-tracker-db 55 | policyTypes: 56 | - Ingress 57 | - Egress 58 | ingress: 59 | - from: 60 | - podSelector: 61 | matchLabels: 62 | app: speedtest-tracker 63 | ports: 64 | - protocol: TCP 65 | port: 5432 66 | egress: [] -------------------------------------------------------------------------------- /speedtest-tracker/speedtest-tracker-pvc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: speedtest-tracker 5 | namespace: speedtest-tracker 6 | labels: 7 | app: speedtest-tracker 8 | spec: 9 | accessModes: 10 | - ReadWriteOnce 11 | storageClassName: longhorn 12 | resources: 13 | requests: 14 | storage: 5Gi -------------------------------------------------------------------------------- /speedtest-tracker/speedtest-tracker-svc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: speedtest-tracker 5 | namespace: speedtest-tracker 6 | labels: 7 | app: speedtest-tracker 8 | role: monitoring 9 | spec: 10 | type: ClusterIP 11 | selector: 12 | app: speedtest-tracker 13 | ports: 14 | - name: http 15 | port: 80 16 | protocol: TCP 17 | targetPort: 80 -------------------------------------------------------------------------------- /speedtest-tracker/speedtest-tracker.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: speedtest-tracker 5 | namespace: speedtest-tracker 6 | labels: 7 | app: speedtest-tracker 8 | spec: 9 | replicas: 1 10 | strategy: 11 | type: Recreate 12 | selector: 13 | matchLabels: 14 | app: speedtest-tracker 15 | template: 16 | metadata: 17 | labels: 18 | app: speedtest-tracker 19 | spec: 20 | securityContext: 21 | fsGroup: 1000 22 | dnsPolicy: None 23 | dnsConfig: 24 | nameservers: 25 | - 10.0.0.1 26 | - 1.1.1.1 27 | searches: 28 | - speedtest-tracker.svc.cluster.local 29 | options: 30 | - name: ndots 31 | value: "5" 32 | containers: 33 | - name: speedtest-tracker 34 | # Official LinuxServer.io image 35 | image: lscr.io/linuxserver/speedtest-tracker:latest 36 | imagePullPolicy: Always 37 | securityContext: 38 | runAsUser: 1000 39 | runAsNonRoot: true 40 | allowPrivilegeEscalation: false 41 | seccompProfile: 42 | type: RuntimeDefault 43 | capabilities: 44 | drop: 45 | - ALL 46 | ports: 47 | - containerPort: 80 48 | name: http 49 | resources: 50 | requests: 51 | cpu: "100m" 52 | memory: "128Mi" 53 | limits: 54 | cpu: "300m" 55 | memory: "256Mi" 56 | livenessProbe: 57 | httpGet: 58 | path: / 59 | port: http 60 | initialDelaySeconds: 60 61 | periodSeconds: 10 62 | timeoutSeconds: 5 63 | readinessProbe: 64 | httpGet: 65 | path: / 66 | port: http 67 | initialDelaySeconds: 30 68 | periodSeconds: 5 69 | env: 70 | - name: PUID 71 | value: "1000" 72 | - name: PGID 73 | value: "1000" 74 | - name: DB_CONNECTION 75 | value: "pgsql" 76 | - name: DB_HOST 77 | value: "speedtest-tracker-db-svc" 78 | - name: DB_PORT 79 | value: "5432" 80 | - name: DB_DATABASE 81 | value: "speedtest_tracker" 82 | - name: DB_USERNAME 83 | value: "speedy" 84 | - name: DB_PASSWORD 85 | valueFrom: 86 | secretKeyRef: 87 | name: db-credentials 88 | key: postgres-password 89 | - name: TZ 90 | value: "America/New_York" 91 | volumeMounts: 92 | - mountPath: /config 93 | name: speedtest-tracker 94 | volumes: 95 | - name: speedtest-tracker 96 | persistentVolumeClaim: 97 | claimName: speedtest-tracker -------------------------------------------------------------------------------- /traefik/default-headers.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: Middleware 3 | metadata: 4 | name: default-headers 5 | namespace: default 6 | spec: 7 | headers: 8 | browserXssFilter: true 9 | contentTypeNosniff: true 10 | forceSTSHeader: true 11 | stsIncludeSubdomains: true 12 | stsPreload: true 13 | stsSeconds: 31536000 14 | customFrameOptionsValue: SAMEORIGIN 15 | contentSecurityPolicy: "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'" 16 | referrerPolicy: "strict-origin-when-cross-origin" 17 | permissionsPolicy: "camera=(), microphone=(), geolocation=()" 18 | customRequestHeaders: 19 | X-Forwarded-Proto: https -------------------------------------------------------------------------------- /traefik/demo-ingress-route-with-cert.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: demo 5 | namespace: default 6 | annotations: 7 | kubernetes.io/ingress.class: traefik-external 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`www.yourdomain.com`) 13 | kind: Rule 14 | services: 15 | - name: demo 16 | port: 80 17 | middlewares: 18 | - name: default-headers 19 | namespace: default 20 | - match: Host(`yourdomain.com`) 21 | kind: Rule 22 | services: 23 | - name: demo 24 | port: 80 25 | middlewares: 26 | - name: default-headers 27 | namespace: default 28 | tls: 29 | certResolver: le -------------------------------------------------------------------------------- /traefik/demo-ingress-route.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: demo 5 | namespace: demo 6 | annotations: 7 | kubernetes.io/ingress.class: traefik-external 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`demo.yourdomain.com`) 13 | kind: Rule 14 | services: 15 | - name: demo-service 16 | port: 80 17 | middlewares: 18 | - name: default-headers 19 | namespace: default 20 | tls: 21 | certResolver: le -------------------------------------------------------------------------------- /traefik/traefik-dashboard-auth.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: traefik-dashboard-auth 5 | namespace: traefik 6 | type: Opaque 7 | data: 8 | # This is a secure hashed password (admin:SecureTraefikPassword) 9 | # In production, generate your own with htpasswd: htpasswd -nb admin YOUR_PASSWORD 10 | users: YWRtaW46JGFwcjEkZ0IvdC4xNFgkZlBGTXlNOGt2OTBuTTdDMHBYZGN2LwotLQo= -------------------------------------------------------------------------------- /traefik/traefik-dashboard-basicauth-middleware.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: Middleware 3 | metadata: 4 | name: traefik-dashboard-basicauth 5 | namespace: traefik 6 | spec: 7 | basicAuth: 8 | secret: traefik-dashboard-auth -------------------------------------------------------------------------------- /traefik/traefik-dashboard-ingress-route-with-auth.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: traefik-dashboard 5 | namespace: traefik 6 | annotations: 7 | kubernetes.io/ingress.class: traefik-external 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`traefik.yourdomain.com`) 13 | kind: Rule 14 | middlewares: 15 | - name: traefik-dashboard-basicauth 16 | namespace: traefik 17 | - name: default-headers 18 | namespace: default 19 | services: 20 | - name: api@internal 21 | kind: TraefikService 22 | tls: 23 | certResolver: le -------------------------------------------------------------------------------- /traefik/values.yml: -------------------------------------------------------------------------------- 1 | globalArguments: 2 | - '--global.checknewversion=false' 3 | - '--global.sendanonymoususage=false' 4 | 5 | additionalArguments: 6 | - '--log.level=INFO' 7 | - '--accesslog=true' 8 | - '--accesslog.bufferingsize=100' 9 | # '--certificatesresolvers.le.acme.email=your-email@yourdomain.com' 10 | # '--certificatesresolvers.le.acme.storage=/data/acme.json' 11 | # '--certificatesresolvers.le.acme.tlschallenge=true' 12 | # 13 | # ACME (Let's Encrypt) is commented out. It is recommended to use cert-manager for certificate management in Kubernetes environments. 14 | # See: https://cert-manager.io/ 15 | - '--metrics.prometheus=true' 16 | - '--metrics.prometheus.addEntryPointsLabels=true' 17 | - '--metrics.prometheus.addServicesLabels=true' 18 | - '--entryPoints.websecure.http.tls.options=default' 19 | 20 | persistence: 21 | enabled: true 22 | path: /data 23 | size: 128Mi 24 | storageClass: longhorn 25 | 26 | deployment: 27 | enabled: true 28 | replicas: 2 29 | annotations: {} 30 | podAnnotations: 31 | prometheus.io/scrape: "true" 32 | prometheus.io/path: "/metrics" 33 | prometheus.io/port: "9100" 34 | additionalContainers: [] 35 | initContainers: [] 36 | 37 | resources: 38 | requests: 39 | cpu: "200m" 40 | memory: "128Mi" 41 | limits: 42 | cpu: "500m" 43 | memory: "256Mi" 44 | 45 | ports: 46 | web: 47 | redirectTo: websecure 48 | websecure: 49 | tls: 50 | enabled: true 51 | 52 | ingressRoute: 53 | dashboard: 54 | enabled: true 55 | annotations: 56 | traefik.ingress.kubernetes.io/router.middlewares: traefik-traefik-dashboard-basicauth@kubernetescrd 57 | 58 | providers: 59 | kubernetesCRD: 60 | enabled: true 61 | ingressClass: traefik-external 62 | namespaces: [] 63 | kubernetesIngress: 64 | enabled: true 65 | publishedService: 66 | enabled: true 67 | 68 | service: 69 | enabled: true 70 | type: LoadBalancer 71 | annotations: 72 | prometheus.io/scrape: "true" 73 | prometheus.io/path: "/metrics" 74 | labels: 75 | app.kubernetes.io/name: traefik 76 | app.kubernetes.io/instance: traefik 77 | spec: 78 | loadBalancerIP: "" 79 | loadBalancerSourceRanges: [] 80 | externalIPs: [] 81 | 82 | securityContext: 83 | capabilities: 84 | drop: 85 | - ALL 86 | readOnlyRootFilesystem: true 87 | runAsGroup: 65532 88 | runAsNonRoot: true 89 | runAsUser: 65532 90 | 91 | podSecurityContext: 92 | fsGroup: 65532 93 | 94 | affinity: 95 | podAntiAffinity: 96 | preferredDuringSchedulingIgnoredDuringExecution: 97 | - weight: 100 98 | podAffinityTerm: 99 | labelSelector: 100 | matchExpressions: 101 | - key: app.kubernetes.io/name 102 | operator: In 103 | values: 104 | - traefik 105 | topologyKey: kubernetes.io/hostname 106 | -------------------------------------------------------------------------------- /uptime/uptime-ingress.yml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: IngressRoute 3 | metadata: 4 | name: uptime-ingressroute 5 | namespace: uptime 6 | labels: 7 | app: uptime 8 | spec: 9 | entryPoints: 10 | - websecure 11 | routes: 12 | - match: Host(`uptime.yourdomain.com`) 13 | kind: Rule 14 | services: 15 | - name: uptime-svc 16 | port: 80 17 | middlewares: 18 | - name: uptime-headers 19 | tls: 20 | certResolver: le 21 | 22 | --- 23 | apiVersion: traefik.io/v1alpha1 24 | kind: Middleware 25 | metadata: 26 | name: uptime-headers 27 | namespace: uptime 28 | spec: 29 | headers: 30 | customRequestHeaders: 31 | X-Forwarded-Proto: "https" -------------------------------------------------------------------------------- /uptime/uptime-kuma-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: uptime 5 | namespace: uptime 6 | labels: 7 | app: uptime 8 | spec: 9 | replicas: 1 10 | strategy: 11 | type: Recreate 12 | selector: 13 | matchLabels: 14 | app: uptime 15 | template: 16 | metadata: 17 | labels: 18 | app: uptime 19 | spec: 20 | securityContext: 21 | fsGroup: 1001 22 | volumes: 23 | - name: uptime 24 | persistentVolumeClaim: 25 | claimName: uptime 26 | containers: 27 | - name: uptime 28 | image: louislam/uptime-kuma:1 29 | imagePullPolicy: IfNotPresent 30 | securityContext: 31 | runAsUser: 1001 32 | runAsNonRoot: true 33 | allowPrivilegeEscalation: false 34 | seccompProfile: 35 | type: RuntimeDefault 36 | capabilities: 37 | drop: 38 | - ALL 39 | ports: 40 | - containerPort: 3001 41 | name: http 42 | resources: 43 | requests: 44 | cpu: "100m" 45 | memory: "128Mi" 46 | limits: 47 | cpu: "300m" 48 | memory: "512Mi" 49 | livenessProbe: 50 | httpGet: 51 | path: / 52 | port: http 53 | initialDelaySeconds: 60 54 | periodSeconds: 10 55 | timeoutSeconds: 5 56 | failureThreshold: 3 57 | readinessProbe: 58 | httpGet: 59 | path: / 60 | port: http 61 | initialDelaySeconds: 30 62 | periodSeconds: 5 63 | timeoutSeconds: 3 64 | failureThreshold: 3 65 | env: 66 | - name: NODE_ENV 67 | value: "production" 68 | - name: TZ 69 | value: "America/New_York" 70 | volumeMounts: 71 | - mountPath: "/app/data" 72 | name: uptime -------------------------------------------------------------------------------- /uptime/uptime-kuma-svc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: uptime-svc 5 | namespace: uptime 6 | labels: 7 | app: uptime 8 | role: monitoring 9 | spec: 10 | type: ClusterIP 11 | selector: 12 | app: uptime 13 | ports: 14 | - name: http 15 | port: 80 16 | protocol: TCP 17 | targetPort: 3001 -------------------------------------------------------------------------------- /uptime/uptime-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: uptime 5 | labels: 6 | name: uptime 7 | app: uptime-kuma -------------------------------------------------------------------------------- /uptime/uptime-netpolicy.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: uptime-network-policy 5 | namespace: uptime 6 | labels: 7 | app: uptime 8 | spec: 9 | podSelector: 10 | matchLabels: 11 | app: uptime 12 | policyTypes: 13 | - Ingress 14 | - Egress 15 | ingress: 16 | - from: 17 | - namespaceSelector: 18 | matchLabels: 19 | kubernetes.io/metadata.name: traefik 20 | ports: 21 | - protocol: TCP 22 | port: 3001 23 | egress: 24 | - to: 25 | - ipBlock: 26 | cidr: 0.0.0.0/0 27 | ports: 28 | - protocol: ICMP 29 | - protocol: TCP 30 | port: 53 31 | - protocol: UDP 32 | port: 53 33 | - protocol: TCP 34 | port: 80 35 | - protocol: TCP 36 | port: 443 -------------------------------------------------------------------------------- /uptime/uptime-pvc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | labels: 5 | app: uptime 6 | name: uptime 7 | namespace: uptime 8 | spec: 9 | accessModes: 10 | - ReadWriteOnce 11 | storageClassName: longhorn 12 | resources: 13 | requests: 14 | storage: 1Gi --------------------------------------------------------------------------------