├── .github ├── metallb-configmap.yaml └── workflows │ ├── lint-test.yaml │ └── release.yaml ├── .gitignore ├── LICENSE ├── README.md └── charts ├── mc-router ├── .helmignore ├── Chart.yaml ├── OWNERS ├── README.md ├── templates │ ├── _helpers.tpl │ ├── api-service.yaml │ ├── autoscale-allow-deny-configmap.yaml │ ├── autoscale-allow-deny-secret.yaml │ ├── clusterrole.yaml │ ├── clusterrolebinding.yaml │ ├── deployment.yaml │ ├── extra-list.yaml │ ├── router-service.yaml │ └── serviceaccount.yaml ├── values.schema.json └── values.yaml ├── minecraft-bedrock ├── .helmignore ├── Chart.yaml ├── OWNERS ├── README.md ├── ci │ └── test-values.yaml ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── datadir-pvc.yaml │ ├── deployment.yaml │ ├── extra-list.yaml │ └── minecraft-svc.yaml └── values.yaml ├── minecraft-proxy ├── .helmignore ├── Chart.yaml ├── README.md ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── configmap.yaml │ ├── datadir-pvc.yaml │ ├── deployment.yaml │ ├── extraports-ing.yaml │ ├── extraports-svc.yaml │ ├── proxy-svc.yaml │ ├── rcon-secret.yaml │ ├── rcon-svc.yaml │ └── velocity-forwarding-secret.yaml └── values.yaml ├── minecraft ├── .helmignore ├── Chart.yaml ├── OWNERS ├── README.md ├── ci │ └── test-values.yaml ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── backupdir-pvc.yaml │ ├── datadir-pvc.yaml │ ├── deployment.yaml │ ├── extra-list.yaml │ ├── extraports-ing.yaml │ ├── extraports-svc.yaml │ ├── minecraft-svc.yaml │ ├── rclone-secret.yaml │ ├── rcon-svc.yaml │ └── secrets.yaml ├── values.schema.json └── values.yaml └── rcon-web-admin ├── .helmignore ├── Chart.yaml ├── README.md ├── ci └── test-values.yaml ├── templates ├── NOTES.txt ├── _helpers.tpl ├── deployment.yaml ├── ingress.yaml ├── role.yaml ├── rolebinding.yaml ├── secrets.yaml ├── serviceaccount.yaml └── services.yaml └── values.yaml /.github/metallb-configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | namespace: metallb-system 5 | name: config 6 | data: 7 | config: | 8 | address-pools: 9 | - name: default 10 | protocol: layer2 11 | addresses: 12 | - 192.168.1.240-192.168.1.250 13 | -------------------------------------------------------------------------------- /.github/workflows/lint-test.yaml: -------------------------------------------------------------------------------- 1 | name: Lint and Test Charts 2 | 3 | on: pull_request 4 | 5 | 6 | jobs: 7 | lint-test: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v4 12 | with: 13 | fetch-depth: 0 14 | 15 | - name: Set up Helm 16 | uses: azure/setup-helm@v4 17 | with: 18 | version: v3.17.2 19 | 20 | - uses: actions/setup-python@v5 21 | with: 22 | python-version: 3.13 23 | 24 | - name: Set up chart-testing 25 | uses: helm/chart-testing-action@v2.7.0 26 | 27 | - name: Run chart-testing (list-changed) 28 | id: list-changed 29 | run: | 30 | changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }}) 31 | if [[ -n "$changed" ]]; then 32 | echo "changed=true" >> "$GITHUB_OUTPUT" 33 | fi 34 | 35 | - name: Run chart-testing (lint) 36 | if: steps.list-changed.outputs.changed == 'true' 37 | run: ct lint --target-branch ${{ github.event.repository.default_branch }} 38 | 39 | - name: Create kind cluster 40 | if: steps.list-changed.outputs.changed == 'true' 41 | uses: helm/kind-action@v1.12.0 42 | 43 | - name: Install LoadBalancer 44 | if: steps.list-changed.outputs.changed == 'true' 45 | run: |- 46 | kubectl config use-context kind-chart-testing 47 | kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml 48 | kubectl apply -f .github/metallb-configmap.yaml 49 | 50 | - name: Run chart-testing (install) 51 | if: steps.list-changed.outputs.changed == 'true' 52 | run: ct install --target-branch ${{ github.event.repository.default_branch }} 53 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release Charts 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | release: 10 | timeout-minutes: 5 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: write 14 | packages: write 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | 19 | - name: Turnstyle 20 | uses: softprops/turnstyle@v2 21 | with: 22 | continue-after-seconds: 180 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | 26 | - name: Fetch history 27 | run: git fetch --prune --unshallow 28 | 29 | - name: Configure Git 30 | run: | 31 | git config user.name "$GITHUB_ACTOR" 32 | git config user.email "$GITHUB_ACTOR@users.noreply.github.com" 33 | 34 | - name: Install Helm 35 | uses: azure/setup-helm@v4 36 | 37 | - name: Login to GitHub Container Registry 38 | uses: docker/login-action@v3 39 | with: 40 | registry: ghcr.io 41 | username: ${{ github.actor }} 42 | password: ${{ secrets.GITHUB_TOKEN }} 43 | 44 | - name: Add dependency chart repos 45 | run: | 46 | helm repo add stable https://charts.helm.sh/stable 47 | helm repo update stable 48 | 49 | - name: Run chart-releaser 50 | uses: helm/chart-releaser-action@v1.7.0 51 | env: 52 | CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 53 | 54 | ## https://github.com/helm/chart-releaser-action/issues/107#issuecomment-2133797963 55 | - name: Push Charts to GHCR 56 | run: | 57 | for pkg in .cr-release-packages/*; do 58 | if [ -z "${pkg:-}" ]; then 59 | break 60 | fi 61 | 62 | helm push "${pkg}" oci://ghcr.io/${{ github.repository }} 63 | done 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /*.iml 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-present Geoff Bourne and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # minecraft-server-charts 2 | 3 | [![](https://github.com/itzg/minecraft-server-charts/workflows/Release%20Charts/badge.svg?branch=master)](https://github.com/itzg/minecraft-server-charts/actions) 4 | 5 | ## Usage 6 | 7 | [Helm](https://helm.sh) must be installed to use the charts. 8 | Please refer to Helm's [documentation](https://helm.sh/docs/) to get started. 9 | 10 | Once Helm is set up properly, add the repo as follows: 11 | 12 | ```console 13 | helm repo add itzg https://itzg.github.io/minecraft-server-charts/ 14 | ``` 15 | 16 | You can then run `helm search repo itzg` to see the charts. 17 | 18 | ## Charts 19 | 20 | * [mc-router](https://github.com/itzg/minecraft-server-charts/tree/master/charts/mc-router) 21 | * [minecraft](https://github.com/itzg/minecraft-server-charts/tree/master/charts/minecraft) 22 | * [minecraft-bedrock](https://github.com/itzg/minecraft-server-charts/tree/master/charts/minecraft-bedrock) 23 | * [minecraft-proxy](https://github.com/itzg/minecraft-server-charts/tree/master/charts/minecraft-proxy) 24 | * [rcon-web-admin](https://github.com/itzg/minecraft-server-charts/tree/master/charts/rcon-web-admin) 25 | 26 | ```bash 27 | helm install --name your-release itzg/minecraft 28 | ``` 29 | 30 | Also see [artifact hub](https://artifacthub.io/packages/search?repo=minecraft-server-charts) for a complete list. 31 | -------------------------------------------------------------------------------- /charts/mc-router/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | # OWNERS file for Kubernetes 23 | OWNERS 24 | -------------------------------------------------------------------------------- /charts/mc-router/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: mc-router 3 | version: 1.4.0 4 | # not used 5 | appVersion: 1.0.0 6 | home: https://github.com/itzg/mc-router 7 | description: Routes Minecraft client connections to backend servers based upon the requested server address. 8 | keywords: 9 | - minecraft 10 | - router 11 | sources: 12 | - https://github.com/itzg/minecraft-server-charts 13 | maintainers: 14 | - name: gtaylor 15 | email: gtaylor@gc-taylor.com 16 | - name: billimek 17 | email: jeff@billimek.com 18 | - name: itzg 19 | email: itzgeoff@gmail.com 20 | - name: bibz87 21 | email: yannik@carbongem.com 22 | annotations: 23 | artifacthub.io/links: | 24 | - name: Image source 25 | url: https://github.com/itzg/mc-router 26 | - name: Image DockerHub 27 | url: https://hub.docker.com/r/itzg/mc-router 28 | -------------------------------------------------------------------------------- /charts/mc-router/OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - gtaylor 3 | - itzg 4 | - billimek 5 | - bibz87 6 | reviewers: 7 | - gtaylor 8 | - itzg 9 | - billimek 10 | - bibz87 11 | -------------------------------------------------------------------------------- /charts/mc-router/README.md: -------------------------------------------------------------------------------- 1 | # Minecraft Router 2 | 3 | Routes Minecraft client connections to backend servers based upon the requested 4 | server address. 5 | 6 | ## Introduction 7 | 8 | This chart creates a single `mc-router` Pod, associated Service and permissions. 9 | 10 | ## Prerequisites 11 | 12 | - 16 MB of RAM 13 | - Kubernetes 1.4+ 14 | - PV provisioner support in the underlying infrastructure 15 | 16 | ## Installing the Chart 17 | 18 | To install the chart with the release name `mc-router`, run: 19 | 20 | ```shell 21 | helm install mc-router itzg/mc-router 22 | ``` 23 | 24 | This command deploys a `mc-router` instance with sensible defaults. 25 | 26 | > **Tip**: List all releases using `helm list` 27 | 28 | ## Uninstalling the Chart 29 | 30 | To uninstall/delete the `mc-router` deployment: 31 | 32 | ```shell 33 | helm delete mc-router 34 | ``` 35 | 36 | The command removes all the Kubernetes components associated with the chart and 37 | deletes the release. 38 | 39 | ## Configuration 40 | 41 | Refer to [values.yaml](values.yaml) for the full run-down on defaults. These are 42 | a mixture of Kubernetes and Minecraft Router -related directives that map to 43 | environment variables in the 44 | [itzg/mc-router](https://hub.docker.com/r/itzg/mc-router/) Docker image. 45 | 46 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm 47 | install`. For example, 48 | 49 | ```shell 50 | helm install mc-router \ 51 | --set minecraftRouter.connectionRateLimit=2,minecraftRouter.debug.enabled=true \ 52 | itzg/mc-router 53 | ``` 54 | 55 | Alternatively, a YAML file that specifies the values for the parameters can be 56 | provided while installing the chart. For example, 57 | 58 | ```shell 59 | helm install mc-router -f values.yaml itzg/mc-router 60 | ``` 61 | 62 | > **Tip**: You can use the default [values.yaml](values.yaml) 63 | 64 | ## Port Range 65 | 66 | Depending on the chosen API and Minecraft ports, you might need to update your 67 | cluster's allowed node port range by adding 68 | `--service-node-port-range=25000-32767` to 69 | `/etc/kubernetes/manifests/kube-apiserver.yaml`. For K3s clusters, refer to K3s' 70 | [documentation](https://docs.k3s.io/installation/configuration) to know how to 71 | change the allowed port range. 72 | -------------------------------------------------------------------------------- /charts/mc-router/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "mc-router.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "mc-router.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "mc-router.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "mc-router.labels" -}} 37 | helm.sh/chart: {{ include "mc-router.chart" . }} 38 | {{ include "mc-router.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "mc-router.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "mc-router.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "mc-router.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "mc-router.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | 64 | {{/* 65 | Helper function for environment variables 66 | */}} 67 | {{- define "mc-router.envMap" -}} 68 | {{- if or (index . 1) (kindIs "float64" (index . 1)) (kindIs "bool" (index . 1)) }} 69 | - name: {{ index . 0 }} 70 | value: {{ index . 1 | quote }} 71 | {{- end }} 72 | {{- end }} 73 | 74 | {{/* 75 | Helper function for multiline environment variables 76 | */}} 77 | {{- define "mc-router.envMultilineMap" -}} 78 | {{- if index . 1 }} 79 | - name: {{ index . 0 }} 80 | value: | 81 | {{- index . 1 }} 82 | {{- end }} 83 | {{- end }} 84 | 85 | {{/* 86 | Helper function for secret environment variables 87 | */}} 88 | {{- define "mc-router.envSecretMap" -}} 89 | {{- if index . 1 }} 90 | - name: {{ index . 0 }} 91 | valueFrom: 92 | secretKeyRef: 93 | name: {{ index . 1 }} 94 | key: {{ index . 2 }} 95 | {{- end }} 96 | {{- end }} 97 | 98 | {{/* 99 | Helper function for mappings formatting 100 | */}} 101 | {{- define "mc-router.formatMappings" -}} 102 | {{- range . }} 103 | {{ printf "%s=%s:%d" .externalHostname .host (.port | int) }} 104 | {{- end -}} 105 | {{- end }} 106 | 107 | {{/* 108 | Helper function for rendering extra resources to deploy 109 | */}} 110 | {{- define "mc-router.extraDeploy.render" -}} 111 | {{- $value := typeIs "string" .value | ternary .value (.value | toYaml) }} 112 | {{- if contains "{{" (toJson .value) }} 113 | {{- if .scope }} 114 | {{- tpl (cat "{{- with $.RelativeScope -}}" $value "{{- end }}") (merge (dict "RelativeScope" .scope) .context) }} 115 | {{- else }} 116 | {{- tpl $value .context }} 117 | {{- end }} 118 | {{- else }} 119 | {{- $value }} 120 | {{- end }} 121 | {{- end -}} 122 | -------------------------------------------------------------------------------- /charts/mc-router/templates/api-service.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.services.api }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ include "mc-router.fullname" . }}-api 6 | labels: 7 | {{- include "mc-router.labels" . | nindent 4 }} 8 | annotations: 9 | {{- toYaml .Values.services.api.annotations | nindent 4 }} 10 | spec: 11 | {{- with .Values.services.api }} 12 | type: {{ .type }} 13 | ports: 14 | - port: {{ default 8080 .port }} 15 | {{- if list "LoadBalancer" "NodePort" | has .type }} 16 | {{- if .nodePort }} 17 | nodePort: {{ .nodePort }} 18 | {{- end }} 19 | {{- end }} 20 | targetPort: api 21 | protocol: TCP 22 | name: api 23 | {{- end }} 24 | selector: 25 | {{- include "mc-router.selectorLabels" . | nindent 4 }} 26 | {{- end }} 27 | -------------------------------------------------------------------------------- /charts/mc-router/templates/autoscale-allow-deny-configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.minecraftRouter.autoScale.configObject "ConfigMap" | and .Values.minecraftRouter.autoScale.allowDeny }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ include "mc-router.fullname" . }}-autoscale-allow-deny 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "mc-router.labels" . | nindent 4 }} 9 | data: 10 | auto-scale-allow-deny-list.json: {{ .Values.minecraftRouter.autoScale.allowDeny | toJson | squote }} 11 | {{- end }} 12 | -------------------------------------------------------------------------------- /charts/mc-router/templates/autoscale-allow-deny-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.minecraftRouter.autoScale.configObject "Secret" | and .Values.minecraftRouter.autoScale.allowDeny }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ include "mc-router.fullname" . }}-autoscale-allow-deny 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "mc-router.labels" . | nindent 4 }} 9 | data: 10 | auto-scale-allow-deny-list.json: {{ .Values.minecraftRouter.autoScale.allowDeny | toJson | b64enc }} 11 | {{- end }} 12 | -------------------------------------------------------------------------------- /charts/mc-router/templates/clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: {{ include "mc-router.fullname" . }} 5 | labels: 6 | {{- include "mc-router.labels" . | nindent 4 }} 7 | rules: 8 | - apiGroups: [""] 9 | resources: ["services"] 10 | verbs: ["watch","list"] 11 | {{- if .Values.minecraftRouter.autoScale.up.enabled }} 12 | - apiGroups: ["apps"] 13 | resources: ["statefulsets", "statefulsets/scale"] 14 | verbs: ["watch","list","get","update"] 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /charts/mc-router/templates/clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: {{ include "mc-router.fullname" . }} 5 | labels: 6 | {{- include "mc-router.labels" . | nindent 4 }} 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: {{ include "mc-router.fullname" . }} 11 | subjects: 12 | - kind: ServiceAccount 13 | name: {{ include "mc-router.fullname" . }} 14 | namespace: {{ .Release.Namespace }} 15 | -------------------------------------------------------------------------------- /charts/mc-router/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- $apiPort := 8080 }} 2 | {{- $minecraftPort := 25565 }} 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: {{ include "mc-router.fullname" . }} 7 | namespace: {{ .Release.Namespace }} 8 | {{- with .Values.deploymentAnnotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | labels: 13 | {{- include "mc-router.labels" . | nindent 4 }} 14 | {{- with .Values.deploymentLabels }} 15 | {{- toYaml . | nindent 4 }} 16 | {{- end }} 17 | spec: 18 | {{- if not .Values.autoscaling.enabled }} 19 | replicas: {{ .Values.replicaCount }} 20 | {{- end }} 21 | selector: 22 | matchLabels: 23 | {{- include "mc-router.selectorLabels" . | nindent 6 }} 24 | strategy: 25 | {{- .Values.deploymentStrategy | toYaml | nindent 4}} 26 | template: 27 | metadata: 28 | {{- if or .Values.minecraftRouter.autoScale.allowDeny .Values.podAnnotations }} 29 | annotations: 30 | {{- if .Values.minecraftRouter.autoScale.allowDeny }} 31 | {{- if eq .Values.minecraftRouter.autoScale.configObject "Secret" }} 32 | checksum/autoscale-allow-deny-config: {{ include (print .Template.BasePath "/autoscale-allow-deny-secret.yaml") . | sha256sum }} 33 | {{- else if eq .Values.minecraftRouter.autoScale.configObject "ConfigMap" }} 34 | checksum/autoscale-allow-deny-config: {{ include (print .Template.BasePath "/autoscale-allow-deny-configmap.yaml") . | sha256sum }} 35 | {{- end }} 36 | {{- end }} 37 | {{- with .Values.podAnnotations }} 38 | {{- toYaml . | nindent 8 }} 39 | {{- end }} 40 | {{- end }} 41 | labels: 42 | {{- include "mc-router.labels" . | nindent 8 }} 43 | {{- with .Values.podLabels }} 44 | {{- toYaml . | nindent 8 }} 45 | {{- end }} 46 | spec: 47 | {{- with .Values.imagePullSecrets }} 48 | imagePullSecrets: 49 | {{- toYaml . | nindent 8 }} 50 | {{- end }} 51 | serviceAccountName: {{ include "mc-router.serviceAccountName" . }} 52 | securityContext: 53 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 54 | containers: 55 | - name: {{ .Chart.Name }} 56 | securityContext: 57 | {{- toYaml .Values.securityContext | nindent 12 }} 58 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 59 | imagePullPolicy: {{ .Values.image.pullPolicy }} 60 | env: 61 | {{- include "mc-router.envMap" (list "IN_KUBE_CLUSTER" "true") }} 62 | {{- include "mc-router.envMap" (list "API_BINDING" (printf ":%d" $apiPort)) }} 63 | {{- include "mc-router.envMap" (list "PORT" $minecraftPort) }} 64 | 65 | {{- with .Values.minecraftRouter }} 66 | {{- include "mc-router.envMap" (list "AUTO_SCALE_UP" .autoScale.up.enabled) }} 67 | {{- include "mc-router.envMap" (list "AUTO_SCALE_DOWN" .autoScale.down.enabled) }} 68 | {{- include "mc-router.envMap" (list "AUTO_SCALE_DOWN_AFTER" .autoScale.down.after) }} 69 | {{- if .autoScale.allowDeny }} 70 | {{- include "mc-router.envMap" (list "AUTO_SCALE_ALLOW_DENY" "etc/mc-router/auto-scale-allow-deny-list.json") }} 71 | {{- end }} 72 | {{- include "mc-router.envMap" (list "CONNECTION_RATE_LIMIT" .connectionRateLimit) }} 73 | {{- include "mc-router.envMap" (list "CPU_PROFILE" .cpuProfilePath) }} 74 | {{- include "mc-router.envMap" (list "DEBUG" .debug.enabled) }} 75 | 76 | {{- with .defaultServer }} 77 | {{- include "mc-router.envMap" (list "DEFAULT" (printf "%s:%d" .host (.port | int))) }} 78 | {{- end }} 79 | 80 | {{- include "mc-router.envMultilineMap" (list "MAPPING" (include "mc-router.formatMappings" .mappings)) }} 81 | 82 | {{- with .metrics }} 83 | {{- include "mc-router.envMap" (list "METRICS_BACKEND" .backend) }} 84 | 85 | {{- if eq .backend "influxdb" }} 86 | {{- with .influxdb }} 87 | {{- include "mc-router.envMap" (list "METRICS_BACKEND_CONFIG_INFLUXDB_ADDR" .address) }} 88 | {{- include "mc-router.envMap" (list "METRICS_BACKEND_CONFIG_INFLUXDB_DATABASE" .database) }} 89 | {{- include "mc-router.envMap" (list "METRICS_BACKEND_CONFIG_INFLUXDB_INTERVAL" .interval) }} 90 | {{- include "mc-router.envMap" (list "METRICS_BACKEND_CONFIG_INFLUXDB_RETENTION_POLICY" .retentionPolicy) }} 91 | {{- include "mc-router.envMap" (list "METRICS_BACKEND_CONFIG_INFLUXDB_TAGS" .tags) }} 92 | {{- with .credentials }} 93 | {{- include "mc-router.envSecretMap" (list "METRICS_BACKEND_CONFIG_INFLUXDB_USERNAME" .existingSecret .usernameKey) }} 94 | {{- include "mc-router.envSecretMap" (list "METRICS_BACKEND_CONFIG_INFLUXDB_PASSWORD" .existingSecret .passwordKey) }} 95 | {{- end }} 96 | {{- end }} 97 | {{- end }} 98 | {{- end }} 99 | 100 | {{- include "mc-router.envSecretMap" (list "NGROK_TOKEN" .ngrokToken.existingSecret .ngrokToken.tokenKey ) }} 101 | {{- include "mc-router.envMap" (list "SIMPLIFY_SRV" .simplifySrv) }} 102 | {{- include "mc-router.envMap" (list "USE_PROXY_PROTOCOL" .useProxyProtocol) }} 103 | {{- include "mc-router.envMap" (list "VERSION" .showVersion) }} 104 | {{- end }} 105 | 106 | {{- range $key, $value := .Values.extraEnv }} 107 | {{- if kindIs "map" $value }} 108 | {{- if hasKey $value "valueFrom" }} 109 | - name: {{ $key }} 110 | valueFrom: 111 | {{- $value.valueFrom | toYaml | nindent 14 }} 112 | {{- end }} 113 | {{- else }} 114 | - name: {{ $key }} 115 | value: {{ $value | quote }} 116 | {{- end }} 117 | {{- end }} 118 | ports: 119 | - name: api 120 | containerPort: {{ $apiPort }} 121 | protocol: TCP 122 | - name: minecraft 123 | containerPort: {{ $minecraftPort }} 124 | protocol: TCP 125 | livenessProbe: 126 | initialDelaySeconds: 30 127 | failureThreshold: 20 128 | httpGet: 129 | path: /routes 130 | httpHeaders: 131 | - name: Accept 132 | value: application/json 133 | port: {{ $apiPort }} 134 | readinessProbe: 135 | initialDelaySeconds: 30 136 | failureThreshold: 20 137 | httpGet: 138 | path: /routes 139 | httpHeaders: 140 | - name: Accept 141 | value: application/json 142 | port: {{ $apiPort }} 143 | startupProbe: 144 | failureThreshold: 30 145 | httpGet: 146 | path: /routes 147 | httpHeaders: 148 | - name: Accept 149 | value: application/json 150 | port: {{ $apiPort }} 151 | resources: 152 | {{- toYaml .Values.resources | nindent 12 }} 153 | {{- if or .Values.minecraftRouter.autoScale.allowDeny .Values.extraVolumes }} 154 | volumeMounts: 155 | {{- if .Values.minecraftRouter.autoScale.allowDeny }} 156 | - name: autoscale-allow-deny 157 | mountPath: /etc/mc-router 158 | readOnly: true 159 | {{- end }} 160 | {{- with .Values.extraVolumes }} 161 | {{- range . }} 162 | {{- if .volumeMounts }} 163 | {{- toYaml .volumeMounts | nindent 12 }} 164 | {{- end }} 165 | {{- end }} 166 | {{- end }} 167 | {{- end }} 168 | {{- with .Values.nodeSelector }} 169 | nodeSelector: 170 | {{- toYaml . | nindent 8 }} 171 | {{- end }} 172 | {{- with .Values.affinity }} 173 | affinity: 174 | {{- toYaml . | nindent 8 }} 175 | {{- end }} 176 | {{- with .Values.tolerations }} 177 | tolerations: 178 | {{- toYaml . | nindent 8 }} 179 | {{- end }} 180 | 181 | {{- if or .Values.minecraftRouter.autoScale.allowDeny .Values.extraVolumes }} 182 | volumes: 183 | {{- if .Values.minecraftRouter.autoScale.allowDeny }} 184 | {{- if eq .Values.minecraftRouter.autoScale.configObject "Secret" }} 185 | - name: autoscale-allow-deny 186 | secret: 187 | secretName: {{ include "mc-router.fullname" . }}-autoscale-allow-deny 188 | {{- else if eq .Values.minecraftRouter.autoScale.configObject "ConfigMap" }} 189 | - name: autoscale-allow-deny 190 | configMap: 191 | name: {{ include "mc-router.fullname" . }}-autoscale-allow-deny 192 | {{- end }} 193 | {{- end }} 194 | {{- with .Values.extraVolumes }} 195 | {{- range . }} 196 | {{- if .volumes }} 197 | {{- toYaml .volumes | nindent 8 }} 198 | {{- end }} 199 | {{- end }} 200 | {{- end }} 201 | {{- end }} 202 | {{- range $key, $value := .Values.extraPodSpec }} 203 | {{ $key }}: {{ tpl $value $ }} 204 | {{- end }} 205 | -------------------------------------------------------------------------------- /charts/mc-router/templates/extra-list.yaml: -------------------------------------------------------------------------------- 1 | {{- range .Values.extraDeploy }} 2 | --- 3 | {{ include "mc-router.extraDeploy.render" (dict "value" . "context" $) }} 4 | {{- end }} 5 | -------------------------------------------------------------------------------- /charts/mc-router/templates/router-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "mc-router.fullname" . }} 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | {{- include "mc-router.labels" . | nindent 4 }} 8 | annotations: 9 | {{- toYaml .Values.services.minecraft.annotations | nindent 4 }} 10 | spec: 11 | {{- with .Values.services.minecraft }} 12 | type: {{ .type }} 13 | ports: 14 | - port: {{ .port }} 15 | {{- if list "LoadBalancer" "NodePort" | has .type }} 16 | {{- if .nodePort }} 17 | nodePort: {{ .nodePort }} 18 | {{- end }} 19 | {{- end }} 20 | targetPort: minecraft 21 | protocol: TCP 22 | name: minecraft 23 | {{- end }} 24 | selector: 25 | {{- include "mc-router.selectorLabels" . | nindent 4 }} 26 | {{- if .Values.services.extraServiceSpec }} 27 | {{ toYaml .Values.services.extraServiceSpec | nindent 2 }} 28 | {{- end }} 29 | -------------------------------------------------------------------------------- /charts/mc-router/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "mc-router.serviceAccountName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "mc-router.labels" . | nindent 4 }} 9 | {{- with .Values.serviceAccount.annotations }} 10 | annotations: 11 | {{- toYaml . | nindent 4 }} 12 | {{- end }} 13 | automountServiceAccountToken: {{ .Values.serviceAccount.automount }} 14 | {{- end }} 15 | -------------------------------------------------------------------------------- /charts/mc-router/values.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "required": [ 4 | "minecraftRouter", 5 | "services" 6 | ], 7 | "properties": { 8 | 9 | "services": { 10 | "type": "object", 11 | "required": [ 12 | "api", 13 | "minecraft" 14 | ], 15 | "properties": { 16 | "api": { 17 | "type": "object", 18 | "properties": { 19 | "type": { 20 | "type": "string", 21 | "enum": [ 22 | "ExternalName", 23 | "ClusterIP", 24 | "NodePort", 25 | "LoadBalancer" 26 | ] 27 | }, 28 | "port": { 29 | "type": "integer", 30 | "minimum": 1 31 | } 32 | } 33 | }, 34 | 35 | "minecraft": { 36 | "type": "object", 37 | "required": [ 38 | "type", 39 | "port" 40 | ], 41 | "properties": { 42 | "type": { 43 | "type": "string", 44 | "enum": [ 45 | "ExternalName", 46 | "ClusterIP", 47 | "NodePort", 48 | "LoadBalancer" 49 | ] 50 | }, 51 | "port": { 52 | "type": "integer", 53 | "minimum": 1 54 | } 55 | } 56 | } 57 | } 58 | }, 59 | 60 | "minecraftRouter": { 61 | "type": "object", 62 | "additionalProperties": false, 63 | "properties": { 64 | "autoScale": { 65 | "type": "object", 66 | "properties": { 67 | "up": { 68 | "type": "object", 69 | "properties": { 70 | "enabled": { 71 | "title": "\"Wake up\" any stopped Minecraft servers.", 72 | "description": "This requires Minecraft servers to be kind: StatefulSet", 73 | "anyOf": [ 74 | { "type": "string", "enum": ["default"] }, 75 | { "type": "boolean" } 76 | ] 77 | } 78 | } 79 | }, 80 | "down": { 81 | "type": "object", 82 | "properties": { 83 | "enabled": { 84 | "title": "Shut down any running Minecraft servers after there are no more connections.", 85 | "description": "This requires Minecraft servers to be kind: StatefulSet", 86 | "anyOf": [ 87 | { "type": "string", "enum": ["default"] }, 88 | { "type": "boolean" } 89 | ] 90 | }, 91 | "after": { 92 | "type": "string", 93 | "title": "Shut down waiting period after there are no more connections.", 94 | "description": "It is recommended that this value is high enough so momentary disconnections do not result in a server shutdown" 95 | } 96 | } 97 | }, 98 | "configObject": { 99 | "type": "string", 100 | "enum": ["Secret", "ConfigMap"], 101 | "title": "Type of Kubernetes object to store autoscale allow/deny list config in." 102 | }, 103 | "allowDeny": { 104 | "title": "Specify a server allow/deny list to restrict which players may trigger the scalers.", 105 | "$comment": "Update tag below and in values.yaml comment when this file changes", 106 | "$ref": "https://raw.githubusercontent.com/itzg/mc-router/refs/tags/1.29.0/docs/allow-deny-list.schema.json" 107 | } 108 | } 109 | }, 110 | 111 | "connectionRateLimit": { 112 | "type": "integer", 113 | "title": "Max number of connections to allow per second", 114 | "minimum": 1 115 | }, 116 | 117 | "cpuProfilePath": { 118 | "type": "string", 119 | "title": "Write CPU profiling to given path" 120 | }, 121 | 122 | "debug": { 123 | "type": "object", 124 | "title": "Enable debug logs", 125 | "properties": { 126 | "enabled": { 127 | "anyOf": [ 128 | { "type": "string", "enum": ["default"] }, 129 | { "type": "boolean" } 130 | ] 131 | } 132 | } 133 | }, 134 | 135 | "defaultServer": { 136 | "type": "object", 137 | "title": "Default Minecraft server to use when mapping not found", 138 | "properties": { 139 | "host": { 140 | "type": "string", 141 | "minLength": 1 142 | }, 143 | "port": { 144 | "type": "integer", 145 | "minimum": 1 146 | } 147 | } 148 | }, 149 | 150 | "mappings": { 151 | "type": "array", 152 | "title": "Minecraft server mappings", 153 | "items": { 154 | "type": "object", 155 | "uniqueItems": true, 156 | "properties": { 157 | "externalHostname": { 158 | "type": "string", 159 | "minLength": 1 160 | }, 161 | "host": { 162 | "type": "string", 163 | "minLength": 1 164 | }, 165 | "port": { 166 | "type": "integer", 167 | "minimum": 1 168 | } 169 | } 170 | } 171 | }, 172 | 173 | "metrics": { 174 | "type": "object", 175 | "properties": { 176 | "backend": { 177 | "type": "string", 178 | "title": "Backend to use for metrics exposure/publishing", 179 | "enum": ["discard", "expvar", "influxdb", "prometheus"] 180 | } 181 | }, 182 | "if": { 183 | "properties": { 184 | "backend": { "const": "influxdb" } 185 | }, 186 | "required": ["backend"] 187 | }, 188 | "then": { 189 | "required": ["influxdb"], 190 | "properties": { 191 | "influxdb": { 192 | "type": "object", 193 | "title": "InfluxDB settings", 194 | "description": "Required if backend is set to influxdb", 195 | "additionalProperties": false, 196 | "minProperties": 6, 197 | "properties": { 198 | "address": { 199 | "type": "string", 200 | "minLength": 1 201 | }, 202 | "database": { 203 | "type": "string", 204 | "minLength": 1 205 | }, 206 | "interval": { 207 | "type": "string", 208 | "minLength": 1 209 | }, 210 | "credentials": { 211 | "type": "object", 212 | "additionalProperties": false, 213 | "minProperties": 3, 214 | "properties": { 215 | "existingSecret": { 216 | "type": "string", 217 | "title": "The name of an existing secret containing the database credentials", 218 | "minLength": 1 219 | }, 220 | "usernameKey": { 221 | "type": "string", 222 | "title": "The key in the existing secret containing the username", 223 | "minLength": 1 224 | }, 225 | "passwordKey": { 226 | "type": "string", 227 | "title": "The key in the existing secret containing the password", 228 | "minLength": 1 229 | } 230 | } 231 | }, 232 | "retentionPolicy": { 233 | "type": "string" 234 | }, 235 | "tags": { 236 | "type": "string", 237 | "title": "Extra tags to be included with all reported metrics" 238 | } 239 | } 240 | } 241 | } 242 | } 243 | }, 244 | 245 | "ngrokToken": { 246 | "type": "object", 247 | "title": "If set, an ngrok tunnel will be established.", 248 | "properties": { 249 | "existingSecret": { 250 | "type": "string", 251 | "title": "The name of an existing secret containing the token", 252 | "minLength": 1 253 | }, 254 | "tokenKey": { 255 | "type": "string", 256 | "title": "The key in the existing secret containing the token", 257 | "minLength": 1 258 | } 259 | } 260 | }, 261 | 262 | "simplifySrv": { 263 | "title": "Simplify fully qualified SRV records for mapping", 264 | "anyOf": [ 265 | { "type": "string", "enum": ["default"] }, 266 | { "type": "boolean" } 267 | ] 268 | }, 269 | 270 | "useProxyProtocol": { 271 | "title": "Send PROXY protocol to backend servers", 272 | "anyOf": [ 273 | { "type": "string", "enum": ["default"] }, 274 | { "type": "boolean" } 275 | ] 276 | }, 277 | 278 | "showVersion": { 279 | "title": "Output version and exit", 280 | "anyOf": [ 281 | { "type": "string", "enum": ["default"] }, 282 | { "type": "boolean" } 283 | ] 284 | } 285 | } 286 | }, 287 | "extraPodSpec": { 288 | "type": "object" 289 | } 290 | } 291 | } 292 | -------------------------------------------------------------------------------- /charts/mc-router/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for mc-router. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: itzg/mc-router 9 | tag: latest 10 | pullPolicy: Always 11 | 12 | imagePullSecrets: [] 13 | nameOverride: "" 14 | fullnameOverride: "" 15 | 16 | serviceAccount: 17 | # Specifies whether a service account should be created 18 | create: true 19 | # Automatically mount a ServiceAccount's API credentials? 20 | automount: true 21 | # Annotations to add to the service account 22 | annotations: {} 23 | # The name of the service account to use. 24 | # If not set and create is true, a name is generated using the fullname template 25 | name: "" 26 | 27 | deploymentStrategy: 28 | type: Recreate 29 | # rollingUpdate: 30 | # maxSurge: 0.25 31 | # maxUnavailable: 0.25 32 | 33 | deploymentAnnotations: {} 34 | deploymentLabels: {} 35 | 36 | podAnnotations: {} 37 | podLabels: {} 38 | 39 | podSecurityContext: {} 40 | # fsGroup: 2000 41 | 42 | securityContext: {} 43 | # capabilities: 44 | # drop: 45 | # - ALL 46 | # readOnlyRootFilesystem: true 47 | # runAsNonRoot: true 48 | # runAsUser: 1000 49 | 50 | services: 51 | # Service for API requests 52 | api: {} 53 | # type: ClusterIP 54 | # # Service port exposed within the cluster 55 | # port: 8080 56 | # # Service port exposed externally on each node 57 | # nodePort: 38080 58 | # Service annotations 59 | # annotations: {} 60 | 61 | # Service for Minecraft client connections 62 | minecraft: 63 | type: NodePort 64 | # Service port exposed within the cluster 65 | port: 25565 66 | # Service port exposed externally on each node 67 | # nodePort: 30065 68 | # Service annotations 69 | # annotations: {} 70 | 71 | # Additional service specs to be defined 72 | # Fields set here will be added to the end of the Service spec 73 | # Can include any fields from https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec 74 | extraServiceSpec: {} 75 | 76 | resources: {} 77 | # limits: 78 | # cpu: 250m 79 | # memory: 100Mi 80 | # requests: 81 | # cpu: 100m 82 | # memory: 50Mi 83 | 84 | autoscaling: 85 | enabled: false 86 | minReplicas: 1 87 | maxReplicas: 100 88 | targetCPUUtilizationPercentage: 80 89 | # targetMemoryUtilizationPercentage: 80 90 | 91 | nodeSelector: {} 92 | 93 | tolerations: [] 94 | 95 | affinity: {} 96 | 97 | # Array of extra volumes to attach to the pod 98 | extraVolumes: [] 99 | # - volumeMounts: 100 | # - name: nfs 101 | # mountPath: /mnt/volume 102 | # readOnly: true 103 | # volumes: 104 | # - name: nfs 105 | # server: some.nfs.server.com 106 | # path: / 107 | # mountOptions: 108 | # - port=2049 109 | # - hard 110 | # - vers=4 111 | 112 | # Additional mc-router container environment variables 113 | # Values can be either variable values or `valueFrom` yaml 114 | extraEnv: {} 115 | # some_variable: some value 116 | # another_variable: 117 | # valueFrom: 118 | # fieldRef: 119 | # fieldPath: status.hostIP 120 | 121 | # Extra fields to set on the pod 122 | # 123 | # Fields set here will be added to the end of the Pod spec 124 | # Can include any fields from https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec 125 | # that are not already set by the chart. 126 | # 127 | # The value of the field will be interpretted as a template. 128 | extraPodSpec: {} 129 | # priorityClassName: 'my-priority-class' 130 | 131 | # Array of extra objects to deploy with the release. 132 | # This value is evaluated as a template 133 | extraDeploy: [] 134 | # - |- 135 | # apiVersion: v1 136 | # kind: ConfigMap 137 | # metadata: 138 | # name: {{ template "mc-router.fullname" . }}-extra-cm 139 | # data: 140 | # key: |- 141 | # { 142 | # "key": "value" 143 | # } 144 | 145 | minecraftRouter: 146 | autoScale: 147 | up: 148 | # "Wake up" any stopped Minecraft servers. 149 | # This requires Minecraft servers to be kind: StatefulSet 150 | enabled: false 151 | down: 152 | # Shut down any running Minecraft servers after there are no more connections. 153 | # This requires Minecraft servers to be kind: StatefulSet 154 | enabled: false 155 | # Shut down waiting period after there are no more connections. 156 | # It is recommended that this value is high enough so momentary disconnections do not result in a server shutdown 157 | after: "" 158 | # Type of Kubernetes object to store autoscale allow/deny list config in. 159 | # Valid options: Secret,ConfigMap 160 | configObject: Secret 161 | # Specify a server allow/deny list to restrict which players may trigger the scalers. 162 | # For more info on the schema, check out the file in `mc-router` 163 | # https://github.com/itzg/mc-router/blob/1.29.0/docs/allow-deny-list.schema.json 164 | allowDeny: {} 165 | # global: 166 | # denylist: 167 | # - uuid: some-player-uuid 168 | # name: somePlayerName 169 | # servers: 170 | # my.server.domain: 171 | # allowlist: 172 | # - uuid: some-player-uuid 173 | # my.other-server.domain: 174 | # denylist: 175 | # - uuid: some-player-uuid 176 | 177 | # Max number of connections to allow per second 178 | connectionRateLimit: 1 179 | 180 | # Write CPU profiling to given path 181 | cpuProfilePath: "" 182 | 183 | # Enable debug logs 184 | debug: 185 | enabled: false 186 | 187 | # Default Minecraft server to use when mapping not found 188 | defaultServer: {} 189 | # host: "" 190 | # port: 25565 191 | 192 | # Minecraft server mappings 193 | mappings: [] 194 | # - externalHostname: "" 195 | # host: "" 196 | # port: 25565 197 | 198 | metrics: 199 | # Backend to use for metrics exposure/publishing: discard,expvar,influxdb,prometheus 200 | backend: discard 201 | 202 | # InfluxDB settings. Required if backend is set to influxdb 203 | # influxdb: 204 | # address: "" 205 | # database: "" 206 | # interval: 1m0s 207 | # credentials: 208 | # # The name of an existing secret containing the database credentials 209 | # existingSecret: "" 210 | # # The key in the existing secret containing the username 211 | # usernameKey: username 212 | # # The key in the existing secret containing the password 213 | # passwordKey: password 214 | # retentionPolicy: "" 215 | # # Extra tags to be included with all reported metrics 216 | # tags: "" 217 | 218 | # If set, an ngrok tunnel will be established. 219 | ngrokToken: {} 220 | # # The name of an existing secret containing the token 221 | # existingSecret: "" 222 | # # The key in the existing secret containing the token 223 | # tokenKey: token 224 | 225 | # Simplify fully qualified SRV records for mapping 226 | simplifySrv: false 227 | 228 | # Send PROXY protocol to backend servers 229 | useProxyProtocol: false 230 | 231 | # Output version and exit 232 | showVersion: false 233 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | # OWNERS file for Kubernetes 23 | OWNERS 24 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: minecraft-bedrock 3 | version: 2.8.4 4 | appVersion: SeeValues 5 | home: https://minecraft.net/ 6 | description: Minecraft server 7 | keywords: 8 | - game 9 | - server 10 | sources: 11 | - https://github.com/itzg/minecraft-server-charts 12 | maintainers: 13 | - name: gtaylor 14 | email: gtaylor@gc-taylor.com 15 | - name: billimek 16 | email: jeff@billimek.com 17 | - name: itzg 18 | email: itzgeoff@gmail.com 19 | annotations: 20 | artifacthub.io/links: | 21 | - name: Image source 22 | url: https://github.com/itzg/docker-minecraft-bedrock-server 23 | - name: Image DockerHub 24 | url: https://hub.docker.com/r/itzg/minecraft-bedrock-server 25 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - gtaylor 3 | - itzg 4 | - billimek 5 | reviewers: 6 | - gtaylor 7 | - itzg 8 | - billimek 9 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/README.md: -------------------------------------------------------------------------------- 1 | # Minecraft 2 | 3 | [Minecraft](https://minecraft.net/en/) is a game about placing blocks and going on adventures. 4 | 5 | ## Introduction 6 | 7 | This chart creates a single [Minecraft Bedrock Server](https://www.minecraft.net/en-us/download/server/bedrock/) Pod, plus Services for the Minecraft server. 8 | 9 | ## Prerequisites 10 | 11 | - 512 MB of RAM 12 | - Kubernetes 1.4+ with Beta APIs enabled 13 | - PV provisioner support in the underlying infrastructure 14 | 15 | ## Installing the Chart 16 | 17 | To install the chart with the release name `minecraft`, read the [Minecraft EULA](https://account.mojang.com/documents/minecraft_eula) run: 18 | 19 | ```shell 20 | helm install minecraft-bedrock \ 21 | --set minecraftServer.eula=true itzg/minecraft 22 | ``` 23 | 24 | This command deploys a Minecraft dedicated server with sensible defaults. 25 | 26 | > **Tip**: List all releases using `helm list` 27 | 28 | ## Uninstalling the Chart 29 | 30 | To uninstall/delete the `minecraft-bedrock` deployment: 31 | 32 | ```shell 33 | helm delete minecraft-bedrock 34 | ``` 35 | 36 | The command removes all the Kubernetes components associated with the chart and deletes the release. 37 | 38 | ## Configuration 39 | 40 | Refer to [values.yaml](values.yaml) for the full run-down on defaults. These are a mixture of Kubernetes and Minecraft-related directives that map to environment variables in the [itzg/minecraft-bedrock-server](https://hub.docker.com/r/itzg/minecraft-bedrock-server/) Docker image. 41 | 42 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, 43 | 44 | ```shell 45 | helm install --name minecraft-bedrock \ 46 | --set minecraftServer.eula=true,minecraftServer.Difficulty=hard \ 47 | itzg/minecraft 48 | ``` 49 | 50 | Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, 51 | 52 | ```shell 53 | helm install --name minecraft -f values.yaml itzg/minecraft 54 | ``` 55 | 56 | > **Tip**: You can use the default [values.yaml](values.yaml) 57 | 58 | ## Persistence 59 | 60 | The [itzg/minecraft-bedrock-server](https://hub.docker.com/r/itzg/minecraft-bedrock-server/) image stores the saved games and mods under /data. 61 | 62 | By default a PersistentVolumeClaim is created and mounted for saves but not mods. In order to disable this functionality 63 | you can change the values.yaml to disable persistence under the sub-sections under `persistence`. 64 | 65 | > *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."* 66 | 67 | ## Backups 68 | 69 | You can backup the state of your minecraft server to your local machine via the `kubectl cp` command. 70 | 71 | ```shell 72 | NAMESPACE=default 73 | POD_ID=lionhope-387ff8d-sdis9 74 | kubectl attach --namespace ${NAMESPACE} ${POD_ID} -it 75 | save hold 76 | save query 77 | ^P + ^Q (CtrlP and CtrlQ) 78 | kubectl cp ${NAMESPACE}/${POD_ID}:/data . 79 | kubectl attach --namespace ${NAMESPACE} ${POD_ID} -it 80 | save resume 81 | ^P + ^Q (CtrlP and CtrlQ) 82 | ``` 83 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/ci/test-values.yaml: -------------------------------------------------------------------------------- 1 | # This must be overridden, since we can't accept this for the user. 2 | minecraftServer: 3 | eula: "TRUE" 4 | # fix in place and rebased 5 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | {{- if eq (printf "%s" .Values.minecraftServer.eula) "FALSE" }} 2 | ############################################################################## 3 | #### ERROR: You did not agree to the EULA in your 'helm install' call. #### 4 | ############################################################################## 5 | 6 | This deployment will be incomplete until you read the Minecraft EULA linked 7 | in the README.md, then: 8 | 9 | helm upgrade {{ .Release.Name }} \ 10 | --set minecraftServer.eula=true stable/minecraft 11 | {{- else -}} 12 | 13 | Get the IP address of your Minecraft server by running these commands in the 14 | same shell: 15 | 16 | {{- if contains "NodePort" .Values.minecraftServer.serviceType }} 17 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} \ 18 | -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "minecraft.fullname" . }}) 19 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} \ 20 | -o jsonpath="{.items[0].status.addresses[0].address}") 21 | echo "You'll need to expose this node through your security groups/firewall" 22 | echo "for it to be world-accessible." 23 | echo $NODE_IP:$NODE_PORT 24 | 25 | {{- else if contains "LoadBalancer" .Values.minecraftServer.serviceType }} 26 | 27 | !! NOTE: It may take a few minutes for the LoadBalancer IP to be available. !! 28 | 29 | You can watch for EXTERNAL-IP to populate by running: 30 | kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "minecraft.fullname" . }} 31 | 32 | {{- else if contains "ClusterIP" .Values.minecraftServer.serviceType }} 33 | export POD_NAME=$(kubectl get pods \ 34 | --namespace {{ .Release.Namespace }} \ 35 | -l "component={{ template "minecraft.fullname" . }}" \ 36 | -o jsonpath="{.items[0].metadata.name}") 37 | kubectl port-forward $POD_NAME 25565:25565 38 | echo "Point your Minecraft client at 127.0.0.1:22565" 39 | 40 | {{- end }} 41 | 42 | {{- if .Values.persistence.dataDir.enabled }} 43 | {{- else }} 44 | 45 | ############################################################################ 46 | ### WARNING: Persistence is disabled!!! You will lose your game state ### 47 | ### when the Minecraft pod is terminated. ### 48 | ### See values.yaml's persistence.dataDir.enabled directive. ### 49 | ############################################################################ 50 | {{- end }} 51 | {{- end }} 52 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "minecraft.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Set the chart fullname 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the labels spec). 12 | We change "+" with "_" for OCI compatibility 13 | */}} 14 | {{- define "chart.fullname" -}} 15 | {{- printf "%s-%s" .Chart.Name (.Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-") -}} 16 | {{- end }} 17 | 18 | {{/* 19 | Create a default fully qualified app name. 20 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 21 | */}} 22 | {{- define "minecraft.fullname" -}} 23 | {{- $name := default .Chart.Name .Values.nameOverride -}} 24 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 25 | {{- end -}} 26 | 27 | {{- define "extraDeploy.render" -}} 28 | {{- $value := typeIs "string" .value | ternary .value (.value | toYaml) }} 29 | {{- if contains "{{" (toJson .value) }} 30 | {{- if .scope }} 31 | {{- tpl (cat "{{- with $.RelativeScope -}}" $value "{{- end }}") (merge (dict "RelativeScope" .scope) .context) }} 32 | {{- else }} 33 | {{- tpl $value .context }} 34 | {{- end }} 35 | {{- else }} 36 | {{- $value }} 37 | {{- end }} 38 | {{- end -}} 39 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/templates/datadir-pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.persistence.dataDir.enabled (not .Values.persistence.dataDir.existingClaim ) (not .Values.workloadAsStatefulSet) -}} 2 | kind: PersistentVolumeClaim 3 | apiVersion: v1 4 | metadata: 5 | name: {{ template "minecraft.fullname" . }}-datadir 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: {{ template "minecraft.fullname" . }} 9 | chart: "{{ include "chart.fullname" . }}" 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | {{- with .Values.persistence.labels }} 13 | {{ toYaml . | nindent 4 }} 14 | {{- end }} 15 | annotations: 16 | {{- if .Values.persistence.storageClass }} 17 | volume.beta.kubernetes.io/storage-class: {{ .Values.persistence.storageClass | quote }} 18 | {{- else }} 19 | volume.alpha.kubernetes.io/storage-class: default 20 | {{- end }} 21 | spec: 22 | accessModes: 23 | {{- .Values.persistence.dataDir.accessModes | toYaml | nindent 4 }} 24 | resources: 25 | requests: 26 | storage: {{ .Values.persistence.dataDir.Size | quote }} 27 | {{- if .Values.persistence.storageClass }} 28 | {{- if (eq "-" .Values.persistence.storageClass) }} 29 | storageClassName: "" 30 | {{- else }} 31 | storageClassName: "{{ .Values.persistence.storageClass }}" 32 | {{- end }} 33 | {{- end }} 34 | {{- end -}} 35 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if ne (printf "%s" .Values.minecraftServer.eula) "FALSE" }} 2 | apiVersion: apps/v1 3 | kind: {{ ternary "StatefulSet" "Deployment" .Values.workloadAsStatefulSet }} 4 | metadata: 5 | name: {{ template "minecraft.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | {{- if .Values.deploymentAnnotations }} 8 | annotations: 9 | {{- range $key, $value := .Values.deploymentAnnotations }} 10 | {{ $key }}: {{ $value | quote }} 11 | {{- end }} 12 | {{- end }} 13 | labels: 14 | app: {{ template "minecraft.fullname" . }} 15 | chart: "{{ include "chart.fullname" . }}" 16 | release: "{{ .Release.Name }}" 17 | heritage: "{{ .Release.Service }}" 18 | {{- with .Values.deploymentLabels }} 19 | {{ toYaml . | nindent 4 }} 20 | {{- end }} 21 | spec: 22 | {{- if .Values.workloadAsStatefulSet }} 23 | serviceName: {{ template "minecraft.fullname" . }} 24 | updateStrategy: 25 | type: {{ .Values.strategyType }} 26 | {{- else }} 27 | strategy: 28 | type: {{ .Values.strategyType }} 29 | {{- end }} 30 | selector: 31 | matchLabels: 32 | app: {{ template "minecraft.fullname" . }} 33 | template: 34 | metadata: 35 | labels: 36 | app: {{ template "minecraft.fullname" . }} 37 | {{- if .Values.podAnnotations }} 38 | annotations: 39 | {{- range $key, $value := .Values.podAnnotations }} 40 | {{ $key }}: {{ $value | quote }} 41 | {{- end }} 42 | {{- end }} 43 | spec: 44 | shareProcessNamespace: {{ .Values.shareProcessNamespace }} 45 | {{- if .Values.image.pullSecret }} 46 | imagePullSecrets: 47 | - name: {{ .Values.image.pullSecret }} 48 | {{- end }} 49 | securityContext: 50 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 51 | {{- if .Values.initContainers }} 52 | initContainers: 53 | {{- toYaml .Values.initContainers | nindent 8 }} 54 | {{- end }} 55 | containers: 56 | - name: {{ template "minecraft.fullname" . }} 57 | {{- if .Values.restoreMode }} 58 | command: 59 | - /bin/bash 60 | args: 61 | - -s 62 | - "while true; do sleep 30; done" 63 | {{- end }} 64 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 65 | imagePullPolicy: {{ .Values.image.pullPolicy }} 66 | stdin: true 67 | tty: true 68 | resources: 69 | {{ toYaml .Values.resources | indent 10 }} 70 | {{- if not .Values.restoreMode }} 71 | readinessProbe: 72 | exec: 73 | command: 74 | - mc-monitor 75 | - status-bedrock 76 | - --host 77 | # force health check against IPv4 port 78 | - 127.0.0.1 79 | - --port 80 | - {{ .Values.minecraftServer.serverPort | quote }} 81 | initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} 82 | {{- end }} 83 | {{- if not .Values.restoreMode }} 84 | livenessProbe: 85 | exec: 86 | command: 87 | - mc-monitor 88 | - status-bedrock 89 | - --host 90 | # force health check against IPv4 port 91 | - 127.0.0.1 92 | - --port 93 | - {{ .Values.minecraftServer.serverPort | quote }} 94 | initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} 95 | {{- end }} 96 | 97 | {{- with .Values.envFrom }} 98 | envFrom: 99 | {{- . | toYaml | nindent 10 }}{{ end }} 100 | 101 | env: 102 | - name: EULA 103 | value: {{ .Values.minecraftServer.eula | quote }} 104 | - name: VERSION 105 | value: {{ .Values.minecraftServer.version | quote }} 106 | - name: DIFFICULTY 107 | value: {{ .Values.minecraftServer.difficulty | quote }} 108 | - name: SERVER_NAME 109 | value: {{ .Values.minecraftServer.serverName | quote }} 110 | - name: WHITE_LIST 111 | value: {{ default "" .Values.minecraftServer.whitelist | quote }} 112 | - name: WHITE_LIST_USERS 113 | value: {{ default "" .Values.minecraftServer.whitelistUsers | quote }} 114 | - name: OPS 115 | value: {{ default "" .Values.minecraftServer.ops | quote }} 116 | - name: MEMBERS 117 | value: {{ default "" .Values.minecraftServer.members | quote }} 118 | - name: VISITORS 119 | value: {{ default "" .Values.minecraftServer.visitors | quote }} 120 | - name: ALLOW_CHEATS 121 | value: {{ .Values.minecraftServer.cheats | quote }} 122 | - name: MAX_PLAYERS 123 | value: {{ .Values.minecraftServer.maxPlayers | quote }} 124 | - name: VIEW_DISTANCE 125 | value: {{ .Values.minecraftServer.viewDistance | quote }} 126 | - name: TICK_DISTANCE 127 | value: {{ .Values.minecraftServer.tickDistance | quote }} 128 | - name: PLAYER_IDLE_TIMEOUT 129 | value: {{ .Values.minecraftServer.playerIdleTimeout | quote }} 130 | - name: MAX_THREADS 131 | value: {{ .Values.minecraftServer.maxThreads | quote }} 132 | - name: GAMEMODE 133 | value: {{ .Values.minecraftServer.gameMode | quote }} 134 | - name: LEVEL_TYPE 135 | value: {{ .Values.minecraftServer.levelType | quote }} 136 | - name: LEVEL_NAME 137 | value: {{ .Values.minecraftServer.levelName | quote }} 138 | - name: LEVEL_SEED 139 | value: {{ default "" .Values.minecraftServer.levelSeed | quote }} 140 | - name: DEFAULT_PLAYER_PERMISSION_LEVEL 141 | value: {{ .Values.minecraftServer.defaultPermission | quote }} 142 | - name: TEXTUREPACK_REQUIRED 143 | value: {{ .Values.minecraftServer.texturepackRequired | quote }} 144 | - name: ONLINE_MODE 145 | value: {{ .Values.minecraftServer.onlineMode | quote }} 146 | - name: EMIT_SERVER_TELEMETRY 147 | value: {{ .Values.minecraftServer.emitServerTelemetry | quote }} 148 | - name: ENABLE_LAN_VISIBILITY 149 | value: {{ .Values.minecraftServer.enableLanVisibility | quote }} 150 | - name: SERVER_PORT 151 | value: {{ .Values.minecraftServer.serverPort | quote }} 152 | 153 | {{- if .Values.minecraftServer.enableSSH }} 154 | - name: ENABLE_SSH 155 | value: "true" 156 | {{- end }} 157 | 158 | {{- if .Values.minecraftServer.passwordSSH }} 159 | - name: RCON_PASSWORD 160 | value: {{ .Values.minecraftServer.passwordSSH }} 161 | {{- end }} 162 | 163 | {{- range $key, $value := .Values.extraEnv }} 164 | {{- if kindIs "map" $value }} 165 | {{- if hasKey $value "valueFrom" }} 166 | - name: {{ $key }} 167 | valueFrom: 168 | {{- $value.valueFrom | toYaml | nindent 12 }} 169 | {{- end }} 170 | {{- else }} 171 | - name: {{ $key }} 172 | value: {{ $value | quote }} 173 | {{- end }} 174 | {{- end }} 175 | 176 | ports: 177 | - name: minecraft 178 | containerPort: {{ .Values.minecraftServer.serverPort }} 179 | protocol: UDP 180 | {{- if .Values.minecraftServer.enableSSH }} 181 | - name: minecraft-ssh 182 | containerPort: 2222 183 | protocol: TCP 184 | {{- end }} 185 | 186 | volumeMounts: 187 | - name: tmp 188 | mountPath: /tmp 189 | - name: datadir 190 | mountPath: /data 191 | {{- range .Values.extraVolumes }} 192 | {{- if .volumeMounts }} 193 | {{- toYaml .volumeMounts | nindent 8 }} 194 | {{- end }} 195 | {{- end }} 196 | securityContext: 197 | {{- toYaml .Values.securityContext | nindent 10 }} 198 | {{- with .Values.sidecarContainers }} 199 | {{- tpl . $ | nindent 6 }} 200 | {{- end }} 201 | volumes: 202 | - name: tmp 203 | emptyDir: {} 204 | {{- if .Values.persistence.dataDir.enabled }} 205 | {{- if .Values.persistence.dataDir.existingClaim }} 206 | - name: datadir 207 | persistentVolumeClaim: 208 | claimName: {{ .Values.persistence.dataDir.existingClaim }} 209 | {{- else if (not .Values.workloadAsStatefulSet) }} 210 | - name: datadir 211 | persistentVolumeClaim: 212 | claimName: {{ template "minecraft.fullname" . }}-datadir 213 | {{- end -}} 214 | {{/* if persistence enabled in stateful set without existing claim, a volume claim template will be defined */}} 215 | {{- else }} 216 | - name: datadir 217 | emptyDir: {} 218 | {{- end }} 219 | {{- range .Values.extraVolumes }} 220 | {{- toYaml .volumes | nindent 6 }} 221 | {{- end }} 222 | {{- if .Values.nodeSelector }} 223 | nodeSelector: 224 | {{ toYaml .Values.nodeSelector | indent 8 }} 225 | {{- end }} 226 | {{- if .Values.affinity }} 227 | affinity: 228 | {{ toYaml .Values.affinity | indent 8 }} 229 | {{- end }} 230 | {{- if .Values.tolerations }} 231 | tolerations: 232 | {{ toYaml .Values.tolerations | indent 8 }} 233 | {{- end }} 234 | {{- range $key, $value := .Values.extraPodSpec }} 235 | {{ $key }}: {{ tpl $value $ }} 236 | {{- end }} 237 | {{- if .Values.workloadAsStatefulSet }} 238 | volumeClaimTemplates: 239 | {{- if and .Values.persistence.dataDir.enabled (not .Values.persistence.dataDir.existingClaim) }} 240 | - metadata: 241 | name: datadir 242 | labels: 243 | app: {{ template "minecraft.fullname" . }} 244 | chart: "{{ include "chart.fullname" . }}" 245 | release: "{{ .Release.Name }}" 246 | heritage: "{{ .Release.Service }}" 247 | annotations: 248 | {{- with .Values.persistence.annotations }} 249 | {{ toYaml . | nindent 10 }} 250 | {{- end }} 251 | {{- if .Values.persistence.storageClass }} 252 | volume.beta.kubernetes.io/storage-class: {{ .Values.persistence.storageClass | quote }} 253 | {{- else }} 254 | volume.alpha.kubernetes.io/storage-class: default 255 | {{- end }} 256 | spec: 257 | accessModes: 258 | - ReadWriteOnce 259 | resources: 260 | requests: 261 | storage: {{ .Values.persistence.dataDir.Size | quote }} 262 | {{- if .Values.persistence.storageClass }} 263 | {{- if (eq "-" .Values.persistence.storageClass) }} 264 | storageClassName: "" 265 | {{- else }} 266 | storageClassName: "{{ .Values.persistence.storageClass }}" 267 | {{- end }} 268 | {{- end }} 269 | {{- end }} 270 | {{- end }} 271 | {{ end }} 272 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/templates/extra-list.yaml: -------------------------------------------------------------------------------- 1 | {{- range .Values.extraDeploy }} 2 | --- 3 | {{ include "extraDeploy.render" (dict "value" . "context" $) }} 4 | {{- end }} 5 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/templates/minecraft-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "minecraft.fullname" . }} 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | app: {{ template "minecraft.fullname" . }} 8 | chart: "{{ include "chart.fullname" . }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | {{- with .Values.serviceLabels }} 12 | {{ toYaml . | nindent 4 }} 13 | {{- end }} 14 | {{- if .Values.serviceAnnotations }} 15 | annotations: 16 | {{- range $key, $value := .Values.serviceAnnotations }} 17 | {{ $key }}: {{ $value | quote }} 18 | {{- end }} 19 | {{- end }} 20 | spec: 21 | {{- if (or (eq .Values.minecraftServer.serviceType "ClusterIP") (empty .Values.minecraftServer.serviceType)) }} 22 | type: ClusterIP 23 | {{- else if eq .Values.minecraftServer.serviceType "LoadBalancer" }} 24 | type: {{ .Values.minecraftServer.serviceType }} 25 | {{- if .Values.minecraftServer.loadBalancerIP }} 26 | loadBalancerIP: {{ .Values.minecraftServer.loadBalancerIP }} 27 | {{- end }} 28 | {{- if .Values.minecraftServer.loadBalancerSourceRanges }} 29 | loadBalancerSourceRanges: 30 | {{ toYaml .Values.minecraftServer.loadBalancerSourceRanges | indent 4 }} 31 | {{- end -}} 32 | {{- else }} 33 | type: {{ .Values.minecraftServer.serviceType }} 34 | {{- end }} 35 | {{- if .Values.minecraftServer.externalTrafficPolicy }} 36 | externalTrafficPolicy: {{ .Values.minecraftServer.externalTrafficPolicy }} 37 | {{- end }} 38 | ports: 39 | - name: minecraft 40 | port: {{ .Values.minecraftServer.serverPort }} 41 | targetPort: minecraft 42 | {{- if .Values.minecraftServer.nodePort }} 43 | nodePort: {{ .Values.minecraftServer.nodePort }} 44 | {{- end }} 45 | protocol: UDP 46 | {{- if .Values.minecraftServer.enableSSH }} 47 | - name: minecraft-ssh 48 | port: {{ default "2222" .Values.minecraftServer.exposedPortSSH }} 49 | targetPort: minecraft-ssh 50 | {{- if .Values.minecraftServer.nodePortSSH }} 51 | nodePort: {{ .Values.minecraftServer.nodePortSSH }} 52 | {{- end }} 53 | protocol: TCP 54 | {{ end }} 55 | selector: 56 | app: {{ template "minecraft.fullname" . }} 57 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/values.yaml: -------------------------------------------------------------------------------- 1 | # ref: https://hub.docker.com/r/itzg/minecraft-server/ 2 | image: 3 | repository: itzg/minecraft-bedrock-server 4 | tag: latest 5 | pullPolicy: Always 6 | pullSecret: "" 7 | 8 | ## Configure resource requests and limits 9 | ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ 10 | ## 11 | resources: 12 | requests: 13 | memory: 512Mi 14 | cpu: 500m 15 | 16 | # If true the workload is defined as a StatefulSet instead of a Deployment. 17 | # Make sure to also update the strategyType! 18 | # All configuration options for the Deployment (e.g. annotations) are used for the StatefulSet. 19 | # Regarding persistence: When an existing PVC is provided it will be shared between all Pods. 20 | # Otherwise the PVC configuration is used as a template to create PVCs for each replica. 21 | workloadAsStatefulSet: false 22 | 23 | # upgrade strategy type, depending on workload type: 24 | # - for Deployment sets strategy: Recreate or RollingUpdate 25 | # - for StatefulSet sets updateStrategy: OnDelete or RollingUpdate 26 | strategyType: Recreate 27 | 28 | nodeSelector: {} 29 | 30 | tolerations: [] 31 | 32 | affinity: {} 33 | 34 | podSecurityContext: 35 | runAsUser: 1000 36 | runAsGroup: 3000 37 | runAsNonRoot: true 38 | fsGroup: 2000 39 | seccompProfile: 40 | type: RuntimeDefault 41 | 42 | securityContext: 43 | capabilities: 44 | drop: 45 | - ALL 46 | readOnlyRootFilesystem: true 47 | allowPrivilegeEscalation: false 48 | 49 | # Most of these map to environment variables. See Minecraft for details: 50 | # https://hub.docker.com/r/itzg/minecraft-server/ 51 | livenessProbe: 52 | initialDelaySeconds: 30 53 | readinessProbe: 54 | initialDelaySeconds: 30 55 | 56 | # https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/ 57 | shareProcessNamespace: false 58 | 59 | # initContainers: 60 | # - name: do-something 61 | # image: busybox 62 | # command: ['do', 'something'] 63 | # volumesMounts: 64 | # - name: nfs 65 | # mountPath: /mnt/volume 66 | # readOnly: true 67 | initContainers: [] 68 | 69 | ## Enable an Specify container in sidecarContainers. To add a sidecar; 70 | sidecarContainers: "" 71 | # sidecarContainers: | 72 | # - name: proxy 73 | # image: "quay.io/my/favourite:image-tag 74 | # args: 75 | # - -setting1 76 | # ports: 77 | # - name: web 78 | # containerPort: 8080 79 | 80 | # extraVolumes: 81 | # - volumeMounts: 82 | # - name: nfs 83 | # mountPath: /mnt/volume 84 | # readOnly: true 85 | # volumes: 86 | # - name: nfs 87 | # server: some.nfs.server.com 88 | # path: / 89 | # mountOptions: 90 | # - port=2049 91 | # - hard 92 | # - vers=4 93 | extraVolumes: [] 94 | 95 | # Extra fields to set on the pod 96 | # 97 | # Fields set here will be added to the end of the Pod spec 98 | # Can include any fields from https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec 99 | # that are not already set by the chart. 100 | # 101 | # The value of the field will be interpretted as a template. 102 | extraPodSpec: {} 103 | # priorityClassName: 'my-priority-class' 104 | 105 | ## Array of extra objects to deploy with the release 106 | ## 107 | # extraDeploy: 108 | # - | 109 | # apiVersion: v1 110 | # kind: ConfigMap 111 | # metadata: 112 | # name: {{ template "minecraft.fullname" . }}-extra-cm 113 | # data: 114 | # key: |- 115 | # { 116 | # "key": "value" 117 | # } 118 | extraDeploy: [] 119 | 120 | minecraftServer: 121 | # This must be overridden, since we can't accept this for the user. 122 | eula: "FALSE" 123 | # One of: LATEST, SNAPSHOT, or a specific version (ie: "1.7.9"). 124 | version: "LATEST" 125 | # One of: peaceful, easy, normal, and hard 126 | difficulty: easy 127 | # A boolean to indicate if whitelist is enabled or not. If this is enabled 128 | # and whitelistUsers is left blank, you will need to provide the whitelist.json 129 | # file via the volume mounted in to the container. Setting whitelistUsers implies 130 | # whitelist is true, so it is not necessary to set it. 131 | whitelist: 132 | # A comma-separated list of player names to whitelist with no whitespace. 133 | # ex: whitelistUsers: player1,player2,player3 134 | whitelistUsers: 135 | # A comma-seperated list of xuid's for operators on server with no 136 | # whitespaces. 137 | # The server logs will print xuids as players connect. 138 | # ex: ops: "12345678,0987654" 139 | ops: 140 | # A comma-seperated list of xuid's for members on server with no 141 | # whitespaces. 142 | # ex: ops: "12345678,0987654" 143 | members: 144 | # A comma-seperated list of xuid's for visitors on server with no 145 | # whitespaces. 146 | # ex: ops: "12345678,0987654" 147 | visitors: 148 | # Max connected players. 149 | maxPlayers: 10 150 | # The world is ticked this many chunks away from any player. 151 | tickDistance: 4 152 | # Max view distance (in chunks). 153 | viewDistance: 10 154 | # The "level-name" value is used as the world name and its folder name. The player may also copy their saved game folder here, and change the name to the same as that folder's to load it instead. 155 | levelName: level 156 | # Define this if you want a specific map generation seed. 157 | levelSeed: 158 | # One of: creative, survival, adventure, spectator 159 | gameMode: survival 160 | # Permission level for new players joining for the first time (visitor, member, operator) 161 | defaultPermission: member 162 | # After a player has idled for this many minutes they get kicked. 163 | playerIdleTimeout: 30 164 | # One of: DEFAULT, FLAT, LEGACY 165 | levelType: DEFAULT 166 | # Force clients to use texture packs in the current world 167 | texturepackRequired: false 168 | # This is the server name shown in the in-game server list. 169 | serverName: "Dedicated Server" 170 | # Check accounts against Minecraft account service. 171 | onlineMode: true 172 | # Maximum number of threads the server tries to use. If set to 0 or removed then it uses as many as possible. 173 | maxThreads: 8 174 | # Cheat like commands can be used. 175 | cheats: false 176 | # Enable emit server telemetry. 177 | emitServerTelemetry: false 178 | # Enable lan visibility. 179 | enableLanVisibility: false 180 | # IPv4 UDP port of server. If using a nodePort, set serverPort and nodePort to the same value (e.g. 30000) so ping time displays. 181 | serverPort: 19132 182 | # type of kubernetes service to use 183 | serviceType: ClusterIP 184 | ## Set the port used if the serviceType is NodePort 185 | # nodePort: 186 | loadBalancerIP: 187 | # loadBalancerSourceRanges: [] 188 | ## Set the externalTrafficPolicy in the Service to either Cluster or Local 189 | # externalTrafficPolicy: Cluster 190 | ## Enable SSH for console access (eg. needed for backup containers like https://github.com/Kaiede/Bedrockifier) 191 | # Please note: if you use this together with serviceType LoadBAlancer, make sure you have at least Kubernetes v1.26 192 | enableSSH: false 193 | ## Set the port used for SSH if the serviceType is NodePort 194 | # nodePortSSH: 195 | ## Set the port used for SSH by the service (defaults to 2222) 196 | # exposedPortSSH: 197 | ## Set password for SSH access (optional, if not set password will be autogenerated) 198 | # passwordSSH: 199 | 200 | # turn off the minecraft bedrock server and just run sleep in a loop, this way you can get to the server files to restore a server without the server already have loaded 201 | # them into memory or something 202 | # kubectl cp -n minecraft survival-server-minecraft-bedrock-b868f4464-nq22m:/data/worlds/. ./ 203 | restoreMode: false 204 | 205 | ## Additional minecraft container environment variables 206 | ## Values can be either variable values or `valueFrom` yaml 207 | ## 208 | extraEnv: 209 | {} 210 | # some_variable: some value 211 | # another_variable: 212 | # valueFrom: 213 | # fieldRef: 214 | # fieldPath: status.hostIP 215 | 216 | ## Additional environment variables to add to the minecraft container from 217 | ## ConfigMaps and Secrets 218 | ## 219 | envFrom: [] 220 | 221 | persistence: 222 | labels: {} 223 | ## minecraft data Persistent Volume Storage Class 224 | ## If defined, storageClassName: 225 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 226 | ## If undefined (the default) or set to null, no storageClassName spec is 227 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 228 | ## GKE, AWS & OpenStack) 229 | ## 230 | # storageClass: "-" 231 | dataDir: 232 | # Set this to false if you don't care to persist state between restarts. 233 | enabled: false 234 | # existingClaim: nil 235 | Size: 1Gi 236 | # access modes used by the volume, RWO by default, 237 | # ensure your storage class supports other modes if chosen 238 | accessModes: 239 | - ReadWriteOnce 240 | 241 | podAnnotations: {} 242 | 243 | deploymentAnnotations: {} 244 | 245 | deploymentLables: {} 246 | 247 | serviceAnnotations: {} 248 | 249 | serviceLables: {} 250 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: minecraft-proxy 3 | version: 3.9.0 4 | appVersion: SeeValues 5 | description: Minecraft proxy server (BungeeCord, Waterfall, Velocity, etc.) 6 | keywords: 7 | - proxy 8 | - game 9 | - server 10 | home: https://github.com/itzg/minecraft-server-charts 11 | sources: 12 | - https://github.com/itzg/minecraft-server-charts 13 | maintainers: 14 | - name: chipwolf 15 | email: hello@chipwolf.uk 16 | - name: gtaylor 17 | email: gtaylor@gc-taylor.com 18 | - name: billimek 19 | email: jeff@billimek.com 20 | - name: itzg 21 | email: itzgeoff@gmail.com 22 | annotations: 23 | artifacthub.io/links: | 24 | - name: Image source 25 | url: https://github.com/itzg/docker-bungeecord 26 | - name: Image DockerHub 27 | url: https://hub.docker.com/r/itzg/bungeecord 28 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/README.md: -------------------------------------------------------------------------------- 1 | # Minecraft Proxy 2 | 3 | [Minecraft](https://minecraft.net/en/) proxies allows for a single server to become a network of seamlessly integrated servers. 4 | 5 | [BungeeCord](https://www.spigotmc.org/wiki/about-bungeecord/) is the most well known solution in this arena, but [several](https://github.com/PaperMC/Waterfall) [other](https://github.com/PaperMC/Travertine) forks of BungeeCord and new projects such as [Velocity](https://velocitypowered.com/) have become popular choices. 6 | 7 | This chart relies on the [itzg/bungeecord](https://hub.docker.com/r/itzg/bungeecord) container which supports BungeeCord, Waterfall, and Velocity out of the box. It is also designed to allow the use of any other custom proxies with some additional configuration. 8 | 9 | ## Introduction 10 | 11 | This chart creates a single Proxy Pod, Services for the BungeeCord, server and RCON. 12 | 13 | ## Prerequisites 14 | 15 | - 512 MB of RAM 16 | - Kubernetes 1.4+ with Beta APIs enabled 17 | - PV provisioner support in the underlying infrastructure 18 | 19 | ## Configuration 20 | 21 | Refer to [values.yaml](values.yaml) for the full run-down on defaults. These are a mixture of Kubernetes and BungeeCord-related directives that map to environment variables in the [itzg/bungeecord](https://hub.docker.com/r/itzg/bungeecord/) Docker image. 22 | 23 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. 24 | 25 | Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. 26 | 27 | > **Tip**: You can use the default [values.yaml](values.yaml) 28 | 29 | ## Persistence 30 | 31 | The [itzg/bungeecord](https://hub.docker.com/r/itzg/bungeecord/) image stores config and state under `/server`. 32 | 33 | When [persistence.dataDir.enabled in values.yaml](https://github.com/ArchitectSMP/charts/blob/main/bungee/values.yaml#L180) is set to true PersistentVolumeClaim is created and mounted. In order to enable this functionality 34 | you can change the values.yaml to enable persistence under the sub-sections under `persistence`. 35 | The config file for the server can be added to the persistent volume manually, or optionally, you can set it by amending the config file path (if your proxy type has a different config path) and pasting your config under [bungeecord.configFilePath and bungeeCord.config in values.yaml](https://github.com/ArchitectSMP/charts/blob/main/bungee/values.yaml#L103). 36 | 37 | > *"If persistence is not enabled, an emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."* 38 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Get the IP address of your {{ .Values.minecraftProxy.type }} server by running these commands in the 2 | same shell: 3 | 4 | {{- if contains "NodePort" .Values.minecraftProxy.serviceType }} 5 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} \ 6 | -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "proxy.fullname" . }}) 7 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} \ 8 | -o jsonpath="{.items[0].status.addresses[0].address}") 9 | echo "You'll need to expose this node through your security groups/firewall" 10 | echo "for it to be world-accessible." 11 | echo $NODE_IP:$NODE_PORT 12 | 13 | {{- else if contains "LoadBalancer" .Values.minecraftProxy.serviceType }} 14 | 15 | !! NOTE: It may take a few minutes for the LoadBalancer IP to be available. !! 16 | 17 | You can watch for EXTERNAL-IP to populate by running: 18 | kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "proxy.fullname" . }} 19 | 20 | {{- else if contains "ClusterIP" .Values.minecraftProxy.serviceType }} 21 | export POD_NAME=$(kubectl get pods \ 22 | --namespace {{ .Release.Namespace }} \ 23 | -l "component={{ template "proxy.fullname" . }}" \ 24 | -o jsonpath="{.items[0].metadata.name}") 25 | kubectl port-forward $POD_NAME 25565:25565 26 | echo "Point your Minecraft client at 127.0.0.1:22565" 27 | 28 | {{- end }} 29 | 30 | {{- if not .Values.persistence.dataDir.enabled }} 31 | 32 | ############################################################################ 33 | ### WARNING: Persistence is disabled!!! You will lose your proxy state ### 34 | ### when the proxy pod is terminated. ### 35 | ### See values.yaml's persistence.dataDir.enabled directive. ### 36 | ############################################################################ 37 | {{- end }} 38 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "proxy.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Set the chart fullname 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the labels spec). 12 | We change "+" with "_" for OCI compatibility 13 | */}} 14 | {{- define "chart.fullname" -}} 15 | {{- printf "%s-%s" .Chart.Name (.Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-") -}} 16 | {{- end }} 17 | 18 | {{/* 19 | Create a default fully qualified app name. 20 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 21 | */}} 22 | {{- define "proxy.fullname" -}} 23 | {{- $name := default .Chart.Name .Values.nameOverride -}} 24 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 25 | {{- end -}} 26 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.minecraftProxy.config }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ include "proxy.fullname" . }}-config 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: {{ template "proxy.fullname" . }} 9 | chart: "{{ include "chart.fullname" . }}" 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | data: 13 | config.yml: {{ toYaml .Values.minecraftProxy.config | indent 2 }} 14 | {{- end }} 15 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/templates/datadir-pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.persistence.dataDir.enabled (not .Values.persistence.dataDir.existingClaim ) -}} 2 | kind: PersistentVolumeClaim 3 | apiVersion: v1 4 | metadata: 5 | name: {{ template "proxy.fullname" . }}-datadir 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: {{ template "proxy.fullname" . }} 9 | chart: "{{ include "chart.fullname" . }}" 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | annotations: 13 | {{- if .Values.persistence.storageClass }} 14 | volume.beta.kubernetes.io/storage-class: {{ .Values.persistence.storageClass | quote }} 15 | {{- else }} 16 | volume.alpha.kubernetes.io/storage-class: default 17 | {{- end }} 18 | spec: 19 | accessModes: 20 | - ReadWriteOnce 21 | resources: 22 | requests: 23 | storage: {{ .Values.persistence.dataDir.Size | quote }} 24 | {{- if .Values.persistence.storageClass }} 25 | {{- if (eq "-" .Values.persistence.storageClass) }} 26 | storageClassName: "" 27 | {{- else }} 28 | storageClassName: "{{ .Values.persistence.storageClass }}" 29 | {{- end }} 30 | {{- end }} 31 | {{- end -}} 32 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "proxy.fullname" . }} 5 | namespace: {{ .Release.Namespace }} 6 | annotations: {{ toYaml .Values.deploymentAnnotations | nindent 4 }} 7 | labels: 8 | app: {{ template "proxy.fullname" . }} 9 | chart: "{{ include "chart.fullname" . }}" 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | spec: 13 | replicas: {{ .Values.replicaCount }} 14 | strategy: 15 | type: {{ .Values.strategyType }} 16 | selector: 17 | matchLabels: 18 | app: {{ template "proxy.fullname" . }} 19 | template: 20 | metadata: 21 | labels: 22 | app: {{ template "proxy.fullname" . }} 23 | annotations: {{ toYaml .Values.podAnnotations | nindent 8 }} 24 | spec: 25 | {{- if .Values.serviceAcccoutName }} 26 | serviceAccountName: {{ .Values.serviceAccountName }} 27 | {{- end }} 28 | {{- if .Values.image.pullSecret }} 29 | imagePullSecrets: 30 | - name: {{ .Values.image.pullSecret }} 31 | {{- end }} 32 | {{- if .Values.dnsPolicy }} 33 | dnsPolicy: {{ .Values.dnsPolicy}} 34 | {{- end }} 35 | {{- if .Values.dnsConfig }} 36 | dnsConfig: 37 | {{- toYaml .Values.dnsConfig | nindent 8 }} 38 | {{- end }} 39 | securityContext: 40 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 41 | initContainers: {{- toYaml .Values.initContainers | nindent 8 }} 42 | containers: 43 | - name: {{ template "proxy.fullname" . }} 44 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 45 | imagePullPolicy: Always 46 | tty: true 47 | stdin: true 48 | resources: {{ toYaml .Values.resources | nindent 10 }} 49 | {{- if .Values.startupProbe.enabled }} 50 | startupProbe: 51 | tcpSocket: 52 | port: 25577 53 | failureThreshold: {{ .Values.startupProbe.failureThreshold }} 54 | periodSeconds: {{ .Values.startupProbe.periodSeconds }} 55 | {{- end }} 56 | readinessProbe: 57 | tcpSocket: 58 | port: 25577 59 | initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} 60 | periodSeconds: {{ .Values.readinessProbe.periodSeconds }} 61 | failureThreshold: {{ .Values.readinessProbe.failureThreshold }} 62 | successThreshold: {{ .Values.readinessProbe.successThreshold }} 63 | timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} 64 | livenessProbe: 65 | tcpSocket: 66 | port: 25577 67 | initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} 68 | periodSeconds: {{ .Values.livenessProbe.periodSeconds }} 69 | failureThreshold: {{ .Values.livenessProbe.failureThreshold }} 70 | successThreshold: {{ .Values.livenessProbe.successThreshold }} 71 | timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} 72 | env: 73 | - name: UID 74 | value: "1000" 75 | - name: GID 76 | value: "1000" 77 | - name: TYPE 78 | value: {{ default "" .Values.minecraftProxy.type | quote }} 79 | {{- if eq .Values.minecraftProxy.type "WATERFALL" }} 80 | - name: WATERFALL_VERSION 81 | value: {{ .Values.minecraftProxy.waterfallVersion | quote }} 82 | - name: WATERFALL_BUILD_ID 83 | value: {{ .Values.minecraftProxy.waterfallBuildId | quote }} 84 | {{- else if eq .Values.minecraftProxy.type "VELOCITY" }} 85 | - name: VELOCITY_VERSION 86 | value: {{ .Values.minecraftProxy.velocityVersion | quote }} 87 | {{- end }} 88 | {{- if .Values.minecraftProxy.jarUrl }} 89 | - name: BUNGEE_JAR_URL 90 | value: {{ .Values.minecraftProxy.jarUrl | quote }} 91 | {{- else if .Values.minecraftProxy.jarFile }} 92 | - name: BUNGEE_JAR_FILE 93 | value: {{ .Values.minecraftProxy.jarFile | quote }} 94 | {{- else }} 95 | {{- if .Values.minecraftProxy.jenkinsJobId }} 96 | - name: BUNGEE_JOB_ID 97 | value: {{ .Values.minecraftProxy.jenkinsJobId }} 98 | {{- end }} 99 | {{- if .Values.minecraftProxy.jenkinsBaseUrl }} 100 | - name: BUNGEE_BASE_URL 101 | value: {{ .Values.minecraftProxy.jenkinsBaseUrl }} 102 | {{- end }} 103 | {{- if .Values.minecraftProxy.jarRevision }} 104 | - name: BUNGEE_JAR_REVISION 105 | value: {{ .Values.minecraftProxy.jarRevision }} 106 | {{- end }} 107 | {{- end }} 108 | {{- if .Values.minecraftProxy.plugins }} 109 | - name: PLUGINS 110 | value: {{ join "," .Values.minecraftProxy.plugins }} 111 | {{- end }} 112 | - name: MEMORY 113 | value: {{ .Values.minecraftProxy.memory | quote }} 114 | - name: JVM_OPTS 115 | value: {{ .Values.minecraftProxy.jvmOpts | quote }} 116 | 117 | {{- if .Values.minecraftProxy.rcon.enabled }} 118 | - name: ENABLE_RCON 119 | value: "true" 120 | - name: RCON_PASSWORD 121 | valueFrom: 122 | secretKeyRef: 123 | name: {{ .Values.minecraftProxy.rcon.existingSecret | default (printf "%s-rcon" (include "proxy.fullname" .)) }} 124 | key: {{ .Values.minecraftProxy.rcon.secretKey | default "rcon-password" }} 125 | {{- else }} 126 | - name: ENABLE_RCON 127 | value: "false" 128 | {{- end }} 129 | 130 | {{- range $key, $value := .Values.extraEnv }} 131 | {{- if kindIs "map" $value }} 132 | {{- if hasKey $value "valueFrom" }} 133 | - name: {{ $key }} 134 | valueFrom: 135 | {{- $value.valueFrom | toYaml | nindent 12 }} 136 | {{- end }} 137 | {{- else }} 138 | - name: {{ $key }} 139 | value: {{ $value | quote }} 140 | {{- end }} 141 | {{- end }} 142 | 143 | ports: 144 | - name: proxy 145 | containerPort: 25577 146 | protocol: TCP 147 | {{- if .Values.minecraftProxy.rcon.enabled }} 148 | - name: rcon 149 | containerPort: 25575 150 | protocol: TCP 151 | {{- end }} 152 | {{- range .Values.minecraftProxy.extraPorts }} 153 | {{- if .service.enabled }} 154 | - name: {{ .name }} 155 | containerPort: {{ .containerPort }} 156 | {{- if .protocol }} 157 | protocol: {{ .protocol }} 158 | {{- else }} 159 | protocol: TCP 160 | {{- end }} 161 | {{- end }} 162 | {{- end }} 163 | volumeMounts: 164 | - name: tmp 165 | mountPath: /tmp 166 | - name: datadir 167 | mountPath: /server 168 | {{- if .Values.minecraftProxy.config }} 169 | - name: config 170 | mountPath: {{ .Values.minecraftProxy.configFilePath }} 171 | subPath: config.yml 172 | {{- end }} 173 | {{- if .Values.minecraftProxy.velocityForwardingSecret }} 174 | - name: velocity-forwarding-secret 175 | mountPath: {{ .Values.minecraftProxy.velocityForwardingSecretFilePath }} 176 | subPath: forwarding.secret 177 | readOnly: true 178 | {{- end }} 179 | {{- range .Values.extraVolumes }} 180 | {{- if .volumeMounts }} 181 | {{- toYaml .volumeMounts | nindent 8 }} 182 | {{- end }} 183 | {{- end }} 184 | securityContext: 185 | {{- toYaml .Values.securityContext | nindent 10 }} 186 | {{- if .Values.sidecarContainers }} 187 | {{- toYaml .Values.sidecarContainers | nindent 6 }} 188 | {{- end }} 189 | volumes: 190 | - name: tmp 191 | emptyDir: {} 192 | - name: datadir 193 | {{- if .Values.persistence.dataDir.enabled }} 194 | persistentVolumeClaim: 195 | {{- if .Values.persistence.dataDir.existingClaim }} 196 | claimName: {{ .Values.persistence.dataDir.existingClaim }} 197 | {{- else }} 198 | claimName: {{ template "proxy.fullname" . }}-datadir 199 | {{- end }} 200 | {{- else }} 201 | emptyDir: {} 202 | {{- end }} 203 | {{- if .Values.minecraftProxy.velocityForwardingSecret }} 204 | - name: velocity-forwarding-secret 205 | secret: 206 | secretName: "{{ template "proxy.fullname" . }}-velocity-forwarding-secret" 207 | items: 208 | - key: velocity-forwarding-secret 209 | path: forwarding.secret 210 | {{- end }} 211 | {{- if .Values.minecraftProxy.config }} 212 | - name: config 213 | configMap: 214 | name: {{ include "proxy.fullname" . }}-config 215 | {{- end }} 216 | {{- range .Values.extraVolumes }} 217 | {{- toYaml .volumes | nindent 6 }} 218 | {{- end }} 219 | {{- if .Values.nodeSelector }} 220 | nodeSelector: {{ toYaml .Values.nodeSelector | nindent 8 }} 221 | {{- end }} 222 | {{- if .Values.affinity }} 223 | affinity: {{ toYaml .Values.affinity | nindent 8 }} 224 | {{- end }} 225 | {{- if .Values.tolerations }} 226 | tolerations: {{ toYaml .Values.tolerations | nindent 8 }} 227 | {{- end }} 228 | {{- range $key, $value := .Values.extraPodSpec }} 229 | {{ $key }}: {{ tpl $value $ }} 230 | {{- end }} 231 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/templates/extraports-ing.yaml: -------------------------------------------------------------------------------- 1 | {{- $proxyFullname := include "proxy.fullname" . }} 2 | {{- range .Values.minecraftProxy.extraPorts }} 3 | {{- if default "" .ingress.enabled }} 4 | {{- $servicePort := .service.port }} 5 | {{- $serviceName := printf "%s-%s" $proxyFullname .name }} 6 | --- 7 | apiVersion: networking.k8s.io/v1 8 | kind: Ingress 9 | metadata: 10 | name: {{ $serviceName }} 11 | namespace: "{{ $.Release.Namespace }}" 12 | {{- if .ingress.annotations }} 13 | annotations: {{- toYaml .ingress.annotations | nindent 4 }} 14 | {{- end }} 15 | labels: 16 | app: {{ $serviceName }} 17 | chart: {{ template "minecraft.fullname" . }} 18 | release: "{{ $.Release.Name }}" 19 | heritage: "{{ $.Release.Service }}" 20 | spec: 21 | {{- if .ingress.ingressClassName }} 22 | ingressClassName: {{ .ingress.ingressClassName }} 23 | {{- end }} 24 | {{- if .ingress.tls }} 25 | tls: 26 | {{- range .ingress.tls }} 27 | - hosts: 28 | {{- range .hosts }} 29 | - {{ . | quote }} 30 | {{- end }} 31 | secretName: {{ .secretName }} 32 | {{- end }} 33 | {{- end }} 34 | rules: 35 | {{- range .ingress.hosts }} 36 | - host: {{ .name }} 37 | http: 38 | paths: 39 | - path: {{ .path | default "/" }} 40 | pathType: Prefix 41 | backend: 42 | service: 43 | name: {{ $serviceName }} 44 | port: 45 | number: {{ $servicePort }} 46 | {{- end }} 47 | {{- end }} 48 | {{- end }} 49 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/templates/extraports-svc.yaml: -------------------------------------------------------------------------------- 1 | {{- $proxyFullname := include "proxy.fullname" . }} 2 | {{- range .Values.minecraftProxy.extraPorts }} 3 | {{- if and .service.enabled (not .service.embedded) }} 4 | {{- $serviceName := printf "%s-%s" $proxyFullname .name }} 5 | --- 6 | apiVersion: v1 7 | kind: Service 8 | metadata: 9 | name: {{ $serviceName }} 10 | namespace: "{{ $.Release.Namespace }}" 11 | annotations: {{ toYaml .service.annotations | nindent 4 }} 12 | labels: 13 | app: {{ $serviceName }} 14 | chart: {{ template "minecraft.fullname" . }} 15 | release: "{{ $.Release.Name }}" 16 | heritage: "{{ $.Release.Service }}" 17 | spec: 18 | {{- if (or (eq .service.type "ClusterIP") (empty .service.type)) }} 19 | type: ClusterIP 20 | {{- else if eq .service.type "LoadBalancer" }} 21 | type: {{ .service.type }} 22 | {{- if .service.loadBalancerIP }} 23 | loadBalancerIP: {{ .service.loadBalancerIP }} 24 | {{- end }} 25 | {{- if .service.loadBalancerSourceRanges }} 26 | loadBalancerSourceRanges: 27 | {{ toYaml .service.loadBalancerSourceRanges | indent 4 }} 28 | {{- end -}} 29 | {{- else }} 30 | type: {{ .service.type }} 31 | {{- end }} 32 | {{- if .service.externalTrafficPolicy }} 33 | externalTrafficPolicy: {{ .service.externalTrafficPolicy }} 34 | {{- end }} 35 | ports: 36 | - name: {{ .name }} 37 | port: {{ .service.port }} 38 | targetPort: {{ .name }} 39 | {{- if .service.nodePort }} 40 | nodePort: {{ .service.nodePort }} 41 | {{- end }} 42 | {{- if .protocol }} 43 | protocol: {{ .protocol }} 44 | {{- else }} 45 | protocol: TCP 46 | {{- end }} 47 | selector: 48 | app: {{ $proxyFullname }} 49 | {{- end }} 50 | {{- end }} 51 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/templates/proxy-svc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ template "proxy.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: {{ template "proxy.fullname" . }} 9 | chart: "{{ include "chart.fullname" . }}" 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | annotations: 13 | {{ toYaml .Values.serviceAnnotations | indent 4 }} 14 | spec: 15 | {{- if (or (eq .Values.minecraftProxy.serviceType "ClusterIP") (empty .Values.minecraftProxy.serviceType)) }} 16 | type: ClusterIP 17 | {{- else if eq .Values.minecraftProxy.serviceType "LoadBalancer" }} 18 | type: {{ .Values.minecraftProxy.serviceType }} 19 | {{- if .Values.minecraftProxy.loadBalancerIP }} 20 | loadBalancerIP: {{ .Values.minecraftProxy.loadBalancerIP }} 21 | {{- end }} 22 | {{- if .Values.minecraftProxy.loadBalancerSourceRanges }} 23 | loadBalancerSourceRanges: 24 | {{ toYaml .Values.minecraftProxy.loadBalancerSourceRanges | indent 4 }} 25 | {{- end -}} 26 | {{- else }} 27 | type: {{ .Values.minecraftProxy.serviceType }} 28 | {{- end }} 29 | {{- if .Values.minecraftProxy.externalTrafficPolicy }} 30 | externalTrafficPolicy: {{ .Values.minecraftProxy.externalTrafficPolicy }} 31 | {{- end }} 32 | {{- if .Values.minecraftProxy.ipFamilyPolicy }} 33 | ipFamilyPolicy: {{ .Values.minecraftProxy.ipFamilyPolicy }} 34 | {{- end }} 35 | ports: 36 | - name: proxy 37 | port: 25565 38 | targetPort: proxy 39 | {{- if .Values.minecraftProxy.nodePort }} 40 | nodePort: {{ .Values.minecraftProxy.nodePort }} 41 | {{- end }} 42 | protocol: TCP 43 | {{- range .Values.minecraftProxy.extraPorts }} 44 | {{- if and .service.enabled .service.embedded }} 45 | - name: {{ .name }} 46 | port: {{ .service.port }} 47 | targetPort: {{ .name }} 48 | {{- if .service.nodePort }} 49 | nodePort: {{ .service.nodePort }} 50 | {{- end }} 51 | {{- if .protocol }} 52 | protocol: {{ .protocol }} 53 | {{- else }} 54 | protocol: TCP 55 | {{- end }} 56 | {{- end }} 57 | {{- end }} 58 | selector: 59 | app: {{ template "proxy.fullname" . }} 60 | {{- if .Values.minecraftProxy.externalIPs }} 61 | externalIPs: 62 | {{- with .Values.minecraftProxy.externalIPs }} 63 | {{- range . }} 64 | - {{ . | quote }} 65 | {{- end }} 66 | {{- end }} 67 | {{- end }} 68 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/templates/rcon-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if not .Values.minecraftProxy.rcon.existingSecret }} 2 | --- 3 | apiVersion: v1 4 | kind: Secret 5 | metadata: 6 | name: "{{ template "proxy.fullname" . }}-rcon" 7 | namespace: {{ .Release.Namespace }} 8 | labels: 9 | app: {{ template "proxy.fullname" . }} 10 | chart: "{{ include "chart.fullname" . }}" 11 | release: "{{ .Release.Name }}" 12 | heritage: "{{ .Release.Service }}" 13 | type: Opaque 14 | data: 15 | rcon-password: 16 | {{ default "" .Values.minecraftProxy.rcon.password | b64enc | quote }} 17 | {{- end }} -------------------------------------------------------------------------------- /charts/minecraft-proxy/templates/rcon-svc.yaml: -------------------------------------------------------------------------------- 1 | {{- if default "" .Values.minecraftProxy.rcon.enabled }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: "{{ template "proxy.fullname" . }}-rcon" 6 | namespace: {{ .Release.Namespace }} 7 | annotations: 8 | {{ toYaml .Values.rconServiceAnnotations | indent 4 }} 9 | labels: 10 | app: {{ template "proxy.fullname" . }} 11 | chart: "{{ include "chart.fullname" . }}" 12 | release: "{{ .Release.Name }}" 13 | heritage: "{{ .Release.Service }}" 14 | spec: 15 | {{- if (or (eq .Values.minecraftProxy.rcon.serviceType "ClusterIP") (empty .Values.minecraftProxy.rcon.serviceType)) }} 16 | type: ClusterIP 17 | {{- else if eq .Values.minecraftProxy.rcon.serviceType "LoadBalancer" }} 18 | type: {{ .Values.minecraftProxy.rcon.serviceType }} 19 | {{- if .Values.minecraftProxy.rcon.loadBalancerIP }} 20 | loadBalancerIP: {{ .Values.minecraftProxy.rcon.loadBalancerIP }} 21 | {{- end }} 22 | {{- if .Values.minecraftProxy.rcon.loadBalancerSourceRanges }} 23 | loadBalancerSourceRanges: 24 | {{ toYaml .Values.minecraftProxy.rcon.loadBalancerSourceRanges | indent 4 }} 25 | {{- end -}} 26 | {{- else }} 27 | type: {{ .Values.minecraftProxy.rcon.serviceType }} 28 | {{- end }} 29 | {{- if .Values.minecraftProxy.rcon.externalTrafficPolicy }} 30 | externalTrafficPolicy: {{ .Values.minecraftProxy.rcon.externalTrafficPolicy }} 31 | {{- end }} 32 | {{- if .Values.minecraftProxy.rcon.ipFamilyPolicy }} 33 | ipFamilyPolicy: {{ .Values.minecraftProxy.rcon.ipFamilyPolicy }} 34 | {{- end }} 35 | ports: 36 | - name: rcon 37 | port: {{ .Values.minecraftProxy.rcon.port }} 38 | targetPort: rcon 39 | protocol: TCP 40 | selector: 41 | app: {{ template "proxy.fullname" . }} 42 | {{- end }} 43 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/templates/velocity-forwarding-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.minecraftProxy.velocityForwardingSecret }} 2 | --- 3 | apiVersion: v1 4 | kind: Secret 5 | metadata: 6 | name: "{{ template "proxy.fullname" . }}-velocity-forwarding-secret" 7 | namespace: {{ .Release.Namespace }} 8 | labels: 9 | app: {{ template "proxy.fullname" . }} 10 | chart: "{{ include "chart.fullname" . }}" 11 | release: "{{ .Release.Name }}" 12 | heritage: "{{ .Release.Service }}" 13 | type: Opaque 14 | data: 15 | velocity-forwarding-secret: 16 | {{ default "" .Values.minecraftProxy.velocityForwardingSecret | b64enc | quote }} 17 | {{- end }} 18 | -------------------------------------------------------------------------------- /charts/minecraft-proxy/values.yaml: -------------------------------------------------------------------------------- 1 | # ref: https://hub.docker.com/r/itzg/docker-bungeecord/ 2 | image: 3 | repository: itzg/bungeecord 4 | tag: latest 5 | pullPolicy: IfNotPresent 6 | 7 | imagePullSecret: "" 8 | 9 | replicaCount: 1 10 | 11 | ## Configure resource requests and limits 12 | ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ 13 | ## 14 | resources: 15 | requests: 16 | memory: 512Mi 17 | cpu: 500m 18 | 19 | podSecurityContext: 20 | runAsUser: 1000 21 | runAsGroup: 3000 22 | runAsNonRoot: true 23 | fsGroup: 2000 24 | seccompProfile: 25 | type: RuntimeDefault 26 | 27 | securityContext: 28 | capabilities: 29 | drop: 30 | - ALL 31 | readOnlyRootFilesystem: true 32 | allowPrivilegeEscalation: false 33 | 34 | # Most of these map to environment variables. See Minecraft for details: 35 | # https://hub.docker.com/r/itzg/docker-bungeecord/ 36 | livenessProbe: 37 | initialDelaySeconds: 30 38 | periodSeconds: 5 39 | failureThreshold: 10 40 | successThreshold: 1 41 | timeoutSeconds: 1 42 | readinessProbe: 43 | initialDelaySeconds: 30 44 | periodSeconds: 5 45 | failureThreshold: 10 46 | successThreshold: 1 47 | timeoutSeconds: 1 48 | startupProbe: 49 | enabled: false 50 | failureThreshold: 30 51 | periodSeconds: 10 52 | 53 | # initContainers: 54 | # - name: do-something 55 | # image: busybox 56 | # command: ['do', 'something'] 57 | # volumesMounts: 58 | # - name: nfs 59 | # mountPath: /mnt/volume 60 | # readOnly: true 61 | initContainers: [] 62 | 63 | # sidecarContainers: 64 | # - name: do-something 65 | # image: busybox 66 | # command: ['do', 'something'] 67 | # volumesMounts: 68 | # - name: nfs 69 | # mountPath: /mnt/volume 70 | # readOnly: true 71 | sidecarContainers: [] 72 | 73 | # extraVolumes: 74 | # - volumeMounts: 75 | # - name: nfs 76 | # mountPath: /mnt/volume 77 | # readOnly: true 78 | # volumes: 79 | # - name: nfs 80 | # server: some.nfs.server.com 81 | # path: / 82 | # mountOptions: 83 | # - port=2049 84 | # - hard 85 | # - vers=4 86 | extraVolumes: [] 87 | 88 | # Extra fields to set on the pod 89 | # 90 | # Fields set here will be added to the end of the Pod spec 91 | # Can include any fields from https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec 92 | # that are not already set by the chart. 93 | # 94 | # The value of the field will be interpretted as a template. 95 | extraPodSpec: {} 96 | # priorityClassName: 'my-priority-class' 97 | 98 | minecraftProxy: 99 | # This can be one of "BUNGEECORD", "WATERFALL", "VELOCITY", "CUSTOM" 100 | type: BUNGEECORD 101 | # If type is set to BUNGEECORD or WATERFALL, this value overrides the base Jenkins URL 102 | jenkinsBaseUrl: 103 | # The Jenkins job ID of the artifact to download and run 104 | jenkinsJobId: lastStableBuild 105 | # If set, the job ID is arbitrarily incremented to force upgrade the proxy jar 106 | jarRevision: 107 | # This value can be set to a fully qualified URL to download a custom proxy jar 108 | jarUrl: 109 | # If set, this value specifies a custom proxy jar located inside the container 110 | jarFile: 111 | # If type is set to WATERFALL, use a specific Waterfall release stream 112 | waterfallVersion: latest 113 | # If type is set to WATERFALL, use a specific build of Waterfall within the specified version 114 | waterfallBuildId: latest 115 | # If type is set to VELOCITY, download and run this version of Velocity 116 | velocityVersion: 1.1.0 117 | # Check accounts against Minecraft account service. 118 | onlineMode: true 119 | # A list of .jar URLs to download into the plugins folder. 120 | plugins: [] 121 | # If you adjust this, you may need to adjust resources.requests above to match. 122 | memory: 512M 123 | # General JVM options to be passed to the Minecraft server invocation 124 | jvmOpts: "" 125 | # Options like -X that need to proceed general JVM options 126 | jvmXXOpts: "" 127 | # DEPRECATED: use top-level rconServiceAnnotations instead 128 | serviceAnnotations: {} 129 | serviceType: ClusterIP 130 | ## Set the port used if the serviceType is NodePort 131 | # nodePort: 132 | loadBalancerIP: 133 | # loadBalancerSourceRanges: [] 134 | ## Set the externalTrafficPolicy in the Service to either Cluster or Local 135 | # externalTrafficPolicy: Cluster 136 | ## Set the ipFamilyPolicy in the service to SingleStack, PreferDualStack, RequireDualStack 137 | # ipFamilyPolicy: SingleStack 138 | externalIPs: 139 | # If set, this overrides the default config file path 140 | configFilePath: /server/config.yml 141 | # This can be set to the contents of your config file (only works with yaml currently) 142 | # config: | 143 | # player_limit: -1 144 | # ip_forward: false 145 | # permissions: 146 | # default: 147 | # - bungeecord.command.server 148 | # - bungeecord.command.list 149 | # admin: 150 | # - bungeecord.command.alert 151 | # - bungeecord.command.end 152 | # - bungeecord.command.ip 153 | # - bungeecord.command.reload 154 | # timeout: 30000 155 | # log_pings: true 156 | # log_commands: false 157 | # online_mode: true 158 | # servers: 159 | # lobby: 160 | # motd: '&1Just another BungeeCord - Forced Host' 161 | # address: localhost:25565 162 | # restricted: false 163 | # listeners: 164 | # - query_port: 25577 165 | # motd: '&1Another Bungee server' 166 | # priorities: 167 | # - lobby 168 | # bind_local_address: true 169 | # tab_list: GLOBAL_PING 170 | # query_enabled: false 171 | # host: 0.0.0.0:25577 172 | # forced_hosts: 173 | # pvp.md-5.net: pvp 174 | # max_players: 1 175 | # tab_size: 60 176 | # ping_passthrough: false 177 | # force_default_server: false 178 | # proxy_protocol: false 179 | # disabled_commands: 180 | # - disabledcommandhere 181 | # network_compression_threshold: 256 182 | # groups: 183 | # md_5: 184 | # - admin 185 | # connection_throttle: 4000 186 | # connection_throttle_limit: 3 187 | # stats: f2876aa6-74d2-468c-90ee-1377111f1c9f 188 | # forge_support: false 189 | # inject_commands: false 190 | 191 | # If running Velocity, you can provide a velocity.toml file like so: 192 | # configFilePath: /server/velocity.toml 193 | # config: |- 194 | # config-version = "2.7" 195 | # bind = "0.0.0.0:25577" 196 | # motd = "Hello from Helmified Velocity!" 197 | # show-max-players = 500 198 | # player-info-forwarding-mode = "modern" 199 | 200 | # Needed when you wish to pass a forwarding secret to Velocity 201 | # velocityForwardingSecret: "CHANGEME!" 202 | # velocityForwardingSecretFilePath: /server/forwarding.secret 203 | 204 | rcon: 205 | # If you enable this, make SURE to change your password below. 206 | enabled: false 207 | port: 25575 208 | password: "CHANGEME!" 209 | existingSecret: 210 | secretKey: rcon-password 211 | serviceType: LoadBalancer 212 | loadBalancerIP: 213 | # loadBalancerSourceRanges: [] 214 | ## Set the externalTrafficPolicy in the Service to either Cluster or Local 215 | # externalTrafficPolicy: Cluster 216 | ## Set the ipFamilyPolicy in the service to SingleStack, PreferDualStack, RequireDualStack 217 | # ipFamilyPolicy: SingleStack 218 | 219 | extraPorts: [] 220 | # These options allow you to expose another port from the Minecraft proxy, plugins such 221 | # as NuVotifier (8192) will require this for incoming webhooks 222 | # 223 | # - name: vote 224 | # containerPort: 8192 225 | # protocol: TCP 226 | # service: 227 | # enabled: false 228 | # embedded: false 229 | # annotations: {} 230 | # type: ClusterIP 231 | # ## Set the external port if the rcon serviceType is NodePort 232 | ## nodePort: 233 | # loadBalancerIP: "" 234 | # loadBalancerSourceRanges: [] 235 | # externalTrafficPolicy: Cluster 236 | # port: 8192 237 | # ingress: 238 | # ingressClassName: nginx 239 | # enabled: false 240 | # annotations: 241 | ## Deprecated way for specifying the ingressClass. Kube.version < 1.18 242 | ## kubernetes.io/ingress.class: nginx 243 | # kubernetes.io/tls-acme: "true" 244 | # hosts: 245 | # - name: vote.local 246 | # path: / 247 | # tls: 248 | # - secretName: vote-tls 249 | # hosts: 250 | # - vote.local 251 | 252 | ## Additional minecraft container environment variables 253 | ## Values can be either variable values or `valueFrom` yaml 254 | ## 255 | extraEnv: 256 | {} 257 | # some_variable: some value 258 | # another_variable: 259 | # valueFrom: 260 | # fieldRef: 261 | # fieldPath: status.hostIP 262 | 263 | persistence: 264 | ## minecraft data Persistent Volume Storage Class 265 | ## If defined, storageClassName: 266 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 267 | ## If undefined (the default) or set to null, no storageClassName spec is 268 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 269 | ## GKE, AWS & OpenStack) 270 | ## 271 | # storageClass: "-" 272 | dataDir: 273 | # Set this to false if you don't care to persist state between restarts. 274 | enabled: false 275 | # existingClaim: nil 276 | Size: 1Gi 277 | 278 | podAnnotations: {} 279 | 280 | deploymentAnnotations: {} 281 | 282 | serviceAnnotations: {} 283 | 284 | rconServiceAnnotations: {} 285 | 286 | # Can allow plugins access to the kubernetes api using a service account 287 | # https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ 288 | serviceAccountName: 289 | 290 | # dnsPolicy: ClusterFirst 291 | # dnsConfig: 292 | # options: 293 | # - name: ndots 294 | # value: '1' 295 | -------------------------------------------------------------------------------- /charts/minecraft/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | # OWNERS file for Kubernetes 23 | OWNERS 24 | -------------------------------------------------------------------------------- /charts/minecraft/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: minecraft 3 | version: 4.26.3 4 | appVersion: SeeValues 5 | home: https://minecraft.net/ 6 | description: Minecraft server 7 | keywords: 8 | - game 9 | - server 10 | sources: 11 | - https://github.com/itzg/minecraft-server-charts 12 | maintainers: 13 | - name: gtaylor 14 | email: gtaylor@gc-taylor.com 15 | - name: billimek 16 | email: jeff@billimek.com 17 | - name: itzg 18 | email: itzgeoff@gmail.com 19 | - name: bibz87 20 | email: yannik@carbongem.com 21 | annotations: 22 | artifacthub.io/links: | 23 | - name: Image source 24 | url: https://github.com/itzg/docker-minecraft-server 25 | - name: Image DockerHub 26 | url: https://hub.docker.com/r/itzg/minecraft-server 27 | -------------------------------------------------------------------------------- /charts/minecraft/OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - gtaylor 3 | - itzg 4 | - billimek 5 | - bibz87 6 | reviewers: 7 | - gtaylor 8 | - itzg 9 | - billimek 10 | - bibz87 11 | -------------------------------------------------------------------------------- /charts/minecraft/README.md: -------------------------------------------------------------------------------- 1 | # Minecraft 2 | 3 | [Minecraft](https://minecraft.net/en/) is a game about placing blocks and going on adventures. 4 | 5 | ## Introduction 6 | 7 | This chart creates a single Minecraft Pod, plus Services for the Minecraft server and RCON. 8 | 9 | ## Prerequisites 10 | 11 | - 512 MB of RAM 12 | - Kubernetes 1.4+ with Beta APIs enabled 13 | - PV provisioner support in the underlying infrastructure 14 | 15 | ## Installing the Chart 16 | 17 | To install the chart with the release name `minecraft`, read the [Minecraft EULA](https://account.mojang.com/documents/minecraft_eula) run: 18 | 19 | ```shell 20 | helm install minecraft \ 21 | --set minecraftServer.eula=true itzg/minecraft 22 | ``` 23 | 24 | This command deploys a Minecraft dedicated server with sensible defaults. 25 | 26 | > **Tip**: List all releases using `helm list` 27 | 28 | ## Uninstalling the Chart 29 | 30 | To uninstall/delete the `minecraft` deployment: 31 | 32 | ```shell 33 | helm delete minecraft 34 | ``` 35 | 36 | The command removes all the Kubernetes components associated with the chart and deletes the release. 37 | 38 | ## Configuration 39 | 40 | Refer to [values.yaml](values.yaml) for the full run-down on defaults. These are a mixture of Kubernetes and Minecraft-related directives that map to environment variables in the [itzg/minecraft-server](https://hub.docker.com/r/itzg/minecraft-server/) Docker image. 41 | 42 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, 43 | 44 | ```shell 45 | helm install --name minecraft \ 46 | --set minecraftServer.eula=true,minecraftServer.Difficulty=hard \ 47 | itzg/minecraft 48 | ``` 49 | 50 | Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, 51 | 52 | ```shell 53 | helm install --name minecraft -f values.yaml itzg/minecraft 54 | ``` 55 | 56 | > **Tip**: You can use the default [values.yaml](values.yaml) 57 | 58 | ## Persistence 59 | 60 | The [itzg/minecraft-server](https://hub.docker.com/r/itzg/minecraft-server/) image stores the saved games and mods under /data. 61 | 62 | When [persistence.dataDir.enabled in values.yaml](https://github.com/itzg/minecraft-server-charts/blob/master/charts/minecraft/values.yaml#L171) is set to true PersistentVolumeClaim is created and mounted for saves but not mods. In order to enable this functionality 63 | you can change the values.yaml to enable persistence under the sub-sections under `persistence`. 64 | 65 | > *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."* 66 | 67 | ## Backups 68 | 69 | You can backup the state of your minecraft server to your local machine via the `kubectl cp` command. 70 | 71 | ```shell 72 | NAMESPACE=default 73 | POD_ID=lionhope-387ff8d-sdis9 74 | kubectl exec --namespace ${NAMESPACE} ${POD_ID} rcon-cli save-off 75 | kubectl exec --namespace ${NAMESPACE} ${POD_ID} rcon-cli save-all 76 | kubectl cp ${NAMESPACE}/${POD_ID}:/data . 77 | kubectl exec --namespace ${NAMESPACE} ${POD_ID} rcon-cli save-on 78 | ``` 79 | 80 | ### Known issues 81 | 82 | `rclone` can attempt to update its configuration file when there is data to be 83 | modified, such as missing configuration entries or tokens. As this configuration 84 | file will most likely be stored in a ConfigMap or a Secret, it will be read-only 85 | and the container will generate errors like this one: 86 | 87 | ``` text 88 | rclone: 2023/11/22 21:41:18 ERROR : Failed to save config after 10 tries: failed to create temp file for new config: open /config/rclone/rclone.conf4086229703: read-only file system 89 | ``` 90 | 91 | In that case, double-check if there are missing entries in your `rclone` 92 | configuration as this might be the reason why `rclone` throws an error. This 93 | might not solve all cases, though. 94 | 95 | For more information, see this GitHub 96 | [issue](https://github.com/rclone/rclone/issues/3655) 97 | 98 | ## Tutorials 99 | 100 | For a quickstart guide to setting up a Kubernetes cluster and deploying 101 | Minecraft servers using this Helm Chart see: 102 | 103 | [gilesknap/k3s-minecraft](https://github.com/gilesknap/k3s-minecraft) 104 | 105 | -------------------------------------------------------------------------------- /charts/minecraft/ci/test-values.yaml: -------------------------------------------------------------------------------- 1 | # This must be overridden, since we can't accept this for the user. 2 | minecraftServer: 3 | eula: "TRUE" 4 | # fix in place and rebased 5 | -------------------------------------------------------------------------------- /charts/minecraft/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | {{- if eq (printf "%s" .Values.minecraftServer.eula) "FALSE" }} 2 | ############################################################################## 3 | #### ERROR: You did not agree to the EULA in your 'helm install' call. #### 4 | ############################################################################## 5 | 6 | This deployment will be incomplete until you read the Minecraft EULA linked 7 | in the README.md, then: 8 | 9 | helm upgrade {{ .Release.Name }} \ 10 | --set minecraftServer.eula=true itzg/minecraft 11 | {{- else -}} 12 | 13 | Get the IP address of your Minecraft server by running these commands in the 14 | same shell: 15 | 16 | {{- if contains "NodePort" .Values.minecraftServer.serviceType }} 17 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} \ 18 | -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "minecraft.fullname" . }}) 19 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} \ 20 | -o jsonpath="{.items[0].status.addresses[0].address}") 21 | echo "You'll need to expose this node through your security groups/firewall" 22 | echo "for it to be world-accessible." 23 | echo $NODE_IP:$NODE_PORT 24 | 25 | {{- else if contains "LoadBalancer" .Values.minecraftServer.serviceType }} 26 | 27 | !! NOTE: It may take a few minutes for the LoadBalancer IP to be available. !! 28 | 29 | You can watch for EXTERNAL-IP to populate by running: 30 | kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "minecraft.fullname" . }} 31 | 32 | {{- else if contains "ClusterIP" .Values.minecraftServer.serviceType }} 33 | export POD_NAME=$(kubectl get pods \ 34 | --namespace {{ .Release.Namespace }} \ 35 | -l "component={{ template "minecraft.fullname" . }}" \ 36 | -o jsonpath="{.items[0].metadata.name}") 37 | kubectl port-forward $POD_NAME 25565:{{ .Values.minecraftServer.servicePort | default 25565 }} 38 | echo "Point your Minecraft client at 127.0.0.1:25565" 39 | 40 | {{- end }} 41 | 42 | {{- if or .Values.persistence.dataDir.enabled .Values.persistence.altDataVolumeName }} 43 | {{- else }} 44 | 45 | ############################################################################ 46 | ### WARNING: Persistence is disabled!!! You will lose your game state ### 47 | ### when the Minecraft pod is terminated. ### 48 | ### See values.yaml's persistence.dataDir.enabled directive. ### 49 | ############################################################################ 50 | {{- end }} 51 | {{- end }} 52 | -------------------------------------------------------------------------------- /charts/minecraft/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "minecraft.name" -}} 6 | {{- $nameOverride := (and .Values (get .Values "nameOverride")) }} 7 | {{- default .Chart.Name $nameOverride | trunc 63 | trimSuffix "-" -}} 8 | {{- end -}} 9 | 10 | {{/* 11 | Set the chart fullname 12 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the labels spec). 13 | We change "+" with "_" for OCI compatibility 14 | */}} 15 | {{- define "chart.fullname" -}} 16 | {{- printf "%s-%s" .Chart.Name (.Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-") -}} 17 | {{- end }} 18 | 19 | {{/* 20 | Set the chart version 21 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the labels spec). 22 | We change "+" with "_" for OCI compatibility 23 | */}} 24 | {{- define "chart.version" -}} 25 | {{- default .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 26 | {{- end }} 27 | 28 | {{/* 29 | Create a default fully qualified app name. 30 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 31 | */}} 32 | {{- define "minecraft.fullname" -}} 33 | {{- if and .Values (hasKey .Values "fullnameOverride") .Values.fullnameOverride }} 34 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 35 | {{- else }} 36 | {{- $name := default .Chart.Name (and .Values (get .Values "nameOverride")) }} 37 | {{- if contains $name .Release.Name }} 38 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 39 | {{- else }} 40 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 41 | {{- end }} 42 | {{- end }} 43 | {{- end }} 44 | 45 | {{- define "minecraft.ingress.apiVersion" -}} 46 | {{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.Version -}} 47 | {{- print "extensions/v1beta1" -}} 48 | {{- else if semverCompare "<1.19-0" .Capabilities.KubeVersion.Version -}} 49 | {{- print "networking.k8s.io/v1beta1" -}} 50 | {{- else -}} 51 | {{- print "networking.k8s.io/v1" -}} 52 | {{- end }} 53 | {{- end -}} 54 | 55 | {{- define "minecraft.envMap" }} 56 | {{- if ne (toString (index . 1)) "default" }} 57 | {{- if or (index . 1) (kindIs "float64" (index . 1)) (kindIs "bool" (index . 1)) }} 58 | - name: {{ index . 0 }} 59 | value: {{ index . 1 | quote }} 60 | {{- end }} 61 | {{- end }} 62 | {{- end }} 63 | 64 | {{- define "tplRender" -}} 65 | {{- $value := typeIs "string" .value | ternary .value (.value | toYaml) }} 66 | {{- if contains "{{" (toJson .value) }} 67 | {{- if .scope }} 68 | {{- tpl (cat "{{- with $.RelativeScope -}}" $value "{{- end }}") (merge (dict "RelativeScope" .scope) .context) }} 69 | {{- else }} 70 | {{- tpl $value .context }} 71 | {{- end }} 72 | {{- else }} 73 | {{- $value }} 74 | {{- end }} 75 | {{- end -}} 76 | 77 | {{- define "isResticWithRclone" -}} 78 | {{- if .Values.mcbackup -}} 79 | {{- if and (eq .Values.mcbackup.backupMethod "restic") (hasPrefix "rclone" .Values.mcbackup.resticRepository) }} 80 | {{- printf "true" }} 81 | {{- else }} 82 | {{- printf "false" }} 83 | {{- end }} 84 | {{- end }} 85 | {{- end -}} 86 | -------------------------------------------------------------------------------- /charts/minecraft/templates/backupdir-pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.mcbackup.persistence.backupDir.enabled (not .Values.mcbackup.persistence.backupDir.existingClaim ) (not .Values.workloadAsStatefulSet) -}} 2 | kind: PersistentVolumeClaim 3 | apiVersion: v1 4 | metadata: 5 | name: {{ template "minecraft.fullname" . }}-backupdir 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: {{ template "minecraft.fullname" . }} 9 | chart: {{ template "chart.fullname" . }} 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | app.kubernetes.io/name: "{{ .Chart.Name }}" 13 | app.kubernetes.io/instance: {{ template "minecraft.fullname" . }} 14 | app.kubernetes.io/version: {{ template "chart.version" . }} 15 | annotations: 16 | {{- with .Values.mcbackup.persistence.annotations }} 17 | {{ toYaml . | nindent 4 }} 18 | {{- end }} 19 | {{- if .Values.mcbackup.persistence.storageClass }} 20 | volume.beta.kubernetes.io/storage-class: {{ .Values.mcbackup.persistence.storageClass | quote }} 21 | {{- else }} 22 | volume.alpha.kubernetes.io/storage-class: default 23 | {{- end }} 24 | spec: 25 | accessModes: 26 | {{ .Values.mcbackup.persistence.backupDir.accessModes | toYaml | nindent 4 }} 27 | resources: 28 | requests: 29 | storage: {{ .Values.mcbackup.persistence.backupDir.Size | quote }} 30 | {{- if .Values.mcbackup.persistence.storageClass }} 31 | {{- if (eq "-" .Values.mcbackup.persistence.storageClass) }} 32 | storageClassName: "" 33 | {{- else }} 34 | storageClassName: "{{ .Values.mcbackup.persistence.storageClass }}" 35 | {{- end }} 36 | {{- end }} 37 | {{- end -}} 38 | -------------------------------------------------------------------------------- /charts/minecraft/templates/datadir-pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.persistence.dataDir.enabled (not .Values.persistence.dataDir.existingClaim ) (not .Values.workloadAsStatefulSet) -}} 2 | kind: PersistentVolumeClaim 3 | apiVersion: v1 4 | metadata: 5 | name: {{ template "minecraft.fullname" . }}-datadir 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: {{ template "minecraft.fullname" . }} 9 | chart: {{ template "chart.fullname" . }} 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | app.kubernetes.io/name: "{{ .Chart.Name }}" 13 | app.kubernetes.io/instance: {{ template "minecraft.fullname" . }} 14 | app.kubernetes.io/version: {{ template "chart.version" . }} 15 | {{- with .Values.persistence.labels }} 16 | {{ toYaml . | nindent 4 }} 17 | {{- end }} 18 | annotations: 19 | {{- with .Values.persistence.annotations }} 20 | {{ toYaml . | nindent 4 }} 21 | {{- end }} 22 | {{- if .Values.persistence.storageClass }} 23 | volume.beta.kubernetes.io/storage-class: {{ .Values.persistence.storageClass | quote }} 24 | {{- else }} 25 | volume.alpha.kubernetes.io/storage-class: default 26 | {{- end }} 27 | spec: 28 | accessModes: 29 | {{ .Values.persistence.dataDir.accessModes | toYaml | nindent 4 }} 30 | resources: 31 | requests: 32 | storage: {{ .Values.persistence.dataDir.Size | quote }} 33 | {{- if .Values.persistence.storageClass }} 34 | {{- if (eq "-" .Values.persistence.storageClass) }} 35 | storageClassName: "" 36 | {{- else }} 37 | storageClassName: "{{ .Values.persistence.storageClass }}" 38 | {{- end }} 39 | {{- end }} 40 | {{- end -}} 41 | -------------------------------------------------------------------------------- /charts/minecraft/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if ne (printf "%s" .Values.minecraftServer.eula) "FALSE" }} 2 | apiVersion: apps/v1 3 | kind: {{ ternary "StatefulSet" "Deployment" .Values.workloadAsStatefulSet }} 4 | metadata: 5 | name: {{ template "minecraft.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | {{- if .Values.deploymentAnnotations }} 8 | annotations: 9 | {{- range $key, $value := .Values.deploymentAnnotations }} 10 | {{ $key }}: {{ $value | quote }} 11 | {{- end }} 12 | {{- end }} 13 | labels: 14 | app: {{ template "minecraft.fullname" . }} 15 | chart: {{ template "chart.fullname" . }} 16 | release: "{{ .Release.Name }}" 17 | heritage: "{{ .Release.Service }}" 18 | app.kubernetes.io/name: "{{ .Chart.Name }}" 19 | app.kubernetes.io/instance: {{ template "minecraft.fullname" . }} 20 | app.kubernetes.io/version: {{ template "chart.version" . }} 21 | {{- if .Values.deploymentLabels }} 22 | {{- range $key, $value := .Values.deploymentLabels}} 23 | {{ $key }}: {{ $value | quote }} 24 | {{- end }} 25 | {{- end }} 26 | spec: 27 | replicas: {{ .Values.replicaCount }} 28 | {{- if .Values.workloadAsStatefulSet }} 29 | serviceName: {{ template "minecraft.fullname" . }} 30 | updateStrategy: 31 | type: {{ .Values.strategyType }} 32 | {{- else }} 33 | strategy: 34 | type: {{ .Values.strategyType }} 35 | {{- end }} 36 | selector: 37 | matchLabels: 38 | app: {{ template "minecraft.fullname" . }} 39 | template: 40 | metadata: 41 | labels: 42 | app: {{ template "minecraft.fullname" . }} 43 | app.kubernetes.io/name: "{{ .Chart.Name }}" 44 | app.kubernetes.io/instance: {{ template "minecraft.fullname" . }} 45 | app.kubernetes.io/version: {{ template "chart.version" . }} 46 | {{- if .Values.podLabels }} 47 | {{- range $key, $value := .Values.podLabels}} 48 | {{ $key }}: {{ $value | quote }} 49 | {{- end }} 50 | {{- end }} 51 | {{- if .Values.podAnnotations }} 52 | annotations: 53 | {{- range $key, $value := .Values.podAnnotations }} 54 | {{ $key }}: {{ $value | quote }} 55 | {{- end }} 56 | {{- end }} 57 | spec: 58 | {{- if .Values.image.pullSecret }} 59 | imagePullSecrets: 60 | - name: {{ .Values.image.pullSecret }} 61 | {{- end }} 62 | {{- if .Values.dnsPolicy }} 63 | dnsPolicy: {{ .Values.dnsPolicy}} 64 | {{- end }} 65 | {{- if .Values.dnsConfig }} 66 | dnsConfig: 67 | {{- toYaml .Values.dnsConfig | nindent 8 }} 68 | {{- end }} 69 | securityContext: 70 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 71 | containers: 72 | - name: {{ template "minecraft.fullname" . }} 73 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 74 | imagePullPolicy: {{ .Values.image.pullPolicy }} 75 | tty: {{ default true .Values.minecraftServer.tty }} 76 | stdin: true 77 | {{- if or (.Values.lifecycle.postStart) (.Values.lifecycle.preStop)}} 78 | lifecycle: 79 | {{- if .Values.lifecycle.postStart }} 80 | postStart: 81 | exec: 82 | command: {{- range .Values.lifecycle.postStart }} 83 | - {{ . }} 84 | {{- end }} 85 | {{- end }} 86 | {{- if .Values.lifecycle.preStop }} 87 | preStop: 88 | exec: 89 | command: {{- range .Values.lifecycle.preStop }} 90 | - {{ . }} 91 | {{- end }} 92 | {{- end }} 93 | {{- end }} 94 | resources: 95 | {{ toYaml .Values.resources | indent 10 }} 96 | {{- if .Values.startupProbe.enabled }} 97 | startupProbe: 98 | exec: 99 | command: 100 | {{- toYaml .Values.startupProbe.command | nindent 12 }} 101 | failureThreshold: {{ .Values.startupProbe.failureThreshold }} 102 | periodSeconds: {{ .Values.startupProbe.periodSeconds }} 103 | {{- end }} 104 | readinessProbe: 105 | exec: 106 | command: 107 | {{- toYaml .Values.readinessProbe.command | nindent 12 }} 108 | initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} 109 | periodSeconds: {{ .Values.readinessProbe.periodSeconds }} 110 | failureThreshold: {{ .Values.readinessProbe.failureThreshold }} 111 | successThreshold: {{ .Values.readinessProbe.successThreshold }} 112 | timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} 113 | livenessProbe: 114 | exec: 115 | command: 116 | {{- toYaml .Values.livenessProbe.command | nindent 12 }} 117 | initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} 118 | periodSeconds: {{ .Values.livenessProbe.periodSeconds }} 119 | failureThreshold: {{ .Values.livenessProbe.failureThreshold }} 120 | successThreshold: {{ .Values.livenessProbe.successThreshold }} 121 | timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} 122 | {{- with .Values.envFrom }} 123 | envFrom: 124 | {{- . | toYaml | nindent 10 }}{{ end }} 125 | env: 126 | {{- template "minecraft.envMap" list "EULA" .Values.minecraftServer.eula }} 127 | {{- template "minecraft.envMap" list "TYPE" .Values.minecraftServer.type }} 128 | {{- if eq .Values.minecraftServer.type "FORGE" }} 129 | {{- if .Values.minecraftServer.forgeInstallerUrl }} 130 | {{- template "minecraft.envMap" list "FORGE_INSTALLER_URL" .Values.minecraftServer.forgeInstallerUrl }} 131 | {{- else }} 132 | {{- template "minecraft.envMap" list "FORGEVERSION" .Values.minecraftServer.forgeVersion }} 133 | {{- end }} 134 | {{- else if eq .Values.minecraftServer.type "SPIGOT" }} 135 | {{- template "minecraft.envMap" list "SPIGOT_DOWNLOAD_URL" .Values.minecraftServer.spigotDownloadUrl }} 136 | {{- else if eq .Values.minecraftServer.type "BUKKIT" }} 137 | {{- template "minecraft.envMap" list "BUKKIT_DOWNLOAD_URL" .Values.minecraftServer.bukkitDownloadUrl }} 138 | {{- else if eq .Values.minecraftServer.type "PAPER" }} 139 | {{- template "minecraft.envMap" list "PAPER_DOWNLOAD_URL" .Values.minecraftServer.paperDownloadUrl }} 140 | {{- else if eq .Values.minecraftServer.type "FTBA" }} 141 | {{- template "minecraft.envMap" list "FTB_MODPACK_ID" (required "You must supply a minecraftserver.ftbModpackVersionID with type=FTBA" .Values.minecraftServer.ftbModpackId) }} 142 | {{- if .Values.minecraftServer.ftbModpackVersionId }} 143 | {{- template "minecraft.envMap" list "FTB_MODPACK_VERSION_ID" .Values.minecraftServer.ftbModpackVersionId }} 144 | {{- end }} 145 | {{- else if eq .Values.minecraftServer.type "CURSEFORGE" }} 146 | {{- template "minecraft.envMap" list "CF_SERVER_MOD" .Values.minecraftServer.cfServerMod }} 147 | {{- template "minecraft.envMap" list "FTB_LEGACYJAVAFIXER" .Values.minecraftServer.ftbLegacyJavaFixer }} 148 | {{- else if eq .Values.minecraftServer.type "FABRIC" }} 149 | {{- template "minecraft.envMap" list "FABRIC_LAUNCHER_VERSION" .Values.minecraftServer.fabricLauncherVersion }} 150 | {{- template "minecraft.envMap" list "FABRIC_LOADER_VERSION" .Values.minecraftServer.fabricLoaderVersion }} 151 | {{- end }} 152 | {{- template "minecraft.envMap" list "VERSION" .Values.minecraftServer.version }} 153 | {{- template "minecraft.envMap" list "DIFFICULTY" .Values.minecraftServer.difficulty }} 154 | {{- template "minecraft.envMap" list "WHITELIST" .Values.minecraftServer.whitelist }} 155 | {{- template "minecraft.envMap" list "OPS" .Values.minecraftServer.ops }} 156 | {{- template "minecraft.envMap" list "ICON" .Values.minecraftServer.icon }} 157 | {{- template "minecraft.envMap" list "MAX_PLAYERS" .Values.minecraftServer.maxPlayers }} 158 | {{- template "minecraft.envMap" list "MAX_WORLD_SIZE" .Values.minecraftServer.maxWorldSize }} 159 | {{- template "minecraft.envMap" list "ALLOW_NETHER" .Values.minecraftServer.allowNether }} 160 | {{- template "minecraft.envMap" list "ANNOUNCE_PLAYER_ACHIEVEMENTS" .Values.minecraftServer.announcePlayerAchievements }} 161 | {{- template "minecraft.envMap" list "ENABLE_COMMAND_BLOCK" .Values.minecraftServer.enableCommandBlock }} 162 | {{- template "minecraft.envMap" list "FORCE_GAMEMODE" .Values.minecraftServer.forcegameMode }} 163 | {{- if .Values.minecraftServer.forceReDownload }} 164 | - name: FORCE_REDOWNLOAD 165 | value: "TRUE" 166 | {{- end }} 167 | {{- template "minecraft.envMap" list "GENERATE_STRUCTURES" .Values.minecraftServer.generateStructures }} 168 | {{- template "minecraft.envMap" list "HARDCORE" .Values.minecraftServer.hardcore }} 169 | {{- template "minecraft.envMap" list "MAX_BUILD_HEIGHT" .Values.minecraftServer.maxBuildHeight }} 170 | {{- template "minecraft.envMap" list "MAX_TICK_TIME" .Values.minecraftServer.maxTickTime }} 171 | {{- template "minecraft.envMap" list "SPAWN_ANIMALS" .Values.minecraftServer.spawnAnimals }} 172 | {{- template "minecraft.envMap" list "SPAWN_MONSTERS" .Values.minecraftServer.spawnMonsters }} 173 | {{- template "minecraft.envMap" list "SPAWN_NPCS" .Values.minecraftServer.spawnNPCs }} 174 | {{- template "minecraft.envMap" list "SPAWN_PROTECTION" .Values.minecraftServer.spawnProtection }} 175 | {{- template "minecraft.envMap" list "VIEW_DISTANCE" .Values.minecraftServer.viewDistance }} 176 | {{- template "minecraft.envMap" list "SEED" .Values.minecraftServer.levelSeed }} 177 | {{- template "minecraft.envMap" list "MODE" .Values.minecraftServer.gameMode }} 178 | {{- template "minecraft.envMap" list "MOTD" .Values.minecraftServer.motd }} 179 | {{- template "minecraft.envMap" list "PVP" .Values.minecraftServer.pvp }} 180 | {{- template "minecraft.envMap" list "LEVEL_TYPE" .Values.minecraftServer.levelType }} 181 | {{- template "minecraft.envMap" list "GENERATOR_SETTINGS" .Values.minecraftServer.generatorSettings }} 182 | {{- template "minecraft.envMap" list "LEVEL" .Values.minecraftServer.worldSaveName }} 183 | {{- if .Values.minecraftServer.downloadWorldUrl }} 184 | {{- template "minecraft.envMap" list "WORLD" .Values.minecraftServer.downloadWorldUrl }} 185 | {{- end }} 186 | {{- if .Values.minecraftServer.downloadModpackUrl }} 187 | {{- template "minecraft.envMap" list "MODPACK" .Values.minecraftServer.downloadModpackUrl }} 188 | {{- end }} 189 | {{- if .Values.minecraftServer.removeOldMods }} 190 | {{- template "minecraft.envMap" list "REMOVE_OLD_MODS" "true" }} 191 | {{- end }} 192 | {{- if .Values.minecraftServer.modUrls }} 193 | {{- template "minecraft.envMap" list "MODS" (join "," .Values.minecraftServer.modUrls) }} 194 | {{- end }} 195 | {{- if .Values.minecraftServer.pluginUrls }} 196 | {{- template "minecraft.envMap" list "PLUGINS" (join "," .Values.minecraftServer.pluginUrls) }} 197 | {{- end }} 198 | {{- if .Values.minecraftServer.spigetResources }} 199 | {{- template "minecraft.envMap" list "SPIGET_RESOURCES" (join "," .Values.minecraftServer.spigetResources) }} 200 | {{- end }} 201 | 202 | {{- if .Values.minecraftServer.modrinth }} 203 | {{- with .Values.minecraftServer.modrinth }} 204 | {{- if .projects }} 205 | {{- template "minecraft.envMap" list "MODRINTH_PROJECTS" (join "," .projects) }} 206 | {{- end }} 207 | {{- if .downloadDependencies }} 208 | {{- template "minecraft.envMap" list "MODRINTH_DOWNLOAD_DEPENDENCIES" .downloadDependencies }} 209 | {{- end }} 210 | {{- template "minecraft.envMap" list "MODRINTH_ALLOWED_VERSION_TYPE" .allowedVersionType }} 211 | {{- end }} 212 | {{- end }} 213 | 214 | {{- if .Values.minecraftServer.vanillaTweaksShareCodes }} 215 | {{- template "minecraft.envMap" list "VANILLATWEAKS_SHARECODE" (join "," .Values.minecraftServer.vanillaTweaksShareCodes) }} 216 | {{- end }} 217 | {{- if .Values.minecraftServer.resourcePackUrl }} 218 | {{- template "minecraft.envMap" list "RESOURCE_PACK" .Values.minecraftServer.resourcePackUrl }} 219 | {{- end }} 220 | {{- if .Values.minecraftServer.resourcePackSha }} 221 | {{- template "minecraft.envMap" list "RESOURCE_PACK_SHA1" .Values.minecraftServer.resourcePackSha }} 222 | {{- end }} 223 | {{- if .Values.minecraftServer.resourcePackEnforce }} 224 | - name: RESOURCE_PACK_ENFORCE 225 | value: "TRUE" 226 | {{- end }} 227 | {{- template "minecraft.envMap" list "ONLINE_MODE" .Values.minecraftServer.onlineMode }} 228 | {{- template "minecraft.envMap" list "ENFORCE_SECURE_PROFILE" .Values.minecraftServer.enforceSecureProfile }} 229 | {{- template "minecraft.envMap" list "MEMORY" .Values.minecraftServer.memory }} 230 | {{- template "minecraft.envMap" list "JVM_OPTS" .Values.minecraftServer.jvmOpts }} 231 | {{- template "minecraft.envMap" list "JVM_XX_OPTS" .Values.minecraftServer.jvmXXOpts }} 232 | {{- template "minecraft.envMap" list "OVERRIDE_SERVER_PROPERTIES" .Values.minecraftServer.overrideServerProperties }} 233 | 234 | {{- if .Values.minecraftServer.rcon.enabled }} 235 | - name: ENABLE_RCON 236 | value: "true" 237 | {{- if not .Values.minecraftServer.rcon.withGeneratedPassword }} 238 | - name: RCON_PASSWORD 239 | valueFrom: 240 | secretKeyRef: 241 | name: {{ .Values.minecraftServer.rcon.existingSecret | default (printf "%s-rcon" (include "minecraft.fullname" .)) }} 242 | key: {{ .Values.minecraftServer.rcon.secretKey | default "rcon-password" }} 243 | {{- end }} 244 | {{- else }} 245 | - name: ENABLE_RCON 246 | value: "false" 247 | {{- end }} 248 | {{- if .Values.minecraftServer.query.enabled }} 249 | - name: ENABLE_QUERY 250 | value: "true" 251 | {{- template "minecraft.envMap" list "QUERY_PORT" .Values.minecraftServer.query.port }} 252 | {{- end }} 253 | 254 | {{- if .Values.minecraftServer.autoCurseForge }} 255 | {{- with .Values.minecraftServer.autoCurseForge }} 256 | - name: CF_API_KEY 257 | valueFrom: 258 | secretKeyRef: 259 | name: {{ .apiKey.existingSecret | default (printf "%s-curseforge" (include "minecraft.fullname" $)) }} 260 | key: {{ .apiKey.secretKey | default "cf-api-key" }} 261 | {{- template "minecraft.envMap" list "CF_PAGE_URL" .pageUrl }} 262 | {{- template "minecraft.envMap" list "CF_SLUG" .slug }} 263 | {{- template "minecraft.envMap" list "CF_FILE_ID" .fileId }} 264 | {{- template "minecraft.envMap" list "CF_FILENAME_MATCHER" .filenameMatcher }} 265 | {{- if .excludeMods }} 266 | {{- template "minecraft.envMap" list "CF_EXCLUDE_MODS" (join "," .excludeMods) }} 267 | {{- end }} 268 | {{- if .includeMods }} 269 | {{- template "minecraft.envMap" list "CF_FORCE_INCLUDE_MODS" (join "," .includeMods) }} 270 | {{- end }} 271 | {{- if not (eq nil .excludeIncludeFile) }} 272 | {{- template "minecraft.envMap" list "CF_EXCLUDE_INCLUDE_FILE" .excludeIncludeFile }} 273 | {{- end }} 274 | {{- if .forceSynchronize }} 275 | {{- template "minecraft.envMap" list "CF_FORCE_SYNCHRONIZE" "true" }} 276 | {{- end }} 277 | {{- template "minecraft.envMap" list "CF_SET_LEVEL_FROM" .setLevelFrom }} 278 | {{- template "minecraft.envMap" list "CF_PARALLEL_DOWNLOADS" .parallelDownloads }} 279 | {{- if .overridesSkipExisting }} 280 | {{- template "minecraft.envMap" list "CF_OVERRIDES_SKIP_EXISTING" "true" }} 281 | {{- end }} 282 | {{- end }} 283 | {{- end }} 284 | 285 | 286 | {{- range $key, $value := .Values.extraEnv }} 287 | {{- if kindIs "map" $value }} 288 | {{- if hasKey $value "valueFrom" }} 289 | - name: {{ $key }} 290 | valueFrom: 291 | {{- $value.valueFrom | toYaml | nindent 12 }} 292 | {{- end }} 293 | {{- else }} 294 | - name: {{ $key }} 295 | value: {{ $value | quote }} 296 | {{- end }} 297 | {{- end }} 298 | 299 | ports: 300 | - name: minecraft 301 | containerPort: 25565 302 | protocol: TCP 303 | {{- if .Values.minecraftServer.rcon.enabled }} 304 | - name: rcon 305 | containerPort: {{ .Values.minecraftServer.rcon.port }} 306 | protocol: TCP 307 | {{- end }} 308 | {{- range .Values.minecraftServer.extraPorts }} 309 | {{- if .service.enabled }} 310 | - name: {{ .name }} 311 | containerPort: {{ .containerPort }} 312 | {{- if .protocol }} 313 | protocol: {{ .protocol }} 314 | {{- else }} 315 | protocol: TCP 316 | {{- end }} 317 | {{- end }} 318 | {{- end }} 319 | volumeMounts: 320 | - name: tmp 321 | mountPath: /tmp 322 | {{- if .Values.persistence.altDataVolumeName }} 323 | - name: {{ .Values.persistence.altDataVolumeName }} 324 | mountPath: /data 325 | {{- else }} 326 | - name: datadir 327 | mountPath: /data 328 | {{- if (and .Values.persistence.dataDir.enabled .Values.persistence.dataDir.subPath) }} 329 | subPath: {{ .Values.persistence.dataDir.subPath }} 330 | {{- end }} 331 | {{- end }} 332 | - name: backupdir 333 | mountPath: {{ default "/backups" .Values.mcbackup.destDir }} 334 | readOnly: true 335 | {{- range .Values.extraVolumes }} 336 | {{- if .volumeMounts }} 337 | {{- toYaml .volumeMounts | nindent 8 }} 338 | {{- end }} 339 | {{- end }} 340 | securityContext: 341 | {{- toYaml .Values.securityContext | nindent 10 }} 342 | {{- if and .Values.mcbackup.enabled .Values.minecraftServer.rcon.enabled }} 343 | - name: {{ template "minecraft.fullname" . }}-mc-backup 344 | image: "{{ .Values.mcbackup.image.repository }}:{{ .Values.mcbackup.image.tag }}" 345 | imagePullPolicy: {{ .Values.mcbackup.image.pullPolicy }} 346 | resources: 347 | {{ toYaml .Values.mcbackup.resources | indent 10 }} 348 | {{- with .Values.mcbackup.envFrom }} 349 | envFrom: 350 | {{- . | toYaml | nindent 10 }}{{ end }} 351 | env: 352 | - name: SRC_DIR 353 | value: "/data" 354 | {{- template "minecraft.envMap" list "BACKUP_NAME" .Values.minecraftServer.worldSaveName }} 355 | {{- template "minecraft.envMap" list "INITIAL_DELAY" .Values.mcbackup.initialDelay }} 356 | {{- template "minecraft.envMap" list "BACKUP_INTERVAL" .Values.mcbackup.backupInterval }} 357 | {{- template "minecraft.envMap" list "PRUNE_BACKUPS_DAYS" .Values.mcbackup.pruneBackupsDays }} 358 | {{- template "minecraft.envMap" list "PAUSE_IF_NO_PLAYERS" .Values.mcbackup.pauseIfNoPlayers }} 359 | - name: SERVER_PORT 360 | value: "25565" 361 | - name: RCON_HOST 362 | value: "localhost" 363 | {{- template "minecraft.envMap" list "RCON_PORT" .Values.minecraftServer.rcon.port }} 364 | - name: RCON_PASSWORD 365 | valueFrom: 366 | secretKeyRef: 367 | name: {{ .Values.minecraftServer.rcon.existingSecret | default (printf "%s-rcon" (include "minecraft.fullname" .)) }} 368 | key: {{ .Values.minecraftServer.rcon.secretKey | default "rcon-password" }} 369 | {{- template "minecraft.envMap" list "RCON_RETRIES" .Values.mcbackup.rconRetries }} 370 | {{- template "minecraft.envMap" list "RCON_RETRY_INTERVAL" .Values.mcbackup.rconRetryInterval }} 371 | {{- template "minecraft.envMap" list "EXCLUDES" .Values.mcbackup.excludes }} 372 | {{- template "minecraft.envMap" list "BACKUP_METHOD" .Values.mcbackup.backupMethod }} 373 | {{- if or (eq .Values.mcbackup.backupMethod "tar") (eq .Values.mcbackup.backupMethod "rclone") (eq .Values.mcbackup.backupMethod "rsync") }} 374 | {{- template "minecraft.envMap" list "DEST_DIR" .Values.mcbackup.destDir }} 375 | {{- template "minecraft.envMap" list "LINK_LATEST" .Values.mcbackup.linkLatest }} 376 | {{- if ne .Values.mcbackup.backupMethod "rsync" }} 377 | {{- template "minecraft.envMap" list "TAR_COMPRESS_METHOD" .Values.mcbackup.compressMethod }} 378 | {{- template "minecraft.envMap" list "ZSTD_PARAMETERS" .Values.mcbackup.zstdParameters }} 379 | {{- end }} 380 | {{- if eq .Values.mcbackup.backupMethod "rclone" }} 381 | {{- template "minecraft.envMap" list "RCLONE_REMOTE" .Values.mcbackup.rcloneRemote }} 382 | {{- template "minecraft.envMap" list "RCLONE_DEST_DIR" .Values.mcbackup.rcloneDestDir }} 383 | {{- template "minecraft.envMap" list "RCLONE_COMPRESS_METHOD" .Values.mcbackup.rcloneCompressMethod }} 384 | {{- end }} 385 | {{- end }} 386 | {{- if eq .Values.mcbackup.backupMethod "restic" }} 387 | {{- template "minecraft.envMap" list "RESTIC_REPOSITORY" .Values.mcbackup.resticRepository }} 388 | {{- template "minecraft.envMap" list "RESTIC_ADDITIONAL_TAGS" .Values.mcbackup.resticAdditionalTags }} 389 | {{- template "minecraft.envMap" list "PRUNE_RESTIC_RETENTION" .Values.mcbackup.pruneResticRetention }} 390 | {{- range $key, $value := .Values.mcbackup.resticEnvs }} 391 | {{- if kindIs "map" $value }} 392 | {{- if hasKey $value "valueFrom" }} 393 | - name: {{ $key }} 394 | valueFrom: 395 | {{- $value.valueFrom | toYaml | nindent 12 }} 396 | {{- end }} 397 | {{- else }} 398 | - name: {{ $key }} 399 | value: {{ $value | quote }} 400 | {{- end }} 401 | {{- end }} 402 | {{- end }} 403 | 404 | {{- range $key, $value := .Values.mcbackup.extraEnv }} 405 | {{- if kindIs "map" $value }} 406 | {{- if hasKey $value "valueFrom" }} 407 | - name: {{ $key }} 408 | valueFrom: 409 | {{- $value.valueFrom | toYaml | nindent 12 }} 410 | {{- end }} 411 | {{- else }} 412 | - name: {{ $key }} 413 | value: {{ $value | quote }} 414 | {{- end }} 415 | {{- end }} 416 | volumeMounts: 417 | - name: tmp 418 | mountPath: /tmp 419 | {{- if .Values.persistence.altDataVolumeName }} 420 | - name: {{ .Values.persistence.altDataVolumeName }} 421 | mountPath: /data 422 | {{- else }} 423 | - name: datadir 424 | mountPath: /data 425 | readOnly: true 426 | {{- end }} 427 | - name: backupdir 428 | mountPath: {{ default "/backups" .Values.mcbackup.destDir }} 429 | {{- if or (eq .Values.mcbackup.backupMethod "rclone") (eq (include "isResticWithRclone" $) "true") }} 430 | - name: rclone-config 431 | mountPath: /config/rclone 432 | {{- end }} 433 | {{- range .Values.extraVolumes }} 434 | {{- if .volumeMounts }} 435 | {{- toYaml .volumeMounts | nindent 8 }} 436 | {{- end }} 437 | {{- end }} 438 | securityContext: 439 | {{- toYaml .Values.securityContext | nindent 10 }} 440 | {{- end }} 441 | {{- range .Values.sidecarContainers }} 442 | - {{ include "tplRender" (dict "value" . "context" $) | nindent 8 | trim }} 443 | {{- end }} 444 | {{- if or .Values.initContainers (eq .Values.mcbackup.backupMethod "rclone") (eq (include "isResticWithRclone" $) "true") }} 445 | initContainers: 446 | {{- if or (eq .Values.mcbackup.backupMethod "rclone") (eq (include "isResticWithRclone" $) "true") }} 447 | - name: init-container 448 | image: busybox 449 | command: ['sh', '-c', 'cp /secret/rclone.conf /config/rclone/'] 450 | volumeMounts: 451 | - name: rclone-secret 452 | mountPath: /secret 453 | - name: rclone-config 454 | mountPath: /config/rclone 455 | {{- end }} 456 | {{- range .Values.initContainers }} 457 | - {{ include "tplRender" (dict "value" . "context" $) | nindent 10 | trim }} 458 | {{- end }} 459 | {{- end }} 460 | volumes: 461 | - name: tmp 462 | emptyDir: {} 463 | {{- if .Values.persistence.dataDir.enabled }} 464 | {{- if .Values.persistence.dataDir.existingClaim }} 465 | - name: datadir 466 | persistentVolumeClaim: 467 | claimName: {{ .Values.persistence.dataDir.existingClaim }} 468 | {{- else if (not .Values.workloadAsStatefulSet) }} 469 | - name: datadir 470 | persistentVolumeClaim: 471 | claimName: {{ template "minecraft.fullname" . }}-datadir 472 | {{- end -}} 473 | {{/* if persistence enabled in stateful set without existing claim, a volume claim template will be defined */}} 474 | {{- else }} 475 | - name: datadir 476 | emptyDir: {} 477 | {{- end }} 478 | {{- if and .Values.mcbackup.persistence.backupDir.enabled .Values.mcbackup.enabled }} 479 | {{- if .Values.mcbackup.persistence.backupDir.existingClaim }} 480 | - name: backupdir 481 | persistentVolumeClaim: 482 | claimName: {{ .Values.mcbackup.persistence.backupDir.existingClaim }} 483 | {{- else if (not .Values.workloadAsStatefulSet) }} 484 | - name: backupdir 485 | persistentVolumeClaim: 486 | claimName: {{ template "minecraft.fullname" . }}-backupdir 487 | {{- end -}} 488 | {{/* if persistence enabled in stateful set without existing claim, a volume claim template will be defined */}} 489 | {{- else }} 490 | - name: backupdir 491 | emptyDir: {} 492 | {{- end }} 493 | {{- if or (eq .Values.mcbackup.backupMethod "rclone") (eq (include "isResticWithRclone" $) "true") }} 494 | - name: rclone-secret 495 | secret: 496 | {{- if .Values.mcbackup.rcloneConfigExistingSecret }} 497 | secretName: {{ .Values.mcbackup.rcloneConfigExistingSecret }} 498 | {{- else }} 499 | secretName: {{ template "minecraft.fullname" . }}-rclone-config 500 | {{- end }} 501 | items: 502 | - key: rclone.conf 503 | path: rclone.conf 504 | - name: rclone-config 505 | emptyDir: {} 506 | {{- end }} 507 | {{- range .Values.extraVolumes }} 508 | {{- if .volumes }} 509 | {{- toYaml .volumes | nindent 6 }} 510 | {{- end }} 511 | {{- end }} 512 | {{- range $key, $value := .Values.extraPodSpec }} 513 | {{ $key }}: {{ tpl $value $ }} 514 | {{- end }} 515 | {{- if .Values.nodeSelector }} 516 | nodeSelector: 517 | {{ toYaml .Values.nodeSelector | indent 8 }} 518 | {{- end }} 519 | {{- if .Values.affinity }} 520 | affinity: 521 | {{ toYaml .Values.affinity | indent 8 }} 522 | {{- end }} 523 | {{- if .Values.tolerations }} 524 | tolerations: 525 | {{ toYaml .Values.tolerations | indent 8 }} 526 | {{- end }} 527 | {{- if .Values.workloadAsStatefulSet }} 528 | volumeClaimTemplates: 529 | {{- if and .Values.persistence.dataDir.enabled (not .Values.persistence.dataDir.existingClaim) }} 530 | - metadata: 531 | name: datadir 532 | labels: 533 | app: {{ template "minecraft.fullname" . }} 534 | chart: {{ template "chart.fullname" . }} 535 | release: "{{ .Release.Name }}" 536 | heritage: "{{ .Release.Service }}" 537 | app.kubernetes.io/name: "{{ .Chart.Name }}" 538 | app.kubernetes.io/instance: {{ template "minecraft.fullname" . }} 539 | app.kubernetes.io/version: {{ template "chart.version" . }} 540 | annotations: 541 | {{- with .Values.persistence.annotations }} 542 | {{ toYaml . | nindent 10 }} 543 | {{- end }} 544 | {{- if .Values.persistence.storageClass }} 545 | volume.beta.kubernetes.io/storage-class: {{ .Values.persistence.storageClass | quote }} 546 | {{- else }} 547 | volume.alpha.kubernetes.io/storage-class: default 548 | {{- end }} 549 | spec: 550 | accessModes: 551 | - ReadWriteOnce 552 | resources: 553 | requests: 554 | storage: {{ .Values.persistence.dataDir.Size | quote }} 555 | {{- if .Values.persistence.storageClass }} 556 | {{- if (eq "-" .Values.persistence.storageClass) }} 557 | storageClassName: "" 558 | {{- else }} 559 | storageClassName: "{{ .Values.persistence.storageClass }}" 560 | {{- end }} 561 | {{- end }} 562 | {{- end }} 563 | {{- if and .Values.mcbackup.persistence.backupDir.enabled (not .Values.mcbackup.persistence.backupDir.existingClaim) }} 564 | - metadata: 565 | name: backupdir 566 | labels: 567 | app: {{ template "minecraft.fullname" . }} 568 | chart: {{ template "chart.fullname" . }} 569 | release: "{{ .Release.Name }}" 570 | heritage: "{{ .Release.Service }}" 571 | app.kubernetes.io/name: "{{ .Chart.Name }}" 572 | app.kubernetes.io/instance: {{ template "minecraft.fullname" . }} 573 | app.kubernetes.io/version: {{ template "chart.version" . }} 574 | annotations: 575 | {{- with .Values.mcbackup.persistence.annotations }} 576 | {{ toYaml . | nindent 10 }} 577 | {{- end }} 578 | {{- if .Values.mcbackup.persistence.storageClass }} 579 | volume.beta.kubernetes.io/storage-class: {{ .Values.mcbackup.persistence.storageClass | quote }} 580 | {{- else }} 581 | volume.alpha.kubernetes.io/storage-class: default 582 | {{- end }} 583 | spec: 584 | accessModes: 585 | - ReadWriteOnce 586 | resources: 587 | requests: 588 | storage: {{ .Values.mcbackup.persistence.backupDir.Size | quote }} 589 | {{- if .Values.mcbackup.persistence.storageClass }} 590 | {{- if (eq "-" .Values.mcbackup.persistence.storageClass) }} 591 | storageClassName: "" 592 | {{- else }} 593 | storageClassName: "{{ .Values.mcbackup.persistence.storageClass }}" 594 | {{- end }} 595 | {{- end }} 596 | {{- end }} 597 | {{- end }} 598 | {{ end }} 599 | -------------------------------------------------------------------------------- /charts/minecraft/templates/extra-list.yaml: -------------------------------------------------------------------------------- 1 | {{- range .Values.extraDeploy }} 2 | --- 3 | {{ include "tplRender" (dict "value" . "context" $) }} 4 | {{- end }} 5 | -------------------------------------------------------------------------------- /charts/minecraft/templates/extraports-ing.yaml: -------------------------------------------------------------------------------- 1 | {{- $minecraftFullname := include "minecraft.fullname" . }} 2 | {{- range .Values.minecraftServer.extraPorts }} 3 | {{- if default "" (.ingress).enabled }} 4 | {{- $servicePort := .service.port }} 5 | {{- $serviceName := printf "%s-%s" $minecraftFullname .name }} 6 | --- 7 | apiVersion: {{ include "minecraft.ingress.apiVersion" $ }} 8 | kind: Ingress 9 | metadata: 10 | name: {{ $serviceName }} 11 | namespace: "{{ $.Release.Namespace }}" 12 | {{- if .ingress.annotations }} 13 | annotations: {{- toYaml .ingress.annotations | nindent 4 }} 14 | {{- end }} 15 | labels: 16 | app: {{ $serviceName }} 17 | chart: {{ template "chart.fullname" $ }} 18 | release: "{{ $.Release.Name }}" 19 | heritage: "{{ $.Release.Service }}" 20 | app.kubernetes.io/name: "{{ $.Chart.Name }}" 21 | app.kubernetes.io/instance: {{ $minecraftFullname }} 22 | app.kubernetes.io/version: {{ template "chart.version" $ }} 23 | spec: 24 | {{- if .ingress.ingressClassName }} 25 | ingressClassName: {{ .ingress.ingressClassName }} 26 | {{- end }} 27 | {{- if .ingress.tls }} 28 | tls: 29 | {{- range .ingress.tls }} 30 | - hosts: 31 | {{- range .hosts }} 32 | - {{ . | quote }} 33 | {{- end }} 34 | secretName: {{ .secretName }} 35 | {{- end }} 36 | {{- end }} 37 | rules: 38 | {{- range .ingress.hosts }} 39 | - host: {{ .name }} 40 | http: 41 | paths: 42 | - path: {{ .path | default "/" }} 43 | {{- if eq (include "minecraft.ingress.apiVersion" $) "networking.k8s.io/v1" }} 44 | pathType: Prefix 45 | {{- end }} 46 | backend: 47 | {{- if eq (include "minecraft.ingress.apiVersion" $) "networking.k8s.io/v1" }} 48 | service: 49 | name: {{ $serviceName }} 50 | port: 51 | number: {{ $servicePort }} 52 | {{- else }} 53 | serviceName: {{ $serviceName }} 54 | servicePort: {{ $servicePort }} 55 | {{- end }} 56 | {{- end }} 57 | {{- end }} 58 | {{- end }} 59 | -------------------------------------------------------------------------------- /charts/minecraft/templates/extraports-svc.yaml: -------------------------------------------------------------------------------- 1 | {{- $minecraftFullname := include "minecraft.fullname" . }} 2 | {{- range .Values.minecraftServer.extraPorts }} 3 | {{- if and .service.enabled (not .service.embedded) }} 4 | {{- $serviceName := printf "%s-%s" $minecraftFullname .name }} 5 | --- 6 | apiVersion: v1 7 | kind: Service 8 | metadata: 9 | name: {{ $serviceName }} 10 | namespace: "{{ $.Release.Namespace }}" 11 | annotations: {{ toYaml .service.annotations | nindent 4 }} 12 | labels: 13 | app: {{ $serviceName }} 14 | chart: {{ template "chart.fullname" $ }} 15 | release: "{{ $.Release.Name }}" 16 | heritage: "{{ $.Release.Service }}" 17 | app.kubernetes.io/name: "{{ $.Chart.Name }}" 18 | app.kubernetes.io/instance: {{ $minecraftFullname }} 19 | app.kubernetes.io/version: {{ template "chart.version" $ }} 20 | spec: 21 | {{- if (or (eq .service.type "ClusterIP") (empty .service.type)) }} 22 | type: ClusterIP 23 | {{- else if eq .service.type "LoadBalancer" }} 24 | type: {{ .service.type }} 25 | {{- if .service.loadBalancerIP }} 26 | loadBalancerIP: {{ .service.loadBalancerIP }} 27 | {{- end }} 28 | {{- if .service.loadBalancerSourceRanges }} 29 | loadBalancerSourceRanges: 30 | {{ toYaml .service.loadBalancerSourceRanges | indent 4 }} 31 | {{- end -}} 32 | {{- else }} 33 | type: {{ .service.type }} 34 | {{- end }} 35 | {{- if .service.externalTrafficPolicy }} 36 | externalTrafficPolicy: {{ .service.externalTrafficPolicy }} 37 | {{- end }} 38 | ports: 39 | - name: {{ .name }} 40 | port: {{ .service.port }} 41 | targetPort: {{ .name }} 42 | {{- if .service.nodePort }} 43 | nodePort: {{ .service.nodePort }} 44 | {{- end }} 45 | {{- if .protocol }} 46 | protocol: {{ .protocol }} 47 | {{- else }} 48 | protocol: TCP 49 | {{- end }} 50 | selector: 51 | app: {{ $minecraftFullname }} 52 | {{- end }} 53 | {{- end }} 54 | -------------------------------------------------------------------------------- /charts/minecraft/templates/minecraft-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "minecraft.fullname" . }} 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | app: {{ template "minecraft.fullname" . }} 8 | chart: {{ template "chart.fullname" . }} 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | app.kubernetes.io/name: "{{ .Chart.Name }}" 12 | app.kubernetes.io/instance: {{ template "minecraft.fullname" . }} 13 | app.kubernetes.io/version: {{ template "chart.version" . }} 14 | {{- if .Values.serviceLabels }} 15 | {{- range $key, $value := .Values.serviceLabels}} 16 | {{ $key }}: {{ $value | quote }} 17 | {{- end }} 18 | {{- end }} 19 | annotations: 20 | {{ toYaml .Values.serviceAnnotations | indent 4 }} 21 | spec: 22 | {{- if (or (eq .Values.minecraftServer.serviceType "ClusterIP") (empty .Values.minecraftServer.serviceType)) }} 23 | type: ClusterIP 24 | {{- else if eq .Values.minecraftServer.serviceType "LoadBalancer" }} 25 | type: {{ .Values.minecraftServer.serviceType }} 26 | {{- if .Values.minecraftServer.loadBalancerIP }} 27 | loadBalancerIP: {{ .Values.minecraftServer.loadBalancerIP }} 28 | {{- end }} 29 | {{- if .Values.minecraftServer.loadBalancerClass }} 30 | loadBalancerClass: {{ .Values.minecraftServer.loadBalancerClass }} 31 | {{- end }} 32 | {{- if .Values.minecraftServer.loadBalancerSourceRanges }} 33 | loadBalancerSourceRanges: 34 | {{ toYaml .Values.minecraftServer.loadBalancerSourceRanges | indent 4 }} 35 | {{- end -}} 36 | {{- else }} 37 | type: {{ .Values.minecraftServer.serviceType }} 38 | {{- end }} 39 | {{- if .Values.minecraftServer.clusterIP }} 40 | clusterIP: {{ .Values.minecraftServer.clusterIP }} 41 | {{- end }} 42 | {{- if .Values.minecraftServer.externalTrafficPolicy }} 43 | externalTrafficPolicy: {{ .Values.minecraftServer.externalTrafficPolicy }} 44 | {{- end }} 45 | ports: 46 | - name: minecraft 47 | port: {{ .Values.minecraftServer.servicePort | default 25565 }} 48 | targetPort: minecraft 49 | {{- if .Values.minecraftServer.nodePort }} 50 | nodePort: {{ .Values.minecraftServer.nodePort }} 51 | {{- end }} 52 | protocol: TCP 53 | {{- range .Values.minecraftServer.extraPorts }} 54 | {{- if and .service.enabled .service.embedded }} 55 | - name: {{ .name }} 56 | port: {{ .service.port }} 57 | targetPort: {{ .name }} 58 | {{- if .service.nodePort }} 59 | nodePort: {{ .service.nodePort }} 60 | {{- end }} 61 | {{- if .protocol }} 62 | protocol: {{ .protocol }} 63 | {{- else }} 64 | protocol: TCP 65 | {{- end }} 66 | {{- end }} 67 | {{- end }} 68 | selector: 69 | app: {{ template "minecraft.fullname" . }} 70 | {{- if .Values.minecraftServer.externalIPs }} 71 | externalIPs: 72 | {{- with .Values.minecraftServer.externalIPs }} 73 | {{- range . }} 74 | - {{ . | quote }} 75 | {{- end }} 76 | {{- end }} 77 | {{- end }} 78 | {{- if .Values.minecraftServer.extraServiceSpec }} 79 | {{ toYaml .Values.minecraftServer.extraServiceSpec | indent 2 }} 80 | {{- end }} 81 | -------------------------------------------------------------------------------- /charts/minecraft/templates/rclone-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.mcbackup.enabled .Values.minecraftServer.rcon.enabled (not .Values.mcbackup.rcloneConfigExistingSecret) }} 2 | {{- if or (eq .Values.mcbackup.backupMethod "rclone") (eq (include "isResticWithRclone" $) "true") }} 3 | apiVersion: v1 4 | kind: Secret 5 | metadata: 6 | name: {{ template "minecraft.fullname" . }}-rclone-config 7 | labels: 8 | app: {{ template "minecraft.fullname" . }} 9 | chart: {{ template "chart.fullname" . }} 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | app.kubernetes.io/name: "{{ .Chart.Name }}" 13 | app.kubernetes.io/instance: {{ template "minecraft.fullname" . }} 14 | app.kubernetes.io/version: {{ template "chart.version" . }} 15 | type: Opaque 16 | data: 17 | rclone.conf: |- 18 | {{- if .Values.mcbackup.rcloneConfig }} 19 | {{ tpl .Values.mcbackup.rcloneConfig . | b64enc | indent 4 }} 20 | {{- end }} 21 | {{- end }} 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /charts/minecraft/templates/rcon-svc.yaml: -------------------------------------------------------------------------------- 1 | {{- if default "" .Values.minecraftServer.rcon.enabled }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: "{{ template "minecraft.fullname" . }}-rcon" 6 | namespace: {{ .Release.Namespace }} 7 | annotations: 8 | {{ toYaml .Values.rconServiceAnnotations | indent 4 }} 9 | labels: 10 | app: {{ template "minecraft.fullname" . }} 11 | chart: {{ template "chart.fullname" . }} 12 | release: "{{ .Release.Name }}" 13 | heritage: "{{ .Release.Service }}" 14 | app.kubernetes.io/name: "{{ .Chart.Name }}" 15 | app.kubernetes.io/instance: {{ template "minecraft.fullname" . }} 16 | app.kubernetes.io/version: {{ template "chart.version" . }} 17 | {{- if .Values.rconServiceLabels }} 18 | {{- range $key, $value := .Values.rconServiceLabels}} 19 | {{ $key }}: {{ $value | quote }} 20 | {{- end }} 21 | {{- end }} 22 | spec: 23 | {{- if (or (eq .Values.minecraftServer.rcon.serviceType "ClusterIP") (empty .Values.minecraftServer.rcon.serviceType)) }} 24 | type: ClusterIP 25 | {{- else if eq .Values.minecraftServer.rcon.serviceType "LoadBalancer" }} 26 | type: {{ .Values.minecraftServer.rcon.serviceType }} 27 | {{- if .Values.minecraftServer.rcon.loadBalancerClass }} 28 | loadBalancerClass: {{ .Values.minecraftServer.rcon.loadBalancerClass }} 29 | {{- end }} 30 | {{- if .Values.minecraftServer.rcon.loadBalancerIP }} 31 | loadBalancerIP: {{ .Values.minecraftServer.rcon.loadBalancerIP }} 32 | {{- end }} 33 | {{- if .Values.minecraftServer.rcon.loadBalancerSourceRanges }} 34 | loadBalancerSourceRanges: 35 | {{ toYaml .Values.minecraftServer.rcon.loadBalancerSourceRanges | indent 4 }} 36 | {{- end -}} 37 | {{- else }} 38 | type: {{ .Values.minecraftServer.rcon.serviceType }} 39 | {{- end }} 40 | {{- if .Values.minecraftServer.rcon.clusterIP }} 41 | clusterIP: {{ .Values.minecraftServer.rcon.clusterIP }} 42 | {{- end }} 43 | {{- if .Values.minecraftServer.rcon.externalTrafficPolicy }} 44 | externalTrafficPolicy: {{ .Values.minecraftServer.rcon.externalTrafficPolicy }} 45 | {{- end }} 46 | ports: 47 | - name: rcon 48 | port: {{ .Values.minecraftServer.rcon.port }} 49 | {{- if .Values.minecraftServer.rcon.nodePort }} 50 | nodePort: {{ .Values.minecraftServer.rcon.nodePort }} 51 | {{- end }} 52 | targetPort: rcon 53 | protocol: TCP 54 | selector: 55 | app: {{ template "minecraft.fullname" . }} 56 | {{- end }} 57 | -------------------------------------------------------------------------------- /charts/minecraft/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | {{- if not .Values.minecraftServer.rcon.existingSecret }} 2 | --- 3 | apiVersion: v1 4 | kind: Secret 5 | metadata: 6 | name: "{{ template "minecraft.fullname" . }}-rcon" 7 | namespace: {{ .Release.Namespace }} 8 | labels: 9 | app: {{ template "minecraft.fullname" . }} 10 | chart: {{ template "chart.fullname" . }} 11 | release: "{{ .Release.Name }}" 12 | heritage: "{{ .Release.Service }}" 13 | app.kubernetes.io/name: "{{ .Chart.Name }}" 14 | app.kubernetes.io/instance: {{ template "minecraft.fullname" . }} 15 | app.kubernetes.io/version: {{ template "chart.version" . }} 16 | type: Opaque 17 | data: 18 | rcon-password: {{ default "" .Values.minecraftServer.rcon.password | b64enc | quote }} 19 | {{- end }} 20 | {{- if not .Values.minecraftServer.autoCurseForge.apiKey.existingSecret }} 21 | --- 22 | apiVersion: v1 23 | kind: Secret 24 | metadata: 25 | name: "{{ template "minecraft.fullname" . }}-curseforge" 26 | namespace: {{ .Release.Namespace }} 27 | labels: 28 | app: {{ template "minecraft.fullname" . }} 29 | chart: {{ template "chart.fullname" . }} 30 | release: "{{ .Release.Name }}" 31 | heritage: "{{ .Release.Service }}" 32 | app.kubernetes.io/name: "{{ .Chart.Name }}" 33 | app.kubernetes.io/instance: {{ template "minecraft.fullname" . }} 34 | app.kubernetes.io/version: {{ template "chart.version" . }} 35 | type: Opaque 36 | data: 37 | cf-api-key: {{ default "" .Values.minecraftServer.autoCurseForge.apiKey.key | b64enc | quote }} 38 | {{- end }} 39 | -------------------------------------------------------------------------------- /charts/minecraft/values.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "required": ["minecraftServer", "initContainers", "sidecarContainers"], 4 | "properties": { 5 | "minecraftServer": { 6 | "type": "object", 7 | "properties": { 8 | "eula": { 9 | "anyOf": [ 10 | { 11 | "type": "string", 12 | "enum": ["true", "TRUE", "false", "FALSE"] 13 | }, 14 | { 15 | "type": "boolean" 16 | } 17 | ] 18 | }, 19 | "version": {"type": "string", 20 | "default": "LATEST", 21 | "title": "Minecraft version for all server types", 22 | "description": "Such as LATEST, SNAPSHOT, or a specific version. Refer to https://docker-minecraft-server.readthedocs.io/en/latest/versions/minecraft/" 23 | }, 24 | "type": {"type": "string", 25 | "default": "VANILLA", 26 | "title": "Server type", 27 | "description": "Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/" 28 | }, 29 | "difficulty": { 30 | "type": "string" 31 | }, 32 | "maxPlayers": { 33 | "oneOf": [ 34 | {"type": "integer"}, 35 | {"enum": ["default"]} 36 | ] 37 | }, 38 | "maxWorldSize": { 39 | "oneOf": [ 40 | {"type": "integer"}, 41 | {"enum": ["default"]} 42 | ] 43 | }, 44 | "modrinth": { 45 | "type": "object", 46 | "required": ["projects"], 47 | "properties": { 48 | "projects": { 49 | "type": "array", 50 | "items": { 51 | "type": "string" 52 | }, 53 | "uniqueItems": true 54 | }, 55 | "downloadDependencies": { 56 | "enum": ["none", "required", "optional"] 57 | }, 58 | "allowedVersionType": { 59 | "enum": ["release", "beta", "alpha", "default"] 60 | } 61 | } 62 | }, 63 | "spigetResources": { 64 | "type": "array", 65 | "items": { 66 | "type": "integer" 67 | } 68 | }, 69 | "modUrls": { 70 | "type": "array", 71 | "items": { 72 | "type": "string" 73 | }, 74 | "uniqueItems": true 75 | }, 76 | "autoCurseForge": { 77 | "type": "object", 78 | "properties": { 79 | "apiKey": { 80 | "type": "object", 81 | "properties": { 82 | "key": { 83 | "type": "string" 84 | }, 85 | "existingSecret": { 86 | "type": "string" 87 | }, 88 | "secretKey": { 89 | "type": "string" 90 | } 91 | } 92 | }, 93 | "pageUrl": { 94 | "type": "string" 95 | }, 96 | "slug": { 97 | "type": "string" 98 | }, 99 | "fileId": { 100 | "type": "string" 101 | }, 102 | "filenameMatcher": { 103 | "type": "string" 104 | }, 105 | "excludeMods": { 106 | "type": "array", 107 | "items": { 108 | "type": ["integer", "string"] 109 | }, 110 | "uniqueItems": true 111 | }, 112 | "includeMods": { 113 | "type": "array", 114 | "items": { 115 | "type": ["integer", "string"] 116 | }, 117 | "uniqueItems": true 118 | }, 119 | "excludeIncludeFile": { 120 | "type": ["string", "null"] 121 | }, 122 | "forceSynchronize": { 123 | "type": "boolean" 124 | }, 125 | "setLevelFrom": { 126 | "enum": ["", "WORLD_FILE", "OVERRIDES"] 127 | }, 128 | "parallelDownloads": { 129 | "type": "integer", 130 | "minimum": 1 131 | }, 132 | "overridesSkipExisting": { 133 | "type": "boolean" 134 | } 135 | } 136 | }, 137 | "pluginUrls": { 138 | "type": "array", 139 | "items": { 140 | "type": "string" 141 | } 142 | }, 143 | "maxBuildHeight": { 144 | "oneOf": [ 145 | {"type": "integer"}, 146 | {"enum": ["default"]} 147 | ] 148 | }, 149 | "maxTickTime": { 150 | "oneOf": [ 151 | {"type": "integer"}, 152 | {"enum": ["default"]} 153 | ] 154 | }, 155 | "spawnProtection": { 156 | "oneOf": [ 157 | {"type": "integer"}, 158 | {"enum": ["default"]} 159 | ] 160 | }, 161 | "viewDistance": { 162 | "oneOf": [ 163 | {"type": "integer"}, 164 | {"enum": ["default"]} 165 | ] 166 | }, 167 | "ftbLegacyJavaFixer": { 168 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 169 | "allowNether": { 170 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 171 | "announcePlayerAchievements": { 172 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 173 | "enableCommandBlock": { 174 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 175 | "forcegameMode": { 176 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 177 | "generateStructures": { 178 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 179 | "hardcore": { 180 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 181 | "spawnAnimals": { 182 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 183 | "spawnMonsters": { 184 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 185 | "spawnNPCs": { 186 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 187 | "pvp": { 188 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 189 | "onlineMode": { 190 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 191 | "enforceSecureProfile": { 192 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]}, 193 | "overrideServerProperties": { 194 | "anyOf": [{"type": "string", "enum": ["default"]}, {"type": "boolean"}]} 195 | }, 196 | "required": [ 197 | "eula" 198 | ] 199 | }, 200 | "mcbackup": { 201 | "type": "object", 202 | "properties": { 203 | "backupMethod": { 204 | "type": "string", 205 | "enum": [ 206 | "tar", 207 | "restic", 208 | "rclone", 209 | "rsync" 210 | ] 211 | }, 212 | "resticRepository": { 213 | "type": "string" 214 | } 215 | } 216 | }, 217 | "extraPodSpec": { 218 | "type": "object" 219 | }, 220 | "initContainers": { 221 | "items": { 222 | "type": ["object", "string"] 223 | }, 224 | "type": "array" 225 | }, 226 | "sidecarContainers": { 227 | "items": { 228 | "type": ["object", "string"] 229 | }, 230 | "type": "array" 231 | }, 232 | "extraDeploy": { 233 | "items": { 234 | "type": ["object", "string"] 235 | }, 236 | "type": "array" 237 | } 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /charts/minecraft/values.yaml: -------------------------------------------------------------------------------- 1 | # ref: https://hub.docker.com/r/itzg/minecraft-server/ 2 | image: 3 | repository: itzg/minecraft-server 4 | tag: latest 5 | pullPolicy: Always 6 | pullSecret: "" 7 | 8 | # ### WARNING ### 9 | # Minecraft is not horizontally scalable, adjusting this will most likely break your setup. 10 | # ### WARNING ### 11 | replicaCount: 1 12 | 13 | nameOverride: "" 14 | fullnameOverride: "" 15 | 16 | ## Configure resource requests and limits 17 | ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ 18 | ## 19 | resources: 20 | requests: 21 | memory: 512Mi 22 | cpu: 500m 23 | 24 | lifecycle: 25 | postStart: [] 26 | preStop: [] 27 | 28 | # If true the workload is defined as a StatefulSet instead of a Deployment. 29 | # Make sure to also update the strategyType! 30 | # All configuration options for the Deployment (e.g. annotations) are used for the StatefulSet. 31 | # Regarding persistence: When an existing PVC is provided it will be shared between all Pods. 32 | # Otherwise the PVC configuration is used as a template to create PVCs for each replica. 33 | workloadAsStatefulSet: false 34 | 35 | # upgrade strategy type, depending on workload type: 36 | # - for Deployment sets strategy: Recreate or RollingUpdate 37 | # - for StatefulSet sets updateStrategy: OnDelete or RollingUpdate 38 | strategyType: Recreate 39 | 40 | nodeSelector: {} 41 | 42 | tolerations: [] 43 | 44 | affinity: {} 45 | 46 | podSecurityContext: 47 | runAsUser: 1000 48 | runAsGroup: 3000 49 | runAsNonRoot: true 50 | fsGroup: 2000 51 | seccompProfile: 52 | type: RuntimeDefault 53 | 54 | securityContext: 55 | capabilities: 56 | drop: 57 | - ALL 58 | readOnlyRootFilesystem: true 59 | allowPrivilegeEscalation: false 60 | 61 | # Most of these map to environment variables. See Minecraft for details: 62 | # https://hub.docker.com/r/itzg/minecraft-server/ 63 | livenessProbe: 64 | command: 65 | - mc-health 66 | initialDelaySeconds: 30 67 | periodSeconds: 5 68 | failureThreshold: 20 69 | successThreshold: 1 70 | timeoutSeconds: 1 71 | readinessProbe: 72 | command: 73 | - mc-health 74 | initialDelaySeconds: 30 75 | periodSeconds: 5 76 | failureThreshold: 20 77 | successThreshold: 1 78 | timeoutSeconds: 1 79 | startupProbe: 80 | command: 81 | - mc-health 82 | enabled: false 83 | failureThreshold: 30 84 | periodSeconds: 10 85 | 86 | ## Array of initContainers to add to include in deployment (supports templating) 87 | ## 88 | # initContainers: 89 | # - name: do-something 90 | # image: busybox 91 | # command: ['do', 'something'] 92 | # volumeMounts: 93 | # - name: nfs 94 | # mountPath: /mnt/volume 95 | # readOnly: true 96 | # - | 97 | # name: {{ template "minecraft.fullname" . }}-init 98 | # image: busybox 99 | # command: ['do', 'something'] 100 | # volumeMounts: 101 | # - name: nfs 102 | # mountPath: /mnt/volume 103 | # readOnly: true 104 | initContainers: [] 105 | 106 | ## Array of additional sidecards to include in the deployment (supports templating) 107 | ## 108 | # sidecarContainers: 109 | # - name: do-something 110 | # image: busybox 111 | # command: ['do', 'something'] 112 | # volumeMounts: 113 | # - name: nfs 114 | # mountPath: /mnt/volume 115 | # readOnly: true 116 | # - | 117 | # name: {{ template "minecraft.fullname" . }}-sidecar 118 | # image: busybox 119 | # command: ['do', 'something', 'with', 'rcon'] 120 | # env: 121 | # - name: RCON_PASSWORD 122 | # valueFrom: 123 | # secretKeyRef: 124 | # name: '{{ .Values.minecraftServer.rcon.existingSecret | default (printf "%s-rcon" (include "minecraft.fullname" .)) }}' 125 | # key: "{{ .Values.minecraftServer.rcon.secretKey | default "rcon-password" }}" 126 | sidecarContainers: [] 127 | 128 | # extraVolumes: 129 | # - volumeMounts: 130 | # - name: nfs 131 | # mountPath: /mnt/volume 132 | # readOnly: true 133 | # volumes: 134 | # - name: nfs 135 | # nfs: 136 | # server: some.nfs.server.com 137 | # path: / 138 | # mountOptions: 139 | # - port=2049 140 | # - hard 141 | # - vers=4 142 | extraVolumes: [] 143 | 144 | 145 | ## Array of extra objects to deploy with the release 146 | ## 147 | # extraDeploy: 148 | # - | 149 | # apiVersion: v1 150 | # kind: ConfigMap 151 | # metadata: 152 | # name: {{ template "minecraft.fullname" . }}-extra-cm 153 | # data: 154 | # key: |- 155 | # { 156 | # "key": "value" 157 | # } 158 | extraDeploy: [] 159 | 160 | ## Extra fields to set on the pod 161 | ## 162 | ## Fields set here will be added to the end of the Pod spec 163 | ## Can include any fields from https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec 164 | ## that are not already set by the chart. 165 | ## 166 | ## The value of the field will be interpretted as a template. 167 | ## 168 | # extraPodSpec: 169 | # priorityClassName: 'my-priority-class' 170 | extraPodSpec: {} 171 | 172 | minecraftServer: 173 | # This must be overridden, since we can't accept this for the user. 174 | eula: "FALSE" 175 | # One of: LATEST, SNAPSHOT, or a specific version (ie: "1.7.9"). 176 | version: "LATEST" 177 | ## The type of Minecraft server to run, check for related settings below 178 | ## Common types: "VANILLA", "FABRIC", "FORGE", "SPIGOT", "BUKKIT", "PAPER", 179 | ## "FTBA", "SPONGEVANILLA", "AUTO_CURSEFORGE" 180 | ## ref: https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms 181 | type: "VANILLA" 182 | # If type is set to FORGE, this sets the version; this is ignored if forgeInstallerUrl is set 183 | forgeVersion: 184 | # If type is set to FORGE, this sets the URL to download the Forge installer 185 | forgeInstallerUrl: 186 | # If type is set to SPONGEVANILLA, this sets the version 187 | spongeVersion: 188 | # If type is set to BUKKIT, this sets the URL to download the Bukkit package 189 | bukkitDownloadUrl: 190 | # If type is set to SPIGOT, this sets the URL to download the Spigot package 191 | spigotDownloadUrl: 192 | # If type is set to PAPER, this sets the URL to download the PaperSpigot package 193 | paperDownloadUrl: 194 | # If type is set to FTBA, this sets the modpack to run 195 | ftbModpackId: 196 | # If type is set to FTBA and a modpack is set, this sets the version to run 197 | ftbModpackVersionId: 198 | # If type is set to CURSEFORGE, this sets the server mod to run. Can also provide url to curseforge package. 199 | cfServerMod: 200 | ## If type is set to FABRIC, this sets the version of fabric server launcher 201 | ## to use. Defaults to latest available for minecraftServer.version. 202 | ## 203 | ## For a custom launcher, see: https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/server-types/fabric/ 204 | fabricLauncherVersion: 205 | ## If type is set to FABRIC, this sets the version of fabric-loader to use. 206 | ## Defaults to latest available for minecraftServer.version. 207 | fabricLoaderVersion: 208 | # Set to true if running Feed The Beast and get an error like "unable to launch forgemodloader" 209 | ftbLegacyJavaFixer: default 210 | # One of: peaceful, easy, normal, and hard 211 | difficulty: easy 212 | # A comma-separated list of player names to whitelist. 213 | whitelist: 214 | # A comma-separated list of player names who should be admins. 215 | ops: 216 | # A server icon URL for server listings. Auto-scaled and transcoded. 217 | icon: 218 | # Max connected players. 219 | maxPlayers: default 220 | # This sets the maximum possible size in blocks, expressed as a radius, that the world border can obtain. 221 | maxWorldSize: default 222 | # Allows players to travel to the Nether. 223 | allowNether: default 224 | # Allows server to announce when a player gets an achievement. 225 | announcePlayerAchievements: default 226 | # Enables command blocks. 227 | enableCommandBlock: default 228 | # If true, players will always join in the default gameMode even if they were previously set to something else. 229 | forcegameMode: default 230 | # Defines whether structures (such as villages) will be generated. 231 | generateStructures: default 232 | # If set to true, players will be set to spectator mode if they die. 233 | hardcore: default 234 | # The maximum height in which building is allowed. 235 | maxBuildHeight: default 236 | # The maximum number of milliseconds a single tick may take before the server watchdog stops the server with the message. -1 disables this entirely. 237 | maxTickTime: default 238 | # Determines if animals will be able to spawn. 239 | spawnAnimals: default 240 | # Determines if monsters will be spawned. 241 | spawnMonsters: default 242 | # Determines if villagers will be spawned. 243 | spawnNPCs: default 244 | # Sets the area that non-ops can not edit (0 to disable) 245 | spawnProtection: default 246 | # Max view distance (in chunks). 247 | viewDistance: default 248 | # Define this if you want a specific map generation seed. 249 | levelSeed: 250 | # One of: creative, survival, adventure, spectator 251 | gameMode: survival 252 | # Message of the Day 253 | motd: "Welcome to Minecraft on Kubernetes!" 254 | # If true, enable player-vs-player damage. 255 | pvp: default 256 | # One of: DEFAULT, FLAT, LARGEBIOMES, AMPLIFIED, CUSTOMIZED 257 | levelType: DEFAULT 258 | # When levelType == FLAT or CUSTOMIZED, this can be used to further customize map generation. 259 | # ref: https://hub.docker.com/r/itzg/minecraft-server/ 260 | generatorSettings: 261 | worldSaveName: world 262 | # If set, this URL will be downloaded at startup and used as a starting point 263 | downloadWorldUrl: 264 | # force re-download of server file 265 | forceReDownload: false 266 | # If set, the modpack at this URL will be downloaded at startup 267 | downloadModpackUrl: 268 | # If true, old versions of downloaded mods will be replaced with new ones from downloadModpackUrl 269 | removeOldMods: false 270 | # A list of VanillaTweaks Share Codes to download. (https://vanillatweaks.net/share#wUq1iz => "wUq1iz") 271 | vanillaTweaksShareCodes: [] 272 | # Optional URI to a resource pack. The player may choose to use it. 273 | resourcePackUrl: 274 | # Optional SHA-1 digest of the resource pack, in lowercase hexadecimal. 275 | # It is recommended to specify this, because it is used to verify the integrity of the resource pack. 276 | resourcePackSha: 277 | # When true, players will be prompted for a response and will be disconnected if they decline the required pack 278 | resourcePackEnforce: false 279 | # Check accounts against Minecraft account service. 280 | onlineMode: default 281 | # Require public key to be signed by Mojang to join 282 | enforceSecureProfile: default 283 | # If you adjust this, you may need to adjust resources.requests above to match. 284 | memory: 1024M 285 | # General JVM options to be passed to the Minecraft server invocation 286 | jvmOpts: "" 287 | # Options like -X that need to proceed general JVM options 288 | jvmXXOpts: "" 289 | overrideServerProperties: default 290 | # DEPRECATED: use top-level rconServiceAnnotations instead 291 | serviceAnnotations: {} 292 | serviceType: ClusterIP 293 | ## Set the port used if the serviceType is NodePort 294 | nodePort: 295 | # Set the external port of the service, usefull when using the LoadBalancer service type 296 | servicePort: 25565 297 | clusterIP: 298 | loadBalancerClass: 299 | loadBalancerIP: 300 | # loadBalancerSourceRanges: [] 301 | ## Set the externalTrafficPolicy in the Service to either Cluster or Local 302 | # externalTrafficPolicy: Cluster 303 | externalIPs: 304 | 305 | # List with URLs and paths to jar files, additionally may be a directory with jars 306 | # This works for both mods and plugins depending on server type 307 | modUrls: [] 308 | pluginUrls: [] 309 | 310 | # A list of Spigot resources/plugins IDs to download. 311 | spigetResources: [] 312 | 313 | # Additional service specs to be defined 314 | extraServiceSpec: {} 315 | 316 | # A list of Modrinth project slugs with optional version after colon 317 | modrinth: 318 | projects: [] 319 | # Specifies whether to download Modrinth dependencies. The allowed values are: none, required, optional 320 | downloadDependencies: none 321 | # The version type is used to determine the newest version to use from each project. The allowed values are: release, beta, alpha 322 | allowedVersionType: default 323 | 324 | # Config for AUTO_CURSEFORGE server type 325 | autoCurseForge: 326 | # CurseForge API key obtained from developer console 327 | apiKey: 328 | key: "CHANGEME!" 329 | existingSecret: "" 330 | secretKey: cf-api-key 331 | # Link to modpack in general or a specific file 332 | # NOTE: In case of specific file - do not point at server file 333 | pageUrl: "" 334 | # Unique id of modpack, can be used instead of url 335 | slug: "" 336 | # Id used to specify which exact modpack file needs to be downloaded 337 | # NOTE: Do not use server file id 338 | fileId: "" 339 | # Less restrictive way of specifying modpack version, uses substring match 340 | filenameMatcher: "" 341 | # List of project slugs or IDs to be excluded from modpack, useful if mod is incorrectly marked as server side 342 | excludeMods: [] 343 | # List of project slugs or IDs to be included in modpack, useful if mod is incorrectly marked as client side only 344 | includeMods: [] 345 | # Path to file with rules for including and excluding mods. If null - use bundled file, if empty - disable it 346 | excludeIncludeFile: null 347 | # Reevaluate exclude and include rules 348 | forceSynchronize: false 349 | # Can be set to either WORLD_FILE or OVERRIDES to specify where to get LEVEL 350 | setLevelFrom: "" 351 | # Sets limit to how many mods can be downloaded in parallel 352 | parallelDownloads: 4 353 | # Set to skip files in modpack "overrides" folder that would replace existing files 354 | # NOTE: World data is always skipped if present 355 | overridesSkipExisting: false 356 | 357 | rcon: 358 | # If you enable this, make SURE to change your password below. 359 | enabled: false 360 | # By default, the container will generate a random password at startup 361 | # to ensure internal RCON tooling, including a backup container, 362 | # can be used, but the password is secure. 363 | withGeneratedPassword: false 364 | port: 25575 365 | password: "CHANGEME!" 366 | existingSecret: 367 | secretKey: rcon-password 368 | serviceType: ClusterIP 369 | ## Set the external port if the rcon serviceType is NodePort 370 | nodePort: 371 | clusterIP: 372 | loadBalancerClass: 373 | loadBalancerIP: 374 | # loadBalancerSourceRanges: [] 375 | ## Set the externalTrafficPolicy in the Service to either Cluster or Local 376 | # externalTrafficPolicy: Cluster 377 | 378 | ## set this to false to not have colorized logs 379 | tty: true 380 | 381 | extraPorts: 382 | [] 383 | 384 | # These options allow you to expose another port from the Minecraft server, plugins such 385 | # as dynmap (8123) and bluemap (8100) will require this for access to their web interfaces 386 | # 387 | # - name: map 388 | # containerPort: 8123 389 | # protocol: TCP 390 | # service: 391 | # enabled: false 392 | # embedded: false 393 | # annotations: {} 394 | # type: ClusterIP 395 | # ## Set the external port if the rcon serviceType is NodePort 396 | ## nodePort: 397 | # loadBalancerIP: "" 398 | # loadBalancerSourceRanges: [] 399 | # externalTrafficPolicy: Cluster 400 | # port: 8123 401 | # ingress: 402 | # ingressClassName: nginx 403 | # enabled: false 404 | # annotations: 405 | ## Deprecated way for specifying the ingressClass. Kube.version < 1.18 406 | ## kubernetes.io/ingress.class: nginx 407 | # kubernetes.io/tls-acme: "true" 408 | # hosts: 409 | # - name: map.local 410 | # path: / 411 | # tls: 412 | # - secretName: map-tls 413 | # hosts: 414 | # - map.local 415 | 416 | query: 417 | # If you enable this, your server will be "published" to Gamespy 418 | enabled: false 419 | port: 25565 420 | 421 | ## Additional minecraft container environment variables 422 | ## Values can be either variable values or `valueFrom` yaml 423 | ## 424 | extraEnv: 425 | {} 426 | # some_variable: some value 427 | # another_variable: 428 | # valueFrom: 429 | # fieldRef: 430 | # fieldPath: status.hostIP 431 | 432 | ## Additional environment variables to add to the minecraft container from 433 | ## ConfigMaps and Secrets 434 | ## 435 | envFrom: [] 436 | 437 | persistence: 438 | labels: {} 439 | annotations: {} 440 | ## specify an alternative volume to be mounted to /data instead of datadir. 441 | # altDataVolumeName: "" 442 | ## minecraft data Persistent Volume Storage Class 443 | ## If defined, storageClassName: 444 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 445 | ## If undefined (the default) or set to null, no storageClassName spec is 446 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 447 | ## GKE, AWS & OpenStack) 448 | ## 449 | # storageClass: "-" 450 | dataDir: 451 | # Set this to false if you don't care to persist state between restarts. 452 | enabled: false 453 | Size: 1Gi 454 | accessModes: 455 | - ReadWriteOnce 456 | # existingClaim: nil 457 | ## specify a subpath in the volume where the data is. Useful when sharing volumes with other apps. 458 | # subPath: /path/to/dataDir 459 | 460 | podAnnotations: {} 461 | podLabels: {} 462 | 463 | deploymentAnnotations: {} 464 | deploymentLabels: {} 465 | 466 | serviceAnnotations: {} 467 | serviceLabels: {} 468 | 469 | rconServiceAnnotations: {} 470 | rconServiceLabels: {} 471 | 472 | # PLEASE NOTE! rcon must be enabled above! It does NOT require a nodePort or loadBalancerIP 473 | mcbackup: 474 | enabled: false 475 | 476 | image: 477 | repository: itzg/mc-backup 478 | tag: latest 479 | pullPolicy: IfNotPresent 480 | 481 | # wait 2 minutes before starting 482 | initialDelay: 2m 483 | 484 | # ***set to 0 or smaller, script will run once and exit. DO NOT SET TO 0 or smaller, this will cause K8s to kill your pod!*** 485 | # backupInterval="1.5d" -> backup every one and a half days (36 hours) 486 | # backupInterval="2h 30m" -> backup every two and a half hours 487 | backupInterval: 24h 488 | 489 | # option lets you pause backups if no players are online. 490 | pauseIfNoPlayers: "false" 491 | 492 | # is set to a positive number, it'll delete old .tgz backup files from DEST_DIR. By default deletes backups older than a week. 493 | pruneBackupsDays: 7 494 | 495 | # Set to a negative value to retry indefinitely 496 | rconRetries: 5 497 | rconRetryInterval: 10s 498 | 499 | # is a comma-separated list of glob(3) patterns to exclude from backups. By default excludes all jar files (plugins, server files), 500 | # logs folder and cache (used by i.e. PaperMC server). 501 | excludes: "*.jar,cache,logs" 502 | 503 | # backup methods, see https://github.com/itzg/docker-mc-backup e.g. tar, rclone, restic, rsync 504 | backupMethod: tar 505 | # tar and rclone methods 506 | destDir: /backups 507 | # is a true/false flag that creates a symbolic link to the latest backup 508 | linkLatest: "false" 509 | # is the compression method used by tar. Valid value: gzip bzip2 zstd 510 | compressMethod: "gzip" 511 | # sets the parameters for zstd compression. The --long parameter affects RAM requirements for both compression and decompression 512 | # (the default of 25 means 2^25 bytes = 32 MB). 513 | zstdParameters: "-3 --long=25 --single-thread" 514 | # the name of the remote you've configured in your rclone.conf 515 | rcloneRemote: 516 | rcloneDestDir: 517 | rcloneCompressMethod: gzip 518 | 519 | # see https://rclone.org/ for details 520 | # this value is evaluated as a template 521 | rcloneConfig: 522 | # [remote] 523 | # type = google cloud storage 524 | # client_id = 525 | # client_secret = 526 | # token = {"AccessToken":"super","RefreshToken":"secret","Expiry":"date","Extra":null} 527 | # project_number = 12345678 528 | # object_acl = private 529 | # bucket_acl = private 530 | 531 | # if you prefer to create a secret from file (e.g. kubectl create secret generic my-rclone-config --from-file=~/.config/rclone/rclone.conf) 532 | # rcloneConfigExistingSecret: my-rclone-config 533 | 534 | resticRepository: "" 535 | # variable to define a space separated list of additional restic tags. see https://hub.docker.com/r/itzg/mc-backup 536 | resticAdditionalTags: "mc_backups" 537 | # see https://restic.readthedocs.io/en/latest/060_forget.html 538 | pruneResticRetention: "--keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 75" 539 | 540 | # At least one of RESTIC_PASSWORD* env variables need to be defined, see https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html 541 | resticEnvs: 542 | {} 543 | # RESTIC_PASSWORD: restic-password 544 | 545 | ## Additional minecraft container environment variables 546 | ## Values can be either variable values or `valueFrom` yaml 547 | ## 548 | extraEnv: 549 | {} 550 | # some_variable: some value 551 | # another_variable: 552 | # valueFrom: 553 | # fieldRef: 554 | # fieldPath: status.hostIP 555 | 556 | ## Additional environment variables to add to the mc-backup container from 557 | ## ConfigMaps and Secrets 558 | ## 559 | envFrom: [] 560 | 561 | resources: 562 | requests: 563 | memory: 512Mi 564 | cpu: 500m 565 | 566 | persistence: 567 | annotations: {} 568 | ## minecraft data Persistent Volume Storage Class 569 | ## If defined, storageClassName: 570 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 571 | ## If undefined (the default) or set to null, no storageClassName spec is 572 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 573 | ## GKE, AWS & OpenStack) 574 | ## 575 | # storageClass: "-" 576 | backupDir: 577 | # Set this to false if you don't care to persist state between restarts. 578 | enabled: false 579 | # existingClaim: nil 580 | Size: 1Gi 581 | accessModes: 582 | - ReadWriteOnce 583 | # dnsPolicy: ClusterFirst 584 | # dnsConfig: 585 | # options: 586 | # - name: ndots 587 | # value: '1' 588 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: rcon-web-admin 3 | home: https://github.com/rcon-web-admin/rcon-web-admin 4 | description: RCon Web UI for managing game servers 5 | type: application 6 | version: 1.1.0 7 | appVersion: "0.14.1-1" 8 | keywords: 9 | - game 10 | - server 11 | sources: 12 | - https://github.com/itzg/minecraft-server-charts 13 | maintainers: 14 | - name: eaglesemanation 15 | email: eaglesemanation@gmail.com 16 | annotations: 17 | artifacthub.io/links: | 18 | - name: Image source 19 | url: https://github.com/itzg/docker-rcon-web-admin 20 | - name: Image DockerHub 21 | url: https://hub.docker.com/r/itzg/rcon 22 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/README.md: -------------------------------------------------------------------------------- 1 | # RCON Web Admin 2 | 3 | RCON Web Admin is a powerful web interface to control your RCON servers. All servers with RCON support should work. 4 | 5 | This application can install and run on a server, Raspberry Pi, or other devices which are online 24/7. 6 | 7 | Out of the box, RCON Web Admin can check users for high ping, VAC status, or filter the chat for you around the clock. 8 | 9 | ## Introduction 10 | 11 | This chart creates a single RCON Web Admin Pod, plus Services for HTTP and WebSocket traffic. 12 | 13 | ## Prerequisites 14 | 15 | - 512 MB of RAM 16 | - Kubernetes 1.23+ 17 | - Ingress Controller or Load Balancer available on Kubernetes cluster 18 | 19 | ## Installing the Chart 20 | 21 | To install the chart with the release name `rcon-web` and expose it through load balancer, run: 22 | 23 | ```shell 24 | helm install \ 25 | --set rconWeb.password=admin_password,service.type=LoadBalancer \ 26 | rcon-web itzg/rcon-web-admin 27 | ``` 28 | 29 | This command deploys a RCON Web Admin dedicated server with sensible defaults. 30 | 31 | > **Tip**: List all releases using `helm list` 32 | 33 | ## Uninstalling the Chart 34 | 35 | To uninstall/delete the `rcon-web` deployment: 36 | 37 | ```shell 38 | helm delete rcon-web 39 | ``` 40 | 41 | The command removes all the Kubernetes components associated with the chart and deletes the release. 42 | 43 | ## Configuration 44 | 45 | Refer to [values.yaml](values.yaml) for the full run-down on defaults. These are a mixture of Kubernetes and RCON-related directives that map to environment variables in the [itzg/rcon](https://hub.docker.com/r/itzg/rcon/) Docker image. 46 | 47 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, 48 | 49 | ```shell 50 | helm install \ 51 | --set rconWeb.password=admin_password,rconWeb.serverName=minecraft_survival \ 52 | rcon-web itzg/rcon-web-admin 53 | ``` 54 | 55 | Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, 56 | 57 | ```shell 58 | helm install -f values.yaml rcon-web itzg/rcon-web-admin 59 | ``` 60 | 61 | > **Tip**: You can use the default [values.yaml](values.yaml) 62 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/ci/test-values.yaml: -------------------------------------------------------------------------------- 1 | service: 2 | type: LoadBalancer 3 | 4 | rconWeb: 5 | password: test 6 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- with .Values.ingress }} 4 | http{{ if .tls }}s{{ end }}://{{ .host }}{{ .path }} 5 | {{- end }} 6 | {{- else if contains "NodePort" .Values.service.type }} 7 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "rcon-web-admin.fullname" . }}) 8 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 9 | echo http://$NODE_IP:$NODE_PORT 10 | {{- else if contains "LoadBalancer" .Values.service.type }} 11 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 12 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "rcon-web-admin.fullname" . }}' 13 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "rcon-web-admin.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 14 | echo http://$SERVICE_IP:{{ .Values.service.httpPort }} 15 | {{- else if contains "ClusterIP" .Values.service.type }} 16 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "rcon-web-admin.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 17 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") 18 | echo "Visit http://127.0.0.1:8080 to use your application" 19 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT 20 | {{- end }} 21 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "rcon-web-admin.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "rcon-web-admin.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "rcon-web-admin.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "rcon-web-admin.labels" -}} 37 | helm.sh/chart: {{ include "rcon-web-admin.chart" . }} 38 | {{ include "rcon-web-admin.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "rcon-web-admin.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "rcon-web-admin.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "rcon-web-admin.fullname" . }} 5 | labels: 6 | {{- include "rcon-web-admin.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "rcon-web-admin.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | {{- with .Values.podAnnotations }} 15 | annotations: 16 | {{- toYaml . | nindent 8 }} 17 | {{- end }} 18 | labels: 19 | {{- include "rcon-web-admin.selectorLabels" . | nindent 8 }} 20 | spec: 21 | {{- with .Values.image.pullSecrets }} 22 | imagePullSecrets: 23 | {{- toYaml . | nindent 8 }} 24 | {{- end }} 25 | serviceAccountName: {{ include "rcon-web-admin.fullname" . }} 26 | securityContext: 27 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 28 | volumes: 29 | - name: db 30 | emptyDir: {} 31 | containers: 32 | - name: {{ .Chart.Name }} 33 | securityContext: 34 | {{- toYaml .Values.securityContext | nindent 12 }} 35 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 36 | imagePullPolicy: {{ .Values.image.pullPolicy }} 37 | env: 38 | - name: RWA_USERNAME 39 | value: {{ .Values.rconWeb.username | default "admin" | quote }} 40 | - name: RWA_PASSWORD 41 | valueFrom: 42 | secretKeyRef: 43 | name: {{ .Values.rconWeb.passwordExistingSecret | default (include "rcon-web-admin.fullname" .) }} 44 | key: {{ .Values.rconWeb.passwordKey | default "password" }} 45 | - name: RWA_ADMIN 46 | value: {{ .Values.rconWeb.isAdmin | default false | ternary "TRUE" "FALSE" | quote }} 47 | - name: RWA_RCON_HOST 48 | value: {{ .Values.rconWeb.rconHost | default "127.0.0.1" | quote }} 49 | - name: RWA_RCON_PORT 50 | value: {{ .Values.rconWeb.rconPort | default "25575" | quote }} 51 | - name: RWA_GAME 52 | value: {{ .Values.rconWeb.game | default "minecraft" | quote }} 53 | - name: RWA_SERVER_NAME 54 | value: {{ .Values.rconWeb.serverName | default .Values.rconWeb.game | quote }} 55 | - name: RWA_RCON_PASSWORD 56 | valueFrom: 57 | secretKeyRef: 58 | name: {{ .Values.rconWeb.rconPasswordExistingSecret | default (include "rcon-web-admin.fullname" .) }} 59 | key: {{ .Values.rconWeb.rconPasswordKey | default "rcon-password" }} 60 | - name: RWA_RESTRICT_COMMANDS 61 | value: {{ join "," .Values.rconWeb.restrictCommands | quote }} 62 | - name: RWA_RESTRICT_WIDGETS 63 | value: {{ join "," .Values.rconWeb.restrictWidgets | quote }} 64 | - name: RWA_READ_ONLY_WIDGET_OPTIONS 65 | value: {{ .Values.rconWeb.immutableWidgetOptions | default false | ternary "TRUE" "FALSE" | quote }} 66 | - name: RWA_WEB_RCON 67 | value: {{ .Values.rconWeb.websocketRcon | default false | ternary "TRUE" "FALSE" | quote }} 68 | {{- if .Values.ingress.enabled }} 69 | {{ $wsUrl := print .Values.ingress.host (trimSuffix "/" .Values.ingress.path) "/websocket" }} 70 | - name: RWA_WEBSOCKET_URL_SSL 71 | value: {{ print "wss://" $wsUrl | quote }} 72 | - name: RWA_WEBSOCKET_URL 73 | value: {{ print "ws://" $wsUrl | quote }} 74 | {{- end }} 75 | {{- if not .Values.ingress.enabled }} 76 | command: 77 | - '/bin/sh' 78 | - '-c' 79 | - |- 80 | # Installing jq to parse k8s response 81 | export DEBIAN_FRONTEND=noninteractive 82 | apt-get -qq update >/dev/null && apt-get -qq install -y jq > /dev/null 83 | # Configuring k8s API auth 84 | APISERVER=https://kubernetes.default.svc 85 | SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount 86 | NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace) 87 | TOKEN=$(cat ${SERVICEACCOUNT}/token) 88 | CACERT=${SERVICEACCOUNT}/ca.crt 89 | # Querying for websocket service 90 | WS_SERVICE="$(curl --silent --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/{{ .Release.Namespace }}/services/{{ include "rcon-web-admin.fullname" . }})" 91 | {{- if contains "LoadBalancer" .Values.service.type }} 92 | WS_IP="$(echo "$WS_SERVICE" | jq -r .status.loadBalancer.ingress[0].ip)" 93 | WS_PORT="{{ .Values.service.wsPort }}" 94 | {{- else }} 95 | {{- fail "Selected service type is not supported"}} 96 | {{- end }} 97 | export RWA_WEBSOCKET_URL="ws://$WS_IP:$WS_PORT" 98 | export RWA_WEBSOCKET_URL_SSL="wss://$WS_IP:$WS_PORT" 99 | /usr/local/bin/node src/main.js start 100 | {{- end}} 101 | ports: 102 | - name: http 103 | containerPort: 4326 104 | protocol: TCP 105 | - name: ws 106 | containerPort: 4327 107 | protocol: TCP 108 | volumeMounts: 109 | - name: db 110 | mountPath: /opt/rcon-web-admin/db 111 | livenessProbe: 112 | httpGet: 113 | path: / 114 | port: http 115 | readinessProbe: 116 | httpGet: 117 | path: / 118 | port: http 119 | resources: 120 | {{- toYaml .Values.resources | nindent 12 }} 121 | {{- with .Values.nodeSelector }} 122 | nodeSelector: 123 | {{- toYaml . | nindent 8 }} 124 | {{- end }} 125 | {{- with .Values.affinity }} 126 | affinity: 127 | {{- toYaml . | nindent 8 }} 128 | {{- end }} 129 | {{- with .Values.tolerations }} 130 | tolerations: 131 | {{- toYaml . | nindent 8 }} 132 | {{- end }} 133 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "rcon-web-admin.fullname" . -}} 3 | {{- $svcHttpPort := .Values.service.httpPort -}} 4 | {{- $svcWsPort := .Values.service.wsPort -}} 5 | {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} 6 | {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} 7 | {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} 8 | {{- end }} 9 | {{- end }} 10 | {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} 11 | apiVersion: networking.k8s.io/v1 12 | {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 13 | apiVersion: networking.k8s.io/v1beta1 14 | {{- else -}} 15 | apiVersion: extensions/v1beta1 16 | {{- end }} 17 | kind: Ingress 18 | metadata: 19 | name: {{ $fullName }} 20 | labels: 21 | {{- include "rcon-web-admin.labels" . | nindent 4 }} 22 | {{- with .Values.ingress.annotations }} 23 | annotations: 24 | {{- toYaml . | nindent 4 }} 25 | {{- end }} 26 | spec: 27 | {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} 28 | ingressClassName: {{ .Values.ingress.className }} 29 | {{- end }} 30 | {{- if .Values.ingress.tls }} 31 | tls: 32 | {{- range .Values.ingress.tls }} 33 | - hosts: 34 | {{- range .hosts }} 35 | - {{ . | quote }} 36 | {{- end }} 37 | secretName: {{ .secretName }} 38 | {{- end }} 39 | {{- end }} 40 | rules: 41 | {{- with .Values.ingress }} 42 | - host: {{ .host | quote }} 43 | http: 44 | paths: 45 | - path: {{ .path }} 46 | {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} 47 | pathType: {{ .pathType }} 48 | {{- end }} 49 | backend: 50 | {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} 51 | service: 52 | name: {{ $fullName }} 53 | port: 54 | number: {{ $svcHttpPort }} 55 | {{- else }} 56 | serviceName: {{ $fullName }} 57 | servicePort: {{ $svcHttpPort }} 58 | {{- end }} 59 | - path: {{ print (trimSuffix "/" .path) "/websocket" }} 60 | {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} 61 | pathType: {{ .pathType }} 62 | {{- end }} 63 | backend: 64 | {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} 65 | service: 66 | name: {{ $fullName }} 67 | port: 68 | number: {{ $svcWsPort }} 69 | {{- else }} 70 | serviceName: {{ $fullName }} 71 | servicePort: {{ $svcWsPort }} 72 | {{- end }} 73 | {{- end }} 74 | {{- end }} 75 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/templates/role.yaml: -------------------------------------------------------------------------------- 1 | {{- if not .Values.ingress.enabled }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: {{ include "rcon-web-admin.fullname" . }} 6 | labels: 7 | {{- include "rcon-web-admin.labels" . | nindent 4 }} 8 | rules: 9 | - apiGroups: [""] 10 | resources: ["services"] 11 | resourceNames: [{{ include "rcon-web-admin.fullname" . | quote }}] 12 | verbs: ["get", "list", "watch"] 13 | {{- end }} 14 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/templates/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if not .Values.ingress.enabled }} 2 | kind: RoleBinding 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | metadata: 5 | name: {{ include "rcon-web-admin.fullname" . }} 6 | labels: 7 | {{- include "rcon-web-admin.labels" . | nindent 4 }} 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: Role 11 | name: {{ include "rcon-web-admin.fullname" . }} 12 | subjects: 13 | - kind: ServiceAccount 14 | name: {{ include "rcon-web-admin.fullname" . }} 15 | namespace: {{ .Release.Namespace }} 16 | {{- end }} 17 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | {{- if not (and .Values.rconWeb.passwordExistingSecret .Values.rconWeb.rconPasswordExistingSecret) }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ include "rcon-web-admin.fullname" . }} 6 | labels: 7 | {{- include "rcon-web-admin.labels" . | nindent 4 }} 8 | type: Opaque 9 | data: 10 | {{- with .Values.rconWeb }} 11 | {{- if not .passwordExistingSecret }} 12 | {{- if .password }} 13 | password: {{ .password | b64enc | quote }} 14 | {{- else }} 15 | {{- fail "UI password required. Configure it either by using rconWeb.password or rconWeb.passwordExistingSecret" }} 16 | {{- end }} 17 | {{- end }} 18 | {{- if not .rconPasswordExistingSecret }} 19 | rcon-password: {{ .rconPassword | default "" | b64enc | quote }} 20 | {{- end }} 21 | {{- end }} 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: {{ include "rcon-web-admin.fullname" . }} 5 | labels: 6 | {{- include "rcon-web-admin.labels" . | nindent 4 }} 7 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/templates/services.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "rcon-web-admin.fullname" . }} 5 | labels: 6 | {{- include "rcon-web-admin.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.httpPort }} 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | - port: {{ .Values.service.wsPort }} 15 | targetPort: ws 16 | protocol: TCP 17 | name: ws 18 | selector: 19 | {{- include "rcon-web-admin.selectorLabels" . | nindent 4 }} 20 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for rcon-web-admin. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: docker.io/itzg/rcon 9 | pullPolicy: Always 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | podAnnotations: {} 18 | 19 | podSecurityContext: 20 | runAsUser: 1000 21 | runAsGroup: 3000 22 | runAsNonRoot: true 23 | fsGroup: 2000 24 | seccompProfile: 25 | type: RuntimeDefault 26 | 27 | securityContext: 28 | capabilities: 29 | drop: 30 | - ALL 31 | readOnlyRootFilesystem: true 32 | allowPrivilegeEscalation: false 33 | 34 | # This will expose 2 different services - http and websockets 35 | # If you want to know why it's separate - ask developer of original project 36 | # because I have no clue 37 | service: 38 | # Supported options: Ingress + ClusterIP or LoadBalancer 39 | type: ClusterIP 40 | httpPort: 80 41 | wsPort: 4327 42 | 43 | ingress: 44 | enabled: false 45 | className: "" 46 | annotations: 47 | {} 48 | # kubernetes.io/ingress.class: nginx 49 | # kubernetes.io/tls-acme: "true" 50 | host: chart-example.local 51 | path: / 52 | pathType: ImplementationSpecific 53 | tls: [] 54 | # - secretName: chart-example-tls 55 | # hosts: 56 | # - chart-example.local 57 | 58 | resources: 59 | {} 60 | # limits: 61 | # cpu: 100m 62 | # memory: 128Mi 63 | # requests: 64 | # cpu: 100m 65 | # memory: 128Mi 66 | 67 | nodeSelector: {} 68 | 69 | tolerations: [] 70 | 71 | affinity: {} 72 | 73 | rconWeb: 74 | # Sets the initial user as an admin 75 | isAdmin: false 76 | # Sets the initial user's username 77 | username: admin 78 | # Sets the initial user's password 79 | password: "" 80 | # Name of existing secret with UI password 81 | passwordExistingSecret: 82 | passwordKey: "password" 83 | # The initial game you wish to control (minecraft / rust / csgo / other) 84 | game: minecraft 85 | # The display name of the initial server (if unset; defaults to value of RWA_GAME) 86 | serverName: minecraft 87 | # The initial RCON server to control 88 | rconHost: 127.0.0.1 89 | # The port number of the initial RCON server to control 90 | rconPort: 25575 91 | # The password for the initial RCON server to control 92 | rconPassword: "" 93 | # Name of existing secret with RCON password 94 | rconPasswordExistingSecret: 95 | rconPasswordKey: "rcon-password" 96 | # Prevent the initial user user executing these commands 97 | restrictCommands: [] 98 | # Hide this list of widgets from the initial user 99 | restrictWidgets: [] 100 | # Prevent the initial user changing options in the widget options tab 101 | immutableWidgetOptions: false 102 | # Enables 'web rcon' if supported by the game server 103 | websocketRcon: false 104 | --------------------------------------------------------------------------------