Deploy WordPress On ECS Fargate Using CICD
Table of contents
- Prerequisites
- VPC
- RDS
- Elastic Container Service
- ECR : Elastic Container Registry
- Retrieve an authentication token and authenticate your Docker client to your registry
- Build your Docker image using the following command
- After the build is completed, tag your image so you can push the image to this repository:
- Run the following command to push this image to your newly created AWS repository:
- Create service for php ‘Backend’
- AWS Cloud Map
- try_files $uri /index.php$is_args$args;
- ECR
- HTTPS Git
This post shows you how to run WordPress without servers using Amazon ECS on AWS Fargate. We will create a VPC and an ECS cluster in which our WordPress tasks will run. An RDS MySQL instance will provide the database that WordPress requires.
Prerequisites
Dockerfile for Nginx
Dockerfile for PHP
AWS VPC
AWS CodeCommit
AWS CodeBuild
AWS CodePipeline
AWS ECR
AWS ECS
AWS CloudMap
VPC
Create a new vpc for your ECS project, must enable DNS Hostname & DNS Resolution.
Go to aws console search VPC - - - > Create a vpc
Name : ecs-vpc
IPv4 CIDR : 10.0.0.0/16
Select your newly created VPC - - - > goto action & enable DNS Hostnames & DNS Resolutions.
By the way, DNS Resolution is enabled by default.
Enable it - - - > then click on save changes button
Now create two public subnets - - - eg
Name : PublicSubnet-1a
CICR : 10.0.0.0/24
Name : PublicSubnet-2b
CICR : 10.0.1.0/24
Click on create subnet - - - > select your newly created vpc - - - >select ecs-vpc
Now create a Internet Gateway for your VPC
After creating an internet gateway - - - > you got a pop-up notification clickon that, it's asking you to attach your vpc from your internet gateway.
Click to : Attach to a VPC
Select your newly created vpc then click on Attach internet gateway button.
Now go to the Route Table, you do not create extra RT when we are creating a vpc it will automatically create a route table, you can see your vpc name so click on that.
Click on Edit routes - - - > then click on Add route.
0.0.0.0/0 that mean it will match to any IP address - - - > select Internet Gateway
Done!
RDS
Now goto ECS, for now create ecs deployment base infrastructure using php & nginx image, after successfully deployment we will test using CICD Pipeline,
Create a ECS Cluster - - - > click on Create Cluster
Elastic Container Service
Select cluster template : Networking Only
Now Configure Cluster :
Enable (mark on) CloudWatch Container Insights
After creating Cluster, move on to Task Definition - - - >
Click on Create new Task Definition - - - > select launch type Fargate - - - > Click on next step.
Select Launch Type : FARGATE
Task definition name : wp-php-td
Task role : ecsTaskExecutionRole
Network mode : awsvpc
OS Family : Linux
Task Execution Role : ecsTaskExecutionRole
Task Memory : 2GB
Task CPU (vCPU) : 1 vCPU
Now go to your workspace, create Dockerfile & other files for both nginx & php then push them into ECR Elastic Container Service.
Create a folder sudo mkdir wp-cicd
Create three folder under wp-cicd
mkdir php
mkdir nginx
Go inside the php folder, then create & download following files
Dockerfile : user could call on the command line to assemble an image
buildpsecfile : CodeBuild uses to run a build
test.html : change in this file (nothing but just Pipeline testing)
Index.php :
We have to download WordPress in the php directory for our Dockerfile.
Download WordPress & extract using linux command & after extracting wordpress file delete latest.tar.gz file
Dockerfile (php)
FROM php:7.2-fpm-stretch
COPY index.php /usr/share/nginx/html/
COPY ./wordpress /usr/share/nginx/html/
RUN apt-get update -y
RUN docker-php-ext-install mysqli pdo pdo_mysql && docker-php-ext-enable pdo_mysql
RUN apt-get install -y libcurl4-openssl-dev ssh nano pkg-config libssl-dev
index.php
<?php
phpinfo();
?>
revisiont.html
Deploying wordpress using cicd
ECR : Elastic Container Registry
Create a repository name : wp-php
Retrieve an authentication token and authenticate your Docker client to your registry
aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin 660645611558.dkr.ecr.us-east-2.amazonaws.com
Build your Docker image using the following command
docker build -t wp-php .
After the build is completed, tag your image so you can push the image to this repository:
docker tag wp-php:latest 660645611558.dkr.ecr.us-east-2.amazonaws.com/wp-php:latest
Run the following command to push this image to your newly created AWS repository:
docker push 660645611558.dkr.ecr.us-east-2.amazonaws.com/wp-php:latest
Goto php directory & follow these commands.
Copy the URI of the php-image - - - > goto ECS - - - > Add container - - - >
Container Name : php-container
Image : copy the URI from ECR of wp-php
Port : 9000
Environment variables | RDS | php-container
AWS_RDS_HOSTNAME : database-1.cvafffm3a4pp.us-east-2.rds.amazonaws.com
AWS_RDS_DB_NAME : wpdb
AWS_RDS_PASSWORD : password
AWS_RDS_PORT : 3306
AWS_RDS_USERNAME : admin
Click on view task definition - - - > Click on Cluster - - -> Click on Cluster
Create service for php ‘Backend’
Select launch type : fargate
Task Definition : wp-php-td
Cluster : ECS-Fargate
Service Name : php-srv
Number Of Task : 1
Remember previously we created vpc & subnet, select that resources.
Enable service discovery.
Namespace : local
Service discovery name : php
AWS Cloud Map
AWS Cloud Map is a cloud resource discovery service. With Cloud Map, you can define custom names for your application resources, and it maintains the updated location of these dynamically changing resources
Go to cloud map - - - > a namespace created there
Php part is completed from this ECS side!
Now go to Nginx directory and create some file
Dockerfile
buildspec.yml
nginx.conf
index.php
test.html
wordpress/
Dockerfile
FROM nginx:mainline
RUN rm -rf /etc/nginx/conf.d/*
COPY ng.conf /etc/nginx/conf.d/
COPY index.php /usr/share/nginx/html/
COPY test.html /usr/share/nginx/html/
nginx.conf
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.php index.html;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, Origin, Response-Type';
add_header 'Access-Control-Allow-Methods' 'GET,PUT,POST,DELETE';
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
#location / {
try_files $uri /index.php$is_args$args;
#}
try_files $uri $uri/ @rewrite;
location @rewrite {
rewrite ^/(.*)$ /index.php?_url=/$1 ;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass php.local:9000;
}
}
“Must (In the loopback ip paste the Cloud Map namespace php.local along with php port 9000)”
This will connect with the php container, in the loopback IP
index.php
<?php
phpinfo();
?>
test.html
Deploying wordpress using CICD
Now we have to download wordpress for nginx.
sudo wget -c http://wordpress.org/latest.tar.gz
sudo tar -xzvf latest.tar.gz
Download WordPress & extract using linux command & after extracting wordpress file delete latest.tar.gz file
sudo rm -rf latest.tar.gz
Now goto ECR created a new repository for nginx.
ECR
Now goto terminal go inside of nginx directory & then follow all these steps.
Build your Docker image using the following command
docker build -t wp-nginx .
After the build is completed, tag your image so you can push the image to this repository:
docker tag nginx:latest 660645611558.dkr.ecr.us-east-2.amazonaws.com/wp-nginx:latest
Run the following command to push this image to your newly created AWS repository:
docker push 660645611558.dkr.ecr.us-east-2.amazonaws.com/wp-nginx:latest
Go back to your ECS Cluster, - - - > create a Task Definition - - ->
Select launch type Fargate
Task definition Name : wp-nginx-td
Task Role : ecsTaskExecutionRole
Network Mode : awsvpc
OS Family : Linux
Task Execution Role : ecsTaskExecutionRole
Task memory : 2GB
Task CPU (vCPU) : 1 vCPU
Click on Add container, copy the nginx image uri from ECR.
Environment variables | RDS | php-container
AWS_RDS_HOSTNAME : database-1.cvafffm3a4pp.us-east-2.rds.amazonaws.com
AWS_RDS_DB_NAME : wpdb
AWS_RDS_PASSWORD : password
AWS_RDS_PORT : 3306
AWS_RDS_USERNAME : admin
Click on View task definition - - - > Click on cluster - - - > click on create
Create a service : nginx
Launch type : fargate
OS family : Linux
Task Definition (family) :wp-nginx-td
Cluster : ECS-Fargate
Service Name : nginx-srv
Number Of Task : 1
Now select your vpc & subnets, security group & enable service discovery.
Select the existing Security Group that we created for both nginx & php.
Enable service discovery
Note :
- Attach source of nginx | php security group in RDS inbound.
Check health both nginx & php service in Cloud Map
All good! Now go to nginx service - - -> click on task - - - > scroll down - - -
Take the public IP of nginx & hit on the web.
Note :
Change the wp-config-sample.php to wp-config.php
Edit the database and enter the same credentials as RDS.
Again build Dockerfile & push the image to ECR.
ECS : stop both services nginx, php it will automatically start with new revision.
test.html
Automate this process using CICD & IAM Policy
CodeCommit
CodeBuild
CodePipeline
Now goto IAM console - - - > Click on users - - - > Click on your username
Click on security credentials - - - > Scroll Down - - - > Come to the HTTPS section - - - > Click on Generate credentials - - - > Download the credentials.
HTTPS Git
Git credentials, an IAM-generated username and password pair you can use to communicate with CodeCommit repositories over HTTPS, perform all tasks eg : git pull, push etc.
Now take the https link to clone the nginx-repo from CodeCommit to your local environment.
IAM
Create two repositories for storing both nginx, php source code.
wp-nginx
Goto AWS console search CodeCommit - - - > create a repository for nginx.
Create a buildspec file for nginx CodeBuild, that will build our source code for deployment stage.
version: 0.2
phases:
install:
runtime-versions:
nodejs: 16
pre_build:
commands:
echo Logging in to Amazon ECR.....
aws --version
aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin 660645611558.dkr.ecr.eu-west-2.amazonaws.com
REPOSITORY_URI=660645611558.dkr.ecr.eu-west-2.amazonaws.co..
IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
build:
commands:
echo Build started on
date
echo Building the Docker image...
docker build -t $REPOSITORY_URI:$IMAGE_TAG .
post_build:
commands:
echo Build completed on
date
echo Pushing the Docker images...
docker push $REPOSITORY_URI:$IMAGE_TAG
echo Writing image definitions file...
printf '[{"name":"nginx-container","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json
Change something like aws region, aws account, image name without tag, container-name same as ecs.
Imagedefinition.json : magedefinitions. json file for Amazon ECS standard deployment actions. An image definitions document is a JSON file that describes your Amazon ECS container name and the image and tag.
wp-nginx
Now create the remaining ones php-repo - - - > click on create repository.
CodeBuild
Breathe build for both nginx & php after that we automate the build process using CodePipeline
wp-nginx-build
Buildspec : leave it as default it will take this buildspec.yml file from CodeCommit repository. If you want to directly write that file you do not need to upload on git, you can directly write your buildspec file in Insert build commands.
Now create build for php
AWS CodePipeline
Pipeline Succeeded
Now create another Pipeline for Php
Go to Pipeline console - - - > Edit - - - > Source - - - > Add stage - - - >
Click on Add action - - - > Source - - - > Edit the action.
For php Source & Build :
Source : SourceArtifact1
Build : BuildArtifact1
Php : Pipeline Editing completed.
Now do some change in any directory content from local (terminal)
Then push it to the CodeCommit Repository.
- v2
Pipeline Succeeded
Take public IP & check new revisions.
Done!