Files
wiki.tipsy.codes/valheim.md
2025-12-25 14:31:08 -08:00

312 lines
8.4 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

It turns out that you can run x86 applications on ARM machines, which is super cool. But it requires a bit of nonsense. Here is how I got the Valheim server to work.
## Dockerfile
I created a docker file like:
```
# Use Ubuntu 22.04 as base
FROM weilbyte/box:debian-11
RUN apt update && apt upgrade -y
RUN apt install -y curl libpulse-dev libatomic1 libc6
https://git.tipsy.codes/charles/skubelb# Create user steam
RUN useradd -m steam
# Change user to steam
USER steam
# Go to /home/steam/Steam
WORKDIR /home/steam/Steam
# Download and extract SteamCMD
RUN curl -sqL "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" | tar zxvf -
RUN /usr/local/bin/box64 /home/steam/Steam/steamcmd.sh +force_install_dir /home/steam/Valheim +login anonymous +app_update 896660 validate +exit
WORKDIR /home/steam/Valheim
COPY start_server.sh /home/steam/Valheim
ENTRYPOINT ["/usr/local/bin/box64", "/home/steam/Valheim/start_server.sh"]
```
I built and pushed this image with:
```
docker build -t docker.tipsy.codes/valheim:20251214 .
```
## k3s config
To deploy this, I made added some files to my Flux repo. Here is a tree:
```
tree apps/prod/valheim
apps/prod/valheim
├── deployment.yaml
├── ingress.yaml
├── kustomization.yaml
├── namespace.yaml
├── pvc.yaml
├── pv.yaml
└── service.yaml
1 directory, 7 files
```
The most interesting files are:
```
find apps/prod/valheim/* -exec echo '# {}' \; -exec cat {} \;
# apps/prod/valheim/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: valheim
 namespace: valheim
spec:
 replicas: 1
 selector:
   matchLabels:
     app: valheim
 template:
   metadata:
     labels:
       app: valheim
   spec:
     containers:
       - name: valheim
         image: docker.tipsy.codes/valheim:20251214
         ports:
           - containerPort: 2456
             protocol: UDP
           - containerPort: 2457
             protocol: UDP
           - containerPort: 9001
             protocol: TCP
           - containerPort: 80
             protocol: TCP
         volumeMounts:
           - name: valheim-data
             mountPath: /opt/valheim
           - name: valheim-config
             mountPath: /config
     volumes:
       - name: valheim-data
         persistentVolumeClaim:
           claimName: valheim-pvc
       - name: valheim-config
         persistentVolumeClaim:
           claimName: valheim-config-pvc
# apps/prod/valheim/ingress.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRouteUDP
metadata:
 name: valheim-udp1
spec:
 # By default, IngressRouteUDP listens to all UDP entry points if 'entryPoints' is not specified.
 entryPoints:
   - valheim-udp1
 routes:
   - services:
       - name: valheim
         port: 2456 # Replace with your service port
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteUDP
metadata:
 name: valheim-udp2
spec:
 # By default, IngressRouteUDP listens to all UDP entry points if 'entryPoints' is not specified.
 entryPoints:
   - valheim-udp2
 routes:
   - services:
       - name: valheim
         port: 2457 # Replace with your service port
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
 name: valheim-tcp1
spec:
 # By default, IngressRouteUDP listens to all UDP entry points if 'entryPoints' is not specified.
 entryPoints:
   - valheim-tcp1
 routes:
   - match: HostSNI(`*`)
     services:
       - name: valheim
         port: 2456 # Replace with your service port
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
 name: valheim-tcp2
spec:
 # By default, IngressRouteUDP listens to all UDP entry points if 'entryPoints' is not specified.
 entryPoints:
   - valheim-tcp2
 routes:
   - match: HostSNI(`*`)
     services:
       - name: valheim
         port: 2457 # Replace with your service port
# apps/prod/valheim/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
 - ./namespace.yaml
 - ./pvc.yaml
 - ./deployment.yaml
 - ./service.yaml
 - ./ingress.yaml
 - ./pv.yaml
patches:
 - patch: |
     - op: replace
       path: /metadata/namespace
       value: valheim
   target:
     name: ".*"
# apps/prod/valheim/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
 name: valheim
# apps/prod/valheim/pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: valheim-pvc
 namespace: valheim
spec:
 storageClassName: local-path
 accessModes:
   - ReadWriteOnce
 resources:
   requests:
     storage: 100Gi
 volumeName: valheim-pv
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: valheim-config-pvc
 namespace: valheim
spec:
 storageClassName: local-path
 accessModes:
   - ReadWriteOnce
 resources:
   requests:
     storage: 100Gi
 volumeName: valheim-config-pv
# apps/prod/valheim/pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
 name: valheim-pv
spec:
 capacity:
   storage: 100Gi
 volumeMode: Filesystem
 accessModes:
   - ReadWriteOnce
 persistentVolumeReclaimPolicy: Retain
 storageClassName: local-path
 claimRef:
   namespace: valheim
   name: valheim-pvc
 local:
   path: /var/lib/rancher/k3s/storage/valheim-pvc
 nodeAffinity:
   required:
     nodeSelectorTerms:
       - matchExpressions:
           - key: kubernetes.io/hostname
             operator: In
             values:
               - machop
---
apiVersion: v1
kind: PersistentVolume
metadata:
 name: valheim-config-pv
spec:
 capacity:
   storage: 100Gi
 volumeMode: Filesystem
 accessModes:
   - ReadWriteOnce
 persistentVolumeReclaimPolicy: Retain
 storageClassName: local-path
 claimRef:
   namespace: valheim
   name: valheim-config-pvc
 local:
   path: /var/lib/rancher/k3s/storage/valheim-config-pvc
 nodeAffinity:
   required:
     nodeSelectorTerms:
       - matchExpressions:
           - key: kubernetes.io/hostname
             operator: In
             values:
               - machop
# apps/prod/valheim/service.yaml
apiVersion: v1
kind: Service
metadata:
 name: valheim
 namespace: valheim
spec:
 selector:
   app: valheim
 ports:
   - name: udp-2456
     protocol: UDP
     port: 2456
     targetPort: 2456
   - name: udp-2457
     protocol: UDP
     port: 2457
     targetPort: 2457
   - name: tcp-2456
     protocol: TCP
     port: 2456
     targetPort: 2456
   - name: tcp-2457
     protocol: TCP
     port: 2457
     targetPort: 2457
```
I did have to make some changes to k3s configuration to open the correct ports:
```
charles@machop:~/p3/palworld-arm64$ sudo cat /var/lib/rancher/k3s/server/manifests/traefik-config.yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
 name: traefik
 namespace: kube-system
spec:
 valuesContent: |-
   ports:
     websecure:
       transport:
         respondingTimeouts:
           readTimeout: 180m
     valheim-udp1:
       port: 2456
       hostPort: 2456
       protocol: UDP
     valheim-udp2:
       port: 2457
       hostPort: 2457
       protocol: UDP
     valheim-tcp1:
       port: 2456
       hostPort: 2456
       protocol: TCP
     valheim-tcp2:
       port: 2457
       hostPort: 2457
       protocol: TCP
```
## Does it work?
Yeah, it seems to work. I had some trouble with crossplay, but I have no interest in playing with console peasants anyway.
Happy hunting!