Undoubtedly, the topic, I think, has been jaded by many holes - nevertheless, it must be done for each project - but I will raise it and tell you about one wonderful tool, which, for some strange reason, is still not wrote on Habré, and indeed in the Russian-language segment somehow there is little written about him. Correct this misunderstanding.
Deployer is good in many ways. The script code for deployment is short. It is written in good old Pykhchansky - that is, most likely, you will not have to install any other tools separately on the server. If it does, then PHP is usually installed by a single command on any server. Why not use it in your projects?
I wrote a utility, a certain Anton Medvedev, by the way, he has a rather nice blog . Thank you, Anton :)
The first commit was made already in 2013, and so far the tool is slowly developing. He also has a nice website where you can find all the documentation about him.
What I personally like the most about what this tool gives is the ability to quickly roll back to the last “working” release if the new release was unsuccessful. It is also quite convenient that if you try to “roll out” a new release, something will go wrong (the migrations did not apply, the front-end files did not compile, the tests did not get out ..) - then your current running application will not affect it - it will work as if nothing had happened. The fact is that Deployer will not change the link in the directory denoting the current active release until your new "release" is fully installed and ready to go.
The only thing that Deployer does not solve is possible problems with applying migrations to your database. But this is generally a difficult topic, I don’t know if there are any elegant solutions in this case at all. If it exists, I will be glad to know which one.
The whole project is divided into three folders: current
, releases
and shared
. In general, this is a fairly common form for such tools, and it is really convenient. Say, in one of my projects on Laravel, this structure looks like this:
current
- link to the folder of the last successfully collected release, i.e. current application.releases
- all releases that have been compiled. By default, only the last three releases are saved, and this value can be easily changed.shared
is the folder where all the "common" files are located, which apply to all releases at the same time and should not be created anew each time. For example, an .env
file, user-uploaded files, and so on.
I like to personally go to my server, run the deployment script and watch the process of its work. Simply, I am so much safer to live, since I can always take some urgent measures if something goes wrong with the Deploy. And as I know, people usually run a similar script from their local machine, which connects via SSH to the server and produces warmth. If this needs to be done on several machines at once, then this approach will certainly be more convenient. By the way, Deployer allows deploying multiple machines at once.
Naturally, before you can run this script, you must first install Deployer on your system.
In one of my projects on Laravel 5 the deployment script deploy.php
looks like this:
<?php // Deployer' require 'recipe/common.php'; require 'recipe/laravel.php'; // localServer('local', 'localhost') ->user('{-}') ->env('deploy_path', '/path/to/project/dir') ->stage('local') ; set('repository', '{-git-.git}'); env('branch', '{--}'); env('git_cache', true); // , // , // shared set('shared_dirs', [ 'storage/app', 'storage/framework/cache', 'storage/framework/sessions', 'storage/framework/views', 'storage/logs', 'public/uploads', 'node_modules', ]); // . , // Laravel "" // - .env set('shared_files', ['.env']); // , // . - set('writable_dirs', ['storage', 'vendor', 'public/uploads' ]); set('http_user', '{-}'); set('composer_command', '/usr/local/bin/composer'); // Composer' // . NPM task('deploy:install-npm', function() { run('cd {{release_path}} && npm i'); }); // : , // Grunt.js task('deploy:compile-assets', function() { run('cd {{release_path}} && grunt deploy-production'); }); // task('deploy:migrations', function() { run('cd {{release_path}} && php artisan migrate --force'); }); // task('deploy:create-route-cache', function() { run('cd {{release_path}} && php artisan route:cache'); }); // task('deploy:create-config-cache', function() { run('cd {{release_path}} && php artisan config:cache'); }); // task('deploy:clean-cached-data', function() { run('cd {{release_path}} && rm bootstrap/cache/*'); }); // PHP task('reload:php-fpm', function() { run('sudo /usr/sbin/service php7.0-fpm restart'); }); task('deploy', [ 'deploy:prepare', 'deploy:release', 'deploy:update_code', // 'deploy:shared', // 'deploy:vendors', // 'deploy:clean-cached-data', // 'deploy:create-route-cache', // 'deploy:create-config-cache', // 'deploy:install-npm', // NPM 'deploy:compile-assets', // 'deploy:migrations', // 'deploy:symlink', // 'cleanup', // ])->desc('Deploy your project'); after('deploy', 'success'); // php after('deploy', 'reload:php-fpm'); // - after('rollback', 'reload:php-fpm');
I also have a couple of small files next to the above file: start-deploy.sh
and rollback-deploy.sh
. In order to quickly launch the patch or, accordingly, roll it back.
File start-deploy.sh
:
dep deploy local
File rollback-deploy.sh
:
dep rollback local
Therefore, in order to start the deployment process, we need to type only one command in Bash:
./start-deploy.sh
Thus, as we see, having entered only one command, we will force the server to execute all necessary steps for expansion of our project. And only if everything went well, the current
folder will change the link to the new release and restart PHP after all this.
In general, this is all that I wanted to tell and show. I hope it will be useful to someone. And of course it will be interesting to know the opinion of other people about how they are engaged in deploying their applications.
Source: https://habr.com/ru/post/302442/
All Articles