GEMVC Documentation

Complete guide to building modern, secure PHP applications with GEMVC framework

🚀 Guide: Deploying a Dockerized GEMVC Application to AWS EKS

This document provides a complete walkthrough for deploying a containerized application to the Amazon Elastic Kubernetes Service (EKS). This method is designed for high availability, automatic scaling, and production-grade workloads, making it a powerful step up from a single VPS setup.

Core Concepts

  • Kubernetes (K8s): An open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications.
  • AWS EKS: A managed Kubernetes service from Amazon. AWS manages the complex Kubernetes "control plane," and you manage the "worker nodes" (the servers where your application runs).
  • `kubectl`: The primary command-line tool for interacting with a Kubernetes cluster.
  • `eksctl`: A simple command-line tool for creating and managing clusters on EKS.
  • Manifests: YAML files that describe the desired state for your application, including deployments, services, and how it's exposed to the internet.
  • AWS Load Balancer Controller: An addon for EKS that automatically provisions an AWS Application Load Balancer (ALB) to route internet traffic to your application.

Part 1: Prerequisites & Local Setup

Before you begin, you must configure your local machine to interact with AWS and Kubernetes.

Step 1: Install and Configure AWS CLI

The AWS Command Line Interface is essential for managing your AWS resources.

  1. Install the AWS CLI: Follow the official AWS instructions for your operating system.
  2. Configure Credentials: You need an AWS account with administrative permissions. Create an IAM user with programmatic access and run:
Terminal
aws configure

Step 2: Install `kubectl`

`kubectl` is the tool you'll use to talk to your EKS cluster.

Step 3: Install `eksctl`

`eksctl` dramatically simplifies creating and managing EKS clusters.

Terminal
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
            

Part 2: Provisioning the AWS EKS Cluster

Now we will create the core Kubernetes infrastructure in your AWS account.

Step 4: Create the EKS Cluster

Run the following command to create a new EKS cluster. This command provisions a basic, cost-effective cluster suitable for getting started.

Tip: This process can take 15-20 minutes.
Terminal
eksctl create cluster \
--name gemvc-cluster \
--region us-east-1 \
--version 1.29 \
--nodegroup-name standard-workers \
--node-type t3.medium \
--nodes 2 \
--nodes-min 1 \
--nodes-max 3 \
--managed
            

Once the command completes, `eksctl` will automatically configure your local `kubectl` to communicate with your new cluster. You can verify this by running:

Terminal
kubectl get nodes

This should show your 2 worker nodes in a `Ready` state.


Part 3: Creating Kubernetes Manifests

Instead of a `docker-compose.yml` file, Kubernetes uses multiple manifest files to define how to run an application. Create a new folder on your local machine named `k8s`. Inside it, create the following three files.

Step 5: `deployment.yaml`

This file tells Kubernetes how to deploy your application: what image to use, how many copies to run (replicas), and what port it listens on.

info: Create `k8s/deployment.yaml`
Terminal
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gemvc-app-deployment
spec:
  replicas: 2 # Run 2 instances of the app for high availability
  selector:
    matchLabels:
      app: gemvc-app
  template:
    metadata:
      labels:
        app: gemvc-app
    spec:
      containers:
      - name: gemvc-app
        image: yourDockerAccount/yourImageName:latest # Your Docker Hub image
        ports:
        - containerPort: 9501 # The port your Swoole server listens on
        envFrom:
        - secretRef:
            name: gemvc-app-secrets
            

Step 6: 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 like database passwords and API keys.

  1. Create a production `.env` file on your local machine. Make sure this file is included in your `.gitignore` and is never committed to your repository.
    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. This command reads your local file and creates a secret object inside your EKS cluster.
    Terminal
    kubectl create secret generic gemvc-app-secrets --from-env-file=.env

The `envFrom` section in the `deployment.yaml` (added in the previous step) will now automatically load the key-value pairs from this secret as environment variables in your application container.

Step 7: `service.yaml`

This file creates a stable internal network endpoint for your application pods. The AWS Load Balancer will send traffic to this service, which then distributes it to your app pods.

info: Create `k8s/service.yaml`
Terminal
apiVersion: v1
kind: Service
metadata:
  name: gemvc-app-service
spec:
  selector:
    app: gemvc-app
  ports:
    - protocol: TCP
      port: 80 # The service port
      targetPort: 9501 # The container port to forward traffic to
  type: NodePort # Use NodePort to allow traffic from the Ingress
            

Step 8: `ingress.yaml`

This file is the most critical for public access. It instructs the AWS Load Balancer Controller to create an Application Load Balancer (ALB) and configure it to route traffic from your domain to your service.

Tip: You must have a public SSL certificate for your domain registered in AWS Certificate Manager (ACM) in the same region as your cluster.
info: Create `k8s/ingress.yaml`
Terminal
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: gemvc-app-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    # This annotation points to your SSL certificate in ACM
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:REGION:ACCOUNT_ID:certificate/CERTIFICATE_ID
spec:
  rules:
    - host: app.your-domain.com # Your public domain
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: gemvc-app-service
                port:
                  number: 80
            
Tip: Important: You must replace `anong-api.your-domain.com` and the full `certificate-arn`.

Part 4: Deploying the Application

With the manifests created, you can now deploy your application to the EKS cluster.

Step 9: Install the AWS Load Balancer Controller

This controller is the bridge between Kubernetes and AWS load balancers. You must install it once per cluster. Follow the official AWS guide for installing the ALB Controller. This involves several `kubectl` commands.

Step 10: Apply the Manifests

Run the following commands from your directory containing the `k8s` folder.

Terminal
# Deploy the application
kubectl apply -f k8s/deployment.yaml

# Create the internal service
kubectl apply -f k8s/service.yaml

# Create the load balancer and public route
kubectl apply -f k8s/ingress.yaml
            

Step 11: Verify the Deployment

  1. Check the pods: See if your application containers are running.
    Terminal
    kubectl get pods
  2. Check the Ingress: This will give you the public URL of your new Application Load Balancer.
    Terminal
    kubectl get ingress gemvc-app-ingress

    Look for the value in the `ADDRESS` column. It will be a long URL ending in `elb.amazonaws.com`.
  3. Configure DNS: Go to your domain registrar and create a `CNAME` record pointing your domain (`app.your-domain.com`) to the ALB address you found in the previous step.

After a few minutes for DNS to propagate, your GEMVC application will be live and running on AWS EKS, secured with SSL.


Part 5: The CI/CD Update Process

Updating your application is simple and enables zero-downtime deployments.

  1. Code & Release: Make changes to your code and create a new release on GitHub. The same GitHub Action from our previous guide will build and push the new version-tagged image to Docker Hub.
  2. Update Manifest: On your local machine, open `k8s/deployment.yaml` and update the image tag to the new version (e.g., from `latest` to `1.0.6`).
  3. Apply the Change: Run the `apply` command for the deployment file.
    Terminal
    kubectl apply -f k8s/deployment.yaml

Kubernetes will automatically perform a rolling update. It will create new pods with the updated image and gracefully terminate the old ones, ensuring your service remains available throughout the process.