diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0f141c8..c2bed7c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -11,9 +11,6 @@ repos:
- id: pretty-format-json
- id: check-merge-conflict
- id: check-symlinks
- - id: check-yaml
- args:
- - --allow-multiple-documents
- id: detect-private-key
- id: trailing-whitespace
diff --git a/.yamllint.yaml b/.yamllint.yaml
index a8e1307..4ffc165 100644
--- a/.yamllint.yaml
+++ b/.yamllint.yaml
@@ -5,6 +5,9 @@ yaml-files:
- '*.yml'
- '.yamllint'
+ignore: |
+ k8s/charts/
+
extends: default
rules:
diff --git a/k8s/argo-apps/valheim.yaml b/k8s/argo-apps/valheim.yaml
new file mode 100644
index 0000000..699f2f2
--- /dev/null
+++ b/k8s/argo-apps/valheim.yaml
@@ -0,0 +1,41 @@
+---
+apiVersion: argoproj.io/v1alpha1
+kind: Application
+metadata:
+ name: valheim
+ namespace: argocd
+spec:
+ destination:
+ name: ''
+ namespace: apps-fuku
+ server: https://kubernetes.default.svc
+ sources:
+ - path: k8s/charts/valheim-server
+ repoURL: https://git.roboces.dev/catalin/fukuops.git
+ targetRevision: main
+ helm:
+ valuesObject:
+ server:
+ name: "Huesoperrers Váljei"
+ public: 1
+ timezone: Europe/Madrid
+ secret:
+ name: valheim-secrets
+ key: server-password
+ persistence:
+ saves:
+ accessMode: ReadWriteMany
+ server:
+ accessMode: ReadWriteMany
+ backups:
+ accessMode: ReadWriteMany
+ resources:
+ requests:
+ memory: 4Gi
+ cpu: 2000m
+ limits:
+ memory: 8Gi
+ cpu: 4000m
+ project: fuku
+ syncPolicy:
+ automated: {}
diff --git a/k8s/charts/valheim-server/.gitignore b/k8s/charts/valheim-server/.gitignore
new file mode 100644
index 0000000..f1a5990
--- /dev/null
+++ b/k8s/charts/valheim-server/.gitignore
@@ -0,0 +1 @@
+custom-values.yaml
diff --git a/k8s/charts/valheim-server/.helmignore b/k8s/charts/valheim-server/.helmignore
new file mode 100644
index 0000000..0e8a0eb
--- /dev/null
+++ b/k8s/charts/valheim-server/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/k8s/charts/valheim-server/Chart.yaml b/k8s/charts/valheim-server/Chart.yaml
new file mode 100644
index 0000000..6c60582
--- /dev/null
+++ b/k8s/charts/valheim-server/Chart.yaml
@@ -0,0 +1,29 @@
+apiVersion: v2
+name: valheim-server
+description: A Helm chart for deploying a Valheim dedicated server on Kubernetes
+type: application
+version: 1.0.0
+appVersion: "3.1.0"
+home: https://www.valheimgame.com/
+icon: https://cdn2.steamgriddb.com/icon/d17892563a6984845a0e23df7841f903/32/256x256.png
+maintainers:
+ - name: kriegalex
+ email: kriegalex@gmail.com
+keywords:
+ - game
+ - valheim
+ - gameserver
+ - dedicated-server
+sources:
+ - https://github.com/mbround18/valheim-docker
+ - https://github.com/kriegalex/k8s-charts/tree/main/charts/valheim-server
+deprecated: false
+annotations:
+ artifacthub.io/links: |
+ - name: Chart source
+ url: https://github.com/kriegalex/k8s-charts/tree/main/charts/valheim-server
+ - name: Docker image source
+ url: https://github.com/mbround18/valheim-docker
+ artifacthub.io/images: |
+ - name: valheim
+ image: mbround18/valheim:3.1.0
diff --git a/k8s/charts/valheim-server/README.md b/k8s/charts/valheim-server/README.md
new file mode 100644
index 0000000..1b42e06
--- /dev/null
+++ b/k8s/charts/valheim-server/README.md
@@ -0,0 +1,193 @@
+# valheim-server
+
+  
+
+A Helm chart for deploying a Valheim dedicated server on Kubernetes
+
+**Homepage:**
+
+## Maintainers
+
+| Name | Email | Url |
+| ---- | ------ | --- |
+| kriegalex | | |
+
+## Source Code
+
+*
+*
+
+## Overview
+
+This Helm chart deploys a Valheim dedicated server based on the [mbround18/valheim-docker](https://github.com/mbround18/valheim-docker) project.
+
+## Features
+
+- Configurable server settings
+- Automatic updates and backups
+- Discord webhook notifications
+- Persistent storage for game saves, server files, and backups
+- Resource management for Kubernetes
+
+## Prerequisites
+
+- Kubernetes 1.29+
+- Helm 3.16.0+
+- PV provisioner support in the underlying infrastructure (for persistent storage)
+- LoadBalancer support or an Ingress controller
+
+## TL;DR
+
+```bash
+helm repo add k8s-charts https://kriegalex.github.io/k8s-charts/
+helm install my-valheim-server k8s-charts/valheim-server
+```
+
+## Important Security Notice
+The default values for this chart include a placeholder password. For production use:
+
+1. Always specify a secure password
+2. Consider using Kubernetes secrets for sensitive values
+3. Restrict access to your server using appropriate network policies
+
+## Installation
+
+### Simple Install with Custom Password and Server Name
+
+```bash
+helm upgrade --install my-valheim-server \
+ --set server.password="YourStrongPassword" \
+ --set server.name="Your Awesome Valheim Server" \
+ k8s-charts/valheim-server
+```
+
+### Custom Configuration File
+Create a YAML file with your custom values:
+
+```yaml
+server:
+ name: "My Custom Valheim Server"
+ password: "SuperSecretPassword"
+ world: "MyWorld"
+ public: 1
+
+persistence:
+ saves:
+ size: 5Gi
+ backups:
+ size: 20Gi
+
+automation:
+ autoBackup: 1 # disabled by default
+ autoBackupSchedule: "*/30 * * * *"
+
+resources:
+ requests:
+ memory: 4Gi
+ cpu: 2000m
+ limits:
+ memory: 12Gi
+ cpu: 4000m
+```
+
+Then install the chart:
+
+```bash
+helm install my-valheim-server -f my-values.yaml k8s-charts/valheim-server
+```
+
+## Updating
+
+```bash
+helm upgrade my-valheim-server k8s-charts/valheim-server
+```
+
+## Uninstallation
+
+```bash
+helm uninstall my-valheim-server
+```
+
+Note: This will not delete the Persistent Volume Claims. To delete them:
+
+```bash
+kubectl delete pvc -l app.kubernetes.io/instance=my-valheim-server
+```
+
+## Values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| affinity | object | `{}` | Affinity for pod assignment |
+| automation.autoBackup | int | `0` | Enable automatic backups (1=enabled, 0=disabled) |
+| automation.autoBackupDaysToLive | int | `7` | Number of days to keep backups |
+| automation.autoBackupOnShutdown | int | `0` | Create backup on server shutdown (1=enabled, 0=disabled) |
+| automation.autoBackupOnUpdate | int | `1` | Create backup before updates (1=enabled, 0=disabled) |
+| automation.autoBackupRemoveOld | int | `1` | Remove old backups automatically (1=enabled, 0=disabled) |
+| automation.autoBackupSchedule | string | `"*/15 * * * *"` | Cron schedule for automatic backups |
+| automation.autoUpdate | int | `1` | Enable automatic updates (1=enabled, 0=disabled) |
+| automation.autoUpdateSchedule | string | `"0 1 * * *"` | Cron schedule for automatic updates |
+| automation.updateOnStartup | int | `0` | Update server when container starts (1=enabled, 0=disabled) |
+| extraEnv | list | `[]` | Additional environment variables for the Valheim server |
+| fullnameOverride | string | `""` | Provide a full name override for resources |
+| image.pullPolicy | string | `"IfNotPresent"` | Image pull policy |
+| image.repository | string | `"mbround18/valheim"` | Docker repository to use |
+| image.tag | string | `""` | Docker tag to use - use "latest" for most current version |
+| initContainers | object | `{"args":[],"command":[],"enabled":false,"image":"busybox:latest"}` | Init container configuration for server preparation |
+| initContainers.args | list | `[]` | Init container arguments |
+| initContainers.command | list | `[]` | Init container command |
+| initContainers.enabled | bool | `false` | Enable init container |
+| initContainers.image | string | `"busybox:latest"` | Init container image |
+| livenessProbe.enabled | bool | `false` | Enable liveness probe |
+| livenessProbe.failureThreshold | int | 6 (allows up to 2 minutes for recovery) | Failure threshold |
+| livenessProbe.initialDelaySeconds | int | `60` | Initial delay seconds |
+| livenessProbe.periodSeconds | int | `20` | Period seconds |
+| livenessProbe.timeoutSeconds | int | `5` | Timeout seconds |
+| modding.bepInEx | int | `0` | Enable BepInEx for mods (1=enabled, 0=disabled) |
+| modding.modPath | string | `"/home/steam/valheim/BepInEx"` | Path to mounted mod directory |
+| modding.useConfigurationManager | bool | `false` | Enable mounting a ConfigurationManager config |
+| nameOverride | string | `""` | Provide a name override for resources |
+| nodeSelector | object | `{}` | Node selector for pod assignment |
+| notifications.includePublicIp | int | `0` | Include the server's public IP in notifications (1=enabled, 0=disabled) |
+| notifications.webhookUrl | string | `""` | Discord webhook URL for server notifications |
+| persistence.backups.accessMode | string | `"ReadWriteOnce"` | Access mode for the PVC |
+| persistence.backups.existingClaim | string | `""` | Existing claim to use (leave empty to create a new one) |
+| persistence.backups.size | string | `"10Gi"` | Size of PVC for backups |
+| persistence.enabled | bool | `true` | Enable persistent storage for server data |
+| persistence.saves.accessMode | string | `"ReadWriteOnce"` | Access mode for the PVC |
+| persistence.saves.existingClaim | string | `""` | Existing claim to use (leave empty to create a new one) |
+| persistence.saves.size | string | `"1Gi"` | Size of PVC for game saves |
+| persistence.server.accessMode | string | `"ReadWriteOnce"` | Access mode for the PVC |
+| persistence.server.existingClaim | string | `""` | Existing claim to use (leave empty to create a new one) |
+| persistence.server.size | string | `"4Gi"` | Size of PVC for server files |
+| persistence.storageClass | string | use default storage class | Storage class to use (use null for default or "" for no storage class) |
+| podSecurityContext.fsGroup | int | `1000` | File system group ID for volume mounts |
+| readinessProbe.enabled | bool | `true` | Enable readiness probe |
+| readinessProbe.failureThreshold | int | 20 (allows up to 5 minutes for readiness) | Failure threshold |
+| readinessProbe.initialDelaySeconds | int | `60` | Initial delay seconds |
+| readinessProbe.periodSeconds | int | `15` | Period seconds |
+| readinessProbe.timeoutSeconds | int | `5` | Timeout seconds |
+| replicaCount | int | `1` | Number of replicas to deploy (should typically stay at 1) |
+| resources | object | `{}` | Resource requests and limits |
+| securityContext.runAsGroup | int | `1000` | Group ID to run the container processes |
+| securityContext.runAsNonRoot | bool | `true` | Force the container to run as a non-root user |
+| securityContext.runAsUser | int | `111` | User ID to run the container processes. Should default to the steam user ID. |
+| server.name | string | `"Valheim Server with Helm"` | Server name as displayed in-game |
+| server.password | string | you MUST change this value | Server access password (minimum 5 characters) |
+| server.port | int | `2456` | UDP port for game server (will use PORT, PORT+1, and PORT+2) |
+| server.public | int | `0` | Set to 1 to make server visible publicly, 0 for private |
+| server.timezone | string | `"UTC"` | Timezone for the server |
+| server.world | string | `"Dedicated"` | World name used for save files |
+| service.annotations | object | `{}` | Annotations for the service |
+| service.loadBalancerIP | string | `""` | Set specific load balancer IP (depends on cloud provider support) |
+| service.loadBalancerSourceRanges | list | `[]` | External source IP ranges allowed to access the server |
+| service.type | string | `"LoadBalancer"` | Service type |
+| startupProbe.enabled | bool | `true` | Enable startup probe |
+| startupProbe.failureThreshold | int | 30 (allows up to 5 minutes for initial startup) | Failure threshold |
+| startupProbe.initialDelaySeconds | int | `30` | Initial delay seconds |
+| startupProbe.periodSeconds | int | `10` | Period seconds |
+| startupProbe.timeoutSeconds | int | `5` | Timeout seconds |
+| tolerations | list | `[]` | Tolerations for pod assignment |
+
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/k8s/charts/valheim-server/README.md.gotmpl b/k8s/charts/valheim-server/README.md.gotmpl
new file mode 100644
index 0000000..7199c29
--- /dev/null
+++ b/k8s/charts/valheim-server/README.md.gotmpl
@@ -0,0 +1,115 @@
+{{ template "chart.header" . }}
+{{ template "chart.deprecationWarning" . }}
+
+{{ template "chart.badgesSection" . }}
+
+{{ template "chart.description" . }}
+
+{{ template "chart.homepageLine" . }}
+
+{{ template "chart.maintainersSection" . }}
+
+{{ template "chart.sourcesSection" . }}
+
+## Overview
+
+This Helm chart deploys a Valheim dedicated server based on the [mbround18/valheim-docker](https://github.com/mbround18/valheim-docker) project.
+
+## Features
+
+- Configurable server settings
+- Automatic updates and backups
+- Discord webhook notifications
+- Persistent storage for game saves, server files, and backups
+- Resource management for Kubernetes
+
+## Prerequisites
+
+- Kubernetes 1.29+
+- Helm 3.16.0+
+- PV provisioner support in the underlying infrastructure (for persistent storage)
+- LoadBalancer support or an Ingress controller
+
+## TL;DR
+
+```bash
+helm repo add k8s-charts https://kriegalex.github.io/k8s-charts/
+helm install my-valheim-server k8s-charts/valheim-server
+```
+
+## Important Security Notice
+The default values for this chart include a placeholder password. For production use:
+
+1. Always specify a secure password
+2. Consider using Kubernetes secrets for sensitive values
+3. Restrict access to your server using appropriate network policies
+
+## Installation
+
+### Simple Install with Custom Password and Server Name
+
+```bash
+helm upgrade --install my-valheim-server \
+ --set server.password="YourStrongPassword" \
+ --set server.name="Your Awesome Valheim Server" \
+ k8s-charts/valheim-server
+```
+
+### Custom Configuration File
+Create a YAML file with your custom values:
+
+```yaml
+server:
+ name: "My Custom Valheim Server"
+ password: "SuperSecretPassword"
+ world: "MyWorld"
+ public: 1
+
+persistence:
+ saves:
+ size: 5Gi
+ backups:
+ size: 20Gi
+
+automation:
+ autoBackup: 1 # disabled by default
+ autoBackupSchedule: "*/30 * * * *"
+
+resources:
+ requests:
+ memory: 4Gi
+ cpu: 2000m
+ limits:
+ memory: 12Gi
+ cpu: 4000m
+```
+
+Then install the chart:
+
+```bash
+helm install my-valheim-server -f my-values.yaml k8s-charts/valheim-server
+```
+
+## Updating
+
+```bash
+helm upgrade my-valheim-server k8s-charts/valheim-server
+```
+
+## Uninstallation
+
+```bash
+helm uninstall my-valheim-server
+```
+
+Note: This will not delete the Persistent Volume Claims. To delete them:
+
+```bash
+kubectl delete pvc -l app.kubernetes.io/instance=my-valheim-server
+```
+
+{{ template "chart.requirementsSection" . }}
+
+{{ template "chart.valuesSection" . }}
+
+{{ template "helm-docs.versionFooter" . }}
diff --git a/k8s/charts/valheim-server/templates/NOTES.txt b/k8s/charts/valheim-server/templates/NOTES.txt
new file mode 100644
index 0000000..95ed7db
--- /dev/null
+++ b/k8s/charts/valheim-server/templates/NOTES.txt
@@ -0,0 +1,40 @@
+Thank you for installing the Valheim Dedicated Server Helm chart!
+
+Your server should be starting up now with the following settings:
+
+Server Name: {{ .Values.server.name }}
+World: {{ .Values.server.world }}
+Game Port: {{ .Values.server.port }} (UDP)
+
+{{- if eq .Values.service.type "LoadBalancer" }}
+To connect to your server:
+
+1. Get the external IP address:
+ kubectl get svc {{ include "valheim-server.fullname" . }} --namespace {{ .Release.Namespace }}
+
+2. In Valheim, select "Join Game" and add the server manually using:
+ :{{ .Values.server.port }}
+
+3. Enter your server password when prompted.
+{{- else if eq .Values.service.type "NodePort" }}
+To connect to your server:
+
+1. Get the NodePort assigned to your service:
+ kubectl get svc {{ include "valheim-server.fullname" . }} --namespace {{ .Release.Namespace }}
+
+2. In Valheim, select "Join Game" and add the server manually using:
+ :
+
+3. Enter your server password when prompted.
+{{- else }}
+Note: You've deployed with service type "{{ .Values.service.type }}" which may not be accessible from outside the cluster.
+You might need to set up port forwarding or ingress to access your server.
+{{- end }}
+
+IMPORTANT SECURITY NOTES:
+- Make sure your server password is at least 5 characters long
+- Properly secure access to your Kubernetes cluster
+- Consider changing the default port if your server is public
+
+For more information and troubleshooting, please visit:
+{{ .Chart.Home }}
diff --git a/k8s/charts/valheim-server/templates/_helpers.tpl b/k8s/charts/valheim-server/templates/_helpers.tpl
new file mode 100644
index 0000000..50664a8
--- /dev/null
+++ b/k8s/charts/valheim-server/templates/_helpers.tpl
@@ -0,0 +1,51 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "valheim-server.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "valheim-server.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "valheim-server.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "valheim-server.labels" -}}
+helm.sh/chart: {{ include "valheim-server.chart" . }}
+{{ include "valheim-server.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "valheim-server.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "valheim-server.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
diff --git a/k8s/charts/valheim-server/templates/deployment.yaml b/k8s/charts/valheim-server/templates/deployment.yaml
new file mode 100644
index 0000000..70a527e
--- /dev/null
+++ b/k8s/charts/valheim-server/templates/deployment.yaml
@@ -0,0 +1,208 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "valheim-server.fullname" . }}
+ labels:
+ {{- include "valheim-server.labels" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ {{- include "valheim-server.selectorLabels" . | nindent 6 }}
+ strategy:
+ type: Recreate
+ template:
+ metadata:
+ labels:
+ {{- include "valheim-server.selectorLabels" . | nindent 8 }}
+ spec:
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ {{- if .Values.initContainers.enabled }}
+ initContainers:
+ - name: init-valheim
+ image: {{ .Values.initContainers.image }}
+ {{- if .Values.initContainers.command }}
+ command: {{ toYaml .Values.initContainers.command | nindent 12 }}
+ {{- end }}
+ {{- if .Values.initContainers.args }}
+ args: {{ toYaml .Values.initContainers.args | nindent 12 }}
+ {{- end }}
+ volumeMounts:
+ - name: saves
+ mountPath: /home/steam/.config/unity3d/IronGate/Valheim
+ - name: server
+ mountPath: /home/steam/valheim
+ - name: backups
+ mountPath: /home/steam/backups
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: PORT
+ value: "{{ .Values.server.port }}"
+ - name: NAME
+ value: "{{ .Values.server.name }}"
+ - name: WORLD
+ value: "{{ .Values.server.world }}"
+ - name: PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Values.secret.name }}
+ key: {{ .Values.secret.key }}
+ - name: TZ
+ value: "{{ .Values.server.timezone }}"
+ - name: PUID
+ value: "{{ .Values.securityContext.runAsUser | default "111" }}"
+ - name: PGID
+ value: "{{ .Values.securityContext.runAsGroup | default "1000" }}"
+ - name: PUBLIC
+ value: "{{ .Values.server.public }}"
+ - name: AUTO_UPDATE
+ value: "{{ .Values.automation.autoUpdate }}"
+ - name: AUTO_UPDATE_SCHEDULE
+ value: "{{ .Values.automation.autoUpdateSchedule }}"
+ - name: UPDATE_ON_STARTUP
+ value: "{{ .Values.automation.updateOnStartup }}"
+ - name: AUTO_BACKUP
+ value: "{{ .Values.automation.autoBackup }}"
+ - name: AUTO_BACKUP_SCHEDULE
+ value: "{{ .Values.automation.autoBackupSchedule }}"
+ - name: AUTO_BACKUP_REMOVE_OLD
+ value: "{{ .Values.automation.autoBackupRemoveOld }}"
+ - name: AUTO_BACKUP_DAYS_TO_LIVE
+ value: "{{ .Values.automation.autoBackupDaysToLive }}"
+ - name: AUTO_BACKUP_ON_UPDATE
+ value: "{{ .Values.automation.autoBackupOnUpdate }}"
+ - name: AUTO_BACKUP_ON_SHUTDOWN
+ value: "{{ .Values.automation.autoBackupOnShutdown }}"
+ {{- if .Values.notifications.webhookUrl }}
+ - name: WEBHOOK_URL
+ value: "{{ .Values.notifications.webhookUrl }}"
+ - name: WEBHOOK_INCLUDE_PUBLIC_IP
+ value: "{{ .Values.notifications.includePublicIp }}"
+ {{- end }}
+ {{- if eq (.Values.modding.bepInEx | toString) "1" }}
+ - name: BEPINEX
+ value: "1"
+ {{- end }}
+ {{- with .Values.extraEnv }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ ports:
+ - name: game
+ containerPort: {{ .Values.server.port }}
+ protocol: UDP
+ - name: game-1
+ containerPort: {{ add .Values.server.port 1 }}
+ protocol: UDP
+ - name: game-2
+ containerPort: {{ add .Values.server.port 2 }}
+ protocol: UDP
+ lifecycle:
+ preStop:
+ exec:
+ command: [ "/bin/sh", "-c", "kill -SIGINT 1 && sleep 5" ]
+ volumeMounts:
+ - name: saves
+ mountPath: /home/steam/.config/unity3d/IronGate/Valheim
+ - name: server
+ mountPath: /home/steam/valheim
+ - name: backups
+ mountPath: /home/steam/backups
+ {{- if eq (.Values.modding.bepInEx | toString) "1" }}
+ - name: mods
+ mountPath: {{ .Values.modding.modPath }}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ # Startup probe - wait for server to initialize
+ {{- if .Values.startupProbe.enabled }}
+ startupProbe:
+ exec:
+ command:
+ - pgrep
+ - -f
+ - valheim_server
+ initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }}
+ periodSeconds: {{ .Values.startupProbe.periodSeconds }}
+ timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }}
+ failureThreshold: {{ .Values.startupProbe.failureThreshold }}
+ {{- end }}
+ # Readiness probe - verify is server is ready
+ {{- if .Values.readinessProbe.enabled }}
+ readinessProbe:
+ exec:
+ command:
+ - pgrep
+ - -f
+ - valheim_server
+ initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+ periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+ timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
+ failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
+ {{- end }}
+ # Liveness probe - check if server is running
+ {{- if .Values.livenessProbe.enabled }}
+ livenessProbe:
+ exec:
+ command:
+ - pgrep
+ - -f
+ - valheim_server
+ initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
+ periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
+ timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
+ failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
+ {{- end }}
+ volumes:
+ - name: saves
+ {{- if and .Values.persistence.enabled .Values.persistence.saves.existingClaim }}
+ persistentVolumeClaim:
+ claimName: {{ .Values.persistence.saves.existingClaim }}
+ {{- else if .Values.persistence.enabled }}
+ persistentVolumeClaim:
+ claimName: {{ include "valheim-server.fullname" . }}-saves
+ {{- else }}
+ emptyDir: { }
+ {{- end }}
+ - name: server
+ {{- if and .Values.persistence.enabled .Values.persistence.server.existingClaim }}
+ persistentVolumeClaim:
+ claimName: {{ .Values.persistence.server.existingClaim }}
+ {{- else if .Values.persistence.enabled }}
+ persistentVolumeClaim:
+ claimName: {{ include "valheim-server.fullname" . }}-server
+ {{- else }}
+ emptyDir: { }
+ {{- end }}
+ - name: backups
+ {{- if and .Values.persistence.enabled .Values.persistence.backups.existingClaim }}
+ persistentVolumeClaim:
+ claimName: {{ .Values.persistence.backups.existingClaim }}
+ {{- else if .Values.persistence.enabled }}
+ persistentVolumeClaim:
+ claimName: {{ include "valheim-server.fullname" . }}-backups
+ {{- else }}
+ emptyDir: { }
+ {{- end }}
+ {{- if eq (.Values.modding.bepInEx | toString) "1" }}
+ - name: mods
+ emptyDir: { }
+ {{- end }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
diff --git a/k8s/charts/valheim-server/templates/pvc.yaml b/k8s/charts/valheim-server/templates/pvc.yaml
new file mode 100644
index 0000000..57b1ced
--- /dev/null
+++ b/k8s/charts/valheim-server/templates/pvc.yaml
@@ -0,0 +1,67 @@
+{{- if and .Values.persistence.enabled (not .Values.persistence.saves.existingClaim) }}
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: {{ include "valheim-server.fullname" . }}-saves
+ labels:
+ {{- include "valheim-server.labels" . | nindent 4 }}
+spec:
+ accessModes:
+ - {{ .Values.persistence.saves.accessMode }}
+ {{- if .Values.persistence.storageClass }}
+ {{- if (eq "-" .Values.persistence.storageClass) }}
+ storageClassName: ""
+ {{- else }}
+ storageClassName: "{{ .Values.persistence.storageClass }}"
+ {{- end }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ .Values.persistence.saves.size }}
+{{- end }}
+
+{{- if and .Values.persistence.enabled (not .Values.persistence.server.existingClaim) }}
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: {{ include "valheim-server.fullname" . }}-server
+ labels:
+ {{- include "valheim-server.labels" . | nindent 4 }}
+spec:
+ accessModes:
+ - {{ .Values.persistence.server.accessMode }}
+ {{- if .Values.persistence.storageClass }}
+ {{- if (eq "-" .Values.persistence.storageClass) }}
+ storageClassName: ""
+ {{- else }}
+ storageClassName: "{{ .Values.persistence.storageClass }}"
+ {{- end }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ .Values.persistence.server.size }}
+{{- end }}
+
+{{- if and .Values.persistence.enabled (not .Values.persistence.backups.existingClaim) }}
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: {{ include "valheim-server.fullname" . }}-backups
+ labels:
+ {{- include "valheim-server.labels" . | nindent 4 }}
+spec:
+ accessModes:
+ - {{ .Values.persistence.backups.accessMode }}
+ {{- if .Values.persistence.storageClass }}
+ {{- if (eq "-" .Values.persistence.storageClass) }}
+ storageClassName: ""
+ {{- else }}
+ storageClassName: "{{ .Values.persistence.storageClass }}"
+ {{- end }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ .Values.persistence.backups.size }}
+{{- end }}
diff --git a/k8s/charts/valheim-server/templates/service.yaml b/k8s/charts/valheim-server/templates/service.yaml
new file mode 100644
index 0000000..628c582
--- /dev/null
+++ b/k8s/charts/valheim-server/templates/service.yaml
@@ -0,0 +1,34 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "valheim-server.fullname" . }}
+ labels:
+ {{- include "valheim-server.labels" . | nindent 4 }}
+ {{- with .Values.service.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ type: {{ .Values.service.type }}
+ {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerIP }}
+ loadBalancerIP: {{ .Values.service.loadBalancerIP }}
+ {{- end }}
+ {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerSourceRanges }}
+ loadBalancerSourceRanges:
+ {{- toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }}
+ {{- end }}
+ ports:
+ - port: {{ .Values.server.port }}
+ targetPort: game
+ protocol: UDP
+ name: game
+ - port: {{ add .Values.server.port 1 }}
+ targetPort: game-1
+ protocol: UDP
+ name: game-1
+ - port: {{ add .Values.server.port 2 }}
+ targetPort: game-2
+ protocol: UDP
+ name: game-2
+ selector:
+ {{- include "valheim-server.selectorLabels" . | nindent 4 }}
diff --git a/k8s/charts/valheim-server/values.yaml b/k8s/charts/valheim-server/values.yaml
new file mode 100644
index 0000000..305b436
--- /dev/null
+++ b/k8s/charts/valheim-server/values.yaml
@@ -0,0 +1,227 @@
+# Specify image settings for the Valheim server container
+image:
+ # -- Docker repository to use
+ repository: mbround18/valheim
+ # -- Docker tag to use - use "latest" for most current version
+ tag: "3.1"
+ # -- Image pull policy
+ pullPolicy: Always
+
+# -- Number of replicas to deploy (should typically stay at 1)
+replicaCount: 1
+
+# -- Provide a name override for resources
+nameOverride: ""
+
+# -- Provide a full name override for resources
+fullnameOverride: ""
+
+# Server configuration settings
+server:
+ # -- UDP port for game server (will use PORT, PORT+1, and PORT+2)
+ port: 2456
+ # -- Server name as displayed in-game
+ name: "Valheim Server with Helm"
+ # -- World name used for save files
+ world: "Dedicated"
+ # -- Server access password (minimum 5 characters)
+ # @default -- you MUST change this value
+ password: "ChangeMe123!"
+ # -- Set to 1 to make server visible publicly, 0 for private
+ public: 0
+ # -- Timezone for the server
+ timezone: "UTC"
+
+secret:
+ name: ""
+ key: "server-password"
+
+# Automation configuration for the server
+automation:
+ # -- Enable automatic updates (1=enabled, 0=disabled)
+ autoUpdate: 1
+ # -- Cron schedule for automatic updates
+ autoUpdateSchedule: "0 1 * * *"
+ # -- Update server when container starts (1=enabled, 0=disabled)
+ updateOnStartup: 0
+ # -- Enable automatic backups (1=enabled, 0=disabled)
+ autoBackup: 0
+ # -- Cron schedule for automatic backups
+ autoBackupSchedule: "*/15 * * * *"
+ # -- Remove old backups automatically (1=enabled, 0=disabled)
+ autoBackupRemoveOld: 1
+ # -- Number of days to keep backups
+ autoBackupDaysToLive: 7
+ # -- Create backup before updates (1=enabled, 0=disabled)
+ autoBackupOnUpdate: 1
+ # -- Create backup on server shutdown (1=enabled, 0=disabled)
+ autoBackupOnShutdown: 0
+
+# Notification settings for server events
+notifications:
+ # -- Discord webhook URL for server notifications
+ webhookUrl: ""
+ # -- Include the server's public IP in notifications (1=enabled, 0=disabled)
+ includePublicIp: 0
+
+# Kubernetes service configuration
+service:
+ # -- Service type
+ type: LoadBalancer
+ # -- Set specific load balancer IP (depends on cloud provider support)
+ loadBalancerIP: ""
+ # -- Annotations for the service
+ annotations: { }
+ # -- External source IP ranges allowed to access the server
+ loadBalancerSourceRanges: [ ]
+
+# Storage configuration for server data
+persistence:
+ # -- Enable persistent storage for server data
+ enabled: true
+ # -- Storage class to use (use null for default or "" for no storage class)
+ # @default -- use default storage class
+ storageClass: null
+
+ # Data volume configuration for game saves
+ saves:
+ # -- Size of PVC for game saves
+ size: 1Gi
+ # -- Access mode for the PVC
+ accessMode: ReadWriteOnce
+ # -- Existing claim to use (leave empty to create a new one)
+ existingClaim: ""
+
+ # Data volume configuration for server files
+ server:
+ # -- Size of PVC for server files
+ size: 4Gi
+ # -- Access mode for the PVC
+ accessMode: ReadWriteOnce
+ # -- Existing claim to use (leave empty to create a new one)
+ existingClaim: ""
+
+ # Data volume configuration for backups. Requires "autoBackup: 1".
+ backups:
+ # -- Size of PVC for backups
+ size: 10Gi
+ # -- Access mode for the PVC
+ accessMode: ReadWriteOnce
+ # -- Existing claim to use (leave empty to create a new one)
+ existingClaim: ""
+
+# -- Resource requests and limits
+resources: { }
+ # We usually recommend not to specify default resources and to leave this as a conscious
+ # choice for the user. This also increases chances charts run on environments with little
+ # resources, such as Minikube.
+ # requests:
+ # # -- Memory request for the server
+ # memory: 2Gi
+ # # -- CPU request for the server
+ # cpu: 1000m
+ # # -- Resource limits
+ # limits:
+ # # -- Memory limit for the server
+# memory: 4Gi
+# # -- CPU limit for the server
+# cpu: 2000m
+
+# -- Node selector for pod assignment
+nodeSelector: { }
+
+# -- Tolerations for pod assignment
+tolerations: [ ]
+
+# -- Affinity for pod assignment
+affinity: { }
+
+# -- Additional environment variables for the Valheim server
+extraEnv: [ ]
+# - name: EXAMPLE_VAR
+# value: "example value"
+
+# -- Init container configuration for server preparation
+initContainers:
+ # -- Enable init container
+ enabled: false
+ # -- Init container image
+ image: busybox:latest
+ # -- Init container command
+ command: [ ]
+ # -- Init container arguments
+ args: [ ]
+
+# Modding configuration
+modding:
+ # -- Enable BepInEx for mods (1=enabled, 0=disabled)
+ bepInEx: 0
+ # -- Path to mounted mod directory
+ modPath: "/home/steam/valheim/BepInEx"
+ # -- Enable mounting a ConfigurationManager config
+ useConfigurationManager: false
+
+# Pod security context settings
+# @descriptionStart
+# Security context settings applied at the pod level.
+# The fsGroup setting ensures that mounted volumes have the proper permissions for the Valheim user.
+# @descriptionEnd
+podSecurityContext:
+ # -- File system group ID for volume mounts
+ fsGroup: 1000
+
+# Container security context settings
+# @descriptionStart
+# Security context settings applied at the container level.
+# These settings ensure the container runs as a non-root user for better security.
+# The user/group IDs must match those used in the container image.
+# @descriptionEnd
+securityContext:
+ # -- User ID to run the container processes. Should default to the steam user ID.
+ runAsUser: 111
+ # -- Group ID to run the container processes
+ runAsGroup: 1000
+ # -- Force the container to run as a non-root user
+ runAsNonRoot: true
+
+# Kubernetes startup probe configuration
+startupProbe:
+ # -- Enable startup probe
+ enabled: true
+ # -- Initial delay seconds
+ initialDelaySeconds: 30
+ # -- Period seconds
+ periodSeconds: 10
+ # -- Timeout seconds
+ timeoutSeconds: 5
+ # -- Failure threshold
+ # @default -- 30 (allows up to 5 minutes for initial startup)
+ failureThreshold: 30
+
+# Kubernetes readiness probe configuration
+readinessProbe:
+ # -- Enable readiness probe
+ enabled: true
+ # -- Initial delay seconds
+ initialDelaySeconds: 60
+ # -- Period seconds
+ periodSeconds: 15
+ # -- Timeout seconds
+ timeoutSeconds: 5
+ # -- Failure threshold
+ # @default -- 20 (allows up to 5 minutes for readiness)
+ failureThreshold: 20
+
+# Kubernetes liveness probe configuration
+livenessProbe:
+ # -- Enable liveness probe
+ enabled: false
+ # -- Initial delay seconds
+ initialDelaySeconds: 60
+ # -- Period seconds
+ periodSeconds: 20
+ # -- Timeout seconds
+ timeoutSeconds: 5
+ # -- Failure threshold
+ # @default -- 6 (allows up to 2 minutes for recovery)
+ failureThreshold: 6
diff --git a/k8s/services/valheim/sealedsecrets.yaml b/k8s/services/valheim/sealedsecrets.yaml
new file mode 100644
index 0000000..ad59cb1
--- /dev/null
+++ b/k8s/services/valheim/sealedsecrets.yaml
@@ -0,0 +1,16 @@
+# yamllint disable rule:line-length
+---
+apiVersion: bitnami.com/v1alpha1
+kind: SealedSecret
+metadata:
+ creationTimestamp: null
+ name: valheim-secrets
+ namespace: apps-fuku
+spec:
+ encryptedData:
+ server-password: AgBsm7Qg9ej7FtFh5twb4ALyL0I/fzVukURvFg17aweeDX7bM/9p/Yq7S2XG8gbqOYbC1GxknGMHQUnTXqXC9YZ4tZVUAptTCrAsPZHhHiet8bM39KCo2tGa5mCyC7lcmxae26cHuKj8Df6iMQCHL9ZH58A2SU8OIaszkonjwvSnbk6u7/HLCE8UyqP1JjXBMd4wx4BFDrhbauZr10f51tI55ksY+x44QQNrz84QEXmQ/dgwdzGAWqcPQTf57BebSI+ZKtUIvrMpNtz1ioqGnH3vWlb7QnqyqcyAYri3W3j8DB03EpfI2QjYi5Rs1NaJoO8L5HFdHW5p+rmttuwRxiEUPmURftH25o6Mgv/EcWGsB1TpyyFXM8JNU01lWJ+Wty316YF1BV3zHqdQeKu82R/wSv+iVm1dYKTfSOLe3YJr+aFnhYX3hCpBup1cB2KeOe/X9wTo2ETdvKhcIJPz8x7TRcXaCerVmVBw6LagmmdtMsCL4AIXw2gdkBeGONQmOzR1hDyTBAmpTv59WYzAJcCPZRE6gGxCPqH32G36E7WGEI4UOsjvT3GkVDnYx4FUDppzSP0ebnHZOwwAPFtXojHUaHg7ZTjZiuXDQa9Hkqt4mIOKa0i1HI0MyPu8eZJjoRXNS4j1yLfDCP2eSuhGjtVNbbyQthaITolitZ0VeUU8St1iKB7rvAGHqhBoPSw9TOBVSsBcHgIAV64oRqto4kM8
+ template:
+ metadata:
+ creationTimestamp: null
+ name: valheim-secrets
+ namespace: apps-fuku