Open Jakin-Liu opened 2 years ago
There's not enough info here to troubleshoot unless there are other errors in the docker build log that you can provide, sorry.
Hi @Jakin-Liu , did you resolve this? - i am getting same issue, my docker file
# The tag here should match the Meteor version of your app, per .meteor/release
FROM geoffreybooth/meteor-base:2.6.1
# Copy app package.json and package-lock.json into container
COPY ./app/package*.json $APP_SOURCE_FOLDER/
RUN bash $SCRIPTS_FOLDER/build-app-npm-dependencies.sh
# Copy app source into container
COPY ./app $APP_SOURCE_FOLDER/
RUN bash $SCRIPTS_FOLDER/build-meteor-bundle.sh
# Use the specific version of Node expected by your Meteor release, per https://docs.meteor.com/changelog.html; this is expected for Meteor 2.6.1
FROM node:14.18.3-alpine
ENV APP_BUNDLE_FOLDER /opt/bundle
ENV SCRIPTS_FOLDER /docker
# Install OS build dependencies, which stay with this intermediate image but don’t become part of the final published image
RUN apk add --no-cache\
bash \
g++ \
make \
python3
RUN apk add --no-cache \
build-base cairo-dev cairo cairo-tools \
# pillow dependencies
pango pango-dev jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev
RUN pip install "flask==1.0.1" "CairoSVG==2.1.3"
RUN npm install canvas@2.9.0
# Copy in entrypoint
COPY --from=0 $SCRIPTS_FOLDER $SCRIPTS_FOLDER/
# Copy in app bundle
COPY --from=0 $APP_BUNDLE_FOLDER/bundle $APP_BUNDLE_FOLDER/bundle/
RUN bash $SCRIPTS_FOLDER/build-meteor-npm-dependencies.sh --build-from-source
# Start another Docker stage, so that the final image doesn’t contain the layer with the build dependencies
# See previous FROM line; this must match
FROM node:14.18.3-alpine
ENV APP_BUNDLE_FOLDER /opt/bundle
ENV SCRIPTS_FOLDER /docker
# Install OS runtime dependencies
RUN apk --no-cache add \
bash \
ca-certificates
# Copy in entrypoint with the built and installed dependencies from the previous image
COPY --from=1 $SCRIPTS_FOLDER $SCRIPTS_FOLDER/
# Copy in app bundle with the built and installed dependencies from the previous image
COPY --from=1 $APP_BUNDLE_FOLDER/bundle $APP_BUNDLE_FOLDER/bundle/
# Start app
ENTRYPOINT ["/docker/entrypoint.sh"]
CMD ["node", "main.js"]
this is the error I get
pp_1 | /opt/bundle/bundle/programs/server/node_modules/fibers/future.js:280
app_1 | throw(ex);
app_1 | ^
app_1 |
app_1 | Error: Error loading shared library libcairo.so.2: No such file or directory (needed by /opt/bundle/bundle/programs/server/npm/node_modules/canvas/build/Release/canvas.node)
app_1 | at Object.Module._extensions..node (internal/modules/cjs/loader.js:1144:18)
app_1 | at Module.load (internal/modules/cjs/loader.js:950:32)
app_1 | at Module.Mp.load (/opt/bundle/bundle/programs/server/runtime.js:46:33)
app_1 | at Function.Module._load (internal/modules/cjs/loader.js:790:12)
app_1 | at Module.require (internal/modules/cjs/loader.js:974:19)
app_1 | at require (internal/modules/cjs/helpers.js:93:18)
app_1 | at Object.<anonymous> (/opt/bundle/bundle/programs/server/npm/node_modules/canvas/lib/bindings.js:3:18)
app_1 | at Module._compile (internal/modules/cjs/loader.js:1085:14)
app_1 | at Module.Mp._compile (/opt/bundle/bundle/programs/server/runtime.js:99:23)
app_1 | at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
app_1 | at Module.load (internal/modules/cjs/loader.js:950:32)
app_1 | at Module.Mp.load (/opt/bundle/bundle/programs/server/runtime.js:46:33)
app_1 | at Function.Module._load (internal/modules/cjs/loader.js:790:12)
app_1 | at Module.require (internal/modules/cjs/loader.js:974:19)
app_1 | at require (internal/modules/cjs/helpers.js:93:18)
app_1 | at Object.<anonymous> (/opt/bundle/bundle/programs/server/npm/node_modules/canvas/lib/canvas.js:9:18) {
app_1 | code: 'ERR_DLOPEN_FAILED'
app_1 | }
Getting this error as well.
Same problem
It's been a year and a month now... Wow.... Just wow.
Spent some time resolving this problem on alpine
:
canvas
to compile: python3 g++ make cairo-dev pango-dev
canvas
while running: cairo pango
ad.1
While running npm install
or yarn install
canvas
package uses node-gyp
to compile canvas
package on the machine. It is necessary to include this packages or else the similar error will be thrown:
Failed to execute '/usr/local/bin/node /usr/local/lib/node_modules/npm/node_mgyp/bin/node-gyp.js build --fallback-to-build --update-binary --module=/app/node_moduleld/Release/canvas.node --module_name=canvas --module_path=/app/node_modules/canvas/builnapi_version=8 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v93'
Rest of additional packages like jpeg-dev
are not mandatory, but will be needed if you want to use more of the functionality of canvas package.
ad.2
While running your app /app/node_moduleld/Release/canvas.node
uses shared libraries that need to be on your machine. Those libraries are provided by packages cairo pango
. Without for example cairo
you will get error:
Error loading shared library libcairo.so.2: No such file or directory
If you've added jpeg-dev
package i think you should add corresponding packages with shared libraries
@Jakin-Liu
You need to add cairo
package to you apk add
to get rid of that error
@adamgins
You're adding packages cairo pango
in the first stage. They won't end up in the second stage where you fire the app, which means that /app/node_moduleld/Release/canvas.node
won't be able to find required shared libraries. Add cairo pango
to your apk add
in second stage. That should make it.
Hope it helps you all 😄
Same issue.
My DockerFile
FROM node:alpine AS BUILDER
WORKDIR /src
ADD package.json package-lock.json ./
RUN apk add --update --no-cache make python3 g++ cairo cairo-dev pango pango-dev jpeg-dev giflib-dev libpng libjpeg
RUN npm install --build-from-source
RUN npm rebuild canvas --build-from-source
FROM node:alpine
WORKDIR /src
COPY --from=BUILDER /src/node_modules ./node_modules
ENV NODE_ENV=production
COPY package.json ./
COPY src ./src
COPY tsconfig.json ./tsconfig.json
CMD ["npm", "run", "prod"]
@tolgaand What is the error that you get?
@tolgaand What is the error that you get?
@tolgaand In your Dockerfile, you have 2 stages:
As stage BUILDER looks fine (you can remove cairo
and pango
from apk add
and I think you don't need to use --build-from-source
on install
and canvas
) there is a problem in second stage.
Add RUN apk add --no-cache cairo pango
in second stage. While running the app, canvas requires those packages at runtime. Installed at first stage, they are not making it to the second final stage.
hi @michalflog I'm using the RUN apk add cairo pango
in the second stage, but im getting the error that this package does not exist. Here's my docker file
# syntax = docker/dockerfile:1
# Adjust NODE_VERSION as desired
ARG NODE_VERSION=17.6.0
FROM node:${NODE_VERSION}-alpine as base
LABEL fly_launch_runtime="Node.js"
# Node.js app lives here
WORKDIR /app
# Set production environment
ENV NODE_ENV=production
# Throw-away build stage to reduce size of final image
FROM base as build
# To install node canvas
RUN apk add --no-cache \
git \
build-base \
g++ \
cairo-dev \
jpeg-dev \
pango-dev \
freetype-dev \
giflib-dev \
make \
python3
# Install node modules
COPY --link package-lock.json package.json ./
RUN npm ci --include=dev
# Copy application code
COPY --link . .
# Build application
RUN npm run build
# Remove development dependencies
RUN npm prune --omit=dev
# Final stage for app image
FROM base
# Copy built application
COPY --from=build /app /app
RUN apk add --no-cache cario pango
# Setup sqlite3 on a separate volume
RUN mkdir -p /data
VOLUME /data
ENV DATABASE_URL="file:///data/sqlite.db"
ENV NODE_PATH=lib/
# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD [ "npm", "run", "start" ]
@HoaX7 what is an exact error that you're getting?
I got the error "Cairo" package was not available, but I was able to resolve it
@HoaX7 was it a typo in cairo
name from my answer above?
I am getting also that error since today:
and this is my Dockerfile:
FROM node:16-alpine AS deps
RUN apk update
RUN apk add --update --no-cache openssl1.1-compat
RUN apk add --no-cache libc6-compat python3 g++ make && ln -sf python3 /usr/bin/python
RUN apk add --no-cache \
sudo \
curl \
build-base \
libpng \
libpng-dev \
jpeg-dev \
pango-dev \
# cairo-dev \
cairo \
giflib-dev \
;
RUN apk --no-cache add ca-certificates wget && \
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r1/glibc-2.35-r1.apk && \
apk add glibc-2.35-r1.apk
WORKDIR /app
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci --legacy-peer-deps; \
elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i; \
else echo "Lockfile not found." && exit 1; \
fi
FROM node:16-alpine AS builder
RUN apk add --update --no-cache openssl1.1-compat
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npx prisma generate
ARG hostfile
COPY $hostfile .env
RUN yarn build
FROM node:16-alpine AS runner
RUN apk add --update --no-cache openssl1.1-compat
VOLUME [ “/sys/fs/cgroup” ]
RUN apk add --no-cache bash
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]
@pavel1860 runner
is your final stage in Dockerfile
where you run your app. You need to add RUN apk add --no-cache cairo pango
in it. node-canvas
needs this packages at runtime.
PS. you can remove cairo
package from
RUN apk add --no-cache \
sudo \
curl \
build-base \
libpng \
libpng-dev \
jpeg-dev \
pango-dev \
# cairo-dev \
cairo \
giflib-dev \
;
in deps
stage as it is not needed here. And I think you need to uncomment the cairo-dev
package as it is needed, but I may be wrong.
it doesn't work. I still has the same error. I was using this dockerfile for a few months and today something happend. here is the updated docker file:
FROM node:16-alpine AS deps
RUN apk update
RUN apk add --update --no-cache openssl1.1-compat
RUN apk add --no-cache libc6-compat python3 g++ make && ln -sf python3 /usr/bin/python
RUN apk add --no-cache \
sudo \
curl \
build-base \
libpng \
libpng-dev \
jpeg-dev \
pango-dev \
cairo-dev \
giflib-dev \
;
RUN apk --no-cache add ca-certificates wget && \
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r1/glibc-2.35-r1.apk && \
apk add glibc-2.35-r1.apk
WORKDIR /app
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci --legacy-peer-deps; \
elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i; \
else echo "Lockfile not found." && exit 1; \
fi
FROM node:16-alpine AS builder
RUN apk add --update --no-cache openssl1.1-compat
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npx prisma generate
ARG hostfile
COPY $hostfile .env
RUN yarn build
FROM node:16-alpine AS runner
RUN apk add --update --no-cache openssl1.1-compat
VOLUME [ “/sys/fs/cgroup” ]
RUN apk add --no-cache bash
RUN apk add --no-cache cairo pango
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]
Same issue, following.
FROM node:18-alpine AS base
# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
# RUN apk add --no-cache libc6-compat
WORKDIR /app
# https://github.com/Automattic/node-canvas/issues/866
RUN apk add --update --no-cache \
make \
g++ \
jpeg-dev \
cairo-dev \
giflib-dev \
pango-dev
RUN echo "Installed packages:" && apk info -vv \
&& echo "\nEnvironment variables:" && printenv
RUN ls -l /usr/lib/libcairo.so.2*
COPY --link package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --link --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1
COPY --link --from=builder /app/public ./public
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --link --from=builder /app/.next/standalone ./
COPY --link --from=builder /app/.next/static ./.next/static
COPY --link --from=builder /app/global-bundle.pem ./
CMD ["node", "server.js"]
If I run a LDD on the canvas.node I get
/app/node_modules/canvas/build/Release # ldd canvas.node
/lib/ld-musl-x86_64.so.1 (0x7f4ae5aee000)
Error loading shared library libcairo.so.2: No such file or directory (needed by canvas.node)
Error loading shared library libpng16.so.16: No such file or directory (needed by canvas.node)
Error loading shared library libpangocairo-1.0.so.0: No such file or directory (needed by canvas.node)
Error loading shared library libpango-1.0.so.0: No such file or directory (needed by canvas.node)
Error loading shared library libgobject-2.0.so.0: No such file or directory (needed by canvas.node)
Error loading shared library libglib-2.0.so.0: No such file or directory (needed by canvas.node)
Error loading shared library libfreetype.so.6: No such file or directory (needed by canvas.node)
Error loading shared library libjpeg.so.8: No such file or directory (needed by canvas.node)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f4ae57f2000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f4ae57ce000)
libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f4ae5aee000)
Error relocating canvas.node: _ZNK2v85Value8ToUint32ENS_5LocalINS_7ContextEEE: symbol not found
Error relocating canvas.node: pango_layout_get_line: symbol not found
@michalflog do you have any advice, it seems you have gotten this to work
EDIT: I was able to get it to work by moving the apk add cairo pango
to the runner stage, not build stage!!
I'd like to add some extra detail for anyone else facing this issue in the future - this isn't node-canvas specific but may help people with related or similar issues:
libuuid.so.1
) into the Alpine Package Search page to find the name of the package that provides the shared library.next build
command executes all of your code as part of the build process ("collecting page data") to detect getStaticProps
.hope this saves someone some trouble!
For anyone facing issues especially with Three.js in a Next.js/React app, use node-slim instead of node-alpine. This will solve the problem.
this is error detail info: Error: Error loading shared library libcairo.so.2: No such file or directory (needed by /app/node_modules/canvas/build/Release/canvas.node) at Object.Module._extensions..node (internal/modules/cjs/loader.js:1057:18) at Module.load (internal/modules/cjs/loader.js:863:32) at Function.Module._load (internal/modules/cjs/loader.js:708:14) at Module.require (internal/modules/cjs/loader.js:887:19) at Module.Hook._require.Module.require (/usr/local/lib/node_modules/pm2/node_modules/require-in-the-middle/index.js:80:39) at require (internal/modules/cjs/helpers.js:74:18) at Object. (/app/node_modules/canvas/lib/bindings.js:3:18)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
at Module.Hook._require.Module.require (/usr/local/lib/node_modules/pm2/node_modules/require-in-the-middle/index.js:80:39)
at require (internal/modules/cjs/helpers.js:74:18)
at Object. (/app/node_modules/canvas/lib/canvas.js:9:18)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
at Module.Hook._require.Module.require (/usr/local/lib/node_modules/pm2/node_modules/require-in-the-middle/index.js:80:39)
at require (internal/modules/cjs/helpers.js:74:18)
at Object. (/app/node_modules/canvas/index.js:1:16)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
this is my dockfile: FROM node:12-alpine as base
WORKDIR /app COPY package.json . COPY package-lock.json . RUN apk add --update --no-cache \ make \ python3 \ g++ \ cairo-dev \ pango \ pango-dev \ jpeg-dev \ giflib-dev \ librsvg \ libpng \ libjpeg
when i run in docker, it show me that Error loading shared library libcairo.so.2: No such file or directory. It can run in my local computer