Closed5
Node.jsのSingle Executable Applicationをscrachコンテナで動かす
Node.js20からSingle Executable Applicationというのが入ったらしく、Node.jsがインストールされていない環境でもNode.jsで書いたアプリケーションを動かせるらしい。
golangみたくscratchコンテナで動かせると面白そうだと思った。
とりあえずこんなのを書いて動かしてみる。
const http = require("http");
const server = http.createServer((req, res) => {
res.end("Hello World\n");
});
server.listen(process.env.PORT || 8080, () => {
console.log("Server is running...");
});
FROM node:20-bullseye as builder
COPY sea-config.json .
COPY main.js .
RUN node --experimental-sea-config sea-config.json
RUN cp $(command -v node) /app
RUN npx postject /app NODE_SEA_BLOB sea-prep.blob \
--sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
FROM scratch
COPY /app /app
COPY ./bin/sh /bin/sh
COPY ./bin/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6
COPY ./bin/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
CMD ["/app"]
動かない
./app: error while loading shared libraries: libdl.so.2: cannot open shared object file: No such file or directory
そもそもNode.jsが依存してる動的リンクライブラリが無いと動かない。それはそう。
というわけで、
- Node.jsを自分でビルドする (ビルド時に静的リンクするようにできる)
- 依存ライブラリをコピーして持ってくる
のどっちか。今回は後者にした。
FROM node:20-alpine as builder
COPY sea-config.json .
COPY main.js .
RUN node --experimental-sea-config sea-config.json
RUN cp $(command -v node) /app
RUN npx postject /app NODE_SEA_BLOB sea-prep.blob \
--sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
FROM scratch
COPY /app /app
COPY ./bin/sh /bin/sh
COPY ./bin/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6
COPY ./bin/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
COPY /lib/ld-musl-x86_64.so.1 /lib/ld-musl-x86_64.so.1
COPY /usr/lib/libstdc++.so.6 /usr/lib/libstdc++.so.6
COPY /usr/lib/libgcc_s.so.1 /usr/lib/libgcc_s.so.1
CMD ["/app"]
動いた!
あと、 require(filename)
は動かないので、ライブラリを使いたかったりする場合はバンドルすると良いらしい。
たぶんアドオンを使う場合も同じような感じになる。
イメージサイズは103MBだった。でかいな…
$ docker images nodejs-sea
REPOSITORY TAG IMAGE ID CREATED SIZE
nodejs-sea latest 02b0b6ef0418 4 minutes ago 103MB
このスクラップは2023/05/15にクローズされました