I'm trying to deploy a Next.js app in a Docker container where I'd like to use the sharp
npm library to work on SVG with text.
Because sharp
relies on the host system's fontconfig
library for its handling of fonts (which is no issue on my local system when doing local development), I need to install it on the Alpine Linux system on top of which I'm running the app in the Docker container.
When I'm installing the packages using docker build -t test .
on the Dockerfile
FROM node:21-alpine AS base
FROM base AS deps
RUN apk add --no-cache libc6-compat freetype pango vips fontconfig font-dejavu ttf-freefont
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; \
elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
RUN npm rebuild --verbose sharp
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
RUN mkdir .next
RUN chown nextjs:nodejs .next
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
ENV HOSTNAME "0.0.0.0"
CMD ["node", "server.js"]
I'm getting the following build messages:
Step 5/33 : RUN apk add --no-cache libc6-compat freetype pango vips fontconfig font-dejavu ttf-freefont
---> Running in fdb2fb972a3b
fetch https://dl-cdn.alpinelinux.org/alpine/v3.19/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.19/community/x86_64/APKINDEX.tar.gz
(1/81) Installing libexpat (2.5.0-r2)
(2/81) Installing brotli-libs (1.1.0-r1)
(3/81) Installing libbz2 (1.0.8-r6)
(4/81) Installing libpng (1.6.40-r0)
(5/81) Installing freetype (2.13.2-r0)
(6/81) Installing fontconfig (2.14.2-r4)
(7/81) Installing encodings (1.0.7-r1)
(8/81) Installing libfontenc (1.1.7-r4)
(9/81) Installing mkfontscale (1.2.2-r4)
(10/81) Installing font-dejavu (2.37-r5)
...
(79/81) Installing libwebpdemux (1.3.2-r0)
(80/81) Installing libwebpmux (1.3.2-r0)
(81/81) Installing vips (8.15.0-r0)
Executing busybox-1.36.1-r15.trigger
Executing fontconfig-2.14.2-r4.trigger
Executing mkfontscale-1.2.2-r4.trigger
Executing glib-2.78.3-r0.trigger
Executing ca-certificates-20230506-r0.trigger
Executing shared-mime-info-2.4-r0.trigger
Executing gdk-pixbuf-2.42.10-r6.trigger
OK: 128 MiB in 98 packages
But afterwards when I run the shell in the live container docker run -it test /bin/sh
, according the command of listing installed packages apk list -i
, those packages are nowhere to be found:
WARNING: opening from cache https://dl-cdn.alpinelinux.org/alpine/v3.19/main: No such file or directory
WARNING: opening from cache https://dl-cdn.alpinelinux.org/alpine/v3.19/community: No such file or directory
alpine-baselayout-3.4.3-r2 x86_64 {alpine-baselayout} (GPL-2.0-only) [installed]
alpine-baselayout-data-3.4.3-r2 x86_64 {alpine-baselayout} (GPL-2.0-only) [installed]
alpine-keys-2.4-r1 x86_64 {alpine-keys} (MIT) [installed]
apk-tools-2.14.0-r5 x86_64 {apk-tools} (GPL-2.0-only) [installed]
busybox-1.36.1-r15 x86_64 {busybox} (GPL-2.0-only) [installed]
busybox-binsh-1.36.1-r15 x86_64 {busybox} (GPL-2.0-only) [installed]
ca-certificates-bundle-20230506-r0 x86_64 {ca-certificates} (MPL-2.0 AND MIT) [installed]
libc-utils-0.7.2-r5 x86_64 {libc-dev} (BSD-2-Clause AND BSD-3-Clause) [installed]
libcrypto3-3.1.4-r2 x86_64 {openssl} (Apache-2.0) [installed]
libgcc-13.2.1_git20231014-r0 x86_64 {gcc} (GPL-2.0-or-later AND LGPL-2.1-or-later) [installed]
libssl3-3.1.4-r2 x86_64 {openssl} (Apache-2.0) [installed]
libstdc++-13.2.1_git20231014-r0 x86_64 {gcc} (GPL-2.0-or-later AND LGPL-2.1-or-later) [installed]
musl-1.2.4_git20230717-r4 x86_64 {musl} (MIT) [installed]
musl-utils-1.2.4_git20230717-r4 x86_64 {musl} (MIT AND BSD-2-Clause AND GPL-2.0-or-later) [installed]
scanelf-1.3.7-r2 x86_64 {pax-utils} (GPL-2.0-only) [installed]
ssl_client-1.36.1-r15 x86_64 {busybox} (GPL-2.0-only) [installed]
zlib-1.3-r2 x86_64 {zlib} (Zlib) [installed]
I've put in bold the WARNINGs that look somewhat suspicious to me. But honestly, I have no clue how to make sure how to install and make fontconfig
work here. Any ideas?
The problem is that you're installing the packages into your deps
stage, but all the following stages are FROM base ...
:
$ grep FROM Dockerfile
FROM node:21-alpine AS base
FROM base AS deps
FROM base AS builder
FROM base AS runner
You would need to change FROM base
to FROM deps
in the final stage (FROM deps AS runner
) in order to see those packages.