- Published on
Hands-On with Kubernetes v1.34 New EnvFiles Feature
- Authors
- Name
- Shedrack Akintayo
- @coder_blvck
The Kubernetes v1.34 release introduced an exciting new alpha feature called EnvFiles, which allows containers to load environment variables directly from files using the new fileKeyRef
field. This feature eliminates the need for complex ConfigMap or Secret management in scenarios where you need to generate configuration dynamically at runtime.
In this hands-on guide, we'll explore the EnvFiles feature by setting up a real Kubernetes cluster and deploying a Node.js application that demonstrates this new capability.
What is the EnvFiles Feature?
As mentioned in a blog post by the official Kubernetes team, the EnvFiles
feature enables a new way to inject environment variables into containers. Instead of pre-creating ConfigMaps or Secrets, you can use init containers to generate environment files on-the-fly, and have your main containers load these variables using the new fileKeyRef
syntax.
Key Benefits:
- Dynamic configuration generation at pod startup
- Reduced API server load (no additional ConfigMap/Secret resources)
- Simplified vendor integrations where configuration is generated programmatically
- Temporary storage in emptyDir volumes (no persistent configuration data)
Prerequisites
Before we begin, ensure you have the following tools installed:
- k3d for local Kubernetes clusters
- kubectl for cluster interaction
- Docker (required by k3d) or Orbstack (For Mac users)
Setting Up the Cluster
The EnvFiles feature is an alpha feature in Kubernetes v1.34, so we need to explicitly enable it using feature gates.
Create K3s Cluster with EnvFiles Support
# Create a k3d cluster with K3s v1.34 and EnvFiles enabled
k3d cluster create envfiles-demo \
--image rancher/k3s:v1.34.1-rc1-k3s1 \
--k3s-arg "--kubelet-arg=feature-gates=EnvFiles=true@server:*" \
--k3s-arg "--kubelet-arg=feature-gates=EnvFiles=true@agent:*" \
--k3s-arg "--kube-apiserver-arg=feature-gates=EnvFiles=true@server:*"
Note: We're using K3s version
v1.34.1-rc1-k3s1
which includes support for the EnvFiles feature gate.
Verify the Cluster
Check cluster version
kubectl version
The output should be something like:
Client Version: v1.33.3
Kustomize Version: v5.6.0
Server Version: v1.34.1-rc1+k3s1
Verify the node is ready
kubectl get nodes
The output should be something like:
k3d-envfiles-demo-server-0 Ready control-plane 2m30s v1.34.1-rc1+k3s1
Node.js Application with Dynamic Configuration
Now let's create a sample Node.js web application that loads multiple environment variables from a file generated by an init container.
Create the Node.js Application Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: node-envfiles-demo
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: node-envfiles-demo
template:
metadata:
labels:
app: node-envfiles-demo
spec:
initContainers:
- name: create-config
image: busybox
command:
- sh
- -c
- |
echo "Creating application configuration..."
echo "PORT=3000" > /config/app.env
echo "NODE_ENV=production" >> /config/app.env
echo "DATABASE_URL=postgresql://user:pass@db:5432/myapp" >> /config/app.env
echo "API_TIMEOUT=30000" >> /config/app.env
echo "FEATURE_FLAGS=dark_mode,new_ui,beta_features" >> /config/app.env
echo ""
echo "Generated configuration file:"
cat /config/app.env
volumeMounts:
- name: config-volume
mountPath: /config
containers:
- name: node-app
image: node:18-alpine
env:
- name: PORT
valueFrom:
fileKeyRef:
path: app.env
volumeName: config-volume
key: PORT
- name: NODE_ENV
valueFrom:
fileKeyRef:
path: app.env
volumeName: config-volume
key: NODE_ENV
- name: DATABASE_URL
valueFrom:
fileKeyRef:
path: app.env
volumeName: config-volume
key: DATABASE_URL
- name: API_TIMEOUT
valueFrom:
fileKeyRef:
path: app.env
volumeName: config-volume
key: API_TIMEOUT
- name: FEATURE_FLAGS
valueFrom:
fileKeyRef:
path: app.env
volumeName: config-volume
key: FEATURE_FLAGS
command:
- sh
- -c
- |
echo "=== Node.js Application Starting ==="
echo "Environment Variables loaded via EnvFiles:"
echo "PORT: $PORT"
echo "NODE_ENV: $NODE_ENV"
echo "DATABASE_URL: $DATABASE_URL"
echo "API_TIMEOUT: $API_TIMEOUT"
echo "FEATURE_FLAGS: $FEATURE_FLAGS"
echo ""
echo "Creating web server..."
node -e "
const http = require('http');
const server = http.createServer((req, res) => {
const config = {
port: process.env.PORT,
nodeEnv: process.env.NODE_ENV,
databaseUrl: process.env.DATABASE_URL,
apiTimeout: process.env.API_TIMEOUT,
featureFlags: process.env.FEATURE_FLAGS?.split(',') || []
};
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify({
message: 'EnvFiles Demo Application',
timestamp: new Date().toISOString(),
configuration: config
}, null, 2));
});
server.listen(process.env.PORT || 3000, () => {
console.log('Server running on port ' + (process.env.PORT || 3000));
});
"
volumeMounts:
- name: config-volume
mountPath: /config
ports:
- containerPort: 3000
volumes:
- name: config-volume
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: node-envfiles-demo
namespace: default
spec:
selector:
app: node-envfiles-demo
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
Save the above YAML to deployment.yaml
and deploy it:
kubectl apply -f node-envfiles-demo.yaml
# Watch the deployment
kubectl get pods -l app=node-envfiles-demo -w
Verify the EnvFiles Feature in Action
Check Init Container Logs
The init container creates our configuration file:
kubectl logs deployment/node-envfiles-demo -c create-config

