8.4 KiB
8.4 KiB
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!