Scripting PM2 startup for a non-root user

I've been working on a bash script for standing up a newly created Linux machine. This particular setup will be running node.js supported by the process manager pm2. In addition, I will be using the Node Version Manager (nvm), to pull down and install node.

My install script will not be run as root, but the pm2 startup command that respawns pm2 on boot needs root access. If you simply run the pm2 startup command as a non-root user, you'll see this:

You have to run this command as root. Execute the following command:
  sudo su -c "env PATH=$PATH:/home/userfoo/.nvm/versions/node/v5.9.1/bin pm2 startup linux -u userfoo --hp /home/userfoo"

I didn't want to hard code the node version, the user name, or the home path, so I came up with the following bash script that will happily run for an arbitrary user and node version.

  • $(nvm which node) returns the absolute path to the node executable.
  • dirname returns the parent directory of a path.
  • $USER returns the current user name.
  • $HOME returns the current user's home directory.
  • pm2 save will save the modifications.

Apply a style to all but the first item in an ng-repeat for angular.js

Angular has a very handy $first (and $last) variable for use when implementing an ng-repeat. Along with ng-class, the following allows you to apply a style to all but the first item in the iteration. You can negate the expression with ! as you would expect.


Ghost Blog GitHub Gist Tab Size Fix

I love how I can embed GitHub Gists in my blog posts, but really dislike how they use 8 spaces for tabs by default. I found a solution in an old GitHub issue thread here.

Simply add this CSS to the Blog Header in the Code Injection section in Settings. Works like a charm.

As an aside, if you don't like the look of the Gist footer bar, it can be removed by adding the following to the same section (CSS gleaned from this StackOverflow thread).

How to get ALL Amazon S3 objects

If you use Amazon S3 and have ever wanted to get a list of all the content (including everything in sub-directories) under a path, this recursive function will do the job.

Since it's recursive, it can be a bit slower than a standard loop if there are many sub-directories, but it is MUCH cleaner.

Why Code?

That moment. You know the one.

It's 2:00 AM and you've been banging your head against the problem for hours. You're exhausted and discouraged, but going to bed with the issue left unresolved is unthinkable. How could you sleep with it just sitting there, not working?

You sigh deeply and jump back into the code; still with no idea how, or even if, you can move forward.

Then it happens. Sometimes it starts as a small spark in the back of your mind. Sometimes - the best times - it's like a nuclear bomb going off behind your eyes. Inspiration strikes and . . . you see it.

The solution.

It's clear and perfect and beautiful and it works. Of course it works.

You sit back and smile. All the doubt, anger, and frustration of the previous hours fade away as if they never existed.

Something that was broken is now whole. Something that was just an idea is now a reality. It is a moment of pure joy. Of magic.

That moment.

That is why I'm a programmer.

That is why I code.

Originally posted by me on