Check Main Container Logs
The Node.js application loads the environment variables:
kubectl logs deployment/node-envfiles-demo -c node-app
You should see output similar to:

Inspect the Pod Configuration
You can also examine how Kubernetes configured the pod:
kubectl get pod -l app=node-envfiles-demo -o yaml | grep -A 20 fileKeyRef

Test the Application
# Get the application URL (if using k3d with LoadBalancer)
curl http://localhost/
# Or port-forward to test locally
kubectl port-forward service/node-envfiles-demo 8080:80
curl http://localhost:8080
You should receive a JSON response showing all the configuration loaded via EnvFiles:

Understanding the EnvFiles Architecture
The EnvFiles feature works through several key components:
1. Init Container
- Runs before the main application container
- Generates configuration files in an
emptyDir
volume - Can fetch data from external services, generate secrets, or create dynamic configuration
2. EmptyDir Volume
- Shared storage between init and main containers
- Lives only for the duration of the pod
- Currently the only supported volume type for EnvFiles (alpha limitation)
3. FileKeyRef Configuration
- New field in container environment variable specification
- Points to a specific file and key within that file
- Loads the value at container startup time
Example fileKeyRef Syntax:
env:
- name: MY_VARIABLE
valueFrom:
fileKeyRef:
path: config.env # File path within the volume
volumeName: config-volume # Name of the volume
key: MY_VARIABLE # Key to extract from the file
Use Cases and Benefits
The EnvFiles feature opens up several powerful use cases:
1. Dynamic License Management
Generate license tokens or fetch them from external services without storing them as persistent secrets.
2. Service Discovery
Query service registries or DNS to build connection strings dynamically.
3. Vendor Tool Integration
Many vendor tools expect environment variables but provide complex configuration logic that's easier to handle in init containers.
4. Temporary Secrets
Generate short-lived credentials or tokens that don't need to persist beyond the pod lifecycle.
5. Complex Configuration Assembly
Combine multiple configuration sources, apply templates, or perform preprocessing before the main application starts.
Current Limitations (Alpha Stage)
As an alpha feature, EnvFiles has some important limitations:
- Volume Support: Only
emptyDir
volumes are supported - File Format: Uses standard key=value format (like .env files)
- Feature Gate: Must be explicitly enabled via feature gates
- Error Handling: Limited error reporting for file parsing issues
Production Considerations
While EnvFiles is exciting, consider these factors for production use:
- Alpha Feature: API may change in future Kubernetes versions
- Error Handling: Implement proper validation in init containers
- Security: Remember that
emptyDir
contents may be accessible via node filesystem access - Monitoring: Add appropriate logging and health checks for configuration generation
- Backup Strategy: Since configuration is ephemeral, ensure your init containers can reliably regenerate it
Cleanup
When you're done experimenting, clean up the resources:
# Delete the demo application
kubectl delete -f node-envfiles-demo.yaml
# Delete the test pod
kubectl delete pod test-envfiles-basic
# Delete the k3d cluster
k3d cluster delete envfiles-demo
Conclusion
The EnvFiles feature in Kubernetes v1.34 represents a significant step forward in dynamic configuration management. By allowing containers to load environment variables from files generated at runtime, it opens up new possibilities for complex application deployment scenarios while maintaining the security and isolation principles of Kubernetes.
While still in alpha, this feature shows great promise for simplifying vendor tool integrations, dynamic secret management, and complex configuration scenarios. As it matures through beta and stable releases, we can expect to see broader adoption and additional volume type support.
The combination of init containers and fileKeyRef provides a clean, Kubernetes-native way to handle dynamic configuration without the overhead of additional API resources or complex external systems.