From time to time I have been known to write a bit of code and whenever one writes a web application, there is always the question of hosting. I've done my time in Ops and I can certainly deploy an application to a VPS and run the surrounding infrastructure to make it work - however, that all sounds like more work than I'm willing to put in. This is the world of Cloud hosting and I'd like to spend my time writing applications, not deployment scripts. What I want is something I can throw code at and have it sort itself out but for my own projects the price needs to be low so I'm not spending a ton of money every month on my own games.
This is an interesting niche as I don't have the same requirements for my own stuff as I would for professional hosting. Initially my requirements were:
- Very low monthly cost
- Rails 5
- Database (probably postgres)
- Ability to hook it into some kind of CI (ideally Codeship, as I'm already using that)
For my own projects I'm not that bothered about high capacity, or extensive DR. These are great, but are also expensive.
I'm going to end up on
Heroku, because the free tier appears to do everything I want and more. However along the way I tried out
Cloud Foundry so I thought it worth writing up how I got started.
Easy stuff first
I
signed up for an account then created an org and a space on the dashboard. I also created a database within the space (no binding - it's better to do that with a manifest). This was all achievable via the web interface. The postgres service has the option of a free database, limited to 20mb storage.
Next, I
installed the command line interface and logged in (
cf l
), choosing the space as the default.
Preparing the application
A Rails 5 application needs no additional configuration, beyond migrating it from sqlite to postgres. The easiest way to tie the application to the production database is via a manifest file. Mine looks like this:
---
applications:
- name: yip-helper
random-route: true
memory: 128M
instances: 1
path: .
command: bundle exec rake db:migrate && bundle exec rails s -p $PORT
services:
- yip-postgres
The name becomes part of the subdomain on deployment. The memory is kept low to keep the costs down for a personal project. The service listed should match the name of the database created in the space, above. Stick this in the repository so it can be used with the CI later.
Now the application should be ready to deploy with a simple
cf push
.
Continuous integration
I use Codeship, and
their docs worked fine for me with two modifications:
- I dropped the
CF_APPLICATION
envar from the script as it's defined in the manifest file
- My first deploy failed as it couldn't find the required gems - subsequent deploys worked fine, despite a warning about including the
.bundle
dir in my repo (which I didn't)
Problems
This all works with minimal fuss, however I'm going to end up going back to Heroku. I originally discounted it because it didn't play well with Docker (a requirement I've since abandoned). Also:
- Heroku encrypts traffic for free on their own domain, whereas Cloud Foundry doesn't have this option. I can pay $20/month to use my own domain and cert but this breaks my first requirement. I can understand them charging for additional domain hosting but honestly, securing their own subdomains should be a given.
- The Cloud Foundry free tier database is tiny. Paying for a database adds a lot to the monthly costs - this is true of all the hosting options I looked at - so a useful free tier offering is important.
- Heroku is better supported. In Codeship, for example, there is a plugin to support it whereas Cloud Foundry requires a custom script. It's a simple one, to be fair, but it's symptomatic.
- The Heroku tooling and web interface are nicer. Again, unsurprising given how much longer Heroku has been around. The Cloud Foundry tools are fine, but the doing the same things with Heroku is just easier.
So there it is. These are just my experiences, based on not a lot of time and with the intention of hosting for a personal project.