Import minecraft-server chart for Fleet migration stage 1 (java8 line)

Imports the chart from cluster-config functionally unchanged, wires it into
the publish/validate/install-test pipelines and publishes it as the first of
three Java lines (0.4.0+upjava8).

The only deviation from the source chart is the chart-global scaleDown flag
plus a server.replicas value, following the satisfactory pattern: two of the
three servers stand at 0 replicas in the cluster, which the chart could not
express, and Fleet would otherwise start them on reconcile. The default
(scaleDown: false) still renders replicas: 1, so the rendering of the running
server is unchanged - verified byte-identical against the three real values
files for all three Java lines.

Known deficiencies (hardening, probes, naming scheme, hardcoded values,
missing icon, the misleading mc-router auto-discovery annotations) are left
untouched on purpose and are scheduled for stage 2.
This commit is contained in:
jklein committed 2026-08-23 15:57:17 +02:00
1 parent d1f2ef0027
commit a68192e5fb
15 files changed
+502

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
+24
View File
@@ -0,0 +1,24 @@
apiVersion: v2
name: minecraft-server
description: A Helm chart for deploying a itzg/minecraft-server
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.4.0+upjava8
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "java8"
+35
View File
@@ -0,0 +1,35 @@
{{/*
Render the replica count for a Deployment/StatefulSet.
Input: dict
"scaleDown" the chart-global .Values.scaleDown flag (may be nil)
"replicas" the workload's replicas value (may be nil)
Rules (issue #25):
- scaleDown: true takes precedence and always yields 0.
- otherwise an explicitly set replicas value is used as given, including an
explicit 0 — Helm's "default" would swallow 0, hence the explicit
kindIs "invalid" nil check.
- a missing replicas value defaults to 1.
Usage (the values path to the workload's replicas varies per chart):
replicas: {{ include "minecraft-server.replicas" (dict "scaleDown" .Values.scaleDown "replicas" .Values.server.replicas) }}
NOTE: charts in this repo deliberately have no dependencies, so this helper is
duplicated into every chart's templates/_helpers.tpl with the chart's name as
define prefix. The reference implementation lives in template-chart.
This chart is a stage-1 import (issue #67) and does not yet follow the repo
conventions; only the replicas helper was taken over, because the scaleDown
flag is needed before the Fleet migration. The resources helper follows in
stage 2 together with the rest of the convention alignment.
*/}}
{{- define "minecraft-server.replicas" -}}
{{- if .scaleDown -}}
0
{{- else if not (kindIs "invalid" .replicas) -}}
{{- .replicas -}}
{{- else -}}
1
{{- end -}}
{{- end -}}
@@ -0,0 +1,42 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-init-config
data:
init.sh: |
echo "downloading serverpack"
wget -O /modpacks/serverpack.zip {{ .Values.curseforgeServerpack.downloadUrl }}
SERVERPACK_DIR="{{ .Values.curseforgeServerpack.workingDirectory }}"
BACKUP_DIR="/data/serverpack-backup"
if [ -d "$SERVERPACK_DIR" ]; then
echo "found installed server. Migrating..."
if [ -d "$BACKUP_DIR" ]; then
echo "clearing old Backup"
rm -rf $BACKUP_DIR
fi
echo "backing up old server-files"
cp -r $SERVERPACK_DIR $BACKUP_DIR
rm -rf $SERVERPACK_DIR
mkdir $SERVERPACK_DIR
echo "extracting new server-files"
tar -xvf /modpacks/serverpack.zip -C $SERVERPACK_DIR
echo "copying old configuration-data"
cp -r $BACKUP_DIR/world $SERVERPACK_DIR/world
cp $BACKUP_DIR/banned-ips.json $SERVERPACK_DIR/banned-ips.json
cp $BACKUP_DIR/banned-players.json $SERVERPACK_DIR/banned-players.json
cp $BACKUP_DIR/ops.json $SERVERPACK_DIR/ops.json
cp $BACKUP_DIR/whitelist.json $SERVERPACK_DIR/whitelist.json
echo "change owner of files"
chown -R 1000:1000 $SERVERPACK_DIR
echo "successfully migrated server"
# echo "deleting serverpack.zip"
# rm /modpacks/serverpack.zip
fi
+11
View File
@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .Release.Name }}-mc-volume-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.minecraft.resources.storage }}
storageClassName: longhorn
@@ -0,0 +1,6 @@
apiVersion: onepassword.com/v1
kind: OnePasswordItem
metadata:
name: {{ .Release.Name }}-mc-secret
spec:
itemPath: {{ .Values.secrets.minecraftServerRef }}
@@ -0,0 +1,25 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-service
{{- if .Values.mcRouterIntegration.enabled }}
annotations:
"mc-router.itzg.me/externalServerName": "{{ .Values.mcRouterIntegration.domain }}"
{{- end }}
spec:
selector:
app: {{ .Release.Name }}-server-deployment
{{- if .Values.mcRouterIntegration.enabled }}
ports:
- name: mc-port
port: 25565
targetPort: 25565
type: ClusterIP
{{- else }}
ports:
- nodePort: {{ .Values.server.outwardPort }}
port: 25565
targetPort: 25565
type: NodePort
{{- end }}
@@ -0,0 +1,153 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ .Release.Name }}-server-deployment
labels:
app: {{ .Release.Name }}
spec:
replicas: {{ include "minecraft-server.replicas" (dict "scaleDown" .Values.scaleDown "replicas" .Values.server.replicas) }}
selector:
matchLabels:
app: {{ .Release.Name }}-server-deployment
template:
metadata:
name: {{ .Release.Name }}-server-deployment
labels:
app: {{ .Release.Name }}-server-deployment
spec:
automountServiceAccountToken: false
containers:
- name: {{ .Release.Name }}-mc-server-container
image: "itzg/minecraft-server:{{ .Chart.AppVersion }}"
imagePullPolicy: IfNotPresent
ports:
- name: mc-port
containerPort: 35565
- name: minecraft-rcon
containerPort: 25575
- name: metrics
containerPort: 19565
env:
- name: EULA
value: "true"
- name: DUMP_SERVER_PROPERTIES
value: "true"
- name: MOTD
value: "{{ .Values.server.motd }}"
- name: DIFFICULTY
value: {{ .Values.minecraft.difficulty }}
{{- if .Values.minecraft.whitelist.enabled }}
- name: EXISTING_WHITELIST_FILE
value: {{ .Values.minecraft.whitelist.overridePolicy }}
- name: WHITELIST
value: {{ .Values.minecraft.whitelist.players }}
{{- end }}
- name: OPS
value: {{ .Values.minecraft.management.opPlayers }}
- name: EXISTING_OPS_FILE
value: "SYNCHRONIZE"
- name: RCON_PASSWORD
valueFrom:
secretKeyRef:
key: rcon-password
name: {{ .Release.Name }}-mc-secret
- name: MAX_PLAYERS
value: "{{ .Values.minecraft.management.maxPlayers }}"
- name: FORCE_GAMEMODE
value: "{{ .Values.minecraft.management.forceGameMode }}"
- name: SNOOPER_ENABLED
value: "false"
- name: MODE
value: "{{ .Values.minecraft.management.gameMode }}"
- name: LEVEL
value: "{{ .Values.minecraft.management.worldSaveName }}"
- name: SERVER_NAME
value: "{{ .Values.minecraft.management.serverName }}"
- name: VERSION
value: "{{ .Values.minecraft.version }}"
- name: ENABLE_RCON
value: "false"
- name: ENABLE_AUTOPAUSE
value: "false"
- name: MEMORY
value: "{{ .Values.minecraft.resources.memory }}G"
{{- if .Values.curseforge.enabled }}
- name: TYPE
value: "AUTO_CURSEFORGE"
- name: CF_API_KEY
valueFrom:
secretKeyRef:
key: curseforge-api-key
name: {{ .Release.Name }}-mc-secret
- name: CF_SLUG
value: "{{ .Values.curseforge.modpack.slug }}"
- name: CF_FILE_ID
value: "{{ .Values.curseforge.modpack.versionId }}"
- name: CF_EXCLUDE_MODS
value: "{{ .Values.curseforge.modpack.exclude }}"
- name: CF_OVERRIDES_EXCLUSIONS
value: "{{ .Values.curseforge.modpack.excludeOverride }}"
- name: CF_FORCE_INCLUDE_MODS
value: "{{ .Values.curseforge.modpack.include }}"
- name: CF_FORCE_SYNCHRONIZE
value: "{{ .Values.curseforge.forceReload }}"
{{- end }}
{{- if .Values.curseforgeServerpack.enabled }}
- name: TYPE
value: "CURSEFORGE"
- name: CF_SERVER_MOD
value: "/modpacks/serverpack.zip"
- name: CF_BASE_DIR
value: "{{ .Values.curseforgeServerpack.workingDirectory }}"
{{- end }}
{{- if .Values.ftb.enabled }}
- name: TYPE
value: FTBA
- name: FTB_MODPACK_ID
value: "{{ .Values.ftb.modpackId }}"
- name: FTB_MODPACK_VERSION_ID
value: "{{ .Values.ftb.versionId }}"
{{- end }}
resources:
requests:
cpu: "2"
memory: "4Gi"
ephemeral-storage: "100Mi"
limits:
cpu: "4"
memory: "12Gi"
ephemeral-storage: "200Mi"
volumeMounts:
- name: "mc-volume"
mountPath: /data
subPath: mc-data/
- name: "mc-volume"
mountPath: /modpacks
subPath: mc-modpacks/
{{- if .Values.curseforgeServerpack }}
initContainers:
- name: download-serverpack
image: alpine
command: [ 'sh', '/init/init.sh' ]
volumeMounts:
- name: "mc-volume"
mountPath: /modpacks
subPath: mc-modpacks/
- name: "mc-volume"
mountPath: /data
subPath: mc-data/
- name: init-script
mountPath: /init/init.sh
subPath: init.sh
{{- end }}
restartPolicy: Always
volumes:
- name: "mc-volume"
persistentVolumeClaim:
claimName: {{ .Release.Name }}-mc-volume-claim
- name: init-script
configMap:
name: {{ .Release.Name }}-init-config
serviceName: {{ .Release.Name }}-service
+55
View File
@@ -0,0 +1,55 @@
# Scale the whole chart down without uninstalling it: scaleDown: true renders
# every Deployment/StatefulSet with replicas: 0 (and suspends CronJobs) and
# takes precedence over any per-workload replicas value. PVCs, Secrets and
# Services stay in place; scaleDown: false brings the workloads back up.
scaleDown: false
secrets:
minecraftServerRef: null
server:
# Replica count for this workload; 0 is allowed and scales it down.
# The chart-global scaleDown flag takes precedence.
replicas: 1
outwardPort: 30565
motd: 'Running \u00A72\u00A7o%MODPACK_NAME% \u00A70version \u00A7r%env:MODPACK_VERSION%'
minecraft:
# Valid values are: peaceful, easy, normal, and hard
difficulty: "easy"
whitelist:
enabled: "true"
overridePolicy: "MERGE"
# Comma-separated List of Players
players: null
management:
# Comma-separated List of Players
opPlayers: null
maxPlayers: 10
forceGameMode: true
# Valid values are: creative, survival, adventure, spectator (only for Minecraft 1.8 or later)
gameMode: survival
worldSaveName: world
serverName: mc-server
resources:
storage: "32Gi"
memory: "4"
version: "LATEST"
curseforge:
enabled: false
forceReload: false
modpack:
slug: null
versionId: null
exclude: null
excludeOverride: null
include: null
ftb:
enabled: false
modpackId: null
versionId: null
curseforgeServerpack:
enabled: false
downloadUrl: null
workingDirectory: '/data/serverpack'
mcRouterIntegration:
enabled: false
domain: null