Hello everyone, after a long time of absence, I came back here, the last time was too busy, so I could not share much, only there was a series about Deploy, so I did 1 article about CI / CD using CircleCI and Deployer everyone.
Like ae Sun, there is SunCI and if you want to setup to be naughty, you have to be keymember or leader or higher to fetch the project to test SunCI so it is quite inadequate.
But come to CircelCI, people build comfortable, functions and interfaces in my opinion are even smoother than SunCI. Ok ramble that let’s start.
To be able to do this lesson, make sure everyone has done it or has done it before:
- [Backend] Deploy your Laravel application (P1)
- [Backend] Deploy your Laravel application (P2 – Last part)
- [Backend] Deploy a Laravel project using Deployer
- [Frontend] Install ESLINT for projects using Laravel and Vuejs
- [Backend] PHP static code analysis tools
- [Docker] Know and use docker
- [Docker] Setup Docker Hub
- Understand what is CI / CD and DevOps?
An extra option if you want to write Test for your project, you need to have experience with UnitTest and IntegrationTest
Finally, to be able to do well and understand CI / CD, you must have quite a lot of experience in Build Server, Auto deploy, Check convention JS, PHP, Config tested in laravel project, Know how to use docker, build dockerhub …
OK, preparing knowledge is enough, let’s develop =))
Setup config.yml file
To get started, everyone must have a project (laravel), 2 must be using Github or Bitbucket.
After you’ve met the two conditions above, in the root folder of your project, you create a folder named .circleci and inside there create another file config.yml. After creating, your folder structure will look like this:
OK its basic content will be as follows
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | version <span class="token punctuation">:</span> <span class="token number">2</span> jobs <span class="token punctuation">:</span> build_and_test <span class="token punctuation">:</span> docker <span class="token punctuation">:</span> <span class="token operator">-</span> image <span class="token punctuation">:</span> framgia <span class="token operator">/</span> laravel <span class="token operator">-</span> workspace steps <span class="token punctuation">:</span> <span class="token operator">-</span> checkout <span class="token operator">-</span> run <span class="token punctuation">:</span> cp <span class="token punctuation">.</span> env <span class="token punctuation">.</span> example <span class="token punctuation">.</span> env <span class="token shell-comment comment"># composer cache</span> <span class="token operator">-</span> restore_cache <span class="token punctuation">:</span> keys <span class="token punctuation">:</span> <span class="token operator">-</span> vendor <span class="token operator">-</span> v1 <span class="token operator">-</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> checksum <span class="token double-quoted-string string">"composer.lock"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator">-</span> run <span class="token punctuation">:</span> composer install <span class="token operator">-</span> save_cache <span class="token punctuation">:</span> key <span class="token punctuation">:</span> vendor <span class="token operator">-</span> v1 <span class="token operator">-</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> checksum <span class="token double-quoted-string string">"composer.lock"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> paths <span class="token punctuation">:</span> <span class="token operator">-</span> vendor <span class="token shell-comment comment"># run test</span> <span class="token operator">-</span> run <span class="token punctuation">:</span> phpcs <span class="token operator">--</span> standard <span class="token operator">=</span> Framgia app |
Explain through some syntax mn
- Including 2 main parts is docker and steps
- First you can see in the docker you are using an image called framgia / laravel-workspace . For those of you who have known about Docker or not yet, Docker is simply an image like a box with some things installed to support us in running test projects such as php, composer, git and tool to check conventions. for php is phpcs and a few other tools. The specific content image you can see here .
- Next, the steps section is the step we will run for our project, specifically:
- checkout – Clone code from github – this is the default command of CircleCI.
- run: [command] – Commands to execute.
- restore_cache – Restore the folder containing the package (vendor /) based on the composer.lock file
- save_cache – Save the vendor vendor folder if the composer.lock file has been changed or you deleted or added a new package.
- The cache of the vendor folder helps speed up your build for later runs because instead of having to reinstall the packages, then you can reuse the vendor folder of the previous build if the composer.lock file is not change.
After configuring, you can push the code to the repo, guys
Init project
Everyone go to https://circleci.com/ then login with github or Bitbucket of everyone, I use github to get used to it, after login is complete it will redirect to the dashboard page is ok
Everyone choose to enter ADD PROJECT Then select the project that needs Setup, Everyone select your project, click the Set up Project button
At this screen, there will be a place to select Operating System, language, it is already default for me, my PHP code =)) Now choose Start Building is ok, select then it will switch to the build screen, and It will run the first build
Wait it build 1 bit ok
Success is right, cool, first floor is smooth like that because I have run the phpcs test first in the local already, and if mn and fail then click on detail to see what it failed to fix then push again
For example, if this fails eslint, I just need to see where it fails then fix and push it again
CI
OK, as above, everyone can build one by themselves, now check more, check ESLINT, TEST in laravel. Please update your config.yml file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | version <span class="token punctuation">:</span> <span class="token number">2</span> jobs <span class="token punctuation">:</span> build_and_test <span class="token punctuation">:</span> docker <span class="token punctuation">:</span> <span class="token operator">-</span> image <span class="token punctuation">:</span> framgia <span class="token operator">/</span> laravel <span class="token operator">-</span> workspace <span class="token operator">-</span> image <span class="token punctuation">:</span> mysql <span class="token punctuation">:</span> <span class="token number">5.7</span> environment <span class="token punctuation">:</span> <span class="token constant">MYSQL_HOST</span> <span class="token punctuation">:</span> <span class="token number">127.0</span> <span class="token number">.0</span> <span class="token number">.1</span> <span class="token constant">MYSQL_DATABASE</span> <span class="token punctuation">:</span> homestead <span class="token constant">MYSQL_USER</span> <span class="token punctuation">:</span> homestead <span class="token constant">MYSQL_PASSWORD</span> <span class="token punctuation">:</span> secret <span class="token constant">MYSQL_ROOT_PASSWORD</span> <span class="token punctuation">:</span> root steps <span class="token punctuation">:</span> <span class="token operator">-</span> checkout <span class="token operator">-</span> run <span class="token punctuation">:</span> cp <span class="token punctuation">.</span> env <span class="token punctuation">.</span> testing <span class="token punctuation">.</span> example <span class="token punctuation">.</span> env <span class="token punctuation">.</span> testing <span class="token shell-comment comment"># composer cache</span> <span class="token operator">-</span> restore_cache <span class="token punctuation">:</span> keys <span class="token punctuation">:</span> <span class="token operator">-</span> vendor <span class="token operator">-</span> v1 <span class="token operator">-</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> checksum <span class="token double-quoted-string string">"composer.lock"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator">-</span> run <span class="token punctuation">:</span> composer install <span class="token operator">-</span> save_cache <span class="token punctuation">:</span> key <span class="token punctuation">:</span> vendor <span class="token operator">-</span> v1 <span class="token operator">-</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> checksum <span class="token double-quoted-string string">"composer.lock"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> paths <span class="token punctuation">:</span> <span class="token operator">-</span> vendor <span class="token shell-comment comment"># Yarn</span> <span class="token operator">-</span> restore_cache <span class="token punctuation">:</span> name <span class="token punctuation">:</span> Restore yarn cache keys <span class="token punctuation">:</span> <span class="token operator">-</span> yarn <span class="token operator">-</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> checksum <span class="token double-quoted-string string">"yarn.lock"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator">-</span> yarn <span class="token operator">-</span> <span class="token operator">-</span> run <span class="token punctuation">:</span> yarn <span class="token operator">-</span> save_cache <span class="token punctuation">:</span> paths <span class="token punctuation">:</span> <span class="token operator">-</span> node_modules key <span class="token punctuation">:</span> yarn <span class="token operator">-</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> checksum <span class="token double-quoted-string string">"composer.json"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator">-</span> run <span class="token punctuation">:</span> name <span class="token punctuation">:</span> Check convention javarscript command <span class="token punctuation">:</span> npm run eslint <span class="token shell-comment comment"># run test</span> <span class="token operator">-</span> run <span class="token punctuation">:</span> php artisan key <span class="token punctuation">:</span> generate <span class="token operator">--</span> env <span class="token operator">=</span> testing <span class="token operator">-</span> run <span class="token punctuation">:</span> name <span class="token punctuation">:</span> Check convention <span class="token constant">PHP</span> command <span class="token punctuation">:</span> phpcs <span class="token operator">--</span> standard <span class="token operator">=</span> Framgia app <span class="token operator">-</span> run <span class="token punctuation">:</span> name <span class="token punctuation">:</span> Check connection database command <span class="token punctuation">:</span> framgia <span class="token operator">-</span> ci test <span class="token operator">-</span> connect <span class="token number">127.0</span> <span class="token number">.0</span> <span class="token number">.1</span> <span class="token number">3306</span> <span class="token number">60</span> <span class="token operator">-</span> run <span class="token punctuation">:</span> php artisan migrate <span class="token operator">--</span> seed <span class="token operator">--</span> env <span class="token operator">=</span> testing <span class="token operator">-</span> run <span class="token punctuation">:</span> name <span class="token punctuation">:</span> Check PhpUnit command <span class="token punctuation">:</span> <span class="token punctuation">.</span> <span class="token operator">/</span> vendor <span class="token operator">/</span> bin <span class="token operator">/</span> phpunit |
To be able to run Test in laravel, you need to have a database to run the test, that’s when adding the image mysql: 5.7
1 2 3 4 5 6 7 8 | <span class="token operator">-</span> image <span class="token punctuation">:</span> mysql <span class="token punctuation">:</span> <span class="token number">5.7</span> environment <span class="token punctuation">:</span> <span class="token constant">MYSQL_HOST</span> <span class="token punctuation">:</span> <span class="token number">127.0</span> <span class="token number">.0</span> <span class="token number">.1</span> <span class="token constant">MYSQL_DATABASE</span> <span class="token punctuation">:</span> homestead <span class="token constant">MYSQL_USER</span> <span class="token punctuation">:</span> homestead <span class="token constant">MYSQL_PASSWORD</span> <span class="token punctuation">:</span> secret <span class="token constant">MYSQL_ROOT_PASSWORD</span> <span class="token punctuation">:</span> root |
Now everyone configures some environment variables to be able to connect, You need to make sure that your .env.testing.example file also has a database declaration with information about the host, name The database, username and password coincide with the item we just added above as follows:
1 2 3 4 5 6 7 | <span class="token constant">DB_CONNECTION</span> <span class="token operator">=</span> mysql <span class="token constant">DB_HOST</span> <span class="token operator">=</span> <span class="token number">127.0</span> <span class="token number">.0</span> <span class="token number">.1</span> <span class="token constant">DB_PORT</span> <span class="token operator">=</span> <span class="token number">3306</span> <span class="token constant">DB_DATABASE</span> <span class="token operator">=</span> homestead <span class="token constant">DB_USERNAME</span> <span class="token operator">=</span> homestead <span class="token constant">DB_PASSWORD</span> <span class="token operator">=</span> secret |
After doing the above two things, we continue to add the following command in the file .circleci / config.yml as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | - run: name: Check convention javarscript command: npm run eslint - run: php artisan key:generate --env=testing - run: name: Check convention PHP command: phpcs --standard=Framgia app - run: name: Check connection database command: framgia-ci test-connect 127.0.0.1 3306 60 - run: php artisan migrate --seed --env=testing - run: name: Check PhpUnit command: ./vendor/bin/phpunit |
Each command trembles, adding two sub-commands, name and command, so that when it builds, it displays the name for it to be good instead of displaying the command. In this paragraph, I have to add check convention of js with Eslint.
1 2 3 4 | - run: name: Check convention javarscript command: npm run eslint |
This should ensure that projec has been setup in projec. Who has not found out, review here
To run the test, make sure the file env of mn must have the correct key, add it and run it
1 2 | <span class="token operator">-</span> run <span class="token punctuation">:</span> php artisan key <span class="token punctuation">:</span> generate <span class="token operator">--</span> env <span class="token operator">=</span> testing |
Followed by a standard check PHPCS Framgia . I think this standard is quite good, it only captures the most necessary conventions. but according to psr2’s full .. it catches a lot, which is writing doc for function for class … everything in the world.
1 2 3 4 | <span class="token operator">-</span> run <span class="token punctuation">:</span> name <span class="token punctuation">:</span> Check convention <span class="token constant">PHP</span> command <span class="token punctuation">:</span> phpcs <span class="token operator">--</span> standard <span class="token operator">=</span> Framgia app |
Next is the test connect to the database to see if it is ok and run migrate
1 2 3 4 5 | <span class="token operator">-</span> run <span class="token punctuation">:</span> name <span class="token punctuation">:</span> Check connection database command <span class="token punctuation">:</span> framgia <span class="token operator">-</span> ci test <span class="token operator">-</span> connect <span class="token number">127.0</span> <span class="token number">.0</span> <span class="token number">.1</span> <span class="token number">3306</span> <span class="token number">60</span> <span class="token operator">-</span> run <span class="token punctuation">:</span> php artisan migrate <span class="token operator">--</span> seed <span class="token operator">--</span> env <span class="token operator">=</span> testing |
The framgia-ci is a tool of Framgia, it is available in the image framgia / laravel-workspace mn, it is open source so please take it and use it hihi
The last part is to run tests
1 2 3 4 | <span class="token operator">-</span> run <span class="token punctuation">:</span> name <span class="token punctuation">:</span> Check PhpUnit command <span class="token punctuation">:</span> <span class="token punctuation">.</span> <span class="token operator">/</span> vendor <span class="token operator">/</span> bin <span class="token operator">/</span> phpunit |
OK, good, push it up and try to see how it runs, but remember to manipulate this, create a new branch and push to create pull compare with develop. After pushing it up, it is building a JS error, ok see the error and check under local and push it up
It’s green, right, look like it wants to merge =))
CD
The upper part is CI setup ok then right, after checking CI all ok then auto deploy only, =)) I find the CD part of this guy is quite good, in the config file I can customize a lot of things, such as CI pass, it must be approved to be deployed to the Development environment, then require to run in turn, Deploy finished this environment to deploy another environment, The interface so that I can imagine how the process of it is quite intuitive.
For example, a process like this
When people finish setting up the Circle build it will be very intuitive and each job will be a build
OK, in theory, that’s the rest, I can deploy it with at most 1-2 environments, like this article, I will only deploy automatically to the development environment.
To do this, everyone must have it
- 1 Server has fully setup to be able to run the laravel project
- Already configured deployer and deployed to this server. If anyone has not done so, then try through these 3 exercises
Anyone who has ever set up the server knows that one way to access the server is via ssh-key, this Circle too, if you want to deploy auto, you must allow this CircleCI ssh to access the server. Right, so do the following
OK after having the server, and the server has been gen ssh okay, everyone copy the private key in the ~ / .ssh / id_rsa directory and paste this into SSH Permission in the project’s settings section on CircleCI.
Insert the hostname and privakey of mn here, click ok and you’re done
Mine is private, so show it up for me to see where hehe, After I have added ok, I need to adjust the config.yml file
1 2 3 4 5 6 7 8 9 | deploy_development <span class="token punctuation">:</span> docker <span class="token punctuation">:</span> <span class="token operator">-</span> image <span class="token punctuation">:</span> framgiaciteam <span class="token operator">/</span> deb <span class="token operator">-</span> deploy <span class="token punctuation">:</span> <span class="token number">7.3</span> steps <span class="token punctuation">:</span> <span class="token operator">-</span> checkout <span class="token operator">-</span> run <span class="token punctuation">:</span> name <span class="token punctuation">:</span> Deploy Develop to development command <span class="token punctuation">:</span> dep deploy <span class="token operator">-</span> vv |
Add 1 part of deploy development to the job section, in this there will be 1 image framgiaciteam / deb-deploy: 7.3, this one I use by Sun, I can free to build the image make by me for the clams also, And finally, run the deployer command only
1 2 | command: dep deploy -vv |
Ok that’s okay, and deployer config how to see it in the article I noted above.
Cicle, this guy has a function to run under the workflows, in this workflow, I want to run if he runs, or I can condition that this guy will pass the other guy quite well,
1 2 3 4 5 6 7 8 9 10 11 12 | workflows <span class="token punctuation">:</span> version <span class="token punctuation">:</span> <span class="token number">2</span> build <span class="token operator">-</span> <span class="token keyword">and</span> <span class="token operator">-</span> deploy <span class="token punctuation">:</span> jobs <span class="token punctuation">:</span> <span class="token operator">-</span> build_and_test <span class="token operator">-</span> deploy_development <span class="token punctuation">:</span> requires <span class="token punctuation">:</span> <span class="token operator">-</span> build_and_test filters <span class="token punctuation">:</span> branches <span class="token punctuation">:</span> only <span class="token punctuation">:</span> develop |
Through this section, the player immediately guess what to do right, that is we will run the job
run build_and_test => deploy_development (Requires build_and_test guy to pass all before running deploy, and in this deploy only run when the code is updated in the develop branch)
. OK, good product, push the code up, everyone put on the branch mn code, wait for it to pass, then merge into develop. When merged, it will have a build
This build is just to check the convention and run the Test
When the build is delicious, it will run job auto deploy
People who click on the other running place will see 2 jobs of mn already configured
It’s done. Waiting for the other build to pass is delicious, let’s have a cup of coffee to enjoy.
In this guy, I prefer the approved part, such as auto deploy to production or an environment where you need to think, for example, this function is quite reasonable.
We just need to add this code to the config file only
1 2 3 4 5 6 | <span class="token operator">-</span> build_and_test <span class="token operator">-</span> hold_for_approval <span class="token punctuation">:</span> type <span class="token punctuation">:</span> approval requires <span class="token punctuation">:</span> <span class="token operator">-</span> build_and_test |
Then push up to feel offline: Go see the build it will look like this
Wait for the build test to finish, the pass will jump to the job, wait for my appprove, if I choose approved, I can go to the job deploy hehe
Image and feel offline
Notification
Part notification it supports slack but not chatwork so I am not config anymore, everyone try to see how.
Conclude
Ok this is my only post here, anyone who reads here is probably quite patient, because in order to be able to manipulate this article, to be able to setup well, your knowledge must also be in the form of pitiful =))
This time I’m doing series about CI / CD. I will do an autodeploy post with github action later, a tool of github has just been developed.