Docker build fails because unable to install `libc-bin`

176 views Asked by At

Using kamal to deploy a rails app, but having trouble with docker and getting all installed. I in the past had it setup to use esbuild and yarn, but switched to bun later. Now, I need to install node for a tool on the ruby side, so trying to go back to esbuild/yarn/node for the setup.

But the Dockerfile below always fails with:

#16 CANCELED
------
 > [linux/arm64 stage-2 1/4] RUN apt-get update -qq &&     apt-get install --no-install-recommends -y curl libvips postgresql-client &&     rm -rf /var/lib/apt/lists /var/cache/apt/archives:
63.28 Processing triggers for libc-bin (2.31-13+deb11u5) ...
63.33 qemu: uncaught target signal 11 (Segmentation fault) - core dumped
63.33 Segmentation fault
63.34 qemu: uncaught target signal 11 (Segmentation fault) - core dumped
63.34 Segmentation fault
63.34 dpkg: error processing package libc-bin (--configure):
63.34  installed libc-bin package post-installation script subprocess returned error exit status 139
63.44 Errors were encountered while processing:
63.44  libc-bin
63.54 E: Sub-process /usr/bin/dpkg returned an error code (1)
------
Dockerfile:64
--------------------
  63 |     # Install packages needed for deployment
  64 | >>> RUN apt-get update -qq && \
  65 | >>>     apt-get install --no-install-recommends -y curl libvips postgresql-client && \
  66 | >>>     rm -rf /var/lib/apt/lists /var/cache/apt/archives
  67 |
--------------------
ERROR: failed to solve: process "/bin/sh -c apt-get update -qq &&     apt-get install --no-install-recommends -y curl libvips postgresql-client &&     rm -rf /var/lib/apt/lists /var/cache/apt/archives" did not complete successfully: exit code: 100

How can I get this working again? The basic requirement is to get the base Ruby 3.2.1 image up and running with Node, but I can't seem to get there. I've tried installing libc-bin directly, but it made no difference.

Dockerfile:

# syntax = docker/dockerfile:1

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.2.1
FROM registry.docker.com/library/ruby:$RUBY_VERSION as base

# Rails app lives here
WORKDIR /rails

# Set production environment
ENV RAILS_ENV="production" \
    BUNDLE_DEPLOYMENT="1" \
    BUNDLE_PATH="/usr/local/bundle" \
    BUNDLE_WITHOUT="development"


# Throw-away build stage to reduce size of final image
FROM base as build

# Install packages needed to build gems and node modules
RUN apt-get update -qq && \
    # apt-get install --no-install-recommends -y build-essential curl git node-gyp pkg-config python-is-python3 libpq-dev libvips unzip
    apt-get install --no-install-recommends -y build-essential curl git node-gyp pkg-config python-is-python3 libpq-dev unzip

# RUN apt-get update -qq && \
#     apt-get install --no-install-recommends -y build-essential curl git node-gyp pkg-config python-is-python3


# Install JavaScript dependencies
ARG NODE_VERSION=21.5.0
ARG YARN_VERSION=1.22.19
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
    /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
    npm install -g yarn@$YARN_VERSION && \
    rm -rf /tmp/node-build-master

# Install application gems
COPY Gemfile Gemfile.lock ./
RUN bundle install && \
    rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
    bundle exec bootsnap precompile --gemfile

# Install node modules
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Copy application code
COPY . .

# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/

# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile


# Final stage for app image
FROM base

# Install packages needed for deployment
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y curl libvips postgresql-client && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Copy built artifacts: gems, application
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /rails /rails

# Run and own only the runtime files as a non-root user for security
RUN useradd rails --create-home --shell /bin/bash && \
    chown -R rails:rails db log storage tmp
USER rails:rails

# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["./bin/rails", "server"]

Update #1

Output of free -h on the Ubuntu host this is running on:

               total        used        free      shared  buff/cache   available
Mem:           949Mi       498Mi        65Mi       1.0Mi       384Mi       289Mi
Swap:             0B          0B          0B

I've also watched htop memory usage. It always hovers around 475M/959M of usage during the build.

I have not yet added swap space, but will experiment with that and report back here.

This is an AWS t2.micro instance with 1G of memory, so that may well not be enough, though it's run fine up to this point. Will experiment with upgrading that and seeing if it resolves the issue. Upgrading to 4g of memory did not help. The error(s) remain the same.

2

There are 2 answers

0
Per Helge Litzheim Frøiland On

I had a similar/same issue. I'm using Ubuntu as base, but had issue with installing python3 and python3-pip due to this error:

Segmentation fault
dpkg: error processing package libc-bin (--configure):
 installed libc-bin package post-installation script subprocess returned error exit status 139
Errors were encountered while processing:
 libc-bin
E: Sub-process /usr/bin/dpkg returned an error code (1)

This answer to similar issue helped me find a fix for it. https://stackoverflow.com/a/76260513/13000654

I added this in my Dockerfile before doing any of my installs

RUN rm /var/lib/dpkg/info/libc-bin.*
RUN apt-get clean
RUN apt-get update
RUN apt-get install libc-bin

Hope this helps

3
datawookie On

I got the Dockerfile below to build.

ARG RUBY_VERSION=3.2.1
FROM registry.docker.com/library/ruby:$RUBY_VERSION as base

WORKDIR /rails

ENV RAILS_ENV="production"
ENV BUNDLE_WITHOUT="development"

FROM base as build

RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y \
        build-essential \
        curl \
        git \
        node-gyp \
        pkg-config \
        python-is-python3 \
        libpq-dev \
        unzip

ARG NODE_VERSION=21.5.0
ARG YARN_VERSION=1.22.19
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
    /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
    npm install -g yarn@$YARN_VERSION && \
    rm -rf /tmp/node-build-master

COPY Gemfile Gemfile.lock .
RUN bundle install && \
    bundle exec bootsnap precompile --gemfile

COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

COPY . .

RUN bundle exec bootsnap precompile app/ lib/

RUN SECRET_KEY_BASE_DUMMY=1 rails assets:precompile

FROM base

RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y curl libvips postgresql-client && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /rails /rails

RUN useradd rails --create-home --shell /bin/bash && \
    chown -R rails:rails .
USER rails:rails

ENTRYPOINT ["/rails/bin/docker-entrypoint"]

EXPOSE 3000
CMD ["rails", "server"]

This is what the project looks like on the host:

├── bin
│   └── docker-entrypoint
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── package.json
└── yarn.lock

However, the fact that you are getting a segmentation fault when building the image suggests that there might be another problem. Perhaps you are running into memory constraints? Have you monitored the memory consumption while you are building the image? How much RAM do you have on the host machine? Have you added swap space? And, if so, how much? Seeing the output from free -h would be helpful!

You can add swap space by running something like this on the host:

SWAPFILE="/var/swap"
SIZE=8G
sudo fallocate -l $SIZE $SWAPFILE
sudo chmod 600 $SWAPFILE
sudo /sbin/mkswap $SWAPFILE
sudo /sbin/swapon $SWAPFILE

If you check the output from free after that you should see that you now have some swap space. If you are using swap then the build will proceed a lot slower but it should still get there (provided that memory is indeed the issue!).