Helm Deploy
A lightweight, Alpine-based container optimized for Kubernetes deployments using Helm, kubectl, and additional DevOps tooling.
Purpose
The Helm Deploy image serves as a specialized deployment environment for Kubernetes infrastructure, providing:
- ✅ Kubernetes deployment via Helm charts and kubectl
- ✅ Multi-cloud support with DigitalOcean CLI integration
- ✅ Secrets management using SOPS for encrypted configurations
- ✅ YAML processing capabilities for configuration manipulation
- ✅ Minimal footprint based on Alpine Linux for fast execution
Image Details
| Property |
Value |
| Base Image |
alpine:3.21.3 |
| Size |
~150MB (minimal Alpine + tools) |
| Architecture |
AMD64 |
| Registry |
webgrip/helm-deploy |
| Dockerfile |
ops/docker/helm-deploy/Dockerfile |
| Tool |
Version |
Purpose |
| kubectl |
v1.32.2 |
Kubernetes command-line tool |
| Helm |
3.17.1 |
Kubernetes package manager |
| doctl |
1.123.0 |
DigitalOcean CLI |
| SOPS |
3.7.3 |
Secrets encryption/decryption |
| yq |
4.45.1 |
YAML processing tool |
System Utilities
- git - Version control for chart repositories
- curl/wget - HTTP clients for API interactions
- bash - Shell scripting environment
- tar - Archive handling
- gnupg - GPG encryption for SOPS
- openssl - SSL/TLS utilities
- ca-certificates - Certificate authority bundle
Architecture
Deployment Workflow
flowchart TD
START[Deployment Start] --> FETCH[Fetch Helm Charts]
FETCH --> DECRYPT[Decrypt Secrets with SOPS]
DECRYPT --> TEMPLATE[Template with yq/Helm]
TEMPLATE --> VALIDATE[Validate with kubectl]
VALIDATE --> DEPLOY[Deploy with Helm]
DEPLOY --> VERIFY[Verify Deployment]
VERIFY --> END[Deployment Complete]
subgraph "Tools Used"
GIT[git] --> FETCH
SOPS[sops] --> DECRYPT
YQ[yq] --> TEMPLATE
HELM[helm] --> TEMPLATE
KUBECTL[kubectl] --> VALIDATE
HELM --> DEPLOY
KUBECTL --> VERIFY
end
Multi-Cloud Architecture
flowchart LR
subgraph "Deployment Container"
HELM_DEPLOY[Helm Deploy Image]
KUBECTL[kubectl]
HELM[helm]
DOCTL[doctl]
SOPS[sops]
end
subgraph "Target Environments"
DO_K8S[DigitalOcean Kubernetes]
OTHER_K8S[Other K8s Clusters]
end
subgraph "Configuration Sources"
CHARTS[Helm Charts Repository]
SECRETS[Encrypted Secrets]
CONFIGS[Configuration Files]
end
HELM_DEPLOY --> DO_K8S
HELM_DEPLOY --> OTHER_K8S
CHARTS --> HELM_DEPLOY
SECRETS --> HELM_DEPLOY
CONFIGS --> HELM_DEPLOY
Usage Examples
Basic Helm Deployment
| # Deploy a Helm chart to Kubernetes
docker run --rm \
-v $(pwd):/workspace \
-v ~/.kube:/root/.kube \
-w /workspace \
webgrip/helm-deploy:latest \
helm upgrade --install myapp ./charts/myapp
|
DigitalOcean Kubernetes Deployment
| # Deploy to DigitalOcean managed Kubernetes
docker run --rm \
-v $(pwd):/workspace \
-e DIGITALOCEAN_ACCESS_TOKEN=$DO_TOKEN \
-w /workspace \
webgrip/helm-deploy:latest \
bash -c "
doctl kubernetes cluster kubeconfig save my-cluster
helm upgrade --install myapp ./charts/myapp --namespace production
"
|
Secrets Management with SOPS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | # Decrypt secrets and deploy
docker run --rm \
-v $(pwd):/workspace \
-v ~/.kube:/root/.kube \
-v ~/.gnupg:/root/.gnupg \
-w /workspace \
webgrip/helm-deploy:latest \
bash -c "
# Decrypt secrets
sops -d secrets/production.enc.yaml > secrets/production.yaml
# Deploy with decrypted secrets
helm upgrade --install myapp ./charts/myapp \
--values secrets/production.yaml \
--namespace production
"
|
Configuration Processing with yq
1
2
3
4
5
6
7
8
9
10
11
12
13 | # Process YAML configurations before deployment
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
webgrip/helm-deploy:latest \
bash -c "
# Modify configuration using yq
yq eval '.image.tag = \"v1.2.3\"' values.yaml > values-updated.yaml
# Deploy with updated values
helm upgrade --install myapp ./charts/myapp \
--values values-updated.yaml
"
|
CI/CD Integration
GitHub Actions Workflow
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 | # .github/workflows/deploy.yml
name: Deploy to Kubernetes
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
container: webgrip/helm-deploy:latest
steps:
- uses: actions/checkout@v4
- name: Setup DigitalOcean CLI
env:
DIGITALOCEAN_ACCESS_TOKEN: ${{ secrets.DO_TOKEN }}
run: |
doctl kubernetes cluster kubeconfig save ${{ vars.CLUSTER_NAME }}
- name: Decrypt secrets
env:
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
run: |
echo "$SOPS_AGE_KEY" > /tmp/age-key
export SOPS_AGE_KEY_FILE=/tmp/age-key
sops -d secrets/production.enc.yaml > secrets/production.yaml
- name: Deploy application
run: |
helm dependency update ./charts/myapp
helm upgrade --install myapp ./charts/myapp \
--namespace production \
--create-namespace \
--values secrets/production.yaml \
--set image.tag=${{ github.sha }}
- name: Verify deployment
run: |
kubectl rollout status deployment/myapp -n production
kubectl get pods -n production
|
Multi-Environment Deployment
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | # Deploy to multiple environments
strategy:
matrix:
environment: [staging, production]
steps:
- name: Deploy to ${{ matrix.environment }}
run: |
# Setup environment-specific configuration
export NAMESPACE=${{ matrix.environment }}
export VALUES_FILE=values-${{ matrix.environment }}.yaml
# Decrypt environment-specific secrets
sops -d secrets/${{ matrix.environment }}.enc.yaml > secrets/${{ matrix.environment }}.yaml
# Deploy with environment-specific settings
helm upgrade --install myapp-${{ matrix.environment }} ./charts/myapp \
--namespace $NAMESPACE \
--create-namespace \
--values $VALUES_FILE \
--values secrets/${{ matrix.environment }}.yaml
|
Configuration
Environment Variables
| Variable |
Purpose |
Example |
DIGITALOCEAN_ACCESS_TOKEN |
DigitalOcean API authentication |
dop_v1_xxx... |
KUBECONFIG |
Kubernetes configuration file path |
/root/.kube/config |
SOPS_AGE_KEY_FILE |
Age key file for SOPS decryption |
/tmp/age-key |
SOPS_AGE_KEY |
Age key content for SOPS |
AGE-SECRET-KEY-1XXX... |
HELM_CACHE_HOME |
Helm cache directory |
/tmp/.helm |
Volume Mounts
| # Essential volume mounts for deployment
docker run --rm \
-v $(pwd):/workspace \ # Project files
-v ~/.kube:/root/.kube \ # Kubernetes config
-v ~/.gnupg:/root/.gnupg \ # GPG keys for SOPS
-v helm-cache:/tmp/.helm \ # Helm cache
webgrip/helm-deploy:latest
|
Advanced Usage
Custom Helm Chart Development
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | # Create and test new Helm charts
docker run -it --rm \
-v $(pwd):/workspace \
-w /workspace \
webgrip/helm-deploy:latest \
bash -c "
# Create new chart
helm create myapp
# Validate chart
helm lint myapp/
# Test template rendering
helm template myapp myapp/ --values myapp/values.yaml
# Package chart
helm package myapp/
"
|
Blue-Green Deployments
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | # Blue-green deployment strategy
docker run --rm \
-v $(pwd):/workspace \
-v ~/.kube:/root/.kube \
-w /workspace \
webgrip/helm-deploy:latest \
bash -c "
# Deploy green version
helm upgrade --install myapp-green ./charts/myapp \
--set color=green \
--set image.tag=$NEW_VERSION \
--namespace production
# Wait for green to be ready
kubectl rollout status deployment/myapp-green -n production
# Switch traffic (update service selector)
yq eval '.spec.selector.color = \"green\"' service.yaml | kubectl apply -f -
# Remove blue version after verification
helm uninstall myapp-blue --namespace production
"
|
Disaster Recovery
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | # Backup current deployment
docker run --rm \
-v $(pwd):/workspace \
-v ~/.kube:/root/.kube \
-w /workspace \
webgrip/helm-deploy:latest \
bash -c "
# Get current values
helm get values myapp -n production > backup/current-values.yaml
# Get current manifests
helm get manifest myapp -n production > backup/current-manifest.yaml
# Backup persistent volumes
kubectl get pv -o yaml > backup/persistent-volumes.yaml
"
|
Security Best Practices
Secrets Management
-
Use SOPS for encryption:
| # Encrypt secrets file
sops -e secrets/production.yaml > secrets/production.enc.yaml
# Never commit unencrypted secrets
echo "secrets/*.yaml" >> .gitignore
|
-
Age keys for SOPS:
| # Generate age key pair
age-keygen -o age-key.txt
# Use in CI/CD
export SOPS_AGE_KEY_FILE=/tmp/age-key
|
-
Kubernetes RBAC:
| # Limit deployment permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: helm-deployer
rules:
- apiGroups: ["apps", ""]
resources: ["deployments", "services", "configmaps"]
verbs: ["get", "list", "create", "update", "patch"]
|
Network Security
| # Use private registries
docker run --rm \
-v ~/.docker:/root/.docker \
webgrip/helm-deploy:latest \
helm upgrade --install myapp ./charts/myapp \
--set image.repository=private-registry.com/myapp
|
Troubleshooting
Common Issues
"Unable to connect to the server"
| # Verify Kubernetes configuration
docker run --rm -v ~/.kube:/root/.kube webgrip/helm-deploy:latest kubectl cluster-info
# Check kubeconfig
kubectl config view
kubectl config current-context
|
"Helm chart not found"
| # Update Helm repositories
helm repo update
# Search for charts
helm search repo myapp
# Verify chart path
ls -la charts/myapp/Chart.yaml
|
SOPS decryption failures
| # Verify age key
echo "$SOPS_AGE_KEY" | age-keygen -y
# Test decryption
sops -d secrets/production.enc.yaml
|
DigitalOcean authentication issues
| # Verify token
doctl auth list
doctl account get
# Test cluster access
doctl kubernetes cluster list
|
Slow Helm operations
| # Use Helm cache
export HELM_CACHE_HOME=/tmp/.helm
helm repo update
# Parallel operations
helm upgrade --install app1 ./charts/app1 &
helm upgrade --install app2 ./charts/app2 &
wait
|
Large chart deployments
| # Increase timeout
helm upgrade --install myapp ./charts/myapp --timeout 10m
# Use atomic deployments
helm upgrade --install myapp ./charts/myapp --atomic
|
Customization
Adding Cloud Providers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | # Dockerfile.custom
FROM webgrip/helm-deploy:latest
# Add AWS CLI
RUN apk add --no-cache python3 py3-pip && \
pip3 install awscli
# Add Azure CLI
RUN apk add --no-cache py3-pip && \
pip3 install azure-cli
# Add Google Cloud SDK
RUN wget https://dl.google.com/dl/cloudsdk/channels/rapid/google-cloud-sdk.tar.gz && \
tar -xzf google-cloud-sdk.tar.gz && \
./google-cloud-sdk/install.sh --quiet
|
Custom Helm Plugins
| # Install Helm plugins in derived image
FROM webgrip/helm-deploy:latest
RUN helm plugin install https://github.com/databus23/helm-diff
RUN helm plugin install https://github.com/jkroepke/helm-secrets
|
Maintenance
Update Schedule
- Tool versions: Updated quarterly or when security issues discovered
- Alpine base: Updated when new Alpine releases available
- Kubernetes compatibility: Tested against latest K8s versions
Version Matrix
| Image Version |
kubectl |
Helm |
Alpine |
Status |
latest |
v1.32.2 |
3.17.1 |
3.21.3 |
Active |
v1.32 |
v1.32.x |
3.17.x |
3.21.x |
Supported |
v1.31 |
v1.31.x |
3.16.x |
3.20.x |
Deprecated |
Assumption: Deployments primarily target DigitalOcean Kubernetes clusters. Support for other cloud providers (AWS EKS, GCP GKE, Azure AKS) may require additional CLI tools. Validation needed: Confirm cloud provider requirements with infrastructure team.
Maintainer: WebGrip Ops Team
Source: ops/docker/helm-deploy/Dockerfile
Registry: webgrip/helm-deploy