├── .gitignore ├── charts ├── rcon-web-admin │ ├── ci │ │ └── test-values.yaml │ ├── templates │ │ ├── serviceaccount.yaml │ │ ├── role.yaml │ │ ├── rolebinding.yaml │ │ ├── services.yaml │ │ ├── secrets.yaml │ │ ├── _helpers.tpl │ │ ├── NOTES.txt │ │ ├── ingress.yaml │ │ └── deployment.yaml │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ └── values.yaml ├── minecraft-bedrock │ ├── OWNERS │ ├── templates │ │ ├── extra-list.yaml │ │ ├── datadir-pvc.yaml │ │ ├── _helpers.tpl │ │ ├── minecraft-svc.yaml │ │ ├── NOTES.txt │ │ └── deployment.yaml │ ├── ci │ │ └── test-values.yaml │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ └── values.yaml ├── minecraft │ ├── templates │ │ ├── extra-list.yaml │ │ ├── rclone-secret.yaml │ │ ├── secrets.yaml │ │ ├── backupdir-pvc.yaml │ │ ├── datadir-pvc.yaml │ │ ├── extraports-svc.yaml │ │ ├── extraports-ing.yaml │ │ ├── rcon-svc.yaml │ │ ├── NOTES.txt │ │ ├── minecraft-svc.yaml │ │ └── _helpers.tpl │ ├── OWNERS │ ├── ci │ │ └── test-values.yaml │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── values.schema.json │ └── values.yaml ├── mc-router │ ├── OWNERS │ ├── templates │ │ ├── extra-list.yaml │ │ ├── clusterrolebinding.yaml │ │ ├── serviceaccount.yaml │ │ ├── autoscale-allow-deny-secret.yaml │ │ ├── autoscale-allow-deny-configmap.yaml │ │ ├── clusterrole.yaml │ │ ├── api-service.yaml │ │ ├── router-service.yaml │ │ ├── _helpers.tpl │ │ └── deployment.yaml │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── values.yaml │ └── values.schema.json └── minecraft-proxy │ ├── .helmignore │ ├── templates │ ├── configmap.yaml │ ├── rcon-secret.yaml │ ├── velocity-forwarding-secret.yaml │ ├── _helpers.tpl │ ├── datadir-pvc.yaml │ ├── extraports-ing.yaml │ ├── extraports-svc.yaml │ ├── rcon-svc.yaml │ ├── NOTES.txt │ ├── proxy-svc.yaml │ └── deployment.yaml │ ├── Chart.yaml │ ├── README.md │ └── values.yaml ├── .github ├── metallb-configmap.yaml └── workflows │ ├── lint-test.yaml │ └── release.yaml ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /*.iml 3 | -------------------------------------------------------------------------------- /charts/rcon-web-admin/ci/test-values.yaml: -------------------------------------------------------------------------------- 1 | service: 2 | type: LoadBalancer 3 | 4 | rconWeb: 5 | password: test 6 | -------------------------------------------------------------------------------- /charts/minecraft-bedrock/OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - gtaylor 3 | - itzg 4 | - billimek 5 | reviewers: 6 | - gtaylor 7 | - itzg 8 | - billimek 9 | -------------------------------------------------------------------------------- /charts/minecraft/templates/extra-list.yaml: -------------------------------------------------------------------------------- 1 | {{- range .Values.extraDeploy }} 2 | --- 3 | {{ include "tplRender" (dict "value" . "context" $) }} 4 | {{- end }} 5 | -------------------------------------------------------------------------------- /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/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-bedrock/templates/extra-list.yaml: -------------------------------------------------------------------------------- 1 | {{- range .Values.extraDeploy }} 2 | --- 3 | {{ include "extraDeploy.render" (dict "value" . "context" $) }} 4 | {{- end }} 5 | -------------------------------------------------------------------------------- /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/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-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/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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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/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/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/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/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-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/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/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/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/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/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/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/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/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/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/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/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/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/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: minecraft 3 | version: 5.0.0 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/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/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/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/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/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/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-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 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/_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-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/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/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-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/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/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/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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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-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/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/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/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/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/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/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-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/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-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/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/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 | -------------------------------------------------------------------------------- /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/_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-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/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/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/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/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/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/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/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/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/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/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-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/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 | revisionHistoryLimit: 10 47 | 48 | podSecurityContext: 49 | runAsUser: 1000 50 | runAsGroup: 3000 51 | runAsNonRoot: true 52 | fsGroup: 2000 53 | seccompProfile: 54 | type: RuntimeDefault 55 | 56 | securityContext: 57 | capabilities: 58 | drop: 59 | - ALL 60 | readOnlyRootFilesystem: true 61 | allowPrivilegeEscalation: false 62 | 63 | # Most of these map to environment variables. See Minecraft for details: 64 | # https://hub.docker.com/r/itzg/minecraft-server/ 65 | livenessProbe: 66 | command: 67 | - mc-health 68 | initialDelaySeconds: 30 69 | periodSeconds: 5 70 | failureThreshold: 20 71 | successThreshold: 1 72 | timeoutSeconds: 1 73 | readinessProbe: 74 | command: 75 | - mc-health 76 | initialDelaySeconds: 30 77 | periodSeconds: 5 78 | failureThreshold: 20 79 | successThreshold: 1 80 | timeoutSeconds: 1 81 | startupProbe: 82 | command: 83 | - mc-health 84 | enabled: false 85 | failureThreshold: 30 86 | periodSeconds: 10 87 | 88 | ## Array of initContainers to add to include in deployment (supports templating) 89 | ## 90 | # initContainers: 91 | # - name: do-something 92 | # image: busybox 93 | # command: ['do', 'something'] 94 | # volumeMounts: 95 | # - name: nfs 96 | # mountPath: /mnt/volume 97 | # readOnly: true 98 | # - | 99 | # name: {{ template "minecraft.fullname" . }}-init 100 | # image: busybox 101 | # command: ['do', 'something'] 102 | # volumeMounts: 103 | # - name: nfs 104 | # mountPath: /mnt/volume 105 | # readOnly: true 106 | initContainers: [] 107 | 108 | ## Array of additional sidecards to include in the deployment (supports templating) 109 | ## 110 | # sidecarContainers: 111 | # - name: do-something 112 | # image: busybox 113 | # command: ['do', 'something'] 114 | # volumeMounts: 115 | # - name: nfs 116 | # mountPath: /mnt/volume 117 | # readOnly: true 118 | # - | 119 | # name: {{ template "minecraft.fullname" . }}-sidecar 120 | # image: busybox 121 | # command: ['do', 'something', 'with', 'rcon'] 122 | # env: 123 | # - name: RCON_PASSWORD 124 | # valueFrom: 125 | # secretKeyRef: 126 | # name: '{{ .Values.minecraftServer.rcon.existingSecret | default (printf "%s-rcon" (include "minecraft.fullname" .)) }}' 127 | # key: "{{ .Values.minecraftServer.rcon.secretKey | default "rcon-password" }}" 128 | sidecarContainers: [] 129 | 130 | # extraVolumes: 131 | # - volumeMounts: 132 | # - name: nfs 133 | # mountPath: /mnt/volume 134 | # readOnly: true 135 | # volumes: 136 | # - name: nfs 137 | # nfs: 138 | # server: some.nfs.server.com 139 | # path: / 140 | # mountOptions: 141 | # - port=2049 142 | # - hard 143 | # - vers=4 144 | extraVolumes: [] 145 | 146 | 147 | ## Array of extra objects to deploy with the release 148 | ## 149 | # extraDeploy: 150 | # - | 151 | # apiVersion: v1 152 | # kind: ConfigMap 153 | # metadata: 154 | # name: {{ template "minecraft.fullname" . }}-extra-cm 155 | # data: 156 | # key: |- 157 | # { 158 | # "key": "value" 159 | # } 160 | extraDeploy: [] 161 | 162 | ## Extra fields to set on the pod 163 | ## 164 | ## Fields set here will be added to the end of the Pod spec 165 | ## Can include any fields from https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec 166 | ## that are not already set by the chart. 167 | ## 168 | ## The value of the field will be interpretted as a template. 169 | ## 170 | # extraPodSpec: 171 | # priorityClassName: 'my-priority-class' 172 | extraPodSpec: {} 173 | 174 | minecraftServer: 175 | # This must be overridden, since we can't accept this for the user. 176 | eula: "FALSE" 177 | # One of: LATEST, SNAPSHOT, or a specific version (ie: "1.7.9"). 178 | version: "LATEST" 179 | ## The type of Minecraft server to run, check for related settings below 180 | ## Common types: "VANILLA", "FABRIC", "FORGE", "SPIGOT", "BUKKIT", "PAPER", 181 | ## "FTBA", "SPONGEVANILLA", "AUTO_CURSEFORGE" 182 | ## ref: https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms 183 | type: "VANILLA" 184 | # If type is set to FORGE, this sets the version; this is ignored if forgeInstallerUrl is set 185 | forgeVersion: 186 | # If type is set to FORGE, this sets the URL to download the Forge installer 187 | forgeInstallerUrl: 188 | # If type is set to SPONGEVANILLA, this sets the version 189 | spongeVersion: 190 | # If type is set to BUKKIT, this sets the URL to download the Bukkit package 191 | bukkitDownloadUrl: 192 | # If type is set to SPIGOT, this sets the URL to download the Spigot package 193 | spigotDownloadUrl: 194 | # If type is set to PAPER, this sets the URL to download the PaperSpigot package 195 | paperDownloadUrl: 196 | # If type is set to FTBA, this sets the modpack to run 197 | ftbModpackId: 198 | # If type is set to FTBA and a modpack is set, this sets the version to run 199 | ftbModpackVersionId: 200 | # If type is set to CURSEFORGE, this sets the server mod to run. Can also provide url to curseforge package. 201 | cfServerMod: 202 | ## If type is set to FABRIC, this sets the version of fabric server launcher 203 | ## to use. Defaults to latest available for minecraftServer.version. 204 | ## 205 | ## For a custom launcher, see: https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/server-types/fabric/ 206 | fabricLauncherVersion: 207 | ## If type is set to FABRIC, this sets the version of fabric-loader to use. 208 | ## Defaults to latest available for minecraftServer.version. 209 | fabricLoaderVersion: 210 | # Set to true if running Feed The Beast and get an error like "unable to launch forgemodloader" 211 | ftbLegacyJavaFixer: default 212 | # One of: peaceful, easy, normal, and hard 213 | difficulty: easy 214 | # A comma-separated list of player names to whitelist. 215 | whitelist: 216 | # A comma-separated list of player names who should be admins. 217 | ops: 218 | # A server icon URL for server listings. Auto-scaled and transcoded. 219 | icon: 220 | # Max connected players. 221 | maxPlayers: default 222 | # This sets the maximum possible size in blocks, expressed as a radius, that the world border can obtain. 223 | maxWorldSize: default 224 | # Allows players to travel to the Nether. 225 | allowNether: default 226 | # Allows server to announce when a player gets an achievement. 227 | announcePlayerAchievements: default 228 | # Enables command blocks. 229 | enableCommandBlock: default 230 | # If true, players will always join in the default gameMode even if they were previously set to something else. 231 | forcegameMode: default 232 | # Defines whether structures (such as villages) will be generated. 233 | generateStructures: default 234 | # If set to true, players will be set to spectator mode if they die. 235 | hardcore: default 236 | # The maximum height in which building is allowed. 237 | maxBuildHeight: default 238 | # The maximum number of milliseconds a single tick may take before the server watchdog stops the server with the message. -1 disables this entirely. 239 | maxTickTime: default 240 | # Determines if animals will be able to spawn. 241 | spawnAnimals: default 242 | # Determines if monsters will be spawned. 243 | spawnMonsters: default 244 | # Determines if villagers will be spawned. 245 | spawnNPCs: default 246 | # Sets the area that non-ops can not edit (0 to disable) 247 | spawnProtection: default 248 | # Max view distance (in chunks). 249 | viewDistance: default 250 | # Define this if you want a specific map generation seed. 251 | levelSeed: 252 | # One of: creative, survival, adventure, spectator 253 | gameMode: survival 254 | # Message of the Day 255 | motd: "Welcome to Minecraft on Kubernetes!" 256 | # If true, enable player-vs-player damage. 257 | pvp: default 258 | # One of: DEFAULT, FLAT, LARGEBIOMES, AMPLIFIED, CUSTOMIZED 259 | levelType: DEFAULT 260 | # When levelType == FLAT or CUSTOMIZED, this can be used to further customize map generation. 261 | # ref: https://hub.docker.com/r/itzg/minecraft-server/ 262 | generatorSettings: 263 | worldSaveName: world 264 | # If set, this URL will be downloaded at startup and used as a starting point 265 | downloadWorldUrl: 266 | # force re-download of server file 267 | forceReDownload: false 268 | # If set, the modpack at this URL will be downloaded at startup 269 | downloadModpackUrl: 270 | # If true, old versions of downloaded mods will be replaced with new ones from downloadModpackUrl 271 | removeOldMods: false 272 | # A list of VanillaTweaks Share Codes to download. (https://vanillatweaks.net/share#wUq1iz => "wUq1iz") 273 | vanillaTweaksShareCodes: [] 274 | # Optional URI to a resource pack. The player may choose to use it. 275 | resourcePackUrl: 276 | # Optional SHA-1 digest of the resource pack, in lowercase hexadecimal. 277 | # It is recommended to specify this, because it is used to verify the integrity of the resource pack. 278 | resourcePackSha: 279 | # When true, players will be prompted for a response and will be disconnected if they decline the required pack 280 | resourcePackEnforce: false 281 | # Check accounts against Minecraft account service. 282 | onlineMode: default 283 | # Require public key to be signed by Mojang to join 284 | enforceSecureProfile: default 285 | # If you adjust this, you may need to adjust resources.requests above to match. 286 | memory: 1024M 287 | # General JVM options to be passed to the Minecraft server invocation 288 | jvmOpts: "" 289 | # Options like -X that need to proceed general JVM options 290 | jvmXXOpts: "" 291 | overrideServerProperties: default 292 | # DEPRECATED: use top-level rconServiceAnnotations instead 293 | serviceAnnotations: {} 294 | serviceType: ClusterIP 295 | ## Set the port used if the serviceType is NodePort 296 | nodePort: 297 | # Set the external port of the service, usefull when using the LoadBalancer service type 298 | servicePort: 25565 299 | clusterIP: 300 | loadBalancerClass: 301 | loadBalancerIP: 302 | # loadBalancerSourceRanges: [] 303 | ## Set the externalTrafficPolicy in the Service to either Cluster or Local 304 | # externalTrafficPolicy: Cluster 305 | externalIPs: 306 | 307 | # List with URLs and paths to jar files, additionally may be a directory with jars 308 | # This works for both mods and plugins depending on server type 309 | modUrls: [] 310 | pluginUrls: [] 311 | 312 | # A list of Spigot resources/plugins IDs to download. 313 | spigetResources: [] 314 | 315 | # Additional service specs to be defined 316 | extraServiceSpec: {} 317 | 318 | # A list of Modrinth project slugs with optional version after colon 319 | modrinth: 320 | projects: [] 321 | # Specifies whether to download Modrinth dependencies. The allowed values are: none, required, optional 322 | downloadDependencies: none 323 | # The version type is used to determine the newest version to use from each project. The allowed values are: release, beta, alpha 324 | allowedVersionType: default 325 | 326 | # Config for AUTO_CURSEFORGE server type 327 | autoCurseForge: 328 | # CurseForge API key obtained from developer console 329 | apiKey: 330 | key: "CHANGEME!" 331 | existingSecret: "" 332 | secretKey: cf-api-key 333 | # Link to modpack in general or a specific file 334 | # NOTE: In case of specific file - do not point at server file 335 | pageUrl: "" 336 | # Unique id of modpack, can be used instead of url 337 | slug: "" 338 | # Id used to specify which exact modpack file needs to be downloaded 339 | # NOTE: Do not use server file id 340 | fileId: "" 341 | # Less restrictive way of specifying modpack version, uses substring match 342 | filenameMatcher: "" 343 | # List of project slugs or IDs to be excluded from modpack, useful if mod is incorrectly marked as server side 344 | excludeMods: [] 345 | # List of project slugs or IDs to be included in modpack, useful if mod is incorrectly marked as client side only 346 | includeMods: [] 347 | # Path to file with rules for including and excluding mods. If null - use bundled file, if empty - disable it 348 | excludeIncludeFile: null 349 | # Reevaluate exclude and include rules 350 | forceSynchronize: false 351 | # Can be set to either WORLD_FILE or OVERRIDES to specify where to get LEVEL 352 | setLevelFrom: "" 353 | # Sets limit to how many mods can be downloaded in parallel 354 | parallelDownloads: 4 355 | # Set to skip files in modpack "overrides" folder that would replace existing files 356 | # NOTE: World data is always skipped if present 357 | overridesSkipExisting: false 358 | 359 | rcon: 360 | # If you enable this, make SURE to change your password below. 361 | enabled: false 362 | # By default, the container will generate a random password at startup 363 | # to ensure internal RCON tooling, including a backup container, 364 | # can be used, but the password is secure. 365 | withGeneratedPassword: false 366 | port: 25575 367 | password: "CHANGEME!" 368 | existingSecret: 369 | secretKey: rcon-password 370 | serviceType: ClusterIP 371 | ## Set the external port if the rcon serviceType is NodePort 372 | nodePort: 373 | clusterIP: 374 | loadBalancerClass: 375 | loadBalancerIP: 376 | # loadBalancerSourceRanges: [] 377 | ## Set the externalTrafficPolicy in the Service to either Cluster or Local 378 | # externalTrafficPolicy: Cluster 379 | 380 | ## set this to false to not have colorized logs 381 | tty: true 382 | 383 | extraPorts: 384 | [] 385 | 386 | # These options allow you to expose another port from the Minecraft server, plugins such 387 | # as dynmap (8123) and bluemap (8100) will require this for access to their web interfaces 388 | # 389 | # - name: map 390 | # containerPort: 8123 391 | # protocol: TCP 392 | # service: 393 | # enabled: false 394 | # embedded: false 395 | # annotations: {} 396 | # type: ClusterIP 397 | # ## Set the external port if the rcon serviceType is NodePort 398 | ## nodePort: 399 | # loadBalancerIP: "" 400 | # loadBalancerSourceRanges: [] 401 | # externalTrafficPolicy: Cluster 402 | # port: 8123 403 | # ingress: 404 | # ingressClassName: nginx 405 | # enabled: false 406 | # annotations: 407 | ## Deprecated way for specifying the ingressClass. Kube.version < 1.18 408 | ## kubernetes.io/ingress.class: nginx 409 | # kubernetes.io/tls-acme: "true" 410 | # hosts: 411 | # - name: map.local 412 | # path: / 413 | # tls: 414 | # - secretName: map-tls 415 | # hosts: 416 | # - map.local 417 | 418 | query: 419 | # If you enable this, your server will be "published" to Gamespy 420 | enabled: false 421 | port: 25565 422 | 423 | ## Additional minecraft container environment variables 424 | ## Values can be either variable values or `valueFrom` yaml 425 | ## 426 | extraEnv: 427 | {} 428 | # some_variable: some value 429 | # another_variable: 430 | # valueFrom: 431 | # fieldRef: 432 | # fieldPath: status.hostIP 433 | 434 | ## Additional environment variables to add to the minecraft container from 435 | ## ConfigMaps and Secrets 436 | ## 437 | envFrom: [] 438 | 439 | persistence: 440 | labels: {} 441 | annotations: {} 442 | ## specify an alternative volume to be mounted to /data instead of datadir. 443 | # altDataVolumeName: "" 444 | ## minecraft data Persistent Volume Storage Class 445 | ## If defined, storageClassName: 446 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 447 | ## If undefined (the default) or set to null, no storageClassName spec is 448 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 449 | ## GKE, AWS & OpenStack) 450 | ## 451 | # storageClass: "-" 452 | dataDir: 453 | # Set this to false if you don't care to persist state between restarts. 454 | enabled: false 455 | Size: 1Gi 456 | accessModes: 457 | - ReadWriteOnce 458 | # existingClaim: nil 459 | ## specify a subpath in the volume where the data is. Useful when sharing volumes with other apps. 460 | # subPath: /path/to/dataDir 461 | 462 | podAnnotations: {} 463 | podLabels: {} 464 | 465 | deploymentAnnotations: {} 466 | deploymentLabels: {} 467 | 468 | serviceAnnotations: {} 469 | serviceLabels: {} 470 | 471 | rconServiceAnnotations: {} 472 | rconServiceLabels: {} 473 | 474 | # PLEASE NOTE! rcon must be enabled above! It does NOT require a nodePort or loadBalancerIP 475 | mcbackup: 476 | enabled: false 477 | 478 | image: 479 | repository: itzg/mc-backup 480 | tag: latest 481 | pullPolicy: IfNotPresent 482 | 483 | # wait 2 minutes before starting 484 | initialDelay: 2m 485 | 486 | # Sets `BACKUP_NAME`, defaults to `minecraftServer.worldSaveName` 487 | # WARN: When using restic and sharing the `mcbackup.resticRepository` across multiple minecraft server deployments: either `mcbackup.backupName` or `mcbackup.resticHostname` must be unique! 488 | backupName: 489 | 490 | # ***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!*** 491 | # backupInterval="1.5d" -> backup every one and a half days (36 hours) 492 | # backupInterval="2h 30m" -> backup every two and a half hours 493 | backupInterval: 24h 494 | 495 | # option lets you pause backups if no players are online. 496 | pauseIfNoPlayers: "false" 497 | 498 | # is set to a positive number, it'll delete old .tgz backup files from DEST_DIR. By default deletes backups older than a week. 499 | pruneBackupsDays: 7 500 | 501 | # Set to a negative value to retry indefinitely 502 | rconRetries: 5 503 | rconRetryInterval: 10s 504 | 505 | # is a comma-separated list of glob(3) patterns to exclude from backups. By default excludes all jar files (plugins, server files), 506 | # logs folder and cache (used by i.e. PaperMC server). 507 | excludes: "*.jar,cache,logs" 508 | 509 | # backup methods, see https://github.com/itzg/docker-mc-backup e.g. tar, rclone, restic, rsync 510 | backupMethod: tar 511 | # tar and rclone methods 512 | destDir: /backups 513 | # is a true/false flag that creates a symbolic link to the latest backup 514 | linkLatest: "false" 515 | # is the compression method used by tar. Valid value: gzip bzip2 zstd 516 | compressMethod: "gzip" 517 | # sets the parameters for zstd compression. The --long parameter affects RAM requirements for both compression and decompression 518 | # (the default of 25 means 2^25 bytes = 32 MB). 519 | zstdParameters: "-3 --long=25 --single-thread" 520 | # the name of the remote you've configured in your rclone.conf 521 | rcloneRemote: 522 | rcloneDestDir: 523 | rcloneCompressMethod: gzip 524 | 525 | # see https://rclone.org/ for details 526 | # this value is evaluated as a template 527 | rcloneConfig: 528 | # [remote] 529 | # type = google cloud storage 530 | # client_id = 531 | # client_secret = 532 | # token = {"AccessToken":"super","RefreshToken":"secret","Expiry":"date","Extra":null} 533 | # project_number = 12345678 534 | # object_acl = private 535 | # bucket_acl = private 536 | 537 | # if you prefer to create a secret from file (e.g. kubectl create secret generic my-rclone-config --from-file=~/.config/rclone/rclone.conf) 538 | # rcloneConfigExistingSecret: my-rclone-config 539 | 540 | resticRepository: "" 541 | # variable to define a space separated list of additional restic tags. see https://hub.docker.com/r/itzg/mc-backup 542 | resticAdditionalTags: "mc_backups" 543 | # see https://restic.readthedocs.io/en/latest/060_forget.html 544 | pruneResticRetention: "--keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 75" 545 | # Sets `RESTIC_HOSTNAME` 546 | # Required because the container hostname changes on every recreate of the pod which prevents restic from pruning snapshots from previous pods/hostnames 547 | # WARN: When using restic and sharing the `mcbackup.resticRepository` across multiple minecraft server deployments: either `mcbackup.backupName` or `mcbackup.resticHostname` must be unique! 548 | resticHostname: 549 | 550 | # 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 551 | resticEnvs: 552 | {} 553 | # RESTIC_PASSWORD: restic-password 554 | 555 | ## Additional minecraft container environment variables 556 | ## Values can be either variable values or `valueFrom` yaml 557 | ## 558 | extraEnv: 559 | {} 560 | # some_variable: some value 561 | # another_variable: 562 | # valueFrom: 563 | # fieldRef: 564 | # fieldPath: status.hostIP 565 | 566 | ## Additional environment variables to add to the mc-backup container from 567 | ## ConfigMaps and Secrets 568 | ## 569 | envFrom: [] 570 | 571 | resources: 572 | requests: 573 | memory: 512Mi 574 | cpu: 500m 575 | 576 | persistence: 577 | annotations: {} 578 | ## minecraft data Persistent Volume Storage Class 579 | ## If defined, storageClassName: 580 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 581 | ## If undefined (the default) or set to null, no storageClassName spec is 582 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 583 | ## GKE, AWS & OpenStack) 584 | ## 585 | # storageClass: "-" 586 | backupDir: 587 | # Set this to false if you don't care to persist state between restarts. 588 | enabled: false 589 | # existingClaim: nil 590 | Size: 1Gi 591 | accessModes: 592 | - ReadWriteOnce 593 | # dnsPolicy: ClusterFirst 594 | # dnsConfig: 595 | # options: 596 | # - name: ndots 597 | # value: '1' 598 | --------------------------------------------------------------------------------