End-to-end deployment of FleetDM with its required backing services inside a local minikube cluster, following FleetDM's Option B — install MySQL and Redis/Valkey separately.
Orchestrated by Helmfile. All
off-the-shelf components use official upstream Helm charts; the
cluster-bootstrap, MySQL, schema-init and TLS-issuer pieces live as
local charts under ../../charts/.
The declarative spec lives at
../../helmfile.yaml.gotmpl. This
directory only holds the values files it references.
| Layer | Namespace | Release | Chart |
|---|---|---|---|
| Bootstrap | (cluster-wide) | bootstrap |
../../charts/bootstrap/ |
| Ingress | ingress-nginx |
ingress-nginx |
ingress-nginx/ingress-nginx |
| TLS — issuers | cert-manager |
cert-manager |
jetstack/cert-manager |
| TLS — root CA | cert-manager |
cert-manager-issuers |
../../charts/cert-manager-issuers/ |
| MySQL | database |
mysql |
../../charts/mysql/ (official mysql:8.4 image) |
| Schema bootstrap | fleet |
fleet-db-init |
../../charts/fleet-db-init/ |
| Valkey cache | cache |
valkey |
valkey/valkey |
| Fleet server | fleet |
fleet |
fleetdm/fleet |
Cross-namespace references used by Fleet:
- MySQL:
mysql.database.svc.cluster.local:3306 - Cache:
valkey.cache.svc.cluster.local:6379
The mysql-credentials Secret is mirrored into both database (for the
init-db Job) and fleet (for the prepare-db Job and the Fleet pod) by
the bootstrap chart.
bootstrap ──┬─► ingress-nginx ◄─── needs cert-manager-issuers
│
├─► cert-manager ─► cert-manager-issuers ──┐
│ │
├─► mysql ──► fleet-db-init ──┐ │
│ ├──► fleet ◄─┘
└─► valkey ───────────────────┘
- bootstrap — creates the four workload namespaces and the
mysql-credentials+ Fleet JWT Secrets. Auto-generates the JWT on first install and preserves it on upgrades via Helmlookup. - cert-manager — official
jetstack/cert-managerchart with CRDs. - cert-manager-issuers —
fleet-selfsignedClusterIssuer bootstraps a self-issued root CA Certificate (fleet-root-ca, 10y, in thecert-managernamespace), which thefleet-caClusterIssuer then uses to sign every leaf cert in the cluster. - ingress-nginx — LoadBalancer Service. Admission-webhook serving
cert is provisioned by cert-manager via
controller.admissionWebhooks.certManager.enabled=true; the chart's default-create/-patchHelm-hook Jobs are disabled to eliminate the race where theValidatingWebhookConfigurationwould briefly exist with an emptycaBundle. - mysql — single-pod StatefulSet running the official
mysql:8.4Docker image. PVC-backed, root password lives inmysql-credentials. - fleet-db-init —
init-dbJob creates thefleetschema + user;prepare-dbJob runsfleet prepare db --no-prompt. Both have a busybox TCP-wait initContainer and run as Helm post-install hooks. - valkey — official chart, standalone, no auth (local dev only).
- fleet — official
fleetdm/fleetchart. Ingress annotationcert-manager.io/cluster-issuer: fleet-camakes cert-manager mint a leaf cert intoSecret/fleet-tlsautomatically.
- A running minikube cluster —
task cluster:create helm,kubectl,curlon PATH- Cluster sized for ≥ 4 vCPU / 6 GiB / 30 GiB (defaults in Taskfile)
- Internet access to pull official images and charts
task fleet:install # = helmfile sync + idempotent fleet:trust-caOr invoke helmfile directly:
helmfile sync # apply
helmfile diff # preview pending changes
helmfile template # render manifests without applying
helmfile destroy # tear down all releasestask fleet:expose # nip.io HTTPS ingress (UI + agents)
task fleet:forward # kubectl port-forward (UI only, HTTP localhost:8080)
task fleet:url # show ingress / port-forward URLsTLS is mandatory for the UI. Fleet's JS bundle stores the auth token in a
__Host-tokencookie markedSecure, which browsers refuse to set on plain HTTP. Runtask fleet:trust-caonce to import the local root CA into the host trust store and the browser stops warning.
task fleet:verify- Pods — every pod
Running+Readyacrossdatabase,cache,fleet. - MySQL —
mysqladmin pingfrom the StatefulSet; table count in thefleetschema confirmsfleet prepare dbran. - Valkey —
valkey-cli PING(withredis-clifallback);SET/GETround-trip. - Fleet server —
GET /healthz,GET /version,GET /api/v1/setup. - Ingress (skipped if
fleet:exposenot run) —GET /healthzvia the published host.
task fleet:prepare-db # = helmfile -l name=fleet-db-init syncRe-runs both Jobs (init-db and prepare-db) by upgrading the
fleet-db-init release, which re-fires the post-install hooks.
task fleet:uninstallRemoves every helm release (fleet, fleet-db-init, valkey, mysql,
cert-manager-issuers, cert-manager, ingress-nginx, bootstrap),
the workload namespaces, and the PVCs.
Version pins (chart versions) are set in
../../helmfile.yaml.gotmpl under
environments.default.values — edit the helmfile to bump them. The
task-level env vars below tweak only what Task itself does:
| Variable | Default | Purpose |
|---|---|---|
FLEET_NAMESPACE |
fleet |
Namespace for the Fleet server |
DATABASE_NAMESPACE |
database |
Namespace for MySQL |
CACHE_NAMESPACE |
cache |
Namespace for Valkey |
INGRESS_NAMESPACE |
ingress-nginx |
Namespace for the ingress controller |
INGRESS_DNS_SUFFIX |
nip.io |
Wildcard-DNS suffix used by fleet:expose |
INGRESS_HOST |
(unset) | Explicit ingress hostname; overrides the auto-derived nip.io |
FLEET_SKIP_TRUST |
0 |
1 skips the auto trust-ca step inside fleet:install |
CI |
(unset) | When true, fleet:trust-ca is a no-op (no sudo prompts) |
values-ingress-nginx.yaml— controller Service type, default IngressClass, admission webhook delegated to cert-manager (with the chart's default patch Jobs disabled)values-valkey.yaml— Valkey values (standalone, no auth, modest PVC)values-fleet.yaml— Fleet server values
- Single-pod MySQL is a dev profile. Production wants a real cluster
(Vitess, an InnoDBCluster on a chart that lets us disable Group
Replication's
DROP PRIMARY KEYcheck, or a managed service). - The MySQL
rootpassword lives inSecret/mysql-credentialsand is defaulted to a placeholder by the bootstrap chart — provision the Secret out of band for anything but local dev. - The local self-signed root CA never leaves the cluster, but it is
imported into the host trust store by
fleet:trust-ca. Usefleet:untrust-cafor symmetric cleanup before tearing down. - Fleet's server-side TLS is intentionally disabled here — TLS
terminates at the ingress and the
fleet-serviceClusterIP is plain-HTTP inside the cluster.