Skaffold Standards Version: 2025.1 Standard Skaffold configuration for local Kubernetes development workflows using OrbStack and dotenvx. Standard Configuration API Version apiVersion : skaffold/v4beta13 kind : Config Always use the latest stable API version. Currently: skaffold/v4beta13 Build Configuration build : local : push : false
Never push to registry for local dev
useDockerCLI : true
Use Docker CLI (better caching)
useBuildkit : true
Enable BuildKit for performance
concurrency : 0
Unlimited parallel builds
Generate secrets from encrypted .env files before building
hooks : before : - command : [ 'sh' , '-c' , 'dotenvx run -- sh scripts/generate-secrets.sh' ] os : [ darwin , linux ] artifacts : - image : app - name context : . docker : dockerfile : Dockerfile
Optional: init container for database migrations
- -
- image
- :
- app
- -
- db
- -
- init
- context
- :
- .
- docker
- :
- dockerfile
- :
- Dockerfile.db
- -
- init
- Port Forwarding (Security)
- IMPORTANT
- Always bind to localhost only: portForward : - resourceType : service resourceName : app - name port : 80 localPort : 8080 address : 127.0.0.1
REQUIRED: Bind to localhost only
Never use 0.0.0.0 or omit the address field. Deploy Configuration deploy : kubeContext : orbstack
OrbStack for local development
kubectl : defaultNamespace : app - name
Optional: validation before deploy
hooks : before : - host : command : [ "sh" , "-c" , "echo 'Deploying...'" ] os : [ darwin , linux ] statusCheck : true
Extended timeout for init containers (db migrations, seeding)
statusCheckDeadlineSeconds : 180 tolerateFailuresUntilDeadline : true
Parse JSON logs from applications for cleaner output
logs : jsonParse : fields : [ "message" , "level" , "timestamp" ] Standard Profiles Profile: db-only Database only - for running app dev server locally with hot-reload: profiles : - name : db - only build : artifacts : [ ]
Don't build app
- manifests
- :
- rawYaml
- :
- -
- k8s/namespace.yaml
- -
- k8s/postgresql
- -
- secret.yaml
- -
- k8s/postgresql
- -
- configmap.yaml
- -
- k8s/postgresql
- -
- service.yaml
- -
- k8s/postgresql
- -
- statefulset.yaml
- portForward
- :
- -
- resourceType
- :
- service
- resourceName
- :
- postgresql
- namespace
- :
- app
- -
- name
- port
- :
- 5432
- localPort
- :
- 5435
- address
- :
- 127.0.0.1
- Use case
- Run skaffold dev -p db-only + bun run dev for hot-reload development Profile: services-only Backend services only (database, APIs) - use with local frontend dev: profiles : - name : services - only build : artifacts : [ ]
Don't build frontend
- manifests
- :
- rawYaml
- :
- -
- k8s/namespace.yaml
- -
- k8s/database/
- *.yaml
- -
- k8s/api/
- *.yaml
- portForward
- :
- -
- resourceType
- :
- service
- resourceName
- :
- postgresql
- port
- :
- 5432
- localPort
- :
- 5435
- address
- :
- 127.0.0.1
- Use case
- Run skaffold dev -p services-only + bun run dev for hot-reload frontend Profile: e2e or e2e-with-prod-data Full stack for end-to-end testing: profiles : - name : e2e manifests : rawYaml : - k8s/ *.yaml
All manifests
Profile: migration-test Database migration testing: profiles : - name : migration - test manifests : rawYaml : - k8s/database/ *.yaml test : - image : migration - tester custom : - command : "run-migrations.sh" Compliance Requirements Cluster Context (CRITICAL) Always specify kubeContext: orbstack in deploy configuration. This is the standard local development context. deploy : kubeContext : orbstack kubectl : { } When using Skaffold commands, always include --kube-context=orbstack : skaffold dev --kube-context = orbstack skaffold run --kube-context = orbstack skaffold delete --kube-context = orbstack Only use a different context if explicitly requested by the user. Required Elements Element Requirement API version skaffold/v4beta13 deploy.kubeContext orbstack (default) local.push false portForward.address 127.0.0.1 statusCheck true recommended dotenvx hooks Recommended for secrets Recommended Profiles Depending on project type: Profile Purpose Required db-only Database only + local app dev Recommended services-only Backend services + local frontend Recommended minimal Without optional features Optional e2e Full stack testing Optional Project Type Variations Frontend with Backend Services
Default: Full stack
manifests : rawYaml : - k8s/namespace.yaml - k8s/frontend/ .yaml - k8s/backend/ .yaml - k8s/database/ .yaml profiles : - name : services - only build : artifacts : [ ] manifests : rawYaml : - k8s/namespace.yaml - k8s/backend/ .yaml - k8s/database/ *.yaml API Service Only
Simpler configuration
manifests : rawYaml : - k8s/ *.yaml
No profiles needed for simple services
- Infrastructure Testing
- Skaffold may not be applicable for pure infrastructure repos. Use Terraform/Helm directly.
- dotenvx Integration
- Projects use
- dotenvx
- for encrypted secrets management in local development.
- How It Works
- Encrypted .env files
- :
- .env
- files contain encrypted values, safe to commit
- Private key
- :
- DOTENV_PRIVATE_KEY
- decrypts values at runtime
- Hooks
-
- Skaffold hooks run
- dotenvx run -- script
- to inject secrets
- Generated secrets
- Scripts create Kubernetes Secret manifests from .env Build Hooks with dotenvx build : hooks : before : - command : [ 'sh' , '-c' , 'dotenvx run -- sh scripts/generate-secrets.sh' ] os : [ darwin , linux ] Deploy Hooks with dotenvx deploy : kubectl : hooks : before : - host : command : [ "sh" , "-c" , "dotenvx run -- sh scripts/generate-secrets.sh" ] Generate Secrets Script Create scripts/generate-secrets.sh :
!/bin/bash
Generate Kubernetes secrets from .env using dotenvx
set -euo pipefail
Validate required env vars are set
: " ${DATABASE_URL :? DATABASE_URL must be set} " : " ${SECRET_KEY :? SECRET_KEY must be set} "
Generate app secrets manifest
cat
k8s/app-secrets.yaml << EOF apiVersion: v1 kind: Secret metadata: name: app-secrets namespace: app-name type: Opaque stringData: DATABASE_URL: " ${DATABASE_URL} " SECRET_KEY: " ${SECRET_KEY} " EOF echo "Generated k8s/app-secrets.yaml" dotenvx Setup
Install dotenvx
curl -sfS https://dotenvx.sh | sh
Create encrypted .env
dotenvx set DATABASE_URL "postgresql://..." dotenvx set SECRET_KEY "..."
Encrypt existing .env
dotenvx encrypt
Store private key securely (NOT in git)
echo "DOTENV_PRIVATE_KEY=..."
~/.zshrc Build Hooks (Validation) Pre-build hooks for validation (in addition to dotenvx): build : artifacts : - image : app hooks : before : - command : [ 'bun' , 'run' , 'check' ] os : [ darwin , linux ] Status Levels Status Condition PASS Compliant configuration WARN Present but missing recommended elements FAIL Security issue (e.g., portForward without localhost) SKIP Not applicable (e.g., infrastructure repo) Troubleshooting Pods Not Starting Check statusCheckDeadlineSeconds (increase if needed) Enable tolerateFailuresUntilDeadline: true Review pod logs: kubectl logs -f
Port Forwarding Issues Ensure port is not already in use Check service name matches deployment Verify address: 127.0.0.1 is set Build Caching Enable BuildKit: useBuildkit: true Use Docker CLI: useDockerCLI: true Set concurrency: 0 for parallel builds