Files
wiki.tipsy.codes/valheim.md

312 lines
8.4 KiB
Markdown
Raw Normal View History

2025-12-18 01:01:43 -08:00
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
2025-12-25 14:31:08 -08:00
https://git.tipsy.codes/charles/skubelb# Create user steam
2025-12-18 01:01:43 -08:00
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!