# Dropcat – Deploy tool for Drupal ## Install globally (Mac/Linux) ### Dropcat 1 (deprecated) `curl -0 https://dropcat.org/dropcat.phar -o /usr/local/bin/dropcat` `chmod +x /usr/local/bin/dropcat` `dropcat about` ### Dropcat 2 (current) `curl -0 https://dropcat.org/dropcat2.phar -o /usr/local/bin/dropcat` `chmod +x /usr/local/bin/dropcat` `dropcat about` ## What does it do and why would anybody need it? Historically we at Digitalist Sweden (formerly Wunderkraut/NodeOne) have used a combination of Jenkins and Aegir to deploy our sites. When we started development of Drupal 8 sites, Aegir was not ready, and we also wanted a simpler deploy workflow, more fitting to our everyday needs. So we started to test out some tools out there that almost worked for us, but we realized that it should take us longer to adapt a tool that almost fits, than to develop our own. ## Symfony We decided to develop the tool using symfony components, because Drupal uses some of them already, and it is therefore a good fit. ## Don't reproduce, re-use The aim is not to replace an existing tool that do things perfect (or almost), the aim is to be the glue between the other tools. So in our deploy flow we use composer (instead of drush make that we have used for all drupal 7 sites in Wunderkraut Sweden), dropcat and drush, with jenkins (but we could also run our deploys locally, using whatever tools you wish to run commands, like your own terminal). ### Wrapping drush, why? Some of the commands are just wrappers around drush, like `dropcat backup` and `dropcat site-install`. We have dropcat as an wrapper because we could use variables from yaml-files in a consistent way. Some parts could be changed to be wrappers for drupal console instead in the future, or changed to use our own defined functions instead - the idea is to keep dropcat consistent, but changing what it is built on the way as needed. ## Commands We have now a bunch of commands to use with dropcat, and we are adding more in the near future. ### Dropcat 2 #### Available commands: | command | description | | ------ | ------ | |about| about dropcat| |backup| backup site| |config-import| Configuration import| |help| Displays help for a command| |list| Lists commands| |reset-login| Reset login| |symlink| Create symlink for target on server, intended for files folders| |tracker| Tracks configuration| |update| Run needed updates after a deploy.| |cache:rebuild| [cache-recreate|cache:recreate|cr] rebuilds the cache| |clean:deploys| [clean:deploy] Remove old deploy directories.| |config:pull| Configuration pull from another instance.| |db:import| [db-import] import database| |debug:check-connection| check ssh connection| |generate:drush-alias| creates a local drush alias| |get:db-backup| run command or script on local environment| |locale:update| update locales| |multi:clone| (deprecated) clone a drupal site| |multi:list| (deprecated) list drupal multi sites| |multi:move| (deprecated) Moves site in place| |node:gulp| run gulp| |node:npm-install| do a npm install| |node:run| run a node command| |node:yarn-install| do a yarn install| |reset:opcache| Reset opcache on web host.| |security:drupal| check drupal security| |self:rollback| (deprecated) [self-rollback] Rollbacks dropcat.phar to the last version| |self:update| (deprecated) [self-update] Updates dropcat.phar to the latest version if needed| |site:install| [site-install] Site install| |site:move| [move] Moves site in place| |site:prepare| [prepare] Prepare site| |site:rollback| (deprecated) [rollback] Rollback a site| |site:tar| [tar] Tar folder| |site:upload| [upload] Upload to server| |sites:backup| Uses the tracker dir for making backups of sites.| |varnish:purge| Purge your varnish instance| |vhost:create| (deprecated) create a vhost on a remote server| ## Drupal 9 support Drupal 9 support was added in dropcat2. Support for drush versions lower than 10 and Drupal 7 was dropped. ## First Drupal 8, then 7 The first target for this tool is to deploy drupal 8 sites, on the list is also to deploy drupal 7 sites, and maybe also other types of sites after that. "It is all just a bunch of files in different languages", as a famous bulgarian web developer said once! ## Run it `dropcat backup` This uses the default settings in dropcat.yml. If the system variable DROPCAT_ENV is set to dev, dropcat uses dropcat.dev.yml, if that exists. The config yaml-file must exits in the folder that dropcat is run from. ## Different commands for different tasks To get a list of all tasks that may be used use: `dropcat list` To get help on a command, and explanation of commands use: `dropcat help backup` ## Building dropcat2 To build dropcat, you need to be a maintainer. Create a protected tag (ref-*), and check the CI pipeline. ## Dropcat 2 in Jenkins pipeline #### Requirements: - Build an image with PHP, dropcat2 and any other dependencies you need. - Pipeline, docker plugin in Jenkins #### Add the "prepare environment" steps to inject environment variables: Properties Content ```bash DROPCAT_ENV=stage ENV=stage # Uses the jenkins plugin "Build timestamp" BUILD_DATE=${BUILD_TIMESTAMP} BACKUP_NAME=${BUILD_ID}_${BUILD_DATE} DB_DUMP_PATH=/backup/${JOB_NAME}/${BACKUP_NAME}.sql MYSQL_ROOT_USER=root MYSQL_ROOT_PASSWORD=rooty ``` #### Add build parameters We usually have one param to determine if we should import the database on stage sites. `Boolean: USE_PROD_DB_BACKUP` And one param to choose the branch to deploy. `Git param: BRANCH` #### Jenkinsfile It can be added to the code repo, or in the build job. ```groovy node { checkout scm docker.image('node:carbon-alpine3.11').inside() { stage('Theme') { sh 'npm install' sh 'npm run production' } } // Second argument: ID of the credentials, created in Jenkins. docker.withRegistry('https://my.private.registry', 'registry-creds') { docker.image('mynamespace/myimage:mytag').inside() { stage('Build') { sh 'mkdir -p $HOME/.ssh && cp /var/jenkins_home/.ssh/known_hosts $HOME/.ssh/known_hosts' sh 'composer install -n --no-dev --no-ansi --no-progress --no-suggest -o' sh 'dropcat2 security:drupal -l ${WORKSPACE}/composer.lock' sh 'dropcat2 prepare -v' sh 'dropcat2 tar --folder=${WORKSPACE}' sh 'dropcat2 upload -v' sh 'dropcat2 backup -v' sh 'dropcat2 move -v' sh 'dropcat2 symlink -v' if (params.USE_PROD_DB_BACKUP == true) { sh 'dropcat2 db-import -v' } sh 'dropcat2 update -v --config-split-settings=prod_split -l ${WORKSPACE}/composer.lock' sh 'dropcat2 locale:update -v' sh 'dropcat2 reset-login -v' sh 'dropcat2 clean:deploys -v -k 3' } } } } ``` ## Run Dropcat from jenkins (deprecated, use Pipeline instead) We are using dropcat from jenkins, in a executed shell. In this example dropcat is installed as required in composer.json (and placed in vednor/bin by default) for the drupal site (also a drush alias is setup for the site: ``` export DROPCAT_ENV=stage export ENV=stage export BUILD_DATE="$(date +"%Y%m%d")" # got to application dir, that is our web folder cd application composer install # only need to be runned once (creates drush alias on deploy server and database # on dbhost dropcat prepare dropcat tar --folder=${WORKSPACE}/application --temp-path=${WORKSPACE}/ -v dropcat upload --tar_dir=${WORKSPACE}/ dropcat symlink dropcat site-install dropcat update ``` All config for the deploy is in dropcat.stage.yml in application folder. ## Config examples Dropcat need as a minimum a dropcat.yml in the running directory. Example is found in examples folder. Also examples for dev and prod environmengt is in the folder. ## PHPunit-testing example ./phpunit This file points to the composer installed phpunit and runs that with the settings from phpunit.xml. This will run all tests found in the Tests folder. This also runs code coverage so you can see how much of your code that has been tested. ## Create Dropcat2 dev environment The dev branch with serve as a Dropcat2 sandbox where to safely implement and test new features. The output package will be available on dropcat.org as dropcat2-dev.phar ## Disclaimer We don't give any gurantee that this tool will work for you, your site could be nuked from orbit by it, and we don't have any support for it, but if you have problems using it, please create an issue.