Does anyone know how to statically compile nodejs to a single executable binary? I means no share libraries needed.
There are some guides for old version nodejs, but not work for last one.
Thanks!
Does anyone know how to statically compile nodejs to a single executable binary? I means no share libraries needed.
There are some guides for old version nodejs, but not work for last one.
Thanks!
As pointed by Daniel Milde, https://hub.docker.com/r/dundee/nodejs-static/ is a alternative, but its deprecated, and has no Dockerfile exposed, that do not inspire trust.
I've tested the node binary in a container from scratch and it worked.
You can build the node statically linked yourself.
~/src$ git clone https://github.com/nodejs/node
cd node
~/src/node$ ./configure --help | grep static
--fully-static Generate an executable without external dynamic
--partly-static Generate an executable with libgcc and libstdc++
--enable-static build as static library
link to a shared http_parser DLL instead of static
--shared-libuv link to a shared libuv DLL instead of static linking
--shared-nghttp2 link to a shared nghttp2 DLL instead of static linking
--shared-openssl link to a shared OpenSSl DLL instead of static linking
--shared-zlib link to a shared zlib DLL instead of static linking
--shared-cares link to a shared cares DLL instead of static linking
~/src/node$ ./configure --fully-static --enable-static
~/src/node$ make
...
~/src/node$ file out/Release/node
out/Release/node: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=e5be29b02e283d0efdfc313e409b1a0802bd0603, with debug_info, not stripped
~/src/node$ /lib64/ld-linux-x86-64.so.2 --list out/Release/node
statically linked
~/src/node$
And let's test with a docker container from scratch:
~/src/node$ cat > /tmp/Dockerfile.node-static <<EOF
FROM scratch
COPY out/Release/node /node
CMD /node
EOF
~/src/node$ docker build -t glaudiston/node-scratch -f /tmp/Dockerfile.node-static .
Sending build context to Docker daemon 1.239GB
Step 1/3 : FROM scratch
--->
Step 2/3 : COPY out/Release/node /node
---> ec9d62bb7eb0
Step 3/3 : CMD /node
---> Running in 2e375fc580f7
Removing intermediate container 2e375fc580f7
---> 5d6a2b5f20b8
Successfully built 5d6a2b5f20b8
Successfully tagged glaudiston/node-scratch:latest
$ docker run -ti node-static:latest /node
Welcome to Node.js v14.0.0-pre.
Type ".help" for more information.
> var x = { 'test': 123 };
undefined
> x.test
123
>
You can build it in a Dockerfile too:
Dockerfile.node
file:
FROM alpine:3.11.3
RUN apk add git python gcc g++ linux-headers make
RUN git clone https://github.com/nodejs/node && \
cd node && \
./configure --fully-static --enable-static && \
make
FROM scratch
COPY --from=0 out/Release/node /node
CMD /node
And to build:
$ docker build -f Dockerfile.node -t node-static .
Sending build context to Docker daemon 121.9kB
Step 1/6 : FROM alpine:3.11.3
---> e7d92cdc71fe
Step 2/6 : RUN apk add git python gcc g++ linux-headers make
---> Using cache
---> c343d63a3094
Step 3/6 : RUN git clone https://github.com/nodejs/node && cd node && ./configure --fully-static --enable-static && make
---> Using cache
---> e7f9fc931827
Step 4/6 : FROM scratch
--->
Step 5/6 : COPY --from=0 /node/out/Release/node /node
---> 045ad784eadc
Step 6/6 : CMD /node
---> Running in f48178348e7b
Removing intermediate container f48178348e7b
---> ff1d93da95c8
Successfully built ff1d93da95c8
Successfully tagged node-static:latest
or, if you trust me, you can use my public docker image glaudiston/node-scratch
.
~/src/node$ docker push glaudiston/node-scratch
The push refers to repository [docker.io/glaudiston/node-scratch]
9251f7e82698: Pushed
latest: digest: sha256:c6f2154daa0144abafc0a7070c48f0c4031a036901c75d432b8c826ae793a1d7 size: 529
Here's another one that can package your application in a single executable https://www.npmjs.com/package/pkg
I´m looking for this today and I found this options:
https://github.com/vercel/pkg
PKG has an option to compile for platform linuxstatic
Note that fully static Node binaries are not capable of loading native bindings, so you may not use Node bindings with linuxstatic.
Both of them are being developed in 2021
There is also NEXE that latest release was in 2017
You can use nodejs-static docker image to get statically compiled Node.JS binary linked with musl libc.
If you are talking about compiling Javascript code, you might get close using pkg
It somehow creates a self-contained binary executable from Javascript, including module dependencies and asset files and produces a self-contained executable.
Installation and use is easy:
$ npm install -g pkg
$ pkg index.js -o my-program
$ ./my-program
My understanding is that this binary contains nodejs bytecode. It also appears that you can cross-compile.
pkg
is archived and overall is not recommended since Node.js
got a support for SEA –
Aragon Meanwhile there is http://enclosejs.com/ which seems to be able to generate a single binary.
pkg
project in another answer seems to be the alternative. –
Estrella Node.js is runtime and JavaScript is interpreted language which means it runs code without compilation step. The problem you're trying to solve is a huge waste of time and manifest of holes in knowledge. De facto, it would be actally faster to learn another programming language than compile Node.js application into single executable binary.
Some runtimes (Bun and Deno) are able to ship runtime and which will run bundled code which may look as compiled application but de facto it's not - outcome may be similar for end-user as they see single file but these two are completly two different things.
I recommend trying out building code with Bun and with enough luck thing will work out but if they do not and bun will not implement fixes on their own I would risk statement that is completly impossible to do so. https://bun.sh/docs/bundler/executables
In ~2022..2023 the preferred way of doing such things was usage of pkg
yet it was archived and probably will not be longer maintained as Node.js introduced experimental support for Single Executable Applications (SEA) which means there is no longer need for tools like pkg
, same goes for nexe
and all other tools that we're used before ecosystem change to ESmodule from CommonJS and others.
I've been in similar place before and also come down with similar question - I recommend reading up https://mcmap.net/q/539722/-how-to-bundle-node-js-application-to-single-executable-application-sea-along-native-modules-napi
© 2022 - 2024 — McMap. All rights reserved.
$ ldd /path/to/bin/node
and getnot a dynamic executable
– Incurve