Problem
faforever/faf-python-server is currently published as an OCI image index that lists only linux/amd64. On Apple Silicon (M1/M2/M3) Macs running the gitops-stack via Tilt against a local Kubernetes cluster (Rancher Desktop / k3d / kind), kubelet refuses to pull the image:
```
Failed to pull image "faforever/faf-python-server:v1.17.0":
no match for platform in manifest: not found
```
This is not a request to build an arm64 image — Rosetta on macOS already runs amd64 binaries transparently inside the VM. The problem is purely the manifest format the registry returns.
Root cause
`docker buildx` (even when building for a single platform) publishes an OCI image index with an explicit platform list:
```json
{
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{ "platform": { "architecture": "amd64", "os": "linux" } }
]
}
```
containerd does strict platform matching against this list, sees no arm64 entry, and fails the pull.
Other FAF images (e.g. faforever/faf-league-service) work fine on Apple Silicon because they are published with the legacy Docker v2 schema 2 manifest — a single manifest with no platform list. containerd has nothing to match against, so it pulls the bytes and Rosetta executes them.
Proposal
Push the image using the legacy single-manifest format instead of an OCI image index. Options:
- Use plain
docker build + docker push instead of docker buildx.
- Or with buildx, disable provenance/SBOM attestations and use the single-platform legacy output:
```bash
docker buildx build \
--platform linux/amd64 \
--provenance=false \
--sbom=false \
--output type=registry \
-t faforever/faf-python-server:$TAG .
```
Either approach yields a manifest that doesn't trigger strict platform matching, so kubelet pulls cleanly and Rosetta handles execution.
Benefit
Local k8s dev workflow (gitops-stack Tiltfile) works out-of-the-box on Apple Silicon — no per-developer manual docker pull --platform linux/amd64 … pre-pulls required.
Notes
Same request will be filed against FAForever/faf-rust-replayserver.
Problem
faforever/faf-python-serveris currently published as an OCI image index that lists onlylinux/amd64. On Apple Silicon (M1/M2/M3) Macs running the gitops-stack via Tilt against a local Kubernetes cluster (Rancher Desktop / k3d / kind), kubelet refuses to pull the image:```
Failed to pull image "faforever/faf-python-server:v1.17.0":
no match for platform in manifest: not found
```
This is not a request to build an arm64 image — Rosetta on macOS already runs amd64 binaries transparently inside the VM. The problem is purely the manifest format the registry returns.
Root cause
`docker buildx` (even when building for a single platform) publishes an OCI image index with an explicit platform list:
```json
{
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{ "platform": { "architecture": "amd64", "os": "linux" } }
]
}
```
containerd does strict platform matching against this list, sees no
arm64entry, and fails the pull.Other FAF images (e.g.
faforever/faf-league-service) work fine on Apple Silicon because they are published with the legacy Docker v2 schema 2 manifest — a single manifest with no platform list. containerd has nothing to match against, so it pulls the bytes and Rosetta executes them.Proposal
Push the image using the legacy single-manifest format instead of an OCI image index. Options:
docker build+docker pushinstead ofdocker buildx.```bash
docker buildx build \
--platform linux/amd64 \
--provenance=false \
--sbom=false \
--output type=registry \
-t faforever/faf-python-server:$TAG .
```
Either approach yields a manifest that doesn't trigger strict platform matching, so kubelet pulls cleanly and Rosetta handles execution.
Benefit
Local k8s dev workflow (gitops-stack Tiltfile) works out-of-the-box on Apple Silicon — no per-developer manual
docker pull --platform linux/amd64 …pre-pulls required.Notes
Same request will be filed against
FAForever/faf-rust-replayserver.