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

  1. Install the Azure CLI: Follow the official Microsoft instructions.
  2. Log In: Authenticate with your Azure account.
    Terminal
    az login

Step 2: Install `kubectl`

The `az` CLI can install `kubectl` for you.

Terminal
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:
    Terminal
    curl 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.

Terminal
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.

Terminal
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`.

Terminal
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.

Terminal
# 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`.

Terminal
# 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)
Terminal
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.

  1. Create a production `.env` file on your local machine. Make sure this file is included in your `.gitignore`.
    Example `.env` file:
    Terminal
    DB_HOST=production-db.internal
    DB_USER=prod_user
    DB_PASS=a-very-secure-password
    API_KEY=another-super-secret-key
  2. Create a Kubernetes Secret from your `.env` file.
    Terminal
    kubectl 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`
Terminal
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`
Terminal
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`
Terminal
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

Terminal
# 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

  1. Find the Ingress IP: It may take a few minutes for Azure to assign a public IP.
    Terminal
    kubectl get service --namespace ingress-nginx ingress-nginx-controller

    Look for the IP in the `EXTERNAL-IP` column.
  2. 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.

  1. Code & Release: A new release on GitHub builds and pushes the new image.
  2. Update Manifest: Change the image tag in `aks-k8s/deployment.yaml`.
  3. Apply the Change:
    Terminal
    kubectl apply -f aks-k8s/deployment.yaml

AKS will perform a zero-downtime rolling update.