How to create an Ubuntu (deb) installer (for NodeJS apps)
Published 2013-4-24Watch on YouTube: youtu.be/FY7Cx6XnpZ4
The Installer Trifecta Series
- HelloNode (example app)
- How to create an OSX (pkg) installer (for NodeJS apps)
- How to create an Ubuntu (deb) installer (for NodeJS apps)
- How to create a Windows (InnoSetup exe) installer (for NodeJS apps)
TLDR
If you're the intelligent and impatient type:
Skip down to Building the deb and see the final steps and then glance back up at Getting Started to see the directory structure.
Why .deb?
Two words: Double Click.
Although I could cite angry flame wars on the topic of
installing via curl installer.com | bash
is evil,
I like that method just fine.
In reality, it's just as secure as a foreign .deb
.
However, from the end-user perspective,
a double-click installer is "more legit".
The best news is that
Debian installers (.deb
s) are actually incredibly simple
(vim
, tar
, and ar
are all you need)
and the Linux (GNU / OpenDesktop, actually) desktop architecture
is also really coherent.
Although I don't strictly follow the debian standards with my example installer, it gets the job done without bothering the user and without using the more robust (read complicated) canonical debian tools.
Getting Started
The demo app I'm packaging in this tutorial is HelloNode
The basic outline of the filesystem structure I used is like so
~/HelloNode/debinstall/deb-src
/DEBIAN
/control # required for .debs
/postinst # preinstall script
/preinst # postinstall script
/prerm # preuninstall script
Those file are needed exclusively for the .deb
and will not be installed.
They will tar
d up as control.tar.gz
before the final build step.
~/HelloNode/debinstall/deb-src
/sysroot
/opt/hello-node/
/etc/init/hello-node.conf # upstart script
/usr/share
/applications/hello-node.desktop # desktop icon
/doc/hello-node/copyright # required for .debs
/doc/hello-node/README # required for .debs
/icons/hicolor/48x48/apps/hello-node.png # desktop icon icon
Everything under sysroot (which is the name I arbitrarily gave this folder)
will be packaged to install to /
, so the directory structure is exactly
as it will be installed. No muss, no fuss, no guessing.
The total size of these files will be caculated by du -s
and then put in
control
as Installed-Size
just before getting tar
d up as data.tar.gz
for the final build step.
I've created a bash script redeb.sh
that packages the app for me very quickly.
The first thing I do is copy deb-src
to /tmp/deb-src
for a fresh start
rm -rf /tmp/hello-node-deb-src
rsync -a ~/HelloNode/debinstall/deb-src/ /tmp/hello-node-deb-src/
App Files
Next I just throw all of the files for my app into /opt/hello-node
because I didn't
organize it in unix-proper fashion before embarking on this endeavor.
rsync -a ~/HelloNode/HelloNode/ /tmp/hello-node-deb-src/sysroot/opt/hello-node/
That's it. Done.
System Service
The upstart file for this project is a very basic one that just spawns the server as soon as the filesystems are mounted and again if it happens to crash.
/etc/init/hello-node.conf
description "Hello Node System Service"
start on filesystem
stop on runlevel [06]
console output
respawn
script
PATH="/opt/hello-node/bin/:/usr/local/bin:/usr/bin:${PATH}"
node /opt/hello-node/bin/server.js
end script
Desktop Icon
The desktop icon is installed at the system level and will show up in menus and search.
You don't generally need a desktop icon for a system service, but I decided it would be cool to have one that opens the app in Chrome's App Mode.
/usr/share/applications/hello-node.desktop
[Desktop Entry]
Name=Hello Node Browser
Comment=Open Hello Node in Chrome
Exec=google-chrome --app="http://localhost:5566#%U"
Terminal=false
Type=Application
Icon=hello-node
Categories=Network;WebBrowser
StartupNotify=true
A cool thing here is that if you were to drag an mp3 onto the icon, it would open the url with the path to the mp3 as the anchor - so you could actually use your service to find the mp3 on the local system and play it with the html5 api. Cool, huh?
The icon for the icon is /usr/share/icons/hicolor/48x48/apps/hello-node.png
Debian metadata
control
is just super basic metadata
Package: hello-node
Version: 1.0-1
Section: base
Priority: optional
Architecture: i386
Installed-Size: SIZE
Depends:
Maintainer: AJ ONeal <coolaj86@gmail.com>
Description: HelloNode! The installable NodeJS System Service
Let's you install a nodejs app as a service, just to see how it feels.
In redeb.sh
I run sed
to replace SIZE
with the size of
/tmp/hello-node-deb-src/sysroot
as per du -s
.
Now Here's where I do a little bit of dirty trickery:
With the preinstall
script I install node
(the wrong way)
and with the postinstall
script I install google-chrome
(the nearly right way)
- https://github.com/coolaj86/HelloNode/blob/master/debinstall/deb-src/DEBIAN/preinst
- https://github.com/coolaj86/HelloNode/blob/master/debinstall/deb-src/DEBIAN/postinst
Aside from that, postinstall
starts the upstart system service and prerm
stops it.
Technically prerm
should also remove the files (node and count.db) that I created
that were not part of data.tar.gz
Building the deb
A few other tricks that redeb.sh
does are to change the file ownership to root:root
,
fix permissions to 0755
for regular dirs and executables, and 0644
for regular files.
As stated previously, it also updates Installed-Size
in control
.
The nitty-gritty aside, it's basically just doing this
pushd deb-src
pushd sysroot/
tar czf ../data.tar.gz *
popd
pushd DEBIAN/
tar czf ../control.tar.gz *
popd
echo 2.0 > debian-binary
ar r ../hellonode-1.deb debian-binary control.tar.gz data.tar.gz
popd
By AJ ONeal
Did I make your day?
Buy me a coffee
(you can learn about the bigger picture I'm working towards on my patreon page )