Skip to main content

Deploy Your First Application

Purpose: For app developers and platform engineers, walks through deploying a sample application on an openCenter cluster using the multi-team GitOps workflow with Gateway API routing and TLS (15 minutes).

What You'll Do

  1. Create an application repository with Kubernetes manifests, Gateway API routing, and TLS
  2. Register the application with FluxCD in the cluster overlay repo
  3. Verify the deployment, HTTPRoute, and TLS certificate

End result: A running application exposed via Gateway API with automatic TLS from cert-manager, deployed and reconciled by FluxCD using the multi-team GitOps pattern from openCenter-customer-app-example.

Prerequisites

  • A running openCenter cluster (any provider — Quick Start if you need one)
  • kubectl configured to access the cluster
  • FluxCD bootstrapped and reconciling (flux get kustomizations shows Ready=True)
  • Gateway API and cert-manager services deployed (included by default in all openCenter clusters)
  • Git CLI installed

How Application Deployment Works

openCenter uses a multi-team GitOps model (demonstrated in openCenter-customer-app-example):

  • Platform team creates GitRepository + Kustomization manifests in the cluster overlay repo to watch application repos
  • App team manages their own repository with Kubernetes manifests — Deployments, Services, HTTPRoutes

FluxCD reconciles both continuously.

Step 1: Create Your Application Repository

mkdir my-app && cd my-app
git init

Create the Kustomize root kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gateway-resources/
- app/

Step 2: Define Gateway Resources

Gateway API provides standardized ingress routing. Create shared gateway resources:

mkdir -p gateway-resources

Create gateway-resources/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gateway.yaml

Create gateway-resources/gateway.yaml:

apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: app-gateway
namespace: my-app
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
gatewayClassName: eg
listeners:
- name: https
port: 443
protocol: HTTPS
hostname: my-app.example.com
allowedRoutes:
namespaces:
from: Same
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: my-app-tls

The cert-manager.io/cluster-issuer annotation tells cert-manager to automatically issue and renew the TLS certificate referenced by my-app-tls.

Step 3: Create Application Manifests

mkdir -p app

Create app/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- deployment.yaml
- service.yaml
- httproute.yaml

Create app/namespace.yaml:

apiVersion: v1
kind: Namespace
metadata:
name: my-app

Create app/deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: my-app
labels:
app: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi

Create app/service.yaml:

apiVersion: v1
kind: Service
metadata:
name: web-app
namespace: my-app
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80

Create app/httproute.yaml:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-app
namespace: my-app
spec:
hostnames:
- my-app.example.com
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: app-gateway
namespace: my-app
sectionName: https
rules:
- backendRefs:
- kind: Service
name: web-app
port: 80
matches:
- path:
type: PathPrefix
value: /

Step 4: Push the Application Repository

git add .
git commit -m "feat: initial application deployment"
git remote add origin git@github.com:your-org/my-app.git
git push -u origin main

Step 5: Platform Team Registers the Application

The platform team adds these manifests to the cluster overlay repository (not the app repo):

Create managed-services/my-app/source.yaml:

apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: my-app
namespace: flux-system
spec:
interval: 1m
url: https://github.com/your-org/my-app
ref:
branch: main

Create managed-services/my-app/kustomization.yaml:

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: my-app
namespace: flux-system
spec:
interval: 10m
prune: true
wait: true
path: ./
sourceRef:
kind: GitRepository
name: my-app

Commit and push to the cluster overlay repo. FluxCD detects the change and deploys the application.

Step 6: Verify the Deployment

# Watch FluxCD pick up the change
flux get kustomizations --watch

# Check application pods
kubectl get pods -n my-app

# Check the HTTPRoute is attached to the Gateway
kubectl get httproutes -n my-app

# Check the TLS certificate is issued
kubectl get certificates -n my-app

Check Your Work

  • Namespace my-app exists
  • Two web-app pods are Running
  • HTTPRoute shows Accepted=True
  • cert-manager issued a certificate (kubectl get cert -n my-app shows Ready=True)
  • FluxCD kustomization my-app shows Ready=True

Validation Before Commit

Run locally before pushing:

kustomize build .
kubeconform <(kustomize build .)

Next Steps