Skip to content

PaperMCServer

The PaperMCServer CRD defines a Minecraft server instance managed by the operator.

Overview

apiVersion: mc.k8s.lex.la/v1alpha1
kind: PaperMCServer
metadata:
  name: my-server
  namespace: minecraft
spec:
  updateStrategy: "auto"
  # ... configuration

Spec Fields

updateStrategy

Required — Defines how Paper version updates are handled.

Value Description
latest Always use newest Paper version from Docker Hub (ignores plugin compatibility)
auto Constraint solver picks best version compatible with all plugins
pin Stay on specific version, auto-update to latest build
build-pin Fully pinned version and build, no automatic updates
spec:
  updateStrategy: "auto"  # Recommended for production

See Update Strategies for detailed guide.

version

Optional — Target Paper version. Required for pin and build-pin strategies.

spec:
  updateStrategy: "pin"
  version: "1.21.1"  # Pinned Minecraft version

build

Optional — Target Paper build number.

  • With pin strategy: minimum build (operator will still auto-update to newer builds)
  • With build-pin strategy: exact build (no automatic updates)
spec:
  updateStrategy: "build-pin"
  version: "1.21.1"
  build: 125  # Exact build number

updateDelay

Optional — Grace period before applying Paper updates. Useful for waiting for community feedback on new releases.

spec:
  updateDelay: "168h"  # Wait 7 days before applying updates

updateSchedule

Required — Defines when to check and apply updates.

Field Description
checkCron Cron expression for checking updates
maintenanceWindow.enabled Enable scheduled updates
maintenanceWindow.cron Cron expression for applying updates
spec:
  updateSchedule:
    checkCron: "0 3 * * *"           # Check daily at 3am
    maintenanceWindow:
      enabled: true
      cron: "0 4 * * 0"              # Apply updates Sunday 4am

Cron Format

Standard cron format: minute hour day-of-month month day-of-week

gracefulShutdown

Required — Configures graceful server shutdown.

Field Description
timeout Shutdown timeout (should match terminationGracePeriodSeconds)
spec:
  gracefulShutdown:
    timeout: 300s  # 5 minutes for world save

Timeout Configuration

The timeout should match your StatefulSet's terminationGracePeriodSeconds. Too short may cause world corruption. Minimum recommended: 300s.

rcon

Required — Configures RCON for graceful shutdown commands.

Field Description Default
enabled Enable RCON
passwordSecret.name Secret name
passwordSecret.key Key in Secret
port RCON port 25575
spec:
  rcon:
    enabled: true
    passwordSecret:
      name: my-server-rcon
      key: password
    port: 25575

Create the secret:

kubectl create secret generic my-server-rcon \
  --from-literal=password=your-secure-password

service

Optional — Configures the Kubernetes Service for the server.

Field Description Default
type Service type LoadBalancer
annotations Custom annotations
loadBalancerIP Static IP for LoadBalancer
spec:
  service:
    type: LoadBalancer
    annotations:
      metallb.universe.tf/loadBalancerIPs: "192.168.1.100"
    loadBalancerIP: "192.168.1.100"

podTemplate

Required — Template for the StatefulSet pod.

This is a standard Kubernetes PodTemplateSpec. Key fields:

Field Description
spec.containers[0].resources CPU/memory requests and limits
spec.containers[0].env Environment variables
spec.volumes Additional volumes
spec:
  podTemplate:
    spec:
      containers:
        - name: minecraft
          resources:
            requests:
              memory: "2Gi"
              cpu: "500m"
            limits:
              memory: "4Gi"
          env:
            - name: JAVA_OPTS
              value: "-Xmx3G -Xms1G"
      volumes:
        - name: config
          configMap:
            name: server-config

Status Fields

The operator updates the status to reflect the current state.

currentVersion / currentBuild

Currently running Paper version and build.

status:
  currentVersion: "1.21.4"
  currentBuild: 125

desiredVersion / desiredBuild

Target version the operator wants to run (resolved from updateStrategy).

status:
  desiredVersion: "1.21.4"
  desiredBuild: 130

plugins

List of matched Plugin resources and their versions.

status:
  plugins:
    - pluginRef:
        name: essentialsx
        namespace: minecraft
      resolvedVersion: "2.21.0"
      currentVersion: "2.20.1"
      desiredVersion: "2.21.0"
      compatible: true
      source: hangar

availableUpdate

Next available update if any.

status:
  availableUpdate:
    version: "1.21.4"
    build: 130
    releasedAt: "2024-01-15T10:00:00Z"
    foundAt: "2024-01-16T03:00:00Z"
    plugins:
      - pluginRef:
          name: essentialsx
          namespace: minecraft
        version: "2.21.0"

lastUpdate

Record of the most recent update attempt.

status:
  lastUpdate:
    appliedAt: "2024-01-14T04:00:00Z"
    previousVersion: "1.21.3"
    successful: true

updateBlocked

Indicates if updates are blocked due to compatibility issues.

status:
  updateBlocked:
    blocked: true
    reason: "Plugin incompatible with target version"
    blockedBy:
      plugin: "old-plugin"
      version: "1.0.0"
      supportedVersions:
        - "1.20.4"
        - "1.20.6"

conditions

Standard Kubernetes conditions.

Type Description
Ready Server is running and accessible
Available StatefulSet is available
Progressing Update in progress
Degraded Server has issues

Complete Example

apiVersion: mc.k8s.lex.la/v1alpha1
kind: PaperMCServer
metadata:
  name: survival
  namespace: minecraft
  labels:
    environment: production
    server-type: survival
spec:
  updateStrategy: "auto"
  updateDelay: "168h"  # Wait 7 days

  updateSchedule:
    checkCron: "0 3 * * *"
    maintenanceWindow:
      enabled: true
      cron: "0 4 * * 0"

  gracefulShutdown:
    timeout: 300s

  rcon:
    enabled: true
    passwordSecret:
      name: survival-rcon
      key: password

  service:
    type: LoadBalancer
    annotations:
      external-dns.alpha.kubernetes.io/hostname: survival.minecraft.example.com

  podTemplate:
    spec:
      containers:
        - name: minecraft
          resources:
            requests:
              memory: "4Gi"
              cpu: "1"
            limits:
              memory: "8Gi"
          env:
            - name: JAVA_OPTS
              value: "-Xmx6G -Xms2G -XX:+UseG1GC"
      nodeSelector:
        minecraft: "true"
      tolerations:
        - key: "minecraft"
          operator: "Exists"
          effect: "NoSchedule"

See Also