diff --git a/deploy/00-infisical.sh b/deploy/00-infisical.sh
new file mode 100755
index 0000000..90c46a6
--- /dev/null
+++ b/deploy/00-infisical.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# Parse command line arguments
+RECREATE=false
+for arg in "$@"; do
+  case $arg in
+    --recreate)
+      RECREATE=true
+      shift
+      ;;
+  esac
+done
+
+# Check if the secret already exists
+SECRET_EXISTS=$(kubectl get secret universal-auth-credentials -n infisical --ignore-not-found -o name)
+
+if [[ -n "$SECRET_EXISTS" && "$RECREATE" == "true" ]]; then
+  echo "Recreating Infisical bootstrap secret..."
+  kubectl delete secret universal-auth-credentials -n infisical
+  kubectl create secret generic universal-auth-credentials -n infisical \
+    --from-literal clientId=$(gopass show -o homelab/infisical/id) \
+    --from-literal clientSecret=$(gopass show -o homelab/infisical/secret)
+elif [[ -z "$SECRET_EXISTS" ]]; then
+  echo "Creating Infisical bootstrap secret..."
+  kubectl create secret generic universal-auth-credentials -n infisical \
+    --from-literal clientId=$(gopass show -o homelab/infisical/id) \
+    --from-literal clientSecret=$(gopass show -o homelab/infisical/secret)
+else
+  echo "Infisical bootstrap secret already exists, skipping creation (use --recreate to force)"
+fi
diff --git a/deploy/00-infisical/kustomization.yaml b/deploy/00-infisical/kustomization.yaml
new file mode 100644
index 0000000..4e8cae3
--- /dev/null
+++ b/deploy/00-infisical/kustomization.yaml
@@ -0,0 +1,5 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - ../../namespaces/infisical/
diff --git a/deploy/01-infra.sh b/deploy/01-infra.sh
new file mode 100755
index 0000000..aca7b56
--- /dev/null
+++ b/deploy/01-infra.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+echo -n "Checking for Infrastructure CRDs... "
+kubectl wait --for condition=established crd/httproutes.gateway.networking.k8s.io > /dev/null
+kubectl wait --for condition=established crd/volumes.longhorn.io > /dev/null
+kubectl wait --for condition=established crd/certificates.cert-manager.io > /dev/null
+echo "done"
diff --git a/deploy/01-infra/kustomization.yaml b/deploy/01-infra/kustomization.yaml
new file mode 100644
index 0000000..57bd8ca
--- /dev/null
+++ b/deploy/01-infra/kustomization.yaml
@@ -0,0 +1,8 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - ../../namespaces/cert-manager/
+  - ../../namespaces/homelab/
+  - ../../namespaces/longhorn/
+  - ../../namespaces/traefik/
diff --git a/deploy/10-apps/kustomization.yaml b/deploy/10-apps/kustomization.yaml
new file mode 100644
index 0000000..866cbee
--- /dev/null
+++ b/deploy/10-apps/kustomization.yaml
@@ -0,0 +1,5 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - ../../namespaces/
diff --git a/justfile b/justfile
new file mode 100644
index 0000000..238300b
--- /dev/null
+++ b/justfile
@@ -0,0 +1,43 @@
+set export := true
+verbose := "false"
+diff := "kubectl diff -k"
+apply := "kubectl apply -k"
+redirect := if verbose == "true" { "" } else { "> /dev/null" }
+
+default:
+    @just --list
+
+infisical_bootstrap_secret recreate="":
+    @echo "-- Adding Infisical Bootstrap secret --"
+    @./deploy/00-infisical.sh {{ recreate }}
+
+_diff_infisical:
+    @echo "-- Diffing Infisical resources --"
+    @{{ diff }} deploy/00-infisical || [ $? -eq 1 ]
+_diff_infra:
+    @echo "-- Diffing Infra resources --"
+    @{{ diff }} deploy/01-infra || [ $? -eq 1 ]
+_diff_apps:
+    @echo "-- Diffing Apps --"
+    @{{ diff }} deploy/10-apps || [ $? -eq 1 ]
+    # @./deploy/10-apps.sh
+
+_apply_infisical:
+    @echo "-- Applying Infisical resources --"
+    @{{ apply }} deploy/00-infisical {{ redirect }}
+_apply_infra:
+    @echo "-- Applying Infra resources --"
+    @{{ apply }} deploy/01-infra {{ redirect }}
+    @./deploy/01-infra.sh
+_apply_apps:
+    @echo "-- Applying Apps --"
+    @{{ apply }} deploy/10-apps {{ redirect }}
+
+_apply_post: _apply_infra _apply_apps
+
+diff: _diff_infisical _diff_infra _diff_apps
+apply: _apply_infisical _apply_post
+_deploy recreate="": _apply_infisical (infisical_bootstrap_secret recreate) _apply_post
+deploy: _deploy
+
+redeploy: (_deploy "--recreate")
diff --git a/namespaces/ai/kustomization.yaml b/namespaces/ai/kustomization.yaml
new file mode 100644
index 0000000..c8b62e6
--- /dev/null
+++ b/namespaces/ai/kustomization.yaml
@@ -0,0 +1,8 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - namespace.yaml
+  - ollama/
+  - tabby/
+  - openwebui/
diff --git a/namespaces/apps/kustomization.yaml b/namespaces/apps/kustomization.yaml
new file mode 100644
index 0000000..8ff9905
--- /dev/null
+++ b/namespaces/apps/kustomization.yaml
@@ -0,0 +1,13 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - namespace.yaml
+  - smtp-secrets.yaml
+  - atuin/
+  - dolibarr/
+  - forgejo/
+  - linkwarden/
+  - mealie/
+  - paperless/
+  - vaultwarden/
diff --git a/namespaces/auth/namespace.yaml b/namespaces/auth/namespace.yaml
new file mode 100644
index 0000000..de5575d
--- /dev/null
+++ b/namespaces/auth/namespace.yaml
@@ -0,0 +1,7 @@
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+  labels:
+    homelab-access: "true"
+  name: auth
diff --git a/namespaces/cert-manager/kustomization.yaml b/namespaces/cert-manager/kustomization.yaml
new file mode 100644
index 0000000..c4065d9
--- /dev/null
+++ b/namespaces/cert-manager/kustomization.yaml
@@ -0,0 +1,6 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - namespace.yaml
+  - cert-manager/
diff --git a/namespaces/cert-manager/cert-manager/post/cluster-issuer.yaml b/namespaces/cert-manager/post-crd/cluster-issuer.yaml
similarity index 100%
rename from namespaces/cert-manager/cert-manager/post/cluster-issuer.yaml
rename to namespaces/cert-manager/post-crd/cluster-issuer.yaml
diff --git a/namespaces/cert-manager/cert-manager/post/consultjlpdotcom-cert.yaml b/namespaces/cert-manager/post-crd/consultjlpdotcom-cert.yaml
similarity index 100%
rename from namespaces/cert-manager/cert-manager/post/consultjlpdotcom-cert.yaml
rename to namespaces/cert-manager/post-crd/consultjlpdotcom-cert.yaml
diff --git a/namespaces/cert-manager/cert-manager/post/jlptechdotconsulting-cert.yaml b/namespaces/cert-manager/post-crd/jlptechdotconsulting-cert.yaml
similarity index 100%
rename from namespaces/cert-manager/cert-manager/post/jlptechdotconsulting-cert.yaml
rename to namespaces/cert-manager/post-crd/jlptechdotconsulting-cert.yaml
diff --git a/namespaces/cert-manager/post-crd/kustomization.yaml b/namespaces/cert-manager/post-crd/kustomization.yaml
new file mode 100644
index 0000000..2c22e3f
--- /dev/null
+++ b/namespaces/cert-manager/post-crd/kustomization.yaml
@@ -0,0 +1,8 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - cluster-issuer.yaml
+  - consultjlpdotcom-cert.yaml
+  - jlptechdotconsulting-cert.yaml
+  - leechpepindotcom-cert.yaml
diff --git a/namespaces/cert-manager/cert-manager/post/leechpepindotcom-cert.yaml b/namespaces/cert-manager/post-crd/leechpepindotcom-cert.yaml
similarity index 100%
rename from namespaces/cert-manager/cert-manager/post/leechpepindotcom-cert.yaml
rename to namespaces/cert-manager/post-crd/leechpepindotcom-cert.yaml
diff --git a/charts/gpu-runtime.yaml b/namespaces/charts/gpu-runtime.yaml
similarity index 100%
rename from charts/gpu-runtime.yaml
rename to namespaces/charts/gpu-runtime.yaml
diff --git a/namespaces/charts/kustomization.yaml b/namespaces/charts/kustomization.yaml
new file mode 100644
index 0000000..ce83de7
--- /dev/null
+++ b/namespaces/charts/kustomization.yaml
@@ -0,0 +1,6 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - namespace.yaml
+  - gpu-runtime.yaml
diff --git a/namespaces/core/kustomization.yaml b/namespaces/core/kustomization.yaml
new file mode 100644
index 0000000..4530ed9
--- /dev/null
+++ b/namespaces/core/kustomization.yaml
@@ -0,0 +1,9 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - namespace.yaml
+  - postgres/
+  - redis/
+  - tika/
+  - gotenburg/
diff --git a/namespaces/homelab/kustomization.yaml b/namespaces/homelab/kustomization.yaml
new file mode 100644
index 0000000..acbe0c1
--- /dev/null
+++ b/namespaces/homelab/kustomization.yaml
@@ -0,0 +1,6 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - namespace.yaml
+  - gateway.yaml
diff --git a/namespaces/infisical/kustomization.yaml b/namespaces/infisical/kustomization.yaml
new file mode 100644
index 0000000..2b24e11
--- /dev/null
+++ b/namespaces/infisical/kustomization.yaml
@@ -0,0 +1,6 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - namespace.yaml
+  - infisical/
diff --git a/namespaces/kustomization.yaml b/namespaces/kustomization.yaml
new file mode 100644
index 0000000..f7ad4ad
--- /dev/null
+++ b/namespaces/kustomization.yaml
@@ -0,0 +1,12 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - cert-manager/post-crd
+  - ai/
+  - apps/
+  - auth/
+  - core/
+  - charts/
+  - monitoring/
+  - public/
diff --git a/namespaces/longhorn/kustomization.yaml b/namespaces/longhorn/kustomization.yaml
new file mode 100644
index 0000000..22e44d4
--- /dev/null
+++ b/namespaces/longhorn/kustomization.yaml
@@ -0,0 +1,6 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - namespace.yaml
+  - longhorn/
diff --git a/namespaces/monitoring/kustomization.yaml b/namespaces/monitoring/kustomization.yaml
new file mode 100644
index 0000000..3e12b0a
--- /dev/null
+++ b/namespaces/monitoring/kustomization.yaml
@@ -0,0 +1,10 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - namespace.yaml
+  - smtp-secrets.yaml
+  - umami/
+  - ntfy/
+  - diun/
+  - healthchecks/
diff --git a/namespaces/public/kustomization.yaml b/namespaces/public/kustomization.yaml
new file mode 100644
index 0000000..dca4a51
--- /dev/null
+++ b/namespaces/public/kustomization.yaml
@@ -0,0 +1,5 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - namespace.yaml
diff --git a/namespaces/traefik/kustomization.yaml b/namespaces/traefik/kustomization.yaml
new file mode 100644
index 0000000..08aa538
--- /dev/null
+++ b/namespaces/traefik/kustomization.yaml
@@ -0,0 +1,6 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+  - namespace.yaml
+  - traefik/