The problem
Capistranos rsync module was deprecated and you were now expected to run git commands on the end server. I wanted to change this so I didn’t need to install extra packages on the server and let jenkins build step run any extra steps like minification.
The Solution
There is an alternative to capistrano, Deployer. Migrating to use deployer over capistrano allows deployment via rsync whilst maintaining the ability to run extra hooks/steps around the deployment.
Steps
First, install the deployer php package:
composer require --dev deployer/deployer
Second create a deploy.php file:
<?php
namespace Deployer;
require 'recipe/common.php';
// Config
set('keep_releases', 5);
set('rsync_src', __DIR__);
set('release_path','/var/www/somewebsite/prod');
add('shared_files', ['file_one.php', 'file_two.php']);
add('shared_dirs', ['folder_one']);
add('writable_dirs', []);
// Hosts
// Set an identitykey in /home/user/.ssh/config or ~/.ssh/config
host('prod.somewebsite.com')
->set('remote_user', 'deploy')
->set('hostname', 'prod.somewebsite.com')
->set('port', 22)
->set('deploy_path','{{release_path}}')
->set('rsync_src', '{{rsync_src}}')
->set('rsync_dest','{{release_path}}');
// Build step - Minify CSS and JS
task('setup:minify', function(){
writeln('<info>Minifying CSS and JS before uploading</info>');
runLocally('bin/ravensholde -o setup:minify');
});
// Override deploy - to use rsync rather than git pull
task('deploy:update_code', function () {
writeln("<info>Uploading files to server</info>");
upload(__DIR__ . "/", '{{deploy_path}}' . "/releases/" . "{{release_name}}", ["options" => ["--exclude-from=deployment-exclude-list.txt"]]);
});
// Override symlink - to point to correct folder
task('deploy:shared', function () {
$sharedPath = "{{deploy_path}}/shared";
// Symlink Folders
foreach (get('shared_dirs') as $dir) {
run("{{bin/symlink}} $sharedPath/$dir {{deploy_path}}/releases/{{release_name}}/$dir");
}
// Symlink Files
foreach (get('shared_files') as $file) {
run("{{bin/symlink}} $sharedPath/$file {{deploy_path}}/releases/{{release_name}}/$file");
}
});
// Tasks
task('deploy', [
]);
// Hooks
// Before
before('deploy:update_code', 'setup:minify');
// After
after('deploy:failed', 'deploy:unlock');
Next, on the jenkins server we update the jenkins ssh config to add the new host
Host prod.somewebsite.com
HostName [x.x.x.x]
User [deploy]
IdentityFile [/path/to/ssh/key]
SetEnv TERM=xterm-256color
Lastly we adjust the jenkins build step to include setting up composer and deploying via deployer
composer install
composer dump-autoload
./vendor/bin/dep deploy prod.somewebsite.com
Now we can run build steps on jenkins, before we push the code out to the server!