dockerfile-rails
dockerfile-rails copied to clipboard
vendor directory is empty in CI
Hello, I am trying to use this dockerfile in a rails 6.1 project to run tests in Gitlab CI.
The build step runs fine with kaniko, but the test step fails with bundler: command not found: rails
. When I check what the vendor directory contains, it looks OK in the build step, but empty in the test step.
This is my dockerfile.yml
# generated by dockerfile-rails
---
options:
cache: true
ci: true
jemalloc: true
mysql: true
redis: true
root: true
packages:
build:
- git
- ruby-dev
- gcc
- make
- g++
- libffi-dev
- libmariadb-dev-compat
This is the Dockerfile
# syntax = docker/dockerfile:1
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.1.4
FROM ruby:$RUBY_VERSION-slim as base
# Rails app lives here
WORKDIR /rails
# Set production environment
ENV RAILS_ENV="production" \
BUNDLE_WITHOUT="development" \
BUNDLE_DEPLOYMENT="1"
# Update gems and bundler
RUN gem update --system --no-document && \
gem install -N bundler
# Throw-away build stage to reduce size of final image
FROM base as build
# Install packages needed to build gems and node modules
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential curl default-libmysqlclient-dev g++ gcc git libffi-dev libmariadb-dev-compat make node-gyp pkg-config python-is-python3 ruby-dev
# Install Node.js
ARG NODE_VERSION=17.6.0
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 && \
rm -rf /tmp/node-build-master
# Install application gems
COPY --link Gemfile Gemfile.lock ./
RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
bundle config set app_config .bundle && \
bundle config set path /srv/vendor && \
bundle install && \
bundle exec bootsnap precompile --gemfile && \
bundle clean && \
mkdir -p vendor && \
bundle config set path vendor && \
cp -ar /srv/vendor .
# Install node modules
COPY --link package.json package-lock.json ./
RUN --mount=type=cache,id=bld-npm-cache,target=/root/.npm \
npm install
# Copy application code
COPY --link . .
# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/
# Final stage for app image
FROM base
# Install packages needed for deployment
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y curl default-mysql-client imagemagick libjemalloc2
# Copy built artifacts: gems, application
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /rails /rails
# Deployment options
ENV LD_PRELOAD="libjemalloc.so.2" \
MALLOC_CONF="dirty_decay_ms:1000,narenas:2,background_thread:true" \
RAILS_LOG_TO_STDOUT="1" \
RAILS_SERVE_STATIC_FILES="true"
# 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"]
This is the kaniko command in the build step:
script:
- mkdir -p /kaniko/.docker
- export container=docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor --force --cache=false --context $CI_PROJECT_DIR --dockerfile Dockerfile --build-arg BUILDKIT_INLINE_CACHE=1 --build-arg RAILS_MASTER_KEY=$MASTER_KEY --destination $CI_REGISTRY_IMAGE:$DESTINATION_TAG
Try without the cache option?
The way dockerfile caches work is that they are on a separate volume that is mounted only for that one step.