Code with Hugo: JS & Node.js in Prod logo

Code with Hugo: JS & Node.js in Prod

Subscribe
Archives
July 23, 2018

Code with Hugo: setup, CI and deployment tips & tricks

Installing redis-cli latest by itself and some bash-ing

Writing setup, CI and deployment flows means a bit of the old bash scripting and weirdness with package versions and so on. This is a write-up of those issues and I solved them ✌️.

In other news, I’ve joined WIP wip.chat/@HugoDF, you can see what’s going on with Code with Hugo on there.

I’ve also started work on a tool to turn blog posts into tweet/instagram-able images, it’s called Chiwawa and I hope you guys don’t mind the ProductHunt Ship widget I’ve now added to the site.

Install just redis-cli on Ubuntu, Debian, Jessie

As part of adding integration tests to an app on CircleCI I ran into the following issues:

  • redis-cli‘s API has changed from version 2 to 3 to 4
    • ie. this works in v4 redis-cli -u ${REDIS_URL} but doesn’t in v2
  • the “only way” to install redis-cli is through a redis-tools or redis-server install and I only need redis-cli not the server or any other tools

What follows is how not to install redis-cli and then how to install redis-cli latest, properly.

Bad

apt-get install redis-tools

This installs an outdated version, 2.8.x where stable is 4.x.x.

Better

apt-get install redis-server

Maybe we don’t need the full redis-server install if we only need the CLI. Sometimes it also installs the old redis-cli… not the best.

Best

cd /tmp
wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
make
cp src/redis-cli /usr/local/bin/
chmod 755 /usr/local/bin/redis-cli

You’ll need libjemalloc1 libjemalloc-dev gcc make most of which should already be installed. We’re building from source… which takes about a minute on the CircleCI containers (so I would expect less everywhere else), which is fine.

Credit: DevOps Zone, install redis-cli without installing server. I shamelessly took the snippet from there, because hey, it works.

Installing redis-cli latest on CircleCI

Same as above except:

sudo cp src/redis-cli /usr/local/bin/
sudo chmod 755 /usr/local/bin/redis-cli

CircleCI runs the jobs with a non-root user by default, and kudos to them for that, more tools should make you think about what privileges you have.

I’m not exactly sure what distribution CircleCI images run, some sort of Debian? Let me know by replying to this email.

Installing redis-cli latest on Alpine in Docker

apk --upgrade redis

If you know why this works but apt-get install redis-server sometimes installs old redis-cli drop me a line by replying to this email.

Just enough bash to be dangerous

Despite my deep interest in the intricacies of Bash (/sarcasm), I’ve kept hitting up Google and StackOverflow for solutions to the same couple of situations.

To avoid having to do this again myself and for your reading pleasure, here they are.

To be dangerous in terms of setup, CI and depoyment flows we will encounter the following: - check if a file exists and do something (or else) - check if a link exists somewhere and do something (or else) - check if an environment variable is set and doing something (or else 😈) - switch over environment variable values and doing all sorts of stuff - prompt the user (of course we don’t do this on CI but local scripts might benefit from it)

Check if file exists

if [ ! -f ./pdfgen/pdfgen ]; then
    echo "Building pdfgen binary"
    npm run --prefix pdfgen build:linux
else
    echo "Pdfgen binary already exists, skipping build"
fi

Check if a (symbolic) link exists

if [ ! -L /usr/local/bin/heroku ];
then
    wget https://cli-assets.heroku.com/branches/stable/heroku-linux-amd64.tar.gz
    sudo mkdir -p /usr/local/lib /usr/local/bin
    sudo tar -xvzf heroku-linux-amd64.tar.gz -C /usr/local/lib
    sudo ln -s /usr/local/lib/heroku/bin/heroku /usr/local/bin/heroku
fi

Check if environment variable is set

# long
if [ [ -z "${CIRCLE_BRANCH}" ] ]; then
    npm run redis-cli flushall
    npm run sync
else 
    npm run sync
fi

# one-liner
[ -z "${CIRCLE_BRANCH}" ] && npm run redis-cli flushall && false || npm run sync

Switch over an environment variable

case $CIRCLE_BRANCH in
    "develop")
        export ENVIRONMENT="dev"
        export HEROKU_APP=dev-app
        ;;
    "staging")
        export ENVIRONMENT="staging"
        export HEROKU_APP=staging-app
        ;;
    "production")
        export ENVIRONMENT="production"
        export HEROKU_APP=production-app
        ;;
esac

Prompt the user

read -p "Are you sure you want to merge 'develop' into 'staging'? (y/N)" -n 1 -r
echo # we like having a new line

if [[ $REPLY =~ ^[Yy]$ ]]
then
  git merge develop --ff-only
  git push
fi

A final bit of advice, if it’s more than a couple of lines, try to use something like JavaScript, or Python to write your script.

I’ve got some resources to do that in modern JavaScript/Node:

  • ES6 by example: a module/CLI to wait for Postgres in docker-compose
  • How to make beautiful, simple CLI apps with Node
Don't miss what's next. Subscribe to Code with Hugo: JS & Node.js in Prod:
Powered by Buttondown, the easiest way to start and grow your newsletter.