Tuesday, 5 September 2023

Laravel CI/CD with Jenkins, Docker, AWS

1. Install docker, docker compose

- add current $USER to docker group

sudo usermod -aG docker $USER

2. Download source code and build in local using docker-compose

https://github.com/thecaringdeveloper/laravel-cicd-tutorial (1)

docker-compose.yml

3. Install, start Jenkins

- install java

- install jenkins

- start jenkins

- access jenkins localhost:8090

- add user jenkins to docker group: sudo usermod -aG docker jenkins

- add plugin for jenkins

+ Pipeline Utility Steps
+ File Operations
+ SSH Agent

4. Create github repository

- push code in (1) to repository

5. Setup pipeline in source local (a job)

- create Makefile

- create Jenkinsfile

- create a job:

 Enter an item name/ Pipeline 

/ General: Testing CICD

/ Pipe script from SCM

/ Repository URL: get from repository in github

/ Credentials select credential create below

/ Branch: select branch in git repository

/ Script path: Jenkinsfile

6. create Credential for jenkins connect to github

Manage Jenkins/ manage credentials/ global /add credentials

    / Kind: SSH username with private key 

    / scope: Global (jenkins, nodes, items, all child items, ect)

    / id: github

    / username: your_github_username

    / create private, public key: private_key for jenkins, public_key  for github

    / Create

* Create a job for CICD

    / name: laravel-test

    / Pipeline: Piple script from SCM

    / SCM: git

    / Repository Url: Your_repo_url

    / Credentials:credential already create above

    / Script path: jenkinsfile 

7. Populate .env by using jenkin

+ copy .env file to jenkin: 

    / create folder in workspace jenkins include .env file: var/lib/jenkins/workspace/envs/laravel-test

    / create .env file in var/lib/jenkins/workspace/envs/laravel-test

    / add script to copy this .env file when deploy 

stage("Populate .env file") {
steps {
dir("/var/lib/jenkins/workspace/envs/LaravelTest02") {
fileOperations([fileCopyOperation(excludes: '', flattenFiles: true, includes: '.env', targetLocation: "${WORKSPACE}")])
}
}
}

- Run pipeline

6. Setup EC2

- get key-ec2.pem to ssh to ec2

- chmode  400 key-ec2.pem

- create credential for ec2 in jenkins

7. Create Artifact 

Create artifact.zip file

8. Copy Artifact artifact.zip file to ec2

update Jenkinsfile to copy Artifact artifact.zip file to ec2

9. Deploy on ec2, install server on ec2

- install server: sudo yum -y install httpd

- start server: sudo service httpd start

- edit inbound, outbound rules

- install php and extension: sudo yum install php-{...}

- set permission: sudo chown ec2-user:ec2-user /var/www/html

- sudo server httpd restart

Jenkinsfile

pipeline {
agent any
stages {
stage("Verify SSH connection to server") {
steps {
sshagent(credentials: ['aws-ec2']) {
sh '''
ssh -o StrictHostKeyChecking=no ec2-user@52.221.199.29 whoami
'''
}
}
}
stage("Verify tooling") {
steps {
sh '''
docker info
docker version
docker compose version
'''
}
}
stage("Clear all running docker containers") {
steps {
script {
try {
sh 'docker rm -f $(docker ps -a -q)'
} catch (Exception e) {
echo 'No running container to clear up...'
}
}
}
}

stage("Start Docker") {
steps {
sh 'make up'
sh 'docker compose ps'
}
}

stage("Run Composer Install") {
steps {
sh 'docker compose run --rm composer install'
}
}

stage("Populate .env file") {
steps {
dir("/var/lib/jenkins/workspace/envs/LaravelTest02") {
fileOperations([fileCopyOperation(excludes: '', flattenFiles: true, includes: '.env', targetLocation: "${WORKSPACE}")])
}
}
}

stage("Run Tests") {
steps {
sh 'docker compose run --rm artisan test'
}
}
}

post {
success {
sh 'cd "/var/lib/jenkins/workspace/LaravelTest02"'
sh 'rm -rf artifact.zip'
sh 'zip -r artifact.zip . -x "*node_modules**"'
withCredentials([sshUserPrivateKey(credentialsId: "aws-ec2", keyFileVariable: 'keyfile')]) {
sh 'scp -v -o StrictHostKeyChecking=no -i ${keyfile} /var/lib/jenkins/workspace/LaravelTest02/artifact.zip ec2-user@52.221.199.29:/home/ec2-user/artifact'
}
sshagent(credentials: ['aws-ec2']) {
sh 'ssh -o StrictHostKeyChecking=no ec2-user@52.221.199.29 unzip -o /home/ec2-user/artifact/artifact.zip -d /var/www/html'
script {
try {
sh 'ssh -o StrictHostKeyChecking=no ec2-user@52.221.199.29 sudo chmod 777 /var/www/html/storage -R'
} catch (Exception e) {
echo 'Some file permissions could not be updated.'
}
}
}
}
always {
sh 'docker compose down --remove-orphans -v'
sh 'docker compose ps'
}
}
}

Makefile

#!/usr/bin/make

SHELL = /bin/sh

UID := $(shell id -u)
GID := $(shell id -g)
USER:= $(shell whoami)

export UID
export GID
export USER

up:
docker compose up -d

Thank you

 

No comments:

Post a Comment

Golang Advanced Interview Q&A