Meet node-snapper a helper to easily create .snap packages of your node.js projects

When I created the “Snappy Chatroom” package for WebRTC Video chat on snappy I used node.js to provide the necessary server bits. During building the snap I noticed how hard it is to actually put the necessary binaries and node modules in place. Especially if you want your snap to be arch independent (javascript is arch independent, so indeed our snap package should be too).

The best way I found was to actually build node.js from source on the respective target arch and run “npm install” for the necessary modules, then tarring up the matching dirs and putting them into my snap package tree.

This is quite some effort !!!

I’m a lazy programmer and surely do not want do that every time I update the package. Luckily there are already binaries of node for all architectures in the Ubuntu archive and it is not to hard to make use of them to run npm install in a qemu-user-static chroot for all target arches and to automate the creation for the respective tarballs. As little bonus i thought it would be nice to have it automatically generate the proper snap execution environment in form of a service startup script (with properly set LD_LIBRARY_PATh etc) so you only need to point node to the to-execute .js file.

This brought me to write node-snapper, a tool that does exactly do the above. It makes it easy to just maintain the actual code I care about in a tree (the site itself and the packaging data for the snap). I leave the caring for node itself or for the modules to the archive, respectively the npm upstreams and just pull in their work as needed.

See https://launchpad.net/node-snapper for the upstream code.

To outline how node-snapper works I took some notes below how I roll the chatroom snap as an example.

Using node-snapper:

First we create a work dir for our snap package.

ogra@anubis:~$ mkdir package

To create the nodejs and npm module setup for our snap package we use node-snapper, let’s branch this so we can use it later.

ogra@anubis:~$ bzr branch lp:node-snapper

Now we move into the package dir and let node-snapper create the tarballs with the “express”, “webrtc.io”, “webrtc.io-client” and “ws” node modules since chatroom makes use of all of them.

ogra@anubis:~$ cd package
ogra@anubis:~/package$ sudo ../node-snapper/node-snapper express webrtc.io webrtc.io-client ws
...

This created three files.

ogra@anubis:~/package$ ls
amd64-dir.tgz  armhf-dir.tgz  start-service.sh

We unpack the tarballs and remove them.

ogra@anubis:~/package$ tar xf amd64-dir.tgz
ogra@anubis:~/package$ tar xf armhf-dir.tgz
ogra@anubis:~/package$ ls
amd64  amd64-dir.tgz  armhf  armhf-dir.tgz  start-service.sh
ogra@anubis:~/package$ rm *.tgz
ogra@anubis:~/package$ ls
amd64  armhf  start-service.sh

… and branch the chatroom site and packaging code branch.

ogra@anubis:~/package$ bzr branch lp:~ogra/+junk/chatroom
ogra@anubis:~/package$ mv chatroom/* .
ogra@anubis:~/package$ rm -rf chatroom/
...
ogra@anubis:~/package$ ls site/
add.png      cam_on.png    expand.png      fullscreen.png  mute.png   server.js  unmute.png
cam_off.png  collapse.png  index.html      script.js  style.css  webrtc.io.js
ogra@anubis:~/package$ ls meta/
icon.png  icon.svg  package.yaml  readme.md

The file we want node to execute on startup is the server.js file in the “site” dir in our snap package. We edit start-service.sh so that the MY_EXECUTABLE variable looks like:

MY_EXECUTABLE=site/server.js

This is it, we are ready to roll a .snap package out of this

ogra@anubis:~/package$ cd ..
ogra@anubis:~$ snappy build package
...
ogra@anubis:~$ ls
chatroom.ogra_0.1-5_multi.snap  package

As you can see, node-snapper makes supplying javascript nodejs code as snap package a breeze. You only need to keep your site and package files in a git or bzr tree and node-snapper will always provide you the latest nodejs setup and npm installed modules as needed just at package build time.

Indeed we now want to test our snap package. I have a RPi2 running snappy at 192.168.2.57 with enabled developer mode, so I can easily use snappy-remote to install the package.

ogra@anubis:~$ snappy-remote --url=ssh://192.168.2.57 install chatroom.ogra_0.1-5_multi.snap

The service should start automatically. Opening chromium, pointing it to http://192.168.2.57:6565 and approving access to microphone and camera will now give us a Video chat (pointing an android phone to it at the same time enables you to talk to yourself while watching you from different angles😉 … note that the mute button is very helpful when doing this …)

I hope we will see some more node.js projects land in the snappy app store soon. A PPA with node-snapper to make it easier installable should be ready next week and if I see there is demand I will also push it to universe in the Ubuntu archive.

I hope you found that little howto helpful🙂

3 comments

  1. Leo Arias · April 14, 2015

    hey ogra, I’m following your guide.

    This is a little wrong:

    ogra@anubis:~/package$ bzr branch lp:~ogra/+junk/chatroom

    ogra@anubis:~/package$ ls site/
    ogra@anubis:~/package$ ls meta/

    If you branch inside the package directory, the site and meta directories will be in the chatroom directory.

    • ograblog · April 14, 2015

      I added two lines to move the subdirs in the right place, thanks !

  2. Pingback: Ubuntu Core — Snappy — Mitelu.info

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s