Context
NeuralNav's Kubernetes deployment currently only works on OpenShift. Three issues prevent it from running on standard Kubernetes (e.g., KIND on ARM Mac):
- Container images are amd64-only — Dockerfile hardcodes
--platform=linux/amd64, docker-compose.yml forces platform: linux/amd64. KIND on M-series Mac runs arm64 nodes.
- PostgreSQL image requires Red Hat auth —
registry.redhat.io/rhel9/postgresql-16:latest returns 401 on clusters without a Red Hat pull secret.
- OpenShift Routes don't exist on standard K8s —
route.openshift.io/v1 CRD is not available.
Proposed Changes
1. Multi-arch container builds
Dockerfile (line 2): Remove --platform=linux/amd64 from FROM line.
docker-compose.yml (lines 46, 90): Remove platform: linux/amd64 from backend and ui services. Local docker compose build will now build for the native platform.
Makefile: Add variables and a docker-buildx target for multi-arch registry pushes:
- New variables:
BACKEND_IMAGE, UI_IMAGE, IMAGE_TAG, PLATFORMS (default linux/amd64,linux/arm64)
- New target
docker-buildx: Uses docker buildx build --platform $(PLATFORMS) --push for both backend and UI images. Creates a buildx builder lazily if one doesn't exist.
- Keep existing
docker-build (local native-arch via docker-compose) and docker-push (single-arch tag+push) unchanged.
PLATFORMS is overridable to add more architectures in the future (e.g., make docker-buildx PLATFORMS=linux/amd64,linux/arm64,linux/s390x).
2. Platform-specific PostgreSQL manifests
Replace deploy/kubernetes/postgres.yaml with two variants:
deploy/kubernetes/postgres-openshift.yaml — Current file renamed. Red Hat image (registry.redhat.io/rhel9/postgresql-16:latest), POSTGRESQL_* env vars, mount at /var/lib/pgsql/data.
deploy/kubernetes/postgres-kubernetes.yaml — New file. Official image (postgres:16, multi-arch, public), POSTGRES_* env vars, mount at /var/lib/postgresql/data. Same PVC, Service, probes, and resource limits.
Delete deploy/kubernetes/postgres.yaml after creating both variants.
3. Rewrite deploy-all.sh with target argument
deploy/kubernetes/deploy-all.sh — Rewrite to accept openshift or kubernetes as a required positional argument:
openshift: Uses oc, applies postgres-openshift.yaml and route.yaml
kubernetes: Uses kubectl, applies postgres-kubernetes.yaml, skips routes, prints kubectl port-forward instructions for accessing UI and backend
Shared manifests applied for both targets: namespace, secrets, ollama, backend, ui, db-init-job.
Script resolves paths relative to its own location (not cwd) so it works from anywhere.
4. Files NOT changed
| File |
Reason |
route.yaml |
Already isolated; only applied for OpenShift |
backend.yaml |
MODEL_CATALOG_URL is inert when service doesn't exist |
ollama.yaml |
ollama/ollama:latest is already multi-arch |
ui/Dockerfile |
Already has no platform constraint |
| All other shared manifests |
Platform-independent |
File Summary
| File |
Action |
Dockerfile |
Edit: remove --platform=linux/amd64 |
docker-compose.yml |
Edit: remove two platform: linux/amd64 lines |
Makefile |
Edit: add variables + docker-buildx target |
deploy/kubernetes/postgres.yaml |
Delete (replaced by two variants) |
deploy/kubernetes/postgres-openshift.yaml |
Create (copy of current postgres.yaml) |
deploy/kubernetes/postgres-kubernetes.yaml |
Create (official postgres:16 image) |
deploy/kubernetes/deploy-all.sh |
Rewrite with target argument |
Verification
- Local docker-compose on ARM Mac:
docker compose build should build arm64 images natively
- KIND deployment on ARM Mac:
./deploy-all.sh kubernetes — all pods should reach Ready
- Multi-arch push:
make docker-buildx should build+push amd64 and arm64 manifests to quay.io
- OpenShift deployment:
./deploy-all.sh openshift should work as before (uses oc, Red Hat postgres, Routes)
Context
NeuralNav's Kubernetes deployment currently only works on OpenShift. Three issues prevent it from running on standard Kubernetes (e.g., KIND on ARM Mac):
--platform=linux/amd64, docker-compose.yml forcesplatform: linux/amd64. KIND on M-series Mac runs arm64 nodes.registry.redhat.io/rhel9/postgresql-16:latestreturns 401 on clusters without a Red Hat pull secret.route.openshift.io/v1CRD is not available.Proposed Changes
1. Multi-arch container builds
Dockerfile(line 2): Remove--platform=linux/amd64from FROM line.docker-compose.yml(lines 46, 90): Removeplatform: linux/amd64from backend and ui services. Localdocker compose buildwill now build for the native platform.Makefile: Add variables and adocker-buildxtarget for multi-arch registry pushes:BACKEND_IMAGE,UI_IMAGE,IMAGE_TAG,PLATFORMS(defaultlinux/amd64,linux/arm64)docker-buildx: Usesdocker buildx build --platform $(PLATFORMS) --pushfor both backend and UI images. Creates a buildx builder lazily if one doesn't exist.docker-build(local native-arch via docker-compose) anddocker-push(single-arch tag+push) unchanged.PLATFORMSis overridable to add more architectures in the future (e.g.,make docker-buildx PLATFORMS=linux/amd64,linux/arm64,linux/s390x).2. Platform-specific PostgreSQL manifests
Replace
deploy/kubernetes/postgres.yamlwith two variants:deploy/kubernetes/postgres-openshift.yaml— Current file renamed. Red Hat image (registry.redhat.io/rhel9/postgresql-16:latest),POSTGRESQL_*env vars, mount at/var/lib/pgsql/data.deploy/kubernetes/postgres-kubernetes.yaml— New file. Official image (postgres:16, multi-arch, public),POSTGRES_*env vars, mount at/var/lib/postgresql/data. Same PVC, Service, probes, and resource limits.Delete
deploy/kubernetes/postgres.yamlafter creating both variants.3. Rewrite deploy-all.sh with target argument
deploy/kubernetes/deploy-all.sh— Rewrite to acceptopenshiftorkubernetesas a required positional argument:openshift: Usesoc, appliespostgres-openshift.yamlandroute.yamlkubernetes: Useskubectl, appliespostgres-kubernetes.yaml, skips routes, printskubectl port-forwardinstructions for accessing UI and backendShared manifests applied for both targets: namespace, secrets, ollama, backend, ui, db-init-job.
Script resolves paths relative to its own location (not cwd) so it works from anywhere.
4. Files NOT changed
route.yamlbackend.yamlMODEL_CATALOG_URLis inert when service doesn't existollama.yamlollama/ollama:latestis already multi-archui/DockerfileFile Summary
Dockerfile--platform=linux/amd64docker-compose.ymlplatform: linux/amd64linesMakefiledocker-buildxtargetdeploy/kubernetes/postgres.yamldeploy/kubernetes/postgres-openshift.yamldeploy/kubernetes/postgres-kubernetes.yamldeploy/kubernetes/deploy-all.shVerification
docker compose buildshould build arm64 images natively./deploy-all.sh kubernetes— all pods should reach Readymake docker-buildxshould build+push amd64 and arm64 manifests to quay.io./deploy-all.sh openshiftshould work as before (uses oc, Red Hat postgres, Routes)