Error building docker image with Dockerfile - ruby-on-rails

I’m trying to build docker image with a configuration in Dockerfile:
FROM ubuntu
MAINTAINER axiom88guru(axiom88guru#gmail.com)
Configuration for app below.
Run upgrades
RUN apt-get update
Install basic packages
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
Install Ruby
RUN apt-get -qq -y install ruby-full
RUN gem install bundler --no-ri --no-rdoc
RUN gem install foreman
Install rails-new-docker
WORKDIR /app
RUN git clone https://github.com/axiom88-guru/rails-docker.git /app
RUN bundle install --without development test
Run rails-new-docker
ENV SECRET_KEY_BASE dockerkeybase
ENV RAILS_ENV production
EXPOSE 5959
CMD foreman start -f Procfile
When I run these commands in bash they work as expected, but not during docker build:
Removing intermediate container 344e99851852
Step 8/14 : WORKDIR /app
—> 3c204a395f23
Removing intermediate container 680b1841a3fc
Step 9/14 : RUN git clone https://github.com/axiom88-guru/rails-docker.git /app
—> Running in d7a9de9f6ab5
/bin/sh: 1: git: not found
The command ‘/bin/sh -c git clone https://github.com/axiom88-guru/rails-docker.git /app’ returned a non-zero code: 127
Could anyone help me find out the solution please?

Need to have git installed since the base ubuntu image provides only a minimal set of installed packages (this is done to keep image size small).
FROM ubuntu
MAINTAINER axiom88guru(axiom88guru#gmail.com)
# Configuration for app below.
# Run upgrades
RUN apt-get update
# Install basic packages
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs git
# Install Ruby
RUN apt-get -qq -y install ruby-full
RUN gem install bundler --no-ri --no-rdoc
RUN gem install foreman
# Install rails-new-docker
WORKDIR /app
RUN git clone https://github.com/axiom88-guru/rails-docker.git /app
RUN bundle install --without development test
# Run rails-new-docker
ENV SECRET_KEY_BASE dockerkeybase
ENV RAILS_ENV production
EXPOSE 5959
CMD foreman start -f Procfile
This version should work. I just added git to the first apt-get install step.

Related

Docker image stuck on bundling

I've been trying to build my Docker image:
docker build -t <tag> -f Dockerfile.production .
However, this hangs while bundling.
I have tried bundling with:
DEBUG_RESOLVER=true bundle install --verbose
Running bundle on my host machine works fine - only the Docker image has this problem.
Attached is my Dockerfile:
FROM cimg/ruby:2.7.4-node
LABEL maintainer=budgeneration#gmail.com
SHELL ["/bin/bash", "-c"]
USER root
RUN sudo apt-get update && \
apt-get install -y nodejs npm libvips-tools libsodium-dev \
apt-transport-https ca-certificates curl software-properties-common \
librocksdb-dev \
libsnappy-dev \
python3-distutils \
rsyslog --no-install-recommends
# Other tools not related to building by still required.
RUN sudo apt-get install -y ffmpeg gifsicle
USER circleci
# Install all gems first.
# This hits the warm cache if unchanged so bundling is faster.
COPY Gemfile* /tmp/
WORKDIR /tmp
RUN gem install sassc-rails -v 2.1.2
RUN gem install bulma-rails -v 0.9.1
RUN bundle config set without 'development test' \
&& bundle install --verbose \
&& bundle binstubs railties
# Remove yarn (the other yarn)
RUN apt-get purge cmdtest
RUN yarn global add mjml
WORKDIR /sapco
# First we copy just Yarn files, to run yarn install
COPY package.json /sapco
COPY yarn.lock /sapco
RUN yarn install
WORKDIR /sapco
# Now copy everything
COPY . /sapco
EXPOSE 3000
Any tips to try to debug this further?
I have managed to resolve this issue but not sure why:
I changed my base image file to FROM circleci/ruby:2.7.4-buster-node and the bundling step continues fine.

"Could not find rake-12.3.3 in any of the sources."

I tried running these commands:
gem uninstall rake
rm Gemfile.lock
bundle install
gem install rake --version=12.3.3
I also tried adding rake 12.3.3 to the gemfile and running bundle install:
gem 'rake', '12.3.3'
This is my Dockerfile:
FROM ruby
RUN apt-get update -qq && apt-get install -y build-essential
# for postgres
RUN apt-get install -y libpq-dev
# for nokogiri
RUN apt-get install -y libxml2-dev libxslt1-dev
# for a JS runtime
RUN apt-get install -y nodejs
ENV APP_HOME /readpaths
WORKDIR $APP_HOME
ADD Gemfile* $APP_HOME/
RUN bundle install
ADD . $APP_HOME
I've just noticed something curios: No matter how often I run gem uninstall rake (I tried five times) I always get a message saying:
Successfully uninstalled rake-12.3.1
When I run gem install rake I get:
Successfully installed rake-12.3.3
Then, when I run gem uninstall rake again, I get again:
Successfully uninstalled rake-12.3.1
If you come to this error because of Heroku/Jekyll, this is how I fixed it:
Make sure you only have this buildpack: https://github.com/heroku/heroku-buildpack-ruby
Make sure your dyno is actually on
Your Procfile should have this: web: jekyll serve --no-watch --port $PORT --host 0.0.0.0
Make sure your have PORT configured in the config vars section of your settings
Try rebuilding the docker container.

Dockerfile returns npm not found on build

I'm really new to Docker and would like to create a container that has all my Ruby on Rails website and its dependencies in it. I read TONS of documentations and how-to's to do it but I keep struggling.
Since I use Rubymine, there is a built-in tool that allows you to Dockerize the current project you're in from the Dockerfile you created in it. However, I keep having the error "npm not found while NodeJS should be installed.
Here is my Dockerfile:
FROM ruby:2.4.3
MAINTAINER Jaeger
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir -p /app
WORKDIR /app
COPY package.json /app
RUN npm i -g yarn && yarn
COPY Gemfile Gemfile.lock ./
RUN gem install bundler && bundle install --jobs 20 --retry 5
RUN yarn
COPY . ./
EXPOSE 3000
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
The ultimate goal should be that, since I use Webpacker and React in it (well it's a dummy project for a test, but the real website has this), I would like to install Yarn, and make Yarn install all the depencies.
I found some other people that had the same problem but got lost trying to understand the Docker layers concept and trying to copy some codes that didn't work either
You need to explicitly install node / npm in your container before running npm install. Add this to your Dockerfile.
RUN apt-get update && apt-get install -y curl
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN apt-get update && apt-get install -y nodejs
Another solution (which might be cleaner) would be to first mount / setup the working directory before installing the dependencies:
FROM ruby:2.4.3
MAINTAINER Jaeger
RUN mkdir -p /app
WORKDIR /app
RUN apt-get update -qq && apt-get install -y build-essential nodejs
...

How do I add a package to an already existing image?

I have a RoR app that uses imagemagick specified in the Gemfile. I am using Docker's official rails image to build my image with the following Dockerfile:
FROM rails:onbuild
RUN apt-get install imagemagick
and get the following error:
Cant install RMagick 2.13.2. Cant find Magick-config in /usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Now, that's probably because the imagemagic package is missing on the OS, even though I specified it in my Dockerfile. So I guess the bundle install command is issued before my RUN apt-get command is issued.
My question - using this base image, is there a way to ensure imagemagic is installed prior to bundling?
Do I need to fork and change the base image Dockerfile to achieve that?
you are right, the ONBUILD instructions from the rails:onbuild image will be executed just after the FROM instruction of your Dockerfile.
What I suggest is to change your Dockerfile as follow:
FROM ruby:2.2.0
RUN apt-get install imagemagick
# throw errors if Gemfile has been modified since Gemfile.lock
RUN bundle config --global frozen 1
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y mysql-client postgresql-client sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/*
COPY Gemfile /usr/src/app/
COPY Gemfile.lock /usr/src/app/
RUN bundle install
COPY . /usr/src/app
EXPOSE 3000
CMD ["rails", "server"]
which I made based on the rails:onbuild Dockerfile moving down the ONBUILD instructions and removing the ONBUILD flavor.
Most packages clean out the cache to save on size. Try this:
apt-get update && apt-get install imagemagick
Or spool up a copy of the container and look for yourself
docker run -it --remove <mycontainernameorid> /bin/bash
The --remove will ensure that the container is removed after you exit the shell. Once in the shell look for the package binary (or dpkg --list)

bundler installed gems not persisting in fig/docker

I am trying to use fig and docker to set up a local development environment for an existing rails app.
In the build process, I clearly see bundler installing the app's gems, but when I try to start the container with fig up or even reopen it with the /bin/bash command, the gems are not visible.
Here is the Dockerfile:
FROM ubuntu:14.04
# REPOS
RUN apt-get -qq update
RUN apt-get install -y software-properties-common
RUN add-apt-repository -y "deb http://archive.ubuntu.com/ubuntu $(lsb_release -sc) universe"
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get -y update
#INSTALL
RUN apt-get install -y -q build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison pkg-config libpq-dev make wget unzip git vim nano nodejs gawk libgdbm-dev libffi-dev
#RUBY
RUN mkdir -p /download
WORKDIR download
RUN wget http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz
RUN tar xvfz ruby-2.1.2.tar.gz
WORKDIR /download/ruby-2.1.2
RUN ./configure
RUN make
RUN make install
RUN gem update --system
RUN gem install bundler
RUN mkdir /rent
WORKDIR /rent
ADD Gemfile /rent/Gemfile
ADD Gemfile.lock /rent/Gemfile.lock
RUN bundle install --deployment
And here is the fig.yml file:
web:
build: .
command: bundle exec rails s -p 3000
volumes:
- .:/rent
ports:
- "3000:3000"
Running fig build clearly shows the app's gems being installed.
Running fig up fails with the message
bundler: command not found: rails
If I run fig run web /bin/bash and check the contents of
/local/lib/ruby/gems/2.1.0/gems
it only has bundler, rdoc, rake and a few others installed.
If I navigate to the app's directory and run the bundle command, it will install the app's gems and I can see that they are installed in the directory above. I can even start the app with rails server.
Why aren't the bundled gems being persisted in the image(container?).
I ran the rails tutuorial from the fig website and didn't have this problem.
Thanks
It seems that the problem was caused by using the --deployment flag with bundle install.
This flag's main effect is to deploy the gems to the vendor/bundle/ directory instead of the normal gem location. I checked and the gems were there, so I'm not sure why ruby couldn't find them.
Anyways, removing --deployment fixed the problem.
If you're using fig and mounted volumes, I found a solution which allows updates to the mounted files in development (like Gemfile.lock when you do fig run web bundle install) while still keeping container caching behavior.
See this for the full thing: https://gist.github.com/fotinakis/04077671bec4edf77c08
It's slightly convoluted, but basically you always install bundler and the gems as the non-root application user:
# Add 'web' user which will run the application.
RUN adduser web --home /home/web --shell /bin/bash --disabled-password --gecos ""
# Add directory where all application code will live and own it by the web user.
RUN mkdir /app
RUN chown -R web:web /app
# Install gems separately here to take advantage of container caching of `bundle install`.
# Also, ensure that gems are installed as the web user and not system-wide so that we can run
# `fig web bundle install` and the web user will have permissions to update the shared Gemfile.lock.
ADD Gemfile /app/
ADD Gemfile.lock /app/
RUN chown -R web:web /app
USER web
ENV HOME /home/web
ENV PATH $PATH:/home/web/.gem/ruby/2.1.0/bin
ENV GEM_HOME /home/web/.gem/ruby/2.1.0
ENV GEM_PATH $GEM_HOME
RUN gem install --user-install bundler
WORKDIR /app/
RUN bundle install
USER root
# Add the whole application source to the image and own it all by web:web.
# Note: this is overwritten in development because fig mounts a shared volume at /app.
ADD . /app/
RUN chown -R web:web /app
Running this will now work and update your local Gemfile.lock:
$ fig run web bundle install

Resources