I have a major problem. I keep waaay too many open tabs on my phone. Every time I see something interesting – via Twitter, Hacker News, or Reddit – I open the link in a tab and promise myself I will check it out more thoroughly soon.
I currently have 47 open tabs 🙁
This is only amplified by the fact I do the same on desktop. Right now, across three desktops I have over a hundred open tabs.
It’s becoming an epidemic.
Anyway, once in a while, one of these tabs becomes useful.
Recently I hit on a problem whereby I needed to deploy a bunch of individual JavaScript files – node.js scripts – to a server to be used as Rabbit MQ workers.
I had a bunch of requirements for these workers:
- start with specific flags (–harmony-async-await )
- restart automatically if the server reboots
- restart if the script crashes
- can run multiple instances
And so on.
These turned out to be the superficial problems – and I say this because there’s a tool out there that already nails this problem – PM2.
Initially I thought these would be the hard problems.
What I hadn’t banked on was how much of a royal pain in the backside it might be to deploy my node.js scripts to dev / prod / wherever.
My requirements are fairly straightforward – they could be solved by using rsync. However, rsync becomes unmanageable as a project grows.
There’s the issue of remembering the right command, and then duplicating the command – altering slightly – for the prod deploy.
And what if it goes wrong? Well, you have to handle that yourself.
Call me spoiled, but having become accustomed to Deployer (Matt did a fantastic job on this course btw, you should check it out), I now use that as my baseline for deployments.
I have a similar tool I use on JavaScript projects called Flightplan. It offers a decent level of functionality, but with one major issue (from my p.o.v):
It is a pain to deploy more than one directory.
Flightplan works on the assumption – as best I can tell – that you will be running your project through some webpack-style setup first, producing a dist directory which contains everything you need to boot your single page app, or whatever.
This is cool, but I needed to run many different worker scripts – all ideally from one directory.
As best I understand it, webpack allows this via it’s multiple entry options, but I’m not using webpack. Actually, I tried to use webpack but it threw out a bunch of errors right away and I gave up.
I also tried Deployer. But that didn’t work much good either. JS mixed with PHP leads to mess.
Enter Ansistrano
Ok, so all that was a very long-winded precursor to the eventual solution.
However, I felt I needed to do justice to how much I have struggled to get this thing working. It’s taken 5 hours… ouch.
Needless to say I tried to give up on getting Ansistrano at numerous times (see how I ended up at Deployer, Flightplan, webpack etc).
In the end though, I cracked it. So here goes:
Firstly, my playbook:
--- - hosts: all vars: ansistrano_deploy_to: "/var/www/your/remote/path" # server side path you want to deploy too ansistrano_keep_releases: 3 ansistrano_deploy_via: "git" ansistrano_git_repo: "ssh://git@your.gitlab.server/your-gitlab-user/your-project.git" ansistrano_git_branch: "master" roles: - { role: ansistrano.deploy }
Pay special attention to the ansistrano_git_repo entry, whereby I needed to add the prefix of ssh:// to make this work. If you don’t, you will find Ansible doesn’t understand the path you are providing, and blanks it out instead :/
I guess I wasn’t the only person to notice this.
Also, note that the typical git path given by gitlab will contains colons, which need to be replaced with spaces:
git@your.gitlab.com:your-user/your-project.git // becomes git@your.gitlab.com/your-user/your-project.git
Now note, this is an Ansible issue, not an Ansistrano issue.
This should be enough to get most of the way there.
However, I hit upon another issue.
No matter what I did, all the Ansistrano managed folders were being created as root .
Since the days of yore, I have been using the same set of flags on my runs of ansible-playbook, and today I was well and truly bitten on the backside:
ansible-playbook playbook/deploy.yml -i hosts -l my-server.dev -k -K -vvvv
Ultimately this command sees me through. I’ve started using -vvvv on every playbook run as it saves me having to re-run when things inevitably go wrong. Also, for the love of God, use snapshots before running.
But yeah, my issue was I was running with the additional flag of -s which forced the playbook to run as root. Silly me.
Anyway, early signs are promising. It all works. I just wish it hadn’t taken me so much time to figure out these problems. Hopefully though, by sharing I can save someone some hassle in future.