The SPA conference website deploys to production automatically on merge to master. It is on shared hosting, and setting this up with Travis was a bit tricky, so I’m blogging how I did it in case it’s useful for others.
Configuring Travis to deploy automatically on merge to master is pretty straightforward if you’re using a supported provider. However, if you’re using shared hosting, the documentation is not amazing.
I figured it out eventually by juggling between a blog post (this one is useful for explanations of how Travis works but less so for step-by-step), the actual config that person uses, another blog post (useful for some of the steps), the Travis docs on encrypting files, custom deployment and the build lifecycle, and yet another blog post (very useful for the actual config, but for a different set-up than I wanted).
That juggling made me think my addition to the genre was worth it.
.travis.yml file. The inital one can just have the language and how to build the site.
language: ruby rvm: - 2.3.3 script: scripts/build.sh branches: only: - master
You can tell Travis how to build the site inline, or call out to a build script as I have done.
#!/bin/bash set -e bundle exec jekyll build
The build script has to be executable (
chmod +x 600).
gem install travis), and, using the command line tool, encrypt any variables that you will use for deploy. For example, if you use FTP, you will want to encrypt at least the password.
travis encrypt SOMEVAR="secretvalue" --add
--add flag in this command adds the required lines to your Travis file.
Write a deploy script: a script that describes the steps you take to deploy to shared hosting. For example, if you use FTP, then write the command that you would use to FTP the built site to the server. Instead of the variables you have encrypted, use
I use Rsync to deploy, and have encrypted the username and deploy host. You can see the deploy script on GitHub.
This also needs to be executable.
Create a dedicated SSH key (no passphrase) for deploying. This makes it easy to to identify and revoke if necessary.
ssh-keygen -t rsa -b 4096 -C '[email protected]' -f ./deploy_rsa
Log in to command line Travis (
travis login) and get Travis to encrypt the private key file. It prints a helpful output reminding you to only commit the
.enc version NOT the
travis encrypt-file deploy_rsa --add
--add flag automatically adds the required lines to your Travis file.
Commit the changes to
.travis.yml and the
Copy the public key to the remote host.
ssh-copy-id -i deploy_rsa.pub <ssh-user>@<deploy-host>
rm -f deploy_rsa deploy_rsa.pub
before_install, change the
out location for the decrypted private key to
/tmp/ so it doesn’t end up in any of the publically accessible directories, and make it executable.
before_install: - openssl [snip...] -out /tmp/deploy_rsa -d - chmod 600 /tmp/deploy_rsa
In the same section, start the ssh agent and add the key to it.
- eval "$(ssh-agent -s)" - ssh-add /tmp/deploy_rsa
.travis.yml to call the deploy script.
This is an example of how the Travis docs could be clearer. You don’t want to deploy if the build script fails, so you might want to call this in an
after_success step as part of a script deployment, but in fact, this will do whatever you ask after every successful build. But in our case, we only want to actually deploy on merges to master, not on any successful build. For example, if we’ve just opened a PR and that builds successfully, we don’t want that branch deployed to production.
So what we actually want is custom deployment.
deploy: provider: script script: scripts/deploy.sh skip_cleanup: true on: branch: master
skip_cleanup is required because otherwise Travis resets the working directory, so you lose the artefects from the build (i.e. exactly what you want to deploy!)
travis.yml we’ve now created looks like this:
language: ruby rvm: - 2.3.3 script: scripts/build.sh branches: only: - master env: global: - secure: qvSoY270qAXOtmWdRio9vvhLEf5HHdyzMS39yS4yZw74[snip for length] - secure: Hr7FV7lHFEblYfn7EYM/4qV3qV8zdHLebXzNyRvP8L/U[snip for length] before_install: - openssl aes-256-cbc -K $encrypted_ed2cb1b127e1_key -iv $encrypted_ed2cb1b127e1_iv -in deploy_rsa.enc -out /tmp/deploy_rsa -d - chmod 600 /tmp/deploy_rsa - eval "$(ssh-agent -s)" - ssh-add /tmp/deploy_rsa deploy: provider: script script: scripts/deploy.sh skip_cleanup: true on: branch: master
This (allegedly deprecated but still working)
travis.yml linter is useful.
Useful commit for future reference is the creating/encrypting SSH key one.
If you’d like to be notified when I publish a new post, and possibly receive occasional announcements, sign up to my mailing list: