Update #1: Added working screenshot and some instructions.
Update #2: Added instructions on how to get the app to autostart through systemd.
Installing a Node.js app on your desktop Linux computer is a messy affair, since you need to add a new repository and install lots of additional packages.
The alternative to messing up your desktop Linux, is to create a new LXD (LexDee) container, and install into that. Once you are done with the app, you can simply delete the container and that’s it. No trace whatsoever and you keep your clean Linux installation.
Second, for this post we are installing chalktalk, a Node.js app that turns your browser into an interactive blackboard. Nothing particular about Chalktalk, it just appeared on HN and it looks interesting.
Here is what we are going to see today,
- Create a LXD container
- Install Node.js in the LXD container
- Install Chalktalk
- Testing Chalktalk
Creating a LXD container
Let’s create a new LXD container with Ubuntu 16.04 (Xenial, therefore ubuntu:x), called mynodejs. Feel free to use something more descriptive, like chalktalk.
$ lxc launch ubuntu:x mynodejs Creating mynodejs Starting mynodejs $ lxc list -c ns4 +----------+---------+----------------------+ | NAME | STATE | IPV4 | +----------+---------+----------------------+ | mynodejs | RUNNING | 10.52.252.246 (eth0) | +---------------+----+----------------------+
Note down the IP address of the container. We need it when we test Chalktalk at the end of this howto.
Then, we get a shell into the LXD container.
$ lxc exec mynodejs -- sudo --login --user ubuntu To run a command as administrator (user "root"), use "sudo <command>". See "man sudo_root" for details. ubuntu@mynodejs:~$
We executed in the mynodejs container the command sudo –login –user ubuntu. It gives as a login shell for the non-root default user ubuntu, that is always found in Ubuntu container images.
Installing Node.js in the LXD container
ubuntu@mynodejs:~$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - ## Installing the NodeSource Node.js v8.x repo... ... ## Run `apt-get install nodejs` (as root) to install Node.js v8.x and npm ubuntu@mynodejs:~$ sudo apt-get install -y nodejs ... Setting up python (2.7.11-1) ... Setting up nodejs (8.9.0-1nodesource1) ... ubuntu@mynodejs:~$ sudo apt-get install -y build-essential ... ubuntu@mynodejs:~$
The curl | sh command makes you want to install in a container rather than on your desktop. Just saying. We also install the build-essential meta-package because it is needed when you install packages on top of Node.js.
We follow the installation instructions for Chalktalk to clone the repository. We use depth=1 to get a shallow copy (18MB) instead of the full repository (100MB).
ubuntu@mynodejs:~$ git clone https://github.com/kenperlin/chalktalk.git --depth=1 Cloning into 'chalktalk'... remote: Counting objects: 195, done. remote: Compressing objects: 100% (190/190), done. remote: Total 195 (delta 5), reused 51 (delta 2), pack-reused 0 Receiving objects: 100% (195/195), 8.46 MiB | 8.34 MiB/s, done. Resolving deltas: 100% (5/5), done. Checking connectivity... done. ubuntu@mynodejs:~$ cd chalktalk/server/ ubuntu@mynodejs:~/chalktalk/server$ npm install > firstname.lastname@example.org install /home/ubuntu/chalktalk/server/node_modules/bufferutil > node-gyp rebuild make: Entering directory '/home/ubuntu/chalktalk/server/node_modules/bufferutil/build' CXX(target) Release/obj.target/bufferutil/src/bufferutil.o SOLINK_MODULE(target) Release/obj.target/bufferutil.node COPY Release/bufferutil.node make: Leaving directory '/home/ubuntu/chalktalk/server/node_modules/bufferutil/build' > email@example.com install /home/ubuntu/chalktalk/server/node_modules/utf-8-validate > node-gyp rebuild make: Entering directory '/home/ubuntu/chalktalk/server/node_modules/utf-8-validate/build' CXX(target) Release/obj.target/validation/src/validation.o SOLINK_MODULE(target) Release/obj.target/validation.node COPY Release/validation.node make: Leaving directory '/home/ubuntu/chalktalk/server/node_modules/utf-8-validate/build' npm WARN firstname.lastname@example.org No description npm WARN email@example.com No repository field. npm WARN firstname.lastname@example.org No license field. added 5 packages in 3.091s ubuntu@mynodejs:~/chalktalk/server$ cd .. ubuntu@mynodejs:~/chalktalk$
Trying out Chalktalk
Let’s run the app, using the following command (you need to be in the chalktalk directory):
ubuntu@mynodejs:~/chalktalk$ node server/main.js HTTP server listening on port 11235
Now, we are ready to try out Chalktalk! Use your favorite browser and visit http://10.52.252.246/11235 (replace according the IP address of your container).
You are presented with a blackboard! You use the mouse to sketch objects, then click on your sketch to get Chalktalk to try to identify it and create the actually responsive object.
It makes more sense if you watch the following video,
And this is how you can cleanly install Node.js into a LXD container. Once you are done testing, you can delete the container and it’s gone.
Here is an actual example. The pendulum responds to the mouse and we can nudge it.
The number can be incremented or decremented using the mouse; do an UP gesture to increment, and a DOWN gesture to decrement. You can also multiply/divide by 10 if you do a LEFT/RIGHT gesture.
Each type of object has a corresponding sketch in Chalktalk. In the source there is a directory with the sketches, with the ability to add new sketches.
Let’s see how to get this Node.js app to autostart when the LXD container is started. We are going to use systemd to control the autostart feature.
First, let’s create a script, called chalktalk-service.sh, that starts the Node.js app:
ubuntu@mynodejs:~$ pwd /home/ubuntu ubuntu@mynodejs:~$ cat chalktalk-service.sh #!/bin/sh cd /home/ubuntu/chalktalk /usr/bin/node /home/ubuntu/chalktalk/server/main.js ubuntu@mynodejs:~$
We have created a script instead of running the command directly. The reason is that chalktalk uses relative pathes and we need to chdir to the appropriate directory first so it works. You may want to contact the author to attend to this.
Then, we create a service file for Chalktalk.
ubuntu@mynodejs:~$ cat /lib/systemd/system/chalktalk.service [Unit] Description=Chalktalk - your live blackboard Documentation=https://github.com/kenperlin/chalktalk/wiki After=network.target After=network-online.target [Service] Type=simple User=ubuntu Group=ubuntu ExecStart=/home/ubuntu/chalktalk-service.sh Restart=on-failure StandardOutput=syslog StandardError=syslog SyslogIdentifier=chalktalk [Install] WantedBy=multi-user.target ubuntu@mynodejs:~$
We have configured to get Chalktalk to autostart once the network is up and online. The service gets to become user ubuntu, then run the command. Any output or error goes to syslog, using the chalktalk syslog identifier.
Let’s get Systemd to learn about this new service file.
ubuntu@mynodejs:~$ sudo systemctl daemon-reload ubuntu@mynodejs:~$
Let’s enable the Chalktalk service, then start it.
ubuntu@mynodejs:~$ sudo systemctl enable chalktalk.service ubuntu@mynodejs:~$ sudo systemctl start chalktalk.service ubuntu@mynodejs:~$
Now we verify whether it works.
Let’s restart the container and test whether the Chalktalk actually autostarted!
ubuntu@mynodejs:~$ logout myusername@mycomputer /home/myusername:~$ lxc restart mynodejs myusername@mycomputer /home/myusername:~$