Build a CI/CD pipeline on Gitlab to build and deploy Laravel Application to ECS.
As per today’s date, there is no official feature/plugin from Gitlab which helps deploy an application to AWS, therefore this blog is all about leveraging Gitlab and it’s a developer-friendly feature to build and manage a CI/CD pipeline for a Laravel application.
Overview of this blog:
- Take sample Laravel app and dockerize it
- Write Gitlab pipeline to build containers
- Setup ECS – Fargate or EC2 hosted
- Modify Gitlab pipeline to upload Docker images to ECR
- Deploy to ECS and monitor
Starting with choosing a demo application for Laravel, we will use quick start Laravel project. The first task will be to Dockerize the Laravel App and for that, you will require Docker installed on your system.
Dockerize Applicaiton
First step will be clone the application code on you local system and writing a Docker Compose file to test run the application on your local machine.
$ git clone https://github.com/laravel/quickstart-basic.git
$ sudo systemctl start docker
Inside the application directory now create a docker-compose.yaml
file and copy-paste the following content.
version: '3.4'
services:
laravel-app:
build: .
ports:
- "80:80"
volumes:
- ./laravel-app/:/var/www/html/
The above code mentions the docker-compose service as 3.4
and defines application name as laravel-app
. The build
parameter points to current directory where the application will be built and mapped to port 80 of your system and the container port 80. The volumes
parameter will mount the local laravel-app directory to /var/www/html
inside the container.
Now you to run the docker-compose file you will require specifications for the container and for that, you will also need a Dockerfile
, therefore, we will create one with below code.
FROM php:7.4-fpm-alpine
# Install packages
RUN apk update && apk add -u apache2 php7-apache2 php7-mbstring php7-session php7-json php7-pdo php7-openssl php7-tokenizer php7-pdo php7-pdo_mysql php7-xml php7-simplexml \
&& ln -s /usr/sbin/httpd /usr/sbin/apache2
RUN apk add --no-cache bash coreutils grep sed
# Install app
RUN rm -rf /var/www/localhost/* && mkdir -p /var/www/html
ADD laravel-app /var/www/html
# Upload and replace apache2 config file
RUN rm -rf /etc/apache2/httpd.conf
COPY httpd.conf_default /etc/apache2/httpd.conf
# Configure apache
RUN chown -R www-data:www-data /var/www/html
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
EXPOSE 80
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]
Note: The Dockerfile is dependent on httpd.conf_default file which is a config file for apache server.
Now you can build and run docker container on your local system:
docker build . -t laravel-app
docker run -it -d -p 80:80 laravel-app:latest
Note: To check if a container has issues use docker logs
command followed by container id. Also, you can run the docker run command without -d
to see the state of the container.
If everything went well you will be able to open the Laravel application in your browser at http://localhost:80
Setup ECS and ECR
Now we have an application which is Dockerized and ready to be shipped to ECS as a service. The next step will be to set up the ECS cluster first and then the ECS service. You can set up ECS service with Fargate or EC2 backed, in this example, we will use EC2 backed ECS cluster.
Follow steps mentioned in …. to setup ECS cluster. After setting up ECS cluster, you will need to create an ECR repo store Docker images, therefore, we will push the Docker image to ECR for the initial time.
You can create ECR repo using cloudformation from here
Now we have the ECR repo we can now push the local docker image.
docker push XXXXXXXXXX.dkr.ecr.eu-west-1.amazonaws.com/app:latest
Note: Your IAM user will require appropriate rights to push and pull images.
Now we will set up ECS service. For that, you can use these cloudformation templates to create an ECS service with Application Load Balancer and Autoscaling.