diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml
new file mode 100644
index 0000000..4b03b1c
--- /dev/null
+++ b/.github/workflows/build-test.yaml
@@ -0,0 +1,44 @@
+name: Test UDS Capability
+
+on:
+  pull_request:
+    paths-ignore:
+      - "**.md"
+      - "docs/**"
+      - "CODEOWNERS"
+
+permissions:
+  id-token: write
+  contents: read
+
+jobs:
+  test-clean-install:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        image: ["ghcr.io/defenseunicorns/oss/uds-k3d-k3s"]
+        version: ["v1.27.11-k3s1", "v1.28.7-k3s1", "v1.29.2-k3s1"]
+        # Test the default image as well
+        include:
+          - image: "rancher/k3s"
+            version: "v1.27.4-k3s1"
+
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Setup UDS
+        if: always()
+        uses: defenseunicorns/uds-common/.github/actions/setup@v0.3.6
+        with:
+          username: ${{secrets.IRON_BANK_ROBOT_USERNAME}}
+          password: ${{secrets.IRON_BANK_ROBOT_PASSWORD}}
+
+      - name: Build the custom k3s image
+        if: ${{matrix.image}} != "rancher/k3s"
+        run: uds run build-image --set VERSION=${{matrix.version}}
+
+      - name: Create and deploy the uds-k3d package
+        run: uds run --set IMAGE_NAME=${{matrix.image}} --set VERSION=${{matrix.version}}
+
+      - name: Validate uds-k3d package
+        run: uds run validate
diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml
deleted file mode 100644
index 6064a0c..0000000
--- a/.github/workflows/build-test.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: Test UDS Capability
-
-on:
-  pull_request:
-    paths-ignore:
-      - "**.md"
-      - "docs/**"
-      - "CODEOWNERS"
-
-permissions:
-  id-token: write
-  contents: read
-
-jobs:
-  test-clean-install:
-    runs-on: ubuntu-latest
-
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Setup UDS
-        if: always()
-        uses: defenseunicorns/uds-common/.github/actions/setup@v0.2.2
-
-      - name: Create and deploy the uds-k3d package
-        run: uds run
-
-      - name: Validate uds-k3d package
-        run: uds run validate
-
diff --git a/.github/workflows/publish-image.yaml b/.github/workflows/publish-image.yaml
new file mode 100644
index 0000000..925e2fc
--- /dev/null
+++ b/.github/workflows/publish-image.yaml
@@ -0,0 +1,40 @@
+name: Publish k3s image
+
+on:
+  push:
+    branches:
+      - main
+    paths:
+      - docker/**
+      - .github/workflows/publish-image.yaml
+
+jobs:
+  publish-k3s-image:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        version: ["v1.27.11-k3s1", "v1.28.7-k3s1", "v1.29.2-k3s1"]
+
+    permissions:
+      contents: read
+      packages: write
+
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Setup UDS
+        if: always()
+        uses: defenseunicorns/uds-common/.github/actions/setup@v0.3.6
+        with:
+          username: ${{secrets.IRON_BANK_ROBOT_USERNAME}}
+          password: ${{secrets.IRON_BANK_ROBOT_PASSWORD}}
+
+      - name: Login to GHCR
+        uses: docker/login-action@v3
+        with:
+          registry: ghcr.io
+          username: dummy
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Publish the custom k3s image
+        run: uds run publish-image --set VERSION=${{matrix.version}}
diff --git a/.github/workflows/tag-and-release.yml b/.github/workflows/tag-and-release.yaml
similarity index 90%
rename from .github/workflows/tag-and-release.yml
rename to .github/workflows/tag-and-release.yaml
index c2ff113..0c39903 100644
--- a/.github/workflows/tag-and-release.yml
+++ b/.github/workflows/tag-and-release.yaml
@@ -34,7 +34,10 @@ jobs:
 
       - name: Setup UDS
         if: always()
-        uses: defenseunicorns/uds-common/.github/actions/setup@v0.2.2
+        uses: defenseunicorns/uds-common/.github/actions/setup@v0.3.6
+        with:
+          username: ${{secrets.IRON_BANK_ROBOT_USERNAME}}
+          password: ${{secrets.IRON_BANK_ROBOT_PASSWORD}}
 
       - name: Login to GHCR
         uses: docker/login-action@v3
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644
index 0000000..85670f8
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,5 @@
+ARG K3S_TAG="v1.28.7-k3s1"
+
+FROM rancher/k3s:$K3S_TAG as k3s
+
+COPY config.toml.tmpl /var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl
diff --git a/docker/config.toml.tmpl b/docker/config.toml.tmpl
new file mode 100644
index 0000000..ed0c46f
--- /dev/null
+++ b/docker/config.toml.tmpl
@@ -0,0 +1,27 @@
+# This is a custom configuration that has a specific registry cert config removed to prevent zarf init issues.
+version = 2
+
+[plugins."io.containerd.internal.v1.opt"]
+  path = "/var/lib/rancher/k3s/agent/containerd"
+
+[plugins."io.containerd.grpc.v1.cri"]
+  stream_server_address = "127.0.0.1"
+  stream_server_port = "10010"
+  enable_selinux = false
+  enable_unprivileged_ports = true
+  enable_unprivileged_icmp = true
+  sandbox_image = "rancher/mirrored-pause:3.6"
+
+[plugins."io.containerd.grpc.v1.cri".containerd]
+  snapshotter = "overlayfs"
+  disable_snapshot_annotations = true
+  
+[plugins."io.containerd.grpc.v1.cri".cni]
+  bin_dir = "/bin"
+  conf_dir = "/var/lib/rancher/k3s/agent/etc/cni/net.d"
+
+[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
+  runtime_type = "io.containerd.runc.v2"
+
+[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
+  SystemdCgroup = false
diff --git a/tasks.yaml b/tasks.yaml
index 6701c49..33b430f 100644
--- a/tasks.yaml
+++ b/tasks.yaml
@@ -1,3 +1,9 @@
+variables:
+  - name: VERSION
+    default: "v1.28.7-k3s1"
+  - name: IMAGE_NAME
+    default: "ghcr.io/defenseunicorns/oss/uds-k3d-k3s"
+
 tasks:
   - name: default
     description: "Build and deploy uds-k3d"
@@ -6,7 +12,7 @@ tasks:
         cmd: "uds zarf package create --confirm"
 
       - description: "Deploy UDS K3d package"
-        cmd: "uds zarf package deploy zarf-package-uds-k3d-*.tar.zst --confirm"
+        cmd: "uds zarf package deploy zarf-package-uds-k3d-*.tar.zst --confirm --set K3D_IMAGE=${IMAGE_NAME}:${VERSION}"
 
   - name: validate
     actions:
@@ -27,3 +33,21 @@ tasks:
             echo "CoreDNS patch failed, foo.uds.dev is resolving to 127.0.0.1"
             exit 1
           fi
+      - description: Validate zarf init
+        cmd: |
+          set -e
+          # uds zarf tools download-init does not work in 0.9.4 - https://github.com/defenseunicorns/uds-cli/issues/517
+          uds zarf package pull oci://ghcr.io/defenseunicorns/packages/init:v$(uds zarf version)
+          mv zarf-init-amd64-v$(uds zarf version).tar.zst zarf-init-amd64-$(uds zarf version).tar.zst
+          # Test zarf init due to containerd issue - https://github.com/defenseunicorns/zarf/issues/592
+          uds zarf init --confirm
+
+  - name: build-image
+    actions:
+      - description: Build the custom k3s image
+        cmd: docker build -t ${IMAGE_NAME}:${VERSION} --build-arg K3S_TAG=${VERSION} docker/
+
+  - name: publish-image 
+    actions:
+      - description: Publish the custom k3s image
+        cmd: docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag ${IMAGE_NAME}:${VERSION} docker