GEMVC Documentation
Complete guide to building modern, secure PHP applications with GEMVC framework
🚀 Guide: Deploying a Dockerized GEMVC Application to Azure Kubernetes Service (AKS)
This document provides a complete walkthrough for deploying a containerized application to the Azure Kubernetes Service (AKS). AKS is Microsoft Azure's managed Kubernetes service, offering a powerful, integrated, and scalable platform for modern applications.
Core Concepts
- Kubernetes (K8s): The core concepts are the same across all cloud providers.
- Azure Kubernetes Service (AKS): A managed Kubernetes service from Microsoft. Azure manages the control plane for free, and you pay for the worker nodes.
- `az` CLI: The primary command-line tool for interacting with your Azure subscription and resources.
- Resource Group: A logical container in Azure that holds related resources for an application.
- Helm: A package manager for Kubernetes. It simplifies the installation of complex applications.
- NGINX Ingress Controller: A popular application that manages external access to your services.
- `cert-manager`: A Kubernetes add-on that automates the management of TLS certificates from Let's Encrypt.
Part 1: Prerequisites & Local Setup
Step 1: Install and Configure the Azure CLI
- Install the Azure CLI: Follow the official Microsoft instructions.
- Log In: Authenticate with your Azure account.
Terminalaz login
Step 2: Install `kubectl`
The `az` CLI can install `kubectl` for you.
az aks install-cli
Step 3: Install Helm
Helm is the Kubernetes package manager.
- Follow the official Helm installation guide. On Linux, a common method is:
Terminalcurl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
Part 2: Provisioning the Azure Infrastructure
Step 4: Create a Resource Group
All Azure resources must belong to a resource group.
az group create --name gemvcResourceGroup --location eastus
Step 5: Create the AKS Cluster
This command creates a standard, cost-effective cluster and can take 5-10 minutes.
az aks create \
--resource-group gemvcResourceGroup \
--name gemvcCluster \
--node-count 2 \
--enable-managed-identity \
--generate-ssh-keys
Step 6: Configure `kubectl` to Connect to Your Cluster
This command downloads credentials and configures `kubectl`.
az aks get-credentials --resource-group gemvcResourceGroup --name gemvcCluster
Verify the connection: `kubectl get nodes`.
Part 3: Setting Up Ingress and Certificate Management
Step 7: Install the NGINX Ingress Controller
We will use Helm to install the ingress controller.
# 1. Add the official Helm repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# 2. Install the controller in its own namespace
helm install ingress-nginx ingress-nginx/ingress-nginx \
--create-namespace \
--namespace ingress-nginx
Step 8: Install `cert-manager`
We will use Helm again to install `cert-manager`.
# 1. Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io
helm repo update
# 2. Install cert-manager
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.14.4 \
--set installCRDs=true
Part 4: Creating Kubernetes Manifests
Create a folder named `aks-k8s`. Inside it, create the following files.
Step 9: `deployment.yaml` & `service.yaml`
These files define your application and its internal service.
info: Create `aks-k8s/deployment.yaml` (identical to previous guides)
apiVersion: apps/v1
kind: Deployment
metadata:
name: gemvc-app-deployment
spec:
replicas: 2
selector:
matchLabels:
app: gemvc-app
template:
metadata:
labels:
app: gemvc-app
spec:
containers:
- name: gemvc-app
image: yourDockerAccount/yourImageName:latest
ports:
- containerPort: 9501
envFrom:
- secretRef:
name: gemvc-app-secrets
Step 10: Managing Configuration and Secrets
In Kubernetes, you should never include your `.env` file in your Docker image. The best practice is to use Kubernetes Secrets to manage sensitive data.
- Create a production `.env` file on your local machine. Make sure this file is included in your `.gitignore`.
Example `.env` file:TerminalDB_HOST=production-db.internal DB_USER=prod_user DB_PASS=a-very-secure-password API_KEY=another-super-secret-key
- Create a Kubernetes Secret from your `.env` file.
Terminalkubectl create secret generic gemvc-app-secrets --from-env-file=.env
The `envFrom` section in the `deployment.yaml` will now load these secrets as environment variables in your application container.
info: Create `aks-k8s/service.yaml`
apiVersion: v1
kind: Service
metadata:
name: gemvc-app-service
spec:
selector:
app: gemvc-app
ports:
- protocol: TCP
port: 80
targetPort: 9501
type: ClusterIP
Step 11: `cluster-issuer.yaml`
This manifest tells `cert-manager` how to obtain certificates.
info: Create `aks-k8s/cluster-issuer.yaml`
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-prod-private-key
solvers:
- http01:
ingress:
class: nginx
Step 12: `ingress.yaml`
This manifest configures the NGINX controller and `cert-manager`.
info: Create `aks-k8s/ingress.yaml`
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gemvc-app-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- app.your-domain.com
secretName: gemvc-app-tls-secret
rules:
- host: app.your-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gemvc-app-service
port:
number: 80
Part 5: Deploying and Verifying
Step 13: Apply the Manifests
# 1. Create the ClusterIssuer for cert-manager
kubectl apply -f aks-k8s/cluster-issuer.yaml
# 2. Deploy your application
kubectl apply -f aks-k8s/deployment.yaml
kubectl apply -f aks-k8s/service.yaml
kubectl apply -f aks-k8s/ingress.yaml
Step 14: Get the External IP and Configure DNS
- Find the Ingress IP: It may take a few minutes for Azure to assign a public IP.
Terminalkubectl get service --namespace ingress-nginx ingress-nginx-controller
Look for the IP in the `EXTERNAL-IP` column. - Configure DNS: Create an `A` record pointing `app.your-domain.com` to this external IP.
After DNS propagates, your application will be live and secure.
Part 6: The CI/CD Update Process
The update process remains the same.
- Code & Release: A new release on GitHub builds and pushes the new image.
- Update Manifest: Change the image tag in `aks-k8s/deployment.yaml`.
- Apply the Change:
Terminalkubectl apply -f aks-k8s/deployment.yaml
AKS will perform a zero-downtime rolling update.