Auto deployment to staging and production server with Travis CI

Two weeks ago I wrote a post about deployment via GitLab. Now I realized the same behavior for a public GitHub repository with Travis, and this post shows you how I did it.

The goal was, like already said, the same like in the GitLab post — I wanted to move a theme to the staging or production server, depending on if the push goes to staging or master branch. Travis CI is free for public GitHub repos.

Travis works with a .travis.yml file, which stores the CI steps. The finished file looks like that:

language: php addons: ssh_known_hosts: - $STAGING_SERVER - $PRODUCTION_SERVER before_script: - echo -e "Host $STAGING_SERVERntStrictHostKeyChecking non" >> ~/.ssh/config - echo -e "Host $PRODUCTION_SERVERntStrictHostKeyChecking non" >> ~/.ssh/config script: - before_deploy: - openssl aes-256-cbc -K $ENCRYPTED_KEY -iv $ENCRYPTED_IV -in deploy_rsa.enc -out /tmp/deploy_rsa -d - eval "$(ssh-agent -s)" - chmod 600 /tmp/deploy_rsa - ssh-add /tmp/deploy_rsa deploy: - provider: script skip_cleanup: true script: ssh -p22 $STAGING_SERVER_USER@$STAGING_SERVER "mkdir -p $STAGING_PATH_STABLE" && ssh -p22 $STAGING_SERVER_USER@$STAGING_SERVER "mkdir -p $STAGING_PATH_TRUNK" && rsync -rav -e ssh --exclude='.git/' --exclude=scripts/ --exclude='.travis.yml' --delete-excluded ./ $STAGING_SERVER_USER@$STAGING_SERVER:$STAGING_PATH_TRUNK && rsync -rav -e ssh --exclude='.git/' --exclude=scripts/ --exclude='.travis.yml' --delete-excluded ./ $STAGING_SERVER_USER@$STAGING_SERVER:$STAGING_PATH_STABLE on: branch: staging - provider: script skip_cleanup: true script: ssh -p22 $PRODUCTION_SERVER_USER@$PRODUCTION_SERVER "mkdir -p $PRODUCTION_SERVER_THEMES_PATH/_tmp-bornholm"&& ssh -p22 $PRODUCTION_SERVER_USER@$PRODUCTION_SERVER "mkdir -p $PRODUCTION_SERVER_THEMES_PATH/bornholm" && rsync -rav -e ssh --exclude='.git/' --exclude=scripts/ --exclude='.travis.yml' --delete-excluded ./ $PRODUCTION_SERVER_USER@$PRODUCTION_SERVER:$PRODUCTION_SERVER_THEMES_PATH/_tmp-bornholm && ssh -p22 $PRODUCTION_SERVER_USER@$PRODUCTION_SERVER "mv $PRODUCTION_SERVER_THEMES_PATH/bornholm $PRODUCTION_SERVER_THEMES_PATH/_old-bornholm && mv $PRODUCTION_SERVER_THEMES_PATH/_tmp-bornholm $PRODUCTION_SERVER_THEMES_PATH/bornholm" && ssh -p22 $PRODUCTION_SERVER_USER@$PRODUCTION_SERVER "rm -rf $PRODUCTION_SERVER_THEMES_PATH/_old-bornholm" on: branch: master
Code language: PHP (php)

At first, we set php as the language of our project and add the server addresses to the known_hosts, like described in the docu post »Adding to SSH Known Hosts« — the variables can be set under Settings in the repo in Travis.

Be careful not to write sensitive data directly into the file, but use the Travis variables as the file is publicly in the GitHub repo!

After that we prevent that we need to confirm the fingerprint of the unknown server in the before_script part. If no script is defined, Travis runs a default procedur depending on the choosen language (for example PHPunit for PHP) – we only want a deployment, so we set an empty script.

How to get ready for the SSH connection is described in the post »SSH deploys with Travis CI« on oncletom.io (the encryption does not work without problems on Windows, you can use the Windows Subsystem for Linux on Windows 10. The command I needed to get it working are listed at the end of the post) — the result is our before_deploy.

The deploy part has two sub areas — one for staging and one for master. The script: commands are mostly the same as in the GitLab deployment post.

Steps for encrypting the SSH key on Windows with the Subsystem for Linux (run in the git repository directory):

apt-get install ruby-dev gem install travis -v 1.8.8 --no-rdoc --no-ri sudo travis login ssh-keygen -t rsa -b 4096 -C 'build@travis-ci.org' -f ./deploy_rsa sudo travis encrypt-file deploy_rsa --add
Code language: JavaScript (javascript)

After that you add the public key to your server and remove the key files (do not leave them in the repository and accidently push them to GitHub!):

rm -f deploy_rsa deploy_rsa.pub
Code language: CSS (css)

Leave a Reply

Your email address will not be published. Required fields are marked *