diff --git a/k8s/forgejo/ingress.yaml b/k8s/forgejo/ingress.yaml new file mode 100644 index 0000000..9a061f5 --- /dev/null +++ b/k8s/forgejo/ingress.yaml @@ -0,0 +1,17 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: forgejo + namespace: forgejo +spec: + rules: + - host: git.janky.solutions + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: forgejo + port: + name: web diff --git a/k8s/forgejo/oauth2-settings.txt b/k8s/forgejo/oauth2-settings.txt new file mode 100644 index 0000000..f078bbc --- /dev/null +++ b/k8s/forgejo/oauth2-settings.txt @@ -0,0 +1,3 @@ +client_id: forgejo +client_secret: 3d8ef8de-4ab1-4690-8bff-3563c4060653 +discovery_url: https://auth.janky.solutions/auth/realms/janky.solutions/.well-known/openid-configuration diff --git a/k8s/forgejo/services.yaml b/k8s/forgejo/services.yaml new file mode 100644 index 0000000..81007bb --- /dev/null +++ b/k8s/forgejo/services.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Service +metadata: + name: forgejo + namespace: forgejo +spec: + ports: + - name: web + port: 3000 + selector: + app: forgejo +--- +apiVersion: v1 +kind: Service +metadata: + name: forgejo-ssh + namespace: forgejo +spec: + type: NodePort + ports: + - name: ssh + port: 22 + nodePort: 30001 + selector: + app: forgejo diff --git a/k8s/forgejo/statefulset.yaml b/k8s/forgejo/statefulset.yaml new file mode 100644 index 0000000..1dcaf02 --- /dev/null +++ b/k8s/forgejo/statefulset.yaml @@ -0,0 +1,82 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: forgejo + namespace: forgejo +spec: + selector: + matchLabels: + app: forgejo + serviceName: forgejo + replicas: 1 + template: + metadata: + labels: + app: forgejo + spec: + containers: + - image: codeberg.org/forgejo/forgejo:1.21 + name: forgejo + resources: {} + volumeMounts: + - name: forgejo-data + mountPath: /data + envFrom: + - secretRef: + name: forgejo + env: + - name: FORGEJO__DEFAULT__APP_NAME + value: Janky Solutions + - name: FORGEJO__server__DOMAIN + value: git.janky.solutions + - name: FORGEJO__server__ROOT_URL + value: https://git.janky.solutions/ + - name: FORGEJO__openid__ENABLE_OPENID_SIGNUP + value: "false" + - name: FORGEJO__oauth2_client__REGISTER_EMAIL_CONFIRM + value: "false" + - name: FORGEJO__oauth2_client__ENABLE_AUTO_REGISTRATION + value: "true" + - name: FORGEJO__service__ENABLE_NOTIFY_MAIL + value: "true" + - name: FORGEJO__service__DEFAULT_KEEP_EMAIL_PRIVATE + value: "true" + - name: FORGEJO__service__SHOW_REGISTRATION_BUTTON + value: "false" + - name: FORGEJO__service__ALLOW_ONLY_EXTERNAL_REGISTRATION + value: "true" + - name: FORGEJO__service__NO_REPLY_ADDRESS + value: noreply.git.janky.solutions + - name: FORGEJO__mailer__ENABLED + value: "true" + - name: FORGEJO__mailer__PROTOCOL + value: smtps + - name: FORGEJO__mailer__SMTP_ADDR + value: mx1.janky.email + - name: FORGEJO__mailer__USER + value: git@janky.solutions + - name: FORGEJO__mailer__FROM + value: git@janky.solutions + - name: FORGEJO__email.incoming__ENABLED + value: "true" + - name: FORGEJO__email.incoming__REPLY_TO_ADDRESS + value: git+%{token}@janky.solutions + - name: FORGEJO__email.incoming__HOST + value: mx1.janky.email + - name: FORGEJO__email.incoming__PORT + value: "993" + - name: FORGEJO__email.incoming__USE_TLS + value: "true" + ports: + - name: web + containerPort: 3000 + - name: ssh + containerPort: 22 + volumeClaimTemplates: + - metadata: + name: forgejo-data + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 10Gi diff --git a/k8s/invoiceninja/database.yaml b/k8s/invoiceninja/database.yaml new file mode 100644 index 0000000..ae6708f --- /dev/null +++ b/k8s/invoiceninja/database.yaml @@ -0,0 +1,77 @@ +# Headless service for stable DNS entries of StatefulSet members. +apiVersion: v1 +kind: Service +metadata: + name: mysql + namespace: invoiceninja +spec: + ports: + - name: mysql + port: 3306 + clusterIP: None + selector: + app: mysql +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: mysql + namespace: invoiceninja +spec: + selector: + matchLabels: + app: mysql + app.kubernetes.io/name: mysql + serviceName: mysql + replicas: 1 + template: + metadata: + labels: + app: mysql + app.kubernetes.io/name: mysql + spec: + containers: + - name: mysql + image: mysql:8 + envFrom: + - secretRef: + name: mysql + env: + - name: MYSQL_ALLOW_EMPTY_PASSWORD + value: "1" + - name: MYSQL_USER + value: ninja + - name: MYSQL_DATABASE + value: ninja + ports: + - name: mysql + containerPort: 3306 + volumeMounts: + - name: data + mountPath: /var/lib/mysql + subPath: mysql + resources: + requests: + cpu: 500m + memory: 1Gi + livenessProbe: + exec: + command: ["mysqladmin", "ping"] + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + readinessProbe: + exec: + # Check we can execute queries over TCP (skip-networking is off). + command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"] + initialDelaySeconds: 5 + periodSeconds: 2 + timeoutSeconds: 1 + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 10Gi diff --git a/k8s/invoiceninja/ingress.yaml b/k8s/invoiceninja/ingress.yaml new file mode 100644 index 0000000..4884f3d --- /dev/null +++ b/k8s/invoiceninja/ingress.yaml @@ -0,0 +1,17 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: invoiceninja + namespace: invoiceninja +spec: + rules: + - host: invoice-ninja.home.finn.io + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: invoiceninja + port: + name: web diff --git a/k8s/invoiceninja/invoiceninja.yaml b/k8s/invoiceninja/invoiceninja.yaml new file mode 100644 index 0000000..bb24a05 --- /dev/null +++ b/k8s/invoiceninja/invoiceninja.yaml @@ -0,0 +1,138 @@ +apiVersion: v1 +kind: Service +metadata: + name: invoiceninja + namespace: invoiceninja +spec: + ports: + - name: web + port: 80 + selector: + app: invoiceninja +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: invoiceninja + namespace: invoiceninja +spec: + selector: + matchLabels: + app: invoiceninja + serviceName: invoiceninja + replicas: 1 + template: + metadata: + labels: + app: invoiceninja + spec: + containers: + - image: docker.io/invoiceninja/invoiceninja + name: invoiceninja + resources: {} + volumeMounts: + - name: public + mountPath: /var/www/app/public + - name: storage + mountPath: /var/www/app/storage + envFrom: + - secretRef: + name: invoiceninja + env: + - name: APP_URL + value: https://invoice-ninja.home.finn.io/ + - name: APP_DEBUG + value: "true" + - name: REQUIRE_HTTPS + value: "false" + - name: DB_HOST + value: mysql + - name: DB_PORT + value: "3306" + - name: DB_DATABASE + value: ninja + - name: DB_USERNAME + value: ninja + - name: IN_USER_EMAIL + value: finn@janky.solutions + - name: IN_PASSWORD + value: aaa + - name: MAIL_HOST + value: mx1.janky.email + - name: MAIL_PORT + value: "587" + - name: MAIL_USERNAME + value: billing@janky.solutions + - name: MAIL_ENCRYPTION + value: tls + - name: MAIL_FROM_ADDRESS + value: billing@janky.solutions + - name: MAIL_FROM_NAME + value: Janky Solutions Billing + - image: nginx:latest + name: nginx + resources: {} + ports: + - name: web + containerPort: 80 + volumeMounts: + - name: public + mountPath: /var/www/app/public + - name: nginx-config + mountPath: /etc/nginx/conf.d + volumes: + - name: public + emptyDir: {} + - name: nginx-config + configMap: + name: nginx-config + volumeClaimTemplates: + - metadata: + name: storage + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 10Gi +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-config + namespace: invoiceninja +data: + nginx.conf: | + server { + listen 80 default_server; + server_name _; + + server_tokens off; + + client_max_body_size 100M; + + root /var/www/app/public/; + index index.php; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + + location ~* /storage/.*\.php$ { + return 401; + } + + location ~ \.php$ { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass localhost:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_intercept_errors off; + fastcgi_buffer_size 16k; + fastcgi_buffers 4 16k; + } + } diff --git a/k8s/monitoring/promtail.yaml b/k8s/monitoring/promtail.yaml new file mode 100644 index 0000000..101b1d8 --- /dev/null +++ b/k8s/monitoring/promtail.yaml @@ -0,0 +1,142 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: promtail + namespace: monitoring +spec: + selector: + matchLabels: + name: promtail + template: + metadata: + labels: + name: promtail + annotations: + prometheus.io/port: "9080" + spec: + serviceAccount: promtail + containers: + - name: promtail + image: grafana/promtail + args: + - -config.file=/etc/promtail/promtail.yaml + env: + - name: 'HOSTNAME' # needed when using kubernetes_sd_configs + valueFrom: + fieldRef: + fieldPath: 'spec.nodeName' + resources: + requests: + cpu: 20m + memory: 65Mi + volumeMounts: + - name: logs + mountPath: /var/log + - name: promtail-config + mountPath: /etc/promtail + - mountPath: /var/log/pods + name: varlogpods + readOnly: true + volumes: + - name: logs + hostPath: + path: /var/log + - name: varlogpods + hostPath: + path: /var/log/pods + - name: promtail-config + configMap: + name: promtail-config +--- # configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: promtail-config + namespace: monitoring +data: + promtail.yaml: | + server: + http_listen_port: 9080 + grpc_listen_port: 0 + + clients: + - url: http://monitoring-0:3100/loki/api/v1/push + + positions: + filename: /tmp/positions.yaml + target_config: + sync_period: 10s + scrape_configs: + - job_name: pod-logs + kubernetes_sd_configs: + - role: pod + pipeline_stages: + - docker: {} + relabel_configs: + - source_labels: + - __meta_kubernetes_pod_node_name + target_label: __host__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + replacement: $1 + separator: / + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_pod_name + target_label: job + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod + - action: replace + source_labels: + - __meta_kubernetes_pod_container_name + target_label: container + - replacement: /var/log/pods/*$1/*.log + separator: / + source_labels: + - __meta_kubernetes_pod_uid + - __meta_kubernetes_pod_container_name + target_label: __path__ + +--- # Clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: promtail +rules: + - apiGroups: [""] + resources: + - nodes + - services + - pods + verbs: + - get + - watch + - list + +--- # ServiceAccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: promtail + namespace: monitoring +--- # Rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: promtail + namespace: monitoring +subjects: + - kind: ServiceAccount + name: promtail + namespace: monitoring +roleRef: + kind: ClusterRole + name: promtail + apiGroup: rbac.authorization.k8s.io diff --git a/k8s/namespaces.yaml b/k8s/namespaces.yaml new file mode 100644 index 0000000..72a9695 --- /dev/null +++ b/k8s/namespaces.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: monitoring +--- +apiVersion: v1 +kind: Namespace +metadata: + name: authentik +--- +apiVersion: v1 +kind: Namespace +metadata: + name: invoiceninja +--- +apiVersion: v1 +kind: Namespace +metadata: + name: forgejo