At JobNinja we have stories to tell and therefore we needed a Blog.
The requirements were simple:
- It looks clean and minimalistic.
- It meets JobNinja CI.
- It doesn’t crash the main server.
- I want to deploy it in subfolder fashion jobninja.com/blog for SEO reasons.
After that, I realised that deploying this stuff won’t be that easy.
This solution works the following: we point the jobninja.com DNS A Record to NGINX server and we let it dispatch (either the blog or the website).
However 2 problems there:
- We have no own SSL certificates and we do not want to buy one (neither do we want to setup Let’s Encrypt).
- We’re not Cloudflare, we cannot guarantee a 100% uptime on the NGINX server, so WHOLE JobNinja may be down (and we do not want that!)
After few tries with Docker and then with installing Ghost on an old VPS, I decided that professionals are doing that much better than me and booked a 10$ Ghost-Droplet on Digital Ocean which works great out of the box!
If you want to use Digital Ocean for your project, here is my referral code.
So the current architecture is a try to combine the best of both worlds: we have the flexibility of NGINX with the security, scalability and reliability of Heroku and Cloudflare.
It works the following:
- Heroku is responsible deploying for NGINX and the python code.
- The python script (in our case a gunicorn script) notifies NGINX that it is ready to operate and write in a text file called
- The Nginx dispatches:
/bloggo to the Ghost server the rest goes to the python (grey arrows).
Activate the Buildpack option of Heroku and set an Nginx in the first place and then apply the original NodeJS Buildpack.
$ heroku buildpacks:add — index 1 heroku-community/nginx --app yourapp // That command puts NGINX before your original buildpack (not necessarily Python). // After that command you should get something like: $ heroku buildpacks --app yourapp === yourapp Buildpack URLs 1. heroku-community/nginx 2. heroku/python
- Add a Procfile which starts the nginx and pass the command to start the python server
// the important part for you is the bin/start-nginx, the rest depends on the technology of you application, we use python & gunicorn. web: bin/start-nginx gunicorn -b 127.0.0.1:5000 -c config/gunicorn.conf app:create_app\(\)
- Setup NGINX properly (and save under
config/nginx.conf.erb). Here is the config we use:
- Add the mime.types in the config folder
- Make your index file (the root of your program) change the /tmp/app-initialized.
Example for python/gunicorn (in
gunicorn.conf) below, example for other tech stacks can be found online i.e Node.
def when_ready(server): # touch app-initialized when ready open('/tmp/app-initialized', 'w').close()
To summary the file structure looks like this: