To CI or not to CI with dockerized app
How to deploy rails app using capistrano and docker-compose
I was happy developer using CI goodies (gitlab) almost every workday in my last company (Experteer).
Feature done => git push (+reviews done) => CI build GREEN => one click in the interface => CI deploys the app to production.
Not much thinking/doing involved. Happiness.
When I came to my new company (Akra) I was assigned to a brand new project and was able to choose whatever deployment way I like.
Travis I thought. Always wanted to try it out. And I did. It’s awesome! Blazing fast github integration, short and simple config file. Also, thanks to very well done documentation, I setup a custom deployment (ssh to app server, pull whole app from the repo, restart app) instead of most popular way (via push docker image to own docker repo) within hours.
Then bad happened. Turned out we can’t actually use Travis because we’d have to use the premium version (it’s the only option for private repositories) and actually it didn’t make sense for this particular project. Ouch…
Stand up and fight soldier! :)
I searched for other options. There were not too many:
- self-hosted CI: gitlab/jenkins
- WWTD: Travis simulator
First was to heavy to maintain at this moment. It only makes sense if you have bigger app (more devs working on it) or more apps. And I think it isn’t cheeper in the end comparing to paid options.
The second doesn’t do much, it just reads .travis.yml config and runs its main “script” command locally (travis-ci does the same inside its image).
I didn’t pick any of the above solution but… I realized I could locally do exactly the same what Travis does using just docker-compose and capistrano! Even better it has some adventages! Let’s see…
The idea
Feature done => git push (+reviews done) => docker-compose run --rm test bundle exec cap staging deploy => DONE
Let’s see the trick:
Before capistrano begins it runs the specs… and breaks unless it’s all GOOD :)
As little does what CI server does in general. It makes sense because the app is dockerized, it uses exactly the same image (environment) either on test/dev or production. So simple! Sooo epic! :) With just:
Plus Capistrano addon for Docker Compose gem with two additional lines:
Benefits
- all done locally — no additional server need
- one 3rd party service dependency less (even travis-ci may collapse)
- deployment requires bit of attention and eventual notification to other teammates so it may seem as disadventage but… in small to mid teams it may enhance the “flow” and knowlegde what actually goes around.
Conclusion
Think twice if you really need CI because capistrano + docker-compose do really great job. Smile! :)