Deploying Versioned Applications
This guide explains how to deploy versioned applications that ICC can manage with skew protection. Each application version runs as a separate, immutable Kubernetes Deployment with its own Service.
Required Labels
Section titled “Required Labels”Every versioned Deployment must include two labels on the pod template:
| Label | Required | Purpose |
|---|---|---|
app.kubernetes.io/name | Yes | Application identity — must be the same across all versions |
plt.dev/version | Yes | Version identifier — must be unique per version |
ICC detects these labels automatically when the pod registers. No environment variables are needed for skew protection.
Optional Labels
Section titled “Optional Labels”| Label | Purpose | Default |
|---|---|---|
plt.dev/path | Custom path prefix for HTTPRoute rules | /{appName} |
plt.dev/hostname | Hostname for HTTPRoute (e.g., myapp.example.com) | Not set (no hostname matching) |
Example Deployment
Section titled “Example Deployment”Create a Deployment and Service for each version. The key requirements:
- Same
app.kubernetes.io/namelabel across all versions - Unique
plt.dev/versionlabel per version - Unique Deployment and Service names (we recommend
{appName}-{version}) PLT_ICC_URLconfigured to connect to ICC
apiVersion: apps/v1kind: Deploymentmetadata: name: myapp-v1.2.4 namespace: platformatic labels: app.kubernetes.io/name: myapp plt.dev/version: "1.2.4"spec: replicas: 3 selector: matchLabels: app.kubernetes.io/name: myapp plt.dev/version: "1.2.4" template: metadata: labels: app.kubernetes.io/name: myapp plt.dev/version: "1.2.4" platformatic.dev/monitor: prometheus spec: containers: - name: watt image: your-registry.com/myapp:1.2.4 ports: - name: app containerPort: 3042 protocol: TCP - name: metrics containerPort: 9090 protocol: TCP env: - name: PLT_ICC_URL value: "http://icc.platformatic.svc.cluster.local" - name: PLT_SERVER_HOSTNAME value: "0.0.0.0"---apiVersion: v1kind: Servicemetadata: name: myapp-v1.2.4 namespace: platformaticspec: selector: app.kubernetes.io/name: myapp plt.dev/version: "1.2.4" ports: - name: app port: 3042 targetPort: 3042 - name: metrics port: 9090 targetPort: 9090Deploying a New Version
Section titled “Deploying a New Version”To deploy a new version of your application:
- Build a new container image with the updated application code (e.g.,
myapp:1.2.5) - Create a new Deployment and Service manifest with the same
app.kubernetes.io/namebut a newplt.dev/version - Apply the manifest:
kubectl apply -f myapp-v1.2.5.yaml- ICC handles the rest — when the pods start and register with ICC, the new version is detected and routing transitions automatically
ICC treats the newest version as the production version immediately upon detection. The previous version transitions to Draining and continues serving existing sessions.
Using a Custom Path Prefix
Section titled “Using a Custom Path Prefix”By default, ICC creates HTTPRoute rules with a path prefix of /{appName} (derived from app.kubernetes.io/name). If your application uses a different path, set the plt.dev/path label:
metadata: labels: app.kubernetes.io/name: myapp plt.dev/version: "1.2.4" plt.dev/path: "/api/leads"The path prefix scopes the routing rules to your application, which is important when multiple applications share the same Gateway.
Using Hostname-Based Routing
Section titled “Using Hostname-Based Routing”For production setups with per-application domains, set the plt.dev/hostname label:
metadata: labels: app.kubernetes.io/name: myapp plt.dev/version: "1.2.4" plt.dev/hostname: "myapp.example.com"When set, ICC adds a hostnames field to the HTTPRoute, restricting the routing rules to requests matching that hostname.
API Clients
Section titled “API Clients”Browser-based clients use the __plt_dpl cookie for version pinning automatically. For API clients (server-to-server, CLI tools, etc.) that don’t support cookies, use the x-deployment-id header:
curl -H "x-deployment-id: v1.2.3-abc123" https://myapp.example.com/api/dataThe deployment ID value is the same identifier used in the __plt_dpl cookie. You can obtain it from the Set-Cookie response header on any request to the application.
Rollback
Section titled “Rollback”To rollback to a previous version, re-deploy it as a new Deployment with the same version label. If the version was previously expired, ICC re-registers it as active.
# Re-deploy version 1.2.3 (which was previously expired)kubectl apply -f myapp-v1.2.3.yamlICC treats this as a new version detection — it becomes the active version and the current version transitions to Draining.
Verifying Deployment
Section titled “Verifying Deployment”After deploying, verify that ICC detected the new version:
- ICC Dashboard — navigate to the Deployments page and check for the new version in the active versions panel
- Logs — check ICC logs for version detection messages
- HTTPRoute — verify the HTTPRoute was created/updated:
kubectl get httproute -n platformatickubectl describe httproute myapp -n platformatic