Home » How to Deploy a WordPress Website using Docker, AWS ECR, and AWS EKS

How to Deploy a WordPress Website using Docker, AWS ECR, and AWS EKS

Deploy Wordpress Using Docker, ECR & EKS

In today’s cloud-native era, deploying applications in containers is a must-have skill especially for dynamic websites like WordPress. In this tutorial, you’ll learn how to deploy a WordPress website using Docker, push the container image to AWS Elastic Container Registry (ECR), and run it on Amazon EKS (Elastic Kubernetes Service).

This approach gives you scalability, resilience, and performance for your WordPress site — while using modern DevOps practices.

Let’s dive into the full step-by-step guide!

Prerequisites

Before starting, make sure you have:

  • An AWS Account

  • AWS CLI configured (aws configure)

  • Docker installed

  • kubectl installed and configured

  • eksctl installed

  • Basic knowledge of Docker and Kubernetes

Step 1: Dockerize Your WordPress Application

First, let’s create a Docker file for frontend wordpress

Similarly, Create Docker file for backend WordPress which means for MySQL

Now, Create docker-compose file

  • We are using docker compose to build and run wordpress website in localhost

Basically, we have created a Dockerfile for both WordPress and MySQL, along with a Docker Compose file to build the docker images and run the containers locally. This allows us to verify that the website is working properly before deploying it to the cloud.

Now, Build Images using docker compose


Multi Copy Code Blocks

Multi Copy Code Blocks
bash

docker compose build
    

Verify your images

Multi Copy Code Blocks
bash

docker images
    

Run docker container Multi Copy Code Blocks

Multi Copy Code Blocks
bash

docker compose up -d
    

After successfully run the container go to browser and paste URL

  • http://localhost:8080/ 

Step 2: Push Your Docker Images to AWS ECR

Prerequisites

  • Configure AWS CLI 
  • Set a AWS region and acoount

Set AWS region and AWS account Multi Copy Code Blocks

Multi Copy Code Blocks
bash

AWS_REGION=us-east-1 
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
    

To verifying Multi Copy Code Blocks

Multi Copy Code Blocks
bash

ehco $AWS_REGION
echo $AWS_ACCOUNT_ID
    

Now, create ECR repositories in AWS for both wp-frontend and wp-mysql. Multi Copy Code Blocks

Multi Copy Code Blocks
bash

# For WordPress
aws ecr create-repository --repository-name wp-frontend --region $AWS_REGION

# For Mysql
aws ecr create-repository --reposiroty-name wp-backend --region $AWS_REGION
    

Login to AWS ECRMulti Copy Code Blocks

Multi Copy Code Blocks
bash

aws ecr get-login-password -–region $AWS_REGION | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com
    

Now tag your images to push to AWS ECRMulti Copy Code Blocks

Multi Copy Code Blocks
bash

# Tag for WordPress-frontend
docker tag cloudwithyuvi/wp-frontend:latest ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/wp-frontend:latest

# tag for Mysql-Backend
docker tag cloudwithyuvi/wp-backend:8.0 ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/wp-backend:8.0
    

Push the wordpress- frontend images in AWS ECR
Multi Copy Code Blocks

Multi Copy Code Blocks
bash

docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/wp-frontend:latest
    

Push the mysql-backend images in AWS ECR Multi Copy Code Blocks

Multi Copy Code Blocks
bash

docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/wp-backend:8.0
    

You can verify your images in AWS ECR 

  • Go to AWS Console and click on ECR 
  • Click on your repository and you will find your images

Step 3: Deploy WordPress to AWS EKS using ECR Images

Prerequisites

  • Configure AWS CLI 
  • Set a AWS region and acoount
  • Install kubectl 
  • Install eksctl 
  • Install Helm 

Install kubectl
Multi Copy Code Blocks

Multi Copy Code Blocks
bash

curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.30.0/2024-06-14/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin

kubectl version --client
    

Install eksctl
Multi Copy Code Blocks

Multi Copy Code Blocks
bash

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

eksctl version
    

Now, create ECR repositories in AWS for both wp-frontend and wp-mysql.
Multi Copy Code Blocks

Multi Copy Code Blocks
bash

# For WordPress
aws ecr create-repository --repository-name wp-frontend --region $AWS_REGION

# For Mysql
aws ecr create-repository --reposiroty-name wp-backend --region $AWS_REGION
    

Now, create role for EC2

  • Go to AWS Console —> click on IAM 
  • Click on role tab and create
    • Use Case: EC2
  • Attach Policies
    • AmazonEKSWorkerNodePolicy
    • AmazonEC2ContainerRegistryReadOnly
    • AmazonEKS_CNI_Policy
  • Role Name: EKSNodeRole

Attach Policy to nodegroup to access EBS volume
Multi Copy Code Blocks

Multi Copy Code Blocks
bash

aws iam attach-role-policy --role-name  --policy-arn arn:aws:iam::aws:policy/AmazonEBSCSIDriverPolicy
    

Now, create AWS EKS cluster
Multi Copy Code Blocks

Multi Copy Code Blocks
bash

