Nodejs dockerized on Alpine OS
Builds a small and highly versatile Docker container, running Alpine Linux OS latest version and Nodejs on top. Optional installation of npm and, depending on that, installs packages on demand.
Configuration
There are various parts that you can define when building your image:
docker build -t nodejs:custom
ENV
variables:
VERSION
- The Nodejs version number; Default:5.6.0
NPM
- Set to "yes" (or whatever) if you want to install npm as well; Default:yes
NPM_VERSION
- Define the npm version you want to install; Default:3.6.0
NPM_NPM_CONFIG_LOGLEVEL
- Define the npm log level for dev installs. For e.g.info
. Default:warn
PREFIX
- The--prefix
for installing Nodejs and npm; Default:/usr
FLAGS
- Any additional flags you want to pass to theconfigure
call when building Nodejs; Default: none, but due to a bug,--fully-static
will be removed even if set.TARGET
- The installation target, prefixed byPREFIX
, so please leave that off; Default:${PREFIX}/lib/app
SRC
- From where to fetch the original files for theONBUILD
commands; Default:./app
; Note will probably get removedADDT_PACKAGES
- Additional (permanent) packages from the Alpine OS package repository, set for e.g.wget
ornano
here; Default: none
As Nodejs was not designed to run with PID 1, this image uses tini as process reaper.
All Tini does is spawn a single child (Tini is meant to be run in a container), and wait for it to exit all the while reaping zombies and performing signal forwarding.
How To
Images are highly versatile and can be customized, using above env variables.
Build the image on the command line (assuming the Dockerfile
is in a subfolder):
docker build -t nodejs:latest ./Docker/Nodejs/
Per default, the container comes without npm. To install with NPM and adjust
both the Node and NPM version, you have to use the --build-arg
flag:
docker build -t nodejs:5.6.0 --build-arg VERSION="5.6.0" NPM_VERSION="3" NPM="yes" ./Docker/Nodejs/
Development builds should be done without cache:
docker build --no-cache -t nodejs:dev ./Docker/Nodejs/
Docker Compose
Docker Compose Example:
version: '2'
services:
nodejs:
container_name: nodejs
build:
context: ./Docker/Nodejs
args:
VERSION: "5.6.0"
NPM_VERSION: "3"
NPM: "yes"
PREFIX: "/usr"
TARGET: "/src/app"
SRC: "./app/node"
restart: on-failure:3
expose:
- "3000"
depends_on:
- app
volumes_from:
- app
command: [ "node", "server.js" ]
#command: npm install --force --loglevel=error
networks:
- front
app:
container_name: app
image: busybox:latest
volumes:
- ./app/node:/usr/src/app
networks:
- front
volumes:
eapp:
networks:
front:
driver: bridge
You can then check your attached volume:
$ docker volume ls
local projectname_app
In case you need to remove your volume container:
docker volume rm $(docker volume ls |awk '{print $2}')
Details about the volume are then available via:
docker volume inspect <volume_name>
# Example:
$ docker volume inspect projectname_app
[
{
"Name" : "projectname_app",
"Driver" : "local",
"Mountpoint" : "/mnt/sda1/var/lib/docker/volumes/projectname_app/_data"
}
]
Sidenote: You might want to docker-compose down
your Nodejs service
to get a fresh start before going to create volumes.
FAQ
Q: What is the license?
A: MIT License (Expat). tl;dr: Basically, you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source. tl;dr. See the attached license file in this repository for the full text.
Q: The GPG verification fails with gpg: no ultimately trusted keys found
. Why that?
A: The only key that you can trust is your own. You can sign other peoples keys as "trusted", something that you only want to do if you know them in person and really trust them. If you have such a person and this person knows someone who knows someone who knows the person who signed that release, then you can build a "chain of trust" and absolutely verify a key. For every real world use case, above verification is more than enough. And key signing never hit a critical mass to build a web of trust easily. In other words: The message is a bit misleading.
Q: The GPG verification states gpg: WARNING: not a detached signature;
. Why that?
A: The signature asc file checked out good, but warned about it not being certified with a trusted signature. As learned in the previous step, it just tells you that you did not sign it yourself.
Q: I get gyp: true not found (cwd: /node-v5.6.0) while trying to load true. Error running GYP
when trying to build the image.
A: You should define all build arguments as strings. Do not set --build-arg NPM=true
, but
use --build-arg NPM="true"
(or better: yes
) instead to avoid using a real boolen.
The same has to be done when using Docker Compose. Set build: args: NPM: "yes"
as string.
Tests
Currently there are acceptance tests shipped with this package. The specs are run using Ruby and the following Gems:
To run tests, you need Ruby and the listed Gems installed. The test can be run on the command line:
$ Print progress bar/dots while running tests
$ rspec --format progress Dockspec.rb
# Short notation
$ rspec -f p Dockspec.rb
# Verbose output (Print spec titles) while running tests
$ rspec --format documentation Dockspec.rb
# Short notation
$ rspec -f d Dockspec.rb
The docker-api Gem will remote execute Docker, which means that the test run is a real world test and will fully expose things that might go wrong.
macOS users can run the tests inside the terminal when they have the docker status bar app installed (running Hypervisor) Windows and older OS X users will have to run the tests inside their Docker Machine.
Security
OS Alpine Linux has a very small foot print and therefore only a tiny attack surface. In addition, it features SELinux for enhanced security. Still it is recommended to have a firewall, proxy or load balancer in front of your Node servers to not expose them directly to the public.
Packages The download gets verified using GNU Privacy Guard/gpg. That means that if the source repo should get compromised, the build will fail with the following message:
node-v5.6.0.tar.gz: FAILED
sha256sum: WARNING: 1 of 1 computed checksums did NOT match
The repo itself comes with a prepackaged public keyring, containing all current and
previous contributors. The validity and integrity of the Nodejs download will be verified
using this trust database. This is to work around unreliable key servers. If you want to
take a look at the keys, check the Dockerfile
, where you will find a GPG_KEYS
env variable containing them all.
TO-DO
The build is currently not running smoothly. There are some things that need fixing. If you can help, please open an issue, to discuss any idea you have in mind. If that results in a pull request, I am happy to give you AAA-access to this repo. Please take a quick look at CONTRIBUTING - you will not find any surprises there.
-
Nodejs probably shouldn't run asroot
on this machine. When everything works asroot
, there should be a non privilegednode
user in place. See uncommented parts of theDockerfile
. -
Maybe there should be anENTRYPOINT
in place to pass commands directly tonpm
and avoid fiddling withnode
. - The file removal after the installation of NPM could be much easier and just set a whitelist. That would also mean that it's more versatile regarding the folder structure of various versions. Also we need to check the folder structure first and maybe switch the whitelist depending on the version.