Search code examples
dockeralpine-linuxfontconfig

Installed Packages Failing to Show up on Alpine Linux in Docker Container


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?


Solution

  • 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.