eksctl create cluster \
  --name wordpress-cluster \
  --region ap-south-1 \
  --nodegroup-name wordpress-nodes \
  --node-type t3.medium \
  --nodes 2 \
  --nodes-min 2 \
  --nodes-max 4 \
  --managed
    

Note: It will take 10-15 min to create AWS EKS Cluster. You can take tea break 😂😂

Update Kubeconfig
Multi Copy Code Blocks

Multi Copy Code Blocks
bash

aws eks --region ap-south-1 update-kubeconfig --name wordpress-cluster
    

Verifying and get nodes
Multi Copy Code Blocks

Multi Copy Code Blocks
bash

kubectl get nodes
    

Install EBS CSI Driver [ For Storage ]Multi Copy Code Blocks

Multi Copy Code Blocks
bash

eksctl create iamserviceaccount --name ebs-csi-controller-sa --namespace kube-system --cluster wordpress-cluster --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy --approve --role-only --role-name AmazonEKS_EBS_CSI_DriverRole
    

Enable Driver from Console

Multi Copy Code Blocks
bash

aws eks create-addon --cluster-name wordpress-cluster --addon-name aws-ebs-csi-driver --service-account-role-arn arn:aws:iam:::role/AmazonEKS_EBS_CSI_DriverRole
    

Verify DriverMulti Copy Code Blocks

Multi Copy Code Blocks
bash

kubectl get pods -n kube-system | grep ebs
    

Now, Create Menifest file for deploy wordpress

For namespace.yml
Multi Copy Code Blocks

Multi Copy Code Blocks
yaml

apiVersion: v1
kind: Namespace
metadata:
  name: wordpress
    

Apply namespace.yml
Multi Copy Code Blocks

Multi Copy Code Blocks
yaml

kubectl apply -f namespace.yaml
    

For wordpress-pvc.yml
Multi Copy Code Blocks

Multi Copy Code Blocks
yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  namespace: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: gp2
    

Apply wordpress-pvc.yml

Multi Copy Code Blocks
yaml

kubectl apply -f wordpress-pvc.yml
    

For mysql-pvc.yml
Multi Copy Code Blocks

Multi Copy Code Blocks
yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  namespace: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: gp2
    

Apply mysql-pvc.yml Multi Copy Code Blocks

Multi Copy Code Blocks
yaml

kubectl apply -f mysql-pvc.yml
    

For wordpress-deployment.ymlMulti Copy Code Blocks

Multi Copy Code Blocks
yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  namespace: wordpress
spec:
  replicas: 2
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
      - image: .dkr.ecr.ap-south-1.amazonaws.com/:latest
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: mysql.wordpress.svc.cluster.local:3306
        - name: WORDPRESS_DB_USER
          value: wpuser
        - name: WORDPRESS_DB_PASSWORD
          value: wppassword
        - name: WORDPRESS_DB_NAME
          value: wordpress
        ports:
        - containerPort: 80
        volumeMounts:
        - name: wp-persistent-storage
          mountPath: /var/www/html
      volumes:
      - name: wp-persistent-storage
        persistentVolumeClaim:
          claimName: wp-pv-claim
    

Apply wordpress-deployment.yml

Multi Copy Code Blocks
yaml

kubectl apply -f wordpress-deployment.yml
    

For wordpress-service.yml
Multi Copy Code Blocks

Multi Copy Code Blocks
yaml

apiVersion: v1
kind: Service
metadata:
  name: wordpress-service
  namespace: wordpress
spec:
  type: LoadBalancer
  ports:
    - port: 80
  selector:
    app: wordpress
    

Apply wordpress-service.ymlMulti Copy Code Blocks

Multi Copy Code Blocks
yaml

kubectl apply -f wordpress-service.yml
    

For mysql-deployment.yml
Multi Copy Code Blocks

Multi Copy Code Blocks
yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: wordpress
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:8.0
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootpassword
        - name: MYSQL_DATABASE
          value: wordpress
        - name: MYSQL_USER
          value: wpuser
        - name: MYSQL_PASSWORD
          value: wppassword
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim
    

Apply mysql-deployment.yml Multi Copy Code Blocks

Multi Copy Code Blocks
yaml

kubectl apply -f mysql-deployment.yml
    

For mysql-servcie.yml
Multi Copy Code Blocks

Multi Copy Code Blocks
yaml

apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: mysql
  clusterIP: None
    

Apply mysql-servcie.yml Multi Copy Code Blocks

Multi Copy Code Blocks
yaml

kubectl apply -f mysql-service.yml
    

Now, Verify persistent volume claim will be bound status
Multi Copy Code Blocks

Multi Copy Code Blocks
yaml

kubectl get pvc -n wordpress
    

Verify pods status are runningMulti Copy Code Blocks

Multi Copy Code Blocks
yaml

kubectl get pods -n wordpress
    

Copy the external IP for run your website on browserMulti Copy Code Blocks

Multi Copy Code Blocks
yaml

kubectl get svc -n wordpress
    

If all are running status then copy the External IP of wordpress-service and paste it on your browser. 

Leave a Reply

Your email address will not be published. Required fields are marked *