diff --git a/minecraft/mc-router.yaml b/minecraft/mc-router.yaml
new file mode 100644
index 0000000..e33ba06
--- /dev/null
+++ b/minecraft/mc-router.yaml
@@ -0,0 +1,193 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: mc-router
+  namespace: minecraft
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: services-watcher
+  namespace: minecraft
+rules:
+  - apiGroups: [""]
+    resources: ["services"]
+    verbs: ["watch", "list"]
+  - apiGroups: ["apps"]
+    resources: ["statefulsets", "statefulsets/scale"]
+    verbs: ["watch", "list", "get", "update"]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: mc-router-services-watcher
+  namespace: minecraft
+subjects:
+  - kind: ServiceAccount
+    name: mc-router
+    namespace: minecraft
+roleRef:
+  kind: ClusterRole
+  name: services-watcher
+  apiGroup: rbac.authorization.k8s.io
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: mc-router
+  namespace: minecraft
+spec:
+  type: NodePort
+  selector:
+    run: mc-router
+  ports:
+    - targetPort: web
+      name: web
+      port: 8080
+      nodePort: 30001
+    - targetPort: proxy
+      name: proxy
+      port: 25565
+      nodePort: 25565
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: mc-router
+  namespace: minecraft
+  labels:
+    run: mc-router
+spec:
+  selector:
+    matchLabels:
+      run: mc-router
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      namespace: minecraft
+      labels:
+        run: mc-router
+    spec:
+      serviceAccountName: mc-router
+      containers:
+        - image: itzg/mc-router
+          imagePullPolicy: Always
+          name: mc-router
+          args:
+            [
+              "--api-binding",
+              ":8080",
+              "--in-kube-cluster",
+              "--auto-scale-up",
+              "--debug",
+            ]
+          env:
+            - name: AUTO_SCALE_UP
+              value: "true"
+          ports:
+            - name: proxy
+              containerPort: 25565
+            - name: web
+              containerPort: 8080
+          resources:
+            requests:
+              memory: 50Mi
+              cpu: "100m"
+            limits:
+              memory: 100Mi
+              cpu: "250m"
+
+# Cron job for stopping empty servers
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: mc-shutdown
+  namespace: minecraft
+rules:
+  - apiGroups: ["apps"]
+    resources: ["statefulsets", "statefulsets/scale"]
+    verbs: ["list", "get", "update", "patch"]
+  - apiGroups: [""]
+    resources: ["pods", "pods/log"]
+    verbs: ["get", "list"]
+  - apiGroups: [""]
+    resources: ["pods/exec"]
+    verbs: ["create"]
+---
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: mc-shutdown
+  namespace: minecraft
+subjects:
+  - kind: ServiceAccount
+    name: mc-shutdown
+    namespace: default
+roleRef:
+  kind: ClusterRole
+  name: mc-shutdown
+  apiGroup: "rbac.authorization.k8s.io"
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: mc-shutdown
+  namespace: minecraft
+---
+apiVersion: batch/v1
+kind: CronJob
+metadata:
+  name: mc-shutdown
+  namespace: minecraft
+spec:
+  schedule: "*/5 * * * *"
+  concurrencyPolicy: Forbid
+  jobTemplate:
+    spec:
+      template:
+        spec:
+          serviceAccountName: mc-shutdown
+          restartPolicy: OnFailure
+          containers:
+            - name: shutdown
+              image: bitnami/kubectl:latest
+              imagePullPolicy: IfNotPresent
+              command:
+                - /bin/bash
+                - -c
+                - source shutdown-script.sh
+              volumeMounts:
+                - name: shutdown-script
+                  mountPath: /shutdown-script.sh
+                  subPath: shutdown-script.sh
+                  readOnly: true
+          volumes:
+            - name: shutdown-script
+              configMap:
+                name: shutdown-script
+                items:
+                  - key: shutdown-script.sh
+                    path: shutdown-script.sh
+# uses container label containertype=minecraft-server to find running servers
+# TODO: get ownerReferences link to StatefulSet/name from pod metadate instead of sed string manipulation
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: shutdown-script
+  namespace: minecraft
+data:
+  shutdown-script.sh: |
+    #!/bin/bash
+    MC_PODS=$(kubectl get pods -l containertype=minecraft-server -o=jsonpath="{range .items[*]}{.metadata.name},"| sed 's/,/\n/g')
+    for p in $MC_PODS; do
+      echo "found minecraft pod $p, sleeping 120 seconds to prevent shutdown before login"
+      sleep 120
+      deployment=$(echo $p |sed 's/-0//g')
+      # check online player count in the mc server
+      if [[ $(kubectl exec -i $p -- /usr/local/bin/mc-monitor status) == *"online=0"* ]] ;then
+        kubectl scale statefulset $deployment --replicas=0
+      fi
+    done
diff --git a/minecraft/tfg-deployment.yaml b/minecraft/tfg-deployment.yaml
index 944c966..2558806 100644
--- a/minecraft/tfg-deployment.yaml
+++ b/minecraft/tfg-deployment.yaml
@@ -1,26 +1,32 @@
 apiVersion: apps/v1
-kind: Deployment
+kind: StatefulSet
 metadata:
   name: tfg
   namespace: minecraft
   labels:
     app.kubernetes.io/name: tfg
 spec:
-  replicas: 1
   selector:
     matchLabels:
       app.kubernetes.io/name: tfg
-  strategy:
-    type: Recreate
+  replicas: 1
   template:
     metadata:
+      namespace: minecraft
       labels:
         app.kubernetes.io/name: tfg
+        containertype: minecraft-server
     spec:
       containers:
         - name: tfg
           image: itzg/minecraft-server:java21-graalvm
           env:
+            # Let jvm figure out memory based on limits
+            - name: MEMORY
+              value: ""
+            - name: JVM_XX_OPTS
+              value: "-XX:MaxRAMPercentage=75"
+
             - name: ALLOW_FLIGHT
               value: "true"
             - name: CF_API_KEY
@@ -38,8 +44,7 @@ spec:
               value: "TRUE"
             - name: MAX_TICK_TIME
               value: "-1"
-            - name: MEMORY
-              value: 12G
+
             - name: MOD_PLATFORM
               value: AUTO_CURSEFORGE
             - name: ONLINE_MODE
@@ -48,6 +53,7 @@ spec:
               value: "true"
             - name: SPAWN_PROTECTION
               value: "0"
+
             - name: OPS
               value: |
                 RoyalCat33
@@ -56,16 +62,32 @@ spec:
           ports:
             - containerPort: 25565
               protocol: TCP
+          resources:
+            requests:
+              cpu: "1"
+              memory: "2Gi"
+            limits:
+              cpu: "4"
+              memory: "10Gi"
+          readinessProbe:
+            exec:
+              command:
+                ["/usr/local/bin/mc-monitor", "status", "--host", "localhost"]
+            # Give it i + p * f seconds to be ready, so 120 seconds
+            initialDelaySeconds: 20
+            periodSeconds: 5
+            failureThreshold: 20
+          # Monitor ongoing liveness
+          livenessProbe:
+            exec:
+              command:
+                ["/usr/local/bin/mc-monitor", "status", "--host", "localhost"]
+            initialDelaySeconds: 120
+            periodSeconds: 60
           volumeMounts:
             - mountPath: /data
               name: tfg-data
-            - mountPath: /downloads
-              name: curseforge-downloads
-      restartPolicy: Always
       volumes:
         - name: tfg-data
           persistentVolumeClaim:
             claimName: tfg-data
-        - name: curseforge-downloads
-          persistentVolumeClaim:
-            claimName: curseforge-downloads
diff --git a/minecraft/tfg-service.yaml b/minecraft/tfg-service.yaml
index 1a771ee..c2b3cd0 100644
--- a/minecraft/tfg-service.yaml
+++ b/minecraft/tfg-service.yaml
@@ -5,6 +5,21 @@ metadata:
   namespace: minecraft
   labels:
     app.kubernetes.io/name: tfg
+  annotations:
+    mc-router.itzg.me/externalServerName: "tfg.mc.konfa.ch"
+spec:
+  selector:
+    app.kubernetes.io/name: tfg
+  ports:
+    - port: 25565
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: tfg-port
+  namespace: minecraft
+  labels:
+    app.kubernetes.io/name: tfg
 spec:
   type: NodePort
   selector:
@@ -14,3 +29,12 @@ spec:
       port: 25565
       targetPort: 25565
       nodePort: 32565
+---
+apiVersion: externaldns.k8s.io/v1alpha1
+kind: DNSEndpoint
+metadata:
+  name: tfg-dns-record
+  namespace: minecraft
+spec:
+  endpoints:
+    - dnsName: tfg.mc.konfa.ch