Deploying an Angular SPA to Kubernetes with Cloudflare
Deploying a Single Page Application (SPA) like an Angular project on Kubernetes can seem daunting at first, but with the right steps, it’s quite straightforward. In this guide, I’ll walk you through the entire process — from building a Docker image to exposing the application using Cloudflare.
# Build stage
FROM node:22 AS builder
WORKDIR /usr/src/app
COPY . .
RUN npm install && npm install -g @angular/cli
RUN npm run build --output-path=dist/my-angular-app
# Runtime stage
FROM nginx:alpine
COPY --from=builder /usr/src/app/dist/my-angular-app /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Now, build and push the image to a container registry (e.g., GitHub Container Registry):
docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/your-username/my-angular-app -f Dockerfile --push .
Step 2: Deploy to Kubernetes
Next, create a Kubernetes Deployment and Service to manage your application. Replace my-angular-app with your preferred name.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-angular-app
namespace: front-end
labels:
app: my-angular-app
spec:
replicas: 2
selector:
matchLabels:
app: my-angular-app
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: my-angular-app
spec:
containers:
- name: my-angular-app
image: ghcr.io/your-username/my-angular-app:latest
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
imagePullSecrets:
- name: secret-github-com
Now, define the Service to expose your deployment:
apiVersion: v1
kind: Service
metadata:
name: my-angular-app
namespace: front-end
labels:
app: my-angular-app
spec:
selector:
app: my-angular-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
Apply the configurations:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
Step 3: Expose the Cluster Using Cloudflare
To securely expose your cluster to the internet, use Cloudflare’s Tunnel feature. Create a deployment for cloudflared:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: cloudflared
name: cloudflared-deployment
namespace: default
spec:
replicas: 2
selector:
matchLabels:
pod: cloudflared
template:
metadata:
labels:
pod: cloudflared
spec:
containers:
- command:
- cloudflared
- tunnel
- --metrics
- 0.0.0.0:2000
- run
args:
- --token
- "YOUR_CLOUDFLARE_TUNNEL_TOKEN"
image: cloudflare/cloudflared:latest
name: cloudflared
livenessProbe:
httpGet:
path: /ready
port: 2000
failureThreshold: 1
initialDelaySeconds: 10
periodSeconds: 10
Apply it with:
kubectl apply -f cloudflare-tunnel.yaml
Once the deployment runs, your Angular app will be accessible via Cloudflare, secured and optimized for global delivery.