Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[500] [IPX_ERROR] Could not load the \"sharp\" module using the linuxmusl-x64 runtime #1253

Closed
vitaliytsoy opened this issue Feb 16, 2024 · 2 comments

Comments

@vitaliytsoy
Copy link

image

Have a problem with the sharp module required by IPX dependency. Some images return 500 status with error.
Happening because of the different installation and runtime environments.

Installation(pnpm i) and build(pnpm build) runs on ubuntu machine in github action.
Then production build copied to Docker container that runs on node:20-alpine linux which uses musl libc and require sharp to use different binaries - specific for alpine environment (linuxmusl-x64).

Tried to install sharp manually as onptional dependency with pnpm.supportedArchitectures(link), had no effect - target binaries are still not present in production build.

  "pnpm": {
    "supportedArchitectures": {
      "os": ["linux", "current"],
      "cpu": ["x64", "current"],
      "libc": ["musl", "current"]
    }
  },

Found pretty ugly fix, which requires you to reinstall sharp package in server production build.
Run npm install sharp --force --omit=dev --cpu=x64 --os=linux --libc=musl
Inside .output/server folder
Which basically installs @img/sharp-linuxmusl-x64 - sharp's optional dependency inside server production build.

Is it possible to take in consideration supportedArchitectures when building production build and add required dependency in server's node_modules?

Setup:

pnpm: v8.15.2
node: v20.7.0
@nuxt/image: ^1.3.0
nuxt": ^3.8.2

@slantz
Copy link

slantz commented Feb 16, 2024

I had similar problem recently:

  • multi-stage dockerfile
  • pnpm@8.9.0
  • docker image node:20.8.0-alpine
  • nuxt@3.10.1

At the end after checking all the installed dependencies under the .output/server/node_modules the sharp distribution for linux was there, since we have it pinned in the pnpm-lock.yaml the project was working but always missing images.

But the problem was in how pnpm resolves the dependencies. Unlike npm or yarn, pnpm uses a content-addressable filesystem to store its packages, which results in a more efficient disk space usage and faster installations. However, this approach means that pnpm heavily relies on symlinks within the node_modules directory to link back to its global store, which is typically located in node_modules/.pnpm.

So on the last stage of the Dockerfile, the one which launches the running container, I had to import node_modules, so .output folder only was not enough. Here's the simple Dockerfile, that also hsa a line of RUN pnpm rebuild sharp just in case if pnpm-lock.yaml misses the linux definition for sharp.

# Base image for installing dependencies
FROM node:20.8.0-alpine as dependencies

WORKDIR /app

# Install system and build dependencies
RUN apk add --update --no-cache python3 make g++ vips-dev fftw-dev gcc libc6-compat autoconf automake libtool nasm libpng-dev \
    && ln -sf python3 /usr/bin/python \
    && python3 -m ensurepip \
    && pip3 install --no-cache --upgrade pip setuptools

# Install and configure pnpm
ENV PNPM_HOME=/pnpm
ENV PATH=$PNPM_HOME:$PATH

RUN corepack enable pnpm

# Copy package files and install dependencies
COPY ["package.json", "pnpm-lock.yaml", ".npmrc", "./"]

RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile

# https://github.com/nuxt/image/issues/1210#issuecomment-1917921546
RUN pnpm rebuild sharp

# Builder stage for compiling the application
FROM dependencies as builder

# Copy the entire project source files and build it
COPY . .
RUN pnpm run build

# Final production stage
FROM node:20.8.0-alpine as production

WORKDIR /app

ARG PORT=80
ENV NODE_ENV=production \
    UV_THREADPOOL_SIZE=16 \
    PORT=${PORT} \
    HOST=0.0.0.0

# Copy built assets and necessary scripts from the builder stage
# Copy the dependencies so pnpm can use those during the runtime
COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=builder /app/.output ./.output

EXPOSE $PORT

CMD ["node", ".output/server/index.mjs"]

HEALTHCHECK --start-period=5s --timeout=5s CMD curl -f http://0.0.0.0:${PORT}/health || exit 1

@manniL
Copy link
Member

manniL commented Feb 16, 2024

Duplicate of #1210

@manniL manniL marked this as a duplicate of #1210 Feb 16, 2024
@manniL manniL closed this as not planned Won't fix, can't repro, duplicate, stale Feb 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants