With the help of automated tools, implementing “Zero Downtime Deployment” is no longer a problem for most web projects. The problem now is which tool to choose for your project. With Laravel, we have quite a few options written in PHP such as:
- Rocketeer – http://rocketeer.autopergamene.eu/
- Envoy – https://laravel.com/docs/6.x/envoy
- Deployer – https://deployer.org/
However, in this article, I will talk about deploying Laravel’s auto deploy project with capistrano – a ruby gem.
1. Introduction
There are quite a lot of articles about Capistrano on viblo so I just briefly introduce Capistrano.
Capistrano is a tool written in Ruby that allows you to automatically execute a set of commands on one or several remote servers using SSH. Capistrano can run in parallel on multiple servers at the same time, this helps us significantly reduce deploy time when deploying to multiple servers.
2. Implementation
I have implemented and pushed the code onto laravel-capistrano , and in this article I will rely on the code on the github above.
After deployment, the project directory structure will be similar to the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token operator">=</span> <span class="token keyword">begin</span> <span class="token constant">Deploy</span> directory structure <span class="token punctuation">:</span> <span class="token operator">/</span> var <span class="token operator">/</span> www <span class="token operator">/</span> test <span class="token operator">-</span> deploy ├── current <span class="token operator">-</span> <span class="token operator">></span> <span class="token operator">/</span> var <span class="token operator">/</span> www <span class="token operator">/</span> test <span class="token operator">-</span> deploy <span class="token operator">/</span> releases <span class="token operator">/</span> <span class="token number">20191216080141</span> ├── releases │ ├── <span class="token number">20191216075447</span> │ ├── <span class="token number">20191216075558</span> │ ├── <span class="token number">20191216075711</span> │ ├── <span class="token number">20191216075932</span> │ └── <span class="token number">20191216080141</span> ├── repo │ ├── <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> │ └── <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> ├── revisions <span class="token punctuation">.</span> log └── shared ├── <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> └── storage <span class="token operator">=</span> <span class="token keyword">end</span> |
2.1. Install the required components
- You need to install ruby and gem capistrano on Capistrano config machine
- You need to make sure this machine can ssh into the server you want to deploy
- You need to make sure the server has access to git / svn / … containing the code to deploy
- Install gem capistrano
1 2 | gem <span class="token function">install</span> capistrano |
- optional : if you want to notify slack then you need to install gem
slackistrano
1 2 | gem <span class="token function">install</span> slackistrano |
2.2. Configure
After clone the code on github, we just need to edit the config file to deploy.
1 2 3 4 | <span class="token function">cp</span> config/deploy.rb.example config/deploy.rb <span class="token function">cp</span> config/deploy/staging.rb.example config/deploy/staging.rb <span class="token function">cp</span> config/deploy/production.rb.example config/deploy/production.rb |
config/deploy.rb
In this file, you need to update the information of the components as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <span class="token comment"># Config application</span> set <span class="token symbol">:application</span> <span class="token punctuation">,</span> <span class="token string">"test-deploy"</span> set <span class="token symbol">:repo_url</span> <span class="token punctuation">,</span> <span class="token string">" <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="d9beb0ad99beb0adb1acbbf7bab6b4">[email protected]</a> :YOUR_USER_NAME/REPOSITORY.git"</span> <span class="token comment"># Config for deploy path</span> set <span class="token symbol">:deploy_to</span> <span class="token punctuation">,</span> <span class="token string">'/var/www/test-deploy'</span> set <span class="token symbol">:releases_dir</span> <span class="token punctuation">,</span> <span class="token string">'/var/www/test-deploy/releases'</span> <span class="token comment"># Default env</span> set <span class="token symbol">:dotenv_file</span> <span class="token punctuation">,</span> <span class="token string">'/PATH/TO/.env'</span> <span class="token comment"># Default value for keep_releases is 5</span> set <span class="token symbol">:keep_releases</span> <span class="token punctuation">,</span> <span class="token number">5</span> <span class="token comment"># List of worker servers</span> set <span class="token symbol">:workers_servers</span> <span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token comment"># Slack configure</span> set <span class="token symbol">:slackistrano</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> klass <span class="token punctuation">:</span> <span class="token constant">Slackistrano</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">CustomMessaging</span> <span class="token punctuation">,</span> channel <span class="token punctuation">:</span> <span class="token string">'#your-channel'</span> <span class="token punctuation">,</span> webhook <span class="token punctuation">:</span> <span class="token string">'your-incoming-webhook-url'</span> <span class="token punctuation">}</span> |
If your project does not use slack, you can comment on the slack config code above.
config/deploy/production.rb
1 2 3 4 5 6 7 8 9 10 11 | <span class="token comment"># server web detail</span> <span class="token comment"># You need to change ip and user for your server</span> server <span class="token string">'10.0.0.10'</span> <span class="token punctuation">,</span> user <span class="token punctuation">:</span> <span class="token string">'deploy'</span> <span class="token punctuation">,</span> roles <span class="token punctuation">:</span> <span class="token string">%w{web app laravel}</span> <span class="token comment"># Config ssh option</span> set <span class="token symbol">:ssh_options</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> keys <span class="token punctuation">:</span> <span class="token string">%w(LINK/TO/YOUR/private_key)</span> <span class="token punctuation">,</span> forward_agent <span class="token punctuation">:</span> <span class="token keyword">false</span> <span class="token punctuation">,</span> auth_methods <span class="token punctuation">:</span> <span class="token string">%w(publickey)</span> <span class="token punctuation">}</span> |
2.3. Deploy
To deploy, you can refer to the usage below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token comment"># Deploy with default branch in config deploy.rb</span> cap staging deploy <span class="token comment"># Deploy with tag 1.0.1</span> cap staging deploy branch <span class="token operator">=</span> 1.0.1 <span class="token comment"># Deploy with tag 1.0.2 and run Seeder_0_0_1 and Seeder_0_0_2</span> cap staging deploy branch <span class="token operator">=</span> 1.0.2 seeders <span class="token operator">=</span> Seeder_0_0_1,Seeder_0_0_2 <span class="token comment"># Rollback deploy</span> cap staging rollback <span class="token comment"># Rollback deploy to specific release</span> cap staging rollback ROLLBACK_RELEASE <span class="token operator">=</span> 20191001101213 |
2.4. Run single task
In addition to executing a set of tasks / statements as above, we can execute each statement individually:
1 2 3 4 5 6 | <span class="token comment"># Rollback migrate</span> cap staging laravel:migrate_rollback <span class="token comment"># List all release (for rollback release above)</span> cap staging web:release_list |
2.5. Extend
My code above only satisfies deploying a basic laravel project. If you need other special tasks, you can write more and put in lib/capistrano/tasks
, it will be automatically include
during the run.
Conclusion
As you can see, implementing deploy project laravel with capistrano is quite simple. Just need some basic config, you can deploy immediately