Skip to content

Handling Native Dependencies

Amnoor Brar edited this page Apr 1, 2026 · 1 revision

Icon

Handling Native Dependencies (C++ Addons)

Because Runtime-Node has no package manager (npm or yarn) and no build tools (make, g++, python), you cannot run npm install inside the final image.

If your project uses pure JavaScript dependencies (like express or lodash), a simple multi-stage copy will work perfectly. However, if you use Native Dependencies (like bcrypt, sharp, prisma, or sqlite3), they must be compiled against the correct system architecture before being copied.

The Multi-Stage Solution

Always use the exact same Node.js Alpine version for your builder stage as the Runtime-Node version you are targeting to ensure C++ binding compatibility.

# 1. THE BUILDER STAGE (Compiles the Native C++ Addons)
FROM node:<node_version>-alpine3.23 AS builder

WORKDIR /dist/

COPY package*.json ./

# Install dependencies (This compiles bcrypt/sharp using Alpine's musl libc)
RUN npm ci --omit=dev --no-cache

COPY ./ ./

# 2. THE RUNTIME STAGE (Distroless)
FROM runtimenode/runtime-node:v<major>.<minor>.<patch>+node<node_version>

WORKDIR /application/

# Copy the pre-compiled code securely into the runtime.
# Using chmod 550 makes the application code immutable (Read/Execute only).
COPY --from=builder --chown=1000:1000 --chmod=550 /dist/ ./

EXPOSE 5500 # Optional, if the application needs it

USER 1000:1000

ENTRYPOINT ["/usr/local/bin/node", "index.js"]

Because Runtime-Node ships with the standard ld-musl, libstdc++, and libgcc_s libraries, your Alpine-compiled binaries will execute flawlessly in our distroless environment.