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.
- Install the AWS CLI: Follow the official AWS instructions for your operating system.
- Configure Credentials: You need an AWS account with administrative permissions. Create an IAM user with programmatic access and run:
aws configure
Step 2: Install `kubectl`
`kubectl` is the tool you'll use to talk to your EKS cluster.
- Follow the official Kubernetes instructions to install `kubectl` on your machine.
Step 3: Install `eksctl`
`eksctl` dramatically simplifies creating and managing EKS clusters.
- Follow the official `eksctl` installation guide for your OS. For Linux, the command is typically:
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.
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:
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`
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.
- 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: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. This command reads your local file and creates a secret object inside your EKS cluster.
Terminalkubectl 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`
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`
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.
# 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
- Check the pods: See if your application containers are running.
Terminalkubectl get pods
- Check the Ingress: This will give you the public URL of your new Application Load Balancer.
Terminalkubectl get ingress gemvc-app-ingress
Look for the value in the `ADDRESS` column. It will be a long URL ending in `elb.amazonaws.com`. - 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.
- 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.
- 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`).
- Apply the Change: Run the `apply` command for the deployment file.
Terminalkubectl 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.