### Problem Docker builds started failing with a misleading dependency resolution error: ``` Could not find compatible versions Because every version of devise-secure_password depends on railties >= 5.0.0, < 8.0.0 ... ``` ### Root Cause [Bundler 4.0.4](https://github.com/ruby/rubygems/releases/tag/bundler-v4.0.4) was released on January 14, 2026. The Dockerfile used `gem install bundler` without version pinning, which installed the latest (4.0.4) instead of the version specified in `Gemfile.lock` (2.5.16). ### Fix - Pin Bundler installation to match `Gemfile.lock`: `gem install bundler -v "$BUNDLER_VERSION"` - Update `BUNDLER_VERSION` from 2.5.11 to 2.5.16 ### ⚠️ Note Fix found by Claude while checking why the deploy was failing, and have not yet checked for alternatives which might be more appropriate, so further investigation might be required.
153 lines
4.3 KiB
Docker
153 lines
4.3 KiB
Docker
# pre-build stage
|
|
FROM node:24-alpine as node
|
|
FROM ruby:3.4.4-alpine3.21 AS pre-builder
|
|
|
|
ARG NODE_VERSION="24.12.0"
|
|
ARG PNPM_VERSION="10.2.0"
|
|
ENV NODE_VERSION=${NODE_VERSION}
|
|
ENV PNPM_VERSION=${PNPM_VERSION}
|
|
|
|
# ARG default to production settings
|
|
# For development docker-compose file overrides ARGS
|
|
ARG BUNDLE_WITHOUT="development:test"
|
|
ENV BUNDLE_WITHOUT ${BUNDLE_WITHOUT}
|
|
ENV BUNDLER_VERSION=2.5.16
|
|
|
|
ARG RAILS_SERVE_STATIC_FILES=true
|
|
ENV RAILS_SERVE_STATIC_FILES ${RAILS_SERVE_STATIC_FILES}
|
|
|
|
ARG RAILS_ENV=production
|
|
ENV RAILS_ENV ${RAILS_ENV}
|
|
|
|
ARG NODE_OPTIONS="--max-old-space-size=4096 --openssl-legacy-provider"
|
|
ENV NODE_OPTIONS ${NODE_OPTIONS}
|
|
|
|
ENV BUNDLE_PATH="/gems"
|
|
|
|
RUN apk update && apk add --no-cache \
|
|
openssl \
|
|
tar \
|
|
build-base \
|
|
tzdata \
|
|
postgresql-dev \
|
|
postgresql-client \
|
|
git \
|
|
curl \
|
|
xz \
|
|
&& mkdir -p /var/app \
|
|
&& gem install bundler -v "$BUNDLER_VERSION"
|
|
|
|
COPY --from=node /usr/local/bin/node /usr/local/bin/
|
|
COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules
|
|
RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
|
|
&& ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
|
|
|
|
RUN npm install -g pnpm@${PNPM_VERSION}
|
|
|
|
RUN echo 'export PNPM_HOME="/root/.local/share/pnpm"' >> /root/.shrc \
|
|
&& echo 'export PATH="$PNPM_HOME:$PATH"' >> /root/.shrc \
|
|
&& export PNPM_HOME="/root/.local/share/pnpm" \
|
|
&& export PATH="$PNPM_HOME:$PATH" \
|
|
&& pnpm --version
|
|
|
|
# Persist the environment variables in Docker
|
|
ENV PNPM_HOME="/root/.local/share/pnpm"
|
|
ENV PATH="$PNPM_HOME:$PATH"
|
|
|
|
WORKDIR /app
|
|
|
|
COPY Gemfile Gemfile.lock ./
|
|
|
|
# natively compile grpc and protobuf to support alpine musl (dialogflow-docker workflow)
|
|
# https://github.com/googleapis/google-cloud-ruby/issues/13306
|
|
# adding xz as nokogiri was failing to build libxml
|
|
# https://github.com/chatwoot/chatwoot/issues/4045
|
|
RUN apk update && apk add --no-cache build-base musl ruby-full ruby-dev gcc make musl-dev openssl openssl-dev g++ linux-headers xz vips
|
|
RUN bundle config set --local force_ruby_platform true
|
|
|
|
# Do not install development or test gems in production
|
|
RUN if [ "$RAILS_ENV" = "production" ]; then \
|
|
bundle config set without 'development test'; bundle install -j 4 -r 3; \
|
|
else bundle install -j 4 -r 3; \
|
|
fi
|
|
|
|
COPY package.json pnpm-lock.yaml ./
|
|
RUN pnpm i
|
|
|
|
COPY . /app
|
|
|
|
# creating a log directory so that image wont fail when RAILS_LOG_TO_STDOUT is false
|
|
# https://github.com/chatwoot/chatwoot/issues/701
|
|
RUN mkdir -p /app/log
|
|
|
|
# generate production assets if production environment
|
|
RUN if [ "$RAILS_ENV" = "production" ]; then \
|
|
SECRET_KEY_BASE=precompile_placeholder RAILS_LOG_TO_STDOUT=enabled bundle exec rake assets:precompile \
|
|
&& rm -rf spec node_modules tmp/cache; \
|
|
fi
|
|
|
|
# Generate .git_sha file with current commit hash
|
|
RUN git rev-parse HEAD > /app/.git_sha
|
|
|
|
# Remove unnecessary files
|
|
RUN rm -rf /gems/ruby/3.4.0/cache/*.gem \
|
|
&& find /gems/ruby/3.4.0/gems/ \( -name "*.c" -o -name "*.o" \) -delete \
|
|
&& rm -rf .git \
|
|
&& rm .gitignore
|
|
|
|
# final build stage
|
|
FROM ruby:3.4.4-alpine3.21
|
|
|
|
ARG NODE_VERSION="24.12.0"
|
|
ARG PNPM_VERSION="10.2.0"
|
|
ENV NODE_VERSION=${NODE_VERSION}
|
|
ENV PNPM_VERSION=${PNPM_VERSION}
|
|
|
|
ARG BUNDLE_WITHOUT="development:test"
|
|
ENV BUNDLE_WITHOUT ${BUNDLE_WITHOUT}
|
|
ENV BUNDLER_VERSION=2.5.16
|
|
|
|
ARG EXECJS_RUNTIME="Disabled"
|
|
ENV EXECJS_RUNTIME ${EXECJS_RUNTIME}
|
|
|
|
ARG RAILS_SERVE_STATIC_FILES=true
|
|
ENV RAILS_SERVE_STATIC_FILES ${RAILS_SERVE_STATIC_FILES}
|
|
|
|
ARG BUNDLE_FORCE_RUBY_PLATFORM=1
|
|
ENV BUNDLE_FORCE_RUBY_PLATFORM ${BUNDLE_FORCE_RUBY_PLATFORM}
|
|
|
|
ARG RAILS_ENV=production
|
|
ENV RAILS_ENV ${RAILS_ENV}
|
|
ENV BUNDLE_PATH="/gems"
|
|
|
|
RUN apk update && apk add --no-cache \
|
|
build-base \
|
|
openssl \
|
|
tzdata \
|
|
postgresql-client \
|
|
imagemagick \
|
|
git \
|
|
vips \
|
|
&& gem install bundler -v "$BUNDLER_VERSION"
|
|
|
|
COPY --from=node /usr/local/bin/node /usr/local/bin/
|
|
COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules
|
|
|
|
RUN if [ "$RAILS_ENV" != "production" ]; then \
|
|
apk add --no-cache curl \
|
|
&& ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
|
|
&& ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx \
|
|
&& npm install -g pnpm@${PNPM_VERSION} \
|
|
&& pnpm --version; \
|
|
fi
|
|
|
|
COPY --from=pre-builder /gems/ /gems/
|
|
COPY --from=pre-builder /app /app
|
|
|
|
# Copy .git_sha file from pre-builder stage
|
|
COPY --from=pre-builder /app/.git_sha /app/.git_sha
|
|
|
|
WORKDIR /app
|
|
|
|
EXPOSE 3000
|