Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 32 additions & 32 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,58 +1,58 @@
FROM ruby:3.3-slim AS base
USER root
Copy link
Member Author

@danschmidt5189 danschmidt5189 Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ruby:3.3-slim runs as root by default so this directive wasn't necessary.

$ docker run --rm ruby:3.3-slim whoami
root


# Configure users and groups
RUN groupadd -g 40054 alma && \
useradd -r -s /sbin/nologin -M -u 40054 -g alma alma && \
useradd -u 40061 bfs && \
useradd -s /sbin/nologin -M -u 40054 -g alma alma && \
groupadd -g 40061 bfs && \
usermod -u 40061 -g bfs -G alma -l bfs default && \
find / -user 1001 -exec chown -h bfs {} \; || true && \
mkdir -p /opt/app && \
chown -R bfs:bfs /opt/app
Copy link
Member Author

@danschmidt5189 danschmidt5189 Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gist of this whole diff is that it sets up the alma group/user (in that order), then the bfs group/user, and finally scaffolds the application directory and bfs's sshkey directory with the proper (tight) permissions.

Also note the alma user is not marked as a "system" user (-r is omitted). It's not necessary, and marking alma as system throws a warning about its uid exceeding SYS_MAX_UID.


# Get list of available packages
RUN apt-get -y update -qq

COPY --chown=bfs . /opt/app
useradd -u 40061 -g bfs -G alma -m bfs && \
install -d -o bfs -g bfs -m 0700 /opt/app /home/bfs/.ssh

# Install packages common to dev/prod
RUN apt-get -y update -qq && \
gem install bundler --version 2.5.22
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bundle install shows a warning that the lockfile was actually built with 2.1.4. I would suggest getting out of the image's way and just re-installing with whatever bundler version it ships with, provided that meets the app's needs.


# Ignore the system's platform and only install native Ruby versions
ENV BUNDLE_FORCE_RUBY_PLATFORM=true
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting these in environment variables is arguably a bit cleaner—I don't actually have a strong preference here. I do wonder how you all want to handle freezing the Gemfile.lock, as that has implications for when you actually want to perform updates. I think with a frozen bundle, to update dependencies you'd need to hop into the container just before the bundle-install, unfreeze, perform the update, and extract/commit the Gemfile/.lock changes. Seems like a lot of steps—not sure the best way to optimize that.

CC @BerkeleyLibrary/apps

# Prevent automatic updates to the Gemfile.lock
ENV BUNDLE_FROZEN=true
# Install Gems to the container's system-wide location
ENV BUNDLE_SYSTEM=true
# Prepend BFS script to PATH so you don't have to prefix with /opt/app/bin.
ENV PATH=/opt/app/bin:$PATH
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's been pretty standard practice to add our bin scripts to the front of the path. How does everyone feel about this?


WORKDIR /opt/app
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workdir is common to both subsequent stages so it makes sense to set it in the base stage.

ENTRYPOINT ["/opt/app/bin/bfs"]
CMD ["help"]

# ===============================================
# Target: development
# ===============================================

FROM base AS development

USER root

RUN apt-get -y --no-install-recommends install \
build-essential \
make

USER bfs
build-essential \
make
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Command continuations should be indented from the previous line so it's visually obvious that they're part of it, and not new commands.


# Base image ships with an older version of bundler
RUN gem install bundler --version 2.5.22

WORKDIR /opt/app
# Install rubygems. This step is separated from copying the
# rest of the codebase to maximize cache hits.
COPY --chown=bfs Gemfile* .ruby-version ./
RUN bundle config set force_ruby_platform true
RUN bundle config set system 'true'
RUN bundle install

# COPY --chown=bfs:bfs . .
# Install the rest of the codebase.
COPY --chown=bfs:bfs . .

# =================================
# Target: production
# =================================
FROM base AS production

# Copy the built codebase from the dev stage
# COPY --from=development --chown=bfs /opt/app /opt/app
COPY --from=development --chown=bfs /usr/local/bundle /usr/local/bundle
# Copy the built codebase/dependencies from the dev stage
COPY --from=development --chown=bfs:bfs /opt/app /opt/app
COPY --from=development --chown=bfs:bfs /usr/local/bundle /usr/local/bundle

WORKDIR /opt/app
RUN bundle config set frozen 'true'
RUN bundle install --local
# Drop privileges
USER bfs

# Verify the installation
RUN bundle check && \
bfs help
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous bundle install --local was, I think, overkill for what we're trying to check here. We just want to know that the dependencies are installed and the app can run, and this combination of bundle check and running the help command should accomplish that.