Skip to content

Instantly share code, notes, and snippets.

@bummzack
Last active April 26, 2021 22:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bummzack/b9e4a3ef0d16ab303aab66a779f92c6e to your computer and use it in GitHub Desktop.
Save bummzack/b9e4a3ef0d16ab303aab66a779f92c6e to your computer and use it in GitHub Desktop.
Rsync Deployment setup à la bummzack

Rsync Deployment setup à la bummzack

Setup

First, you'll need to install the deployer rsync recipe. To get the recipe for deployer 3.x, use:

composer require --dev deployphp/recipes ~3.0

The deploy.php recipe assumes, that you have a dev-deploy folder in your project-folder. This folder must contain an .htaccess and _ss_environment.php file, prefixed with the stage it should be deployed to. It also must contain a rsync.filter.txt file with the Rsync filter-rules (these are usually the same for each project).

So these are the files that should be in dev-deploy if you have a stage named live and staging:

  • live.htaccess (required): The .htaccess file that will be copied to the live server.
  • live_ss_environment.php (required): The _ss_environement.php file that will be copied to the live server.
  • staging.htaccess (required): The .htaccess file that will be copied to the staging server.
  • staging_ss_environment.php (required): The _ss_environement.php file that will be copied to the staging server.
  • rsync.filter.txt (required): The filter rules that should be used for the rsync-task.
  • robots.txt (optional): A robots.txt that will be copied to all stages.

Tasks

These are the additional tasks that are added by the deploy.php recipe.

  • my_cnf creates a file called ~/.my_cnf on the remote server that will contain the DB credentials for mysqldumps that won't require user credentials via command-line.
  • installcomposer will install composer in ~/bin/ on the remote server
  • setup just runs my_cnf and installcomposer
  • rsync copies your website data via rsync (this is being run during a standard "deploy")
  • silverstripe:prepare can be used to copy a .htaccess and .web.config file for your assets folder (this is being run during a standard "deploy")
  • silverstripe:dump creates a database dump (this is being run during a standard "deploy")
  • silverstripe:migrate runs dev/build?flush=1 (this is being run during a standard "deploy")

Note: The rsync task will run gulp release locally. So make sure there's a gulp task for that. See: https://gist.github.com/bummzack/e49517fb7a9d9f7fae64b6838ea8986f to see my gulp setup.

Description of rsync.filter.txt

The default contents of rsync.filter.txt are:

- */.DS_Store
- */.git
- dev-*
+ themes/***
+ mysite/***
+ composer.*
- *

This basically copies themes and mysite and everything within these directories, unless the file/dir is named .DS_Store, .git or starts with dev-. composer.json and composer.lock are being copied as well, everything else is ignored.

<?php
server('live', '{{LiveServer}}', 22)
->user('{{SshUser}}')
->forwardAgent() // You can use identity key, ssh config, or username/password to auth on the server.
->stage('live')
->env('deploy_path', '{{DeployDir}}'); // Define the base path to deploy your project to.
server('staging', '{{StagingServer}}', 22)
->user('{{SshUser}}')
->forwardAgent() // You can use identity key, ssh config, or username/password to auth on the server.
->stage('staging')
->env('deploy_path', '{{DeployDir}}'); // Define the base path to deploy your project to.
set('default_stage', 'staging');
# Running `dep deploy` will deploy to the staging server (default_stage), `dep deploy live` will deploy to the live server.
<?php
require 'recipe/composer.php';
require 'vendor/deployphp/recipes/recipes/rsync.php';
require 'deploy-stages.php';
env('rsync_src', __DIR__);
env('rsync_dest','{{release_path}}');
env('bin/composer', '~/bin/composer.phar');
set('keep_releases', 10);
set('shared_dirs', ['assets']);
set('composer_command', '~/bin/composer.phar');
set('rsync',[
'exclude' => [],
'exclude-file' => false,
'include' => [],
'include-file' => realpath('dev-deploy/rsync.filter.txt'),
'filter' => [],
'filter-file' => false,
'filter-perdir' => false,
'flags' => 'rz', // Recursive, with compress
'options' => ['delete'],
'timeout' => 60
]);
task('silverstripe:readenv', function(){
$env = env('stages.0');
require_once ('dev-deploy/'. $env .'_ss_environment.php');
env('ss.db_name', SS_DATABASE_NAME);
env('ss.db_host', SS_DATABASE_SERVER);
env('ss.db_pass', SS_DATABASE_PASSWORD);
env('ss.db_user', SS_DATABASE_USERNAME);
})->setPrivate();
task('gulp_build', function (){
runLocally('gulp release');
})->setPrivate();
before('rsync', 'gulp_build');
task('installcomposer', function(){
run('curl https://getcomposer.org/composer.phar --create-dirs -o ~/bin/composer.phar');
run('chmod +x ~/bin/composer.phar');
})->desc('install composer');
task('my_cnf', function() {
$cmd = <<<CONFIG
cat >~/.my.cnf <<EOL
[mysqldump]
user=%s
password="%s"
host=%s
EOL
CONFIG;
run(sprintf($cmd, env('ss.db_user'), env('ss.db_pass'), env('ss.db_host')));
})->desc('create .my.cnf file');
before('my_cnf', 'silverstripe:readenv');
task('silverstripe:prepare', function() {
if(file_exists('dev-deploy/assets/web.config')) {
upload('dev-deploy/assets/web.config', '{{deploy_path}}/shared/assets/web.config');
}
if(file_exists('dev-deploy/assets/.htaccess')) {
upload('dev-deploy/assets/.htaccess', '{{deploy_path}}/shared/assets/.htaccess');
}
})->desc('uploads assets .htaccess, web.config');
task('silverstripe:setup', function() {
// upload files if they locally exist for the current stage
$env = env('stages.0');
if(file_exists('dev-deploy/'. $env .'_ss_environment.php')) {
upload('dev-deploy/{{stages.0}}_ss_environment.php', '{{release_path}}/_ss_environment.php');
}
if(file_exists('dev-deploy/'. $env .'.htaccess')) {
upload('dev-deploy/{{stages.0}}.htaccess', '{{release_path}}/.htaccess');
}
if(file_exists('dev-deploy/'. $env .'.htaccess')) {
upload('dev-deploy/{{stages.0}}.htaccess', '{{release_path}}/.htaccess');
}
if(file_exists('dev-deploy/robots.txt')) {
upload('dev-deploy/robots.txt', '{{release_path}}/robots.txt');
}
run('mkdir -p {{release_path}}/silverstripe-cache');
})->desc('create silverstripe-cache, upload .htaccess & _ss_environment.php');
task('silverstripe:dump', function() {
try {
run('mkdir -p {{deploy_path}}/dumps');
run('mysqldump {{ss.db_name}} | gzip -v > {{deploy_path}}/dumps/dump-{{release}}.sql.gz');
} catch (Exception $ex) {
}
})->desc('dump DB');
before('silverstripe:dump', 'silverstripe:readenv');
task('silverstripe:migrate', function() {
run('php {{release_path}}/framework/cli-script.php dev/build flush=1');
})->desc('Run SilverStripe migration');
task('setup', [
'installcomposer',
'my_cnf'
]);
// and now say what to do in which order
task('deploy', [
'deploy:prepare',
'silverstripe:prepare',
'silverstripe:dump',
'deploy:release',
'rsync',
'deploy:shared',
'silverstripe:setup',
'deploy:vendors',
'silverstripe:migrate',
'deploy:symlink',
'cleanup',
])->desc('Deploy your project');
after('deploy', 'success');
- */.DS_Store
- */.git
- dev-*
+ themes/***
+ mysite/***
+ composer.*
- *
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment