Problem:
So let's understand the problem first. Whenever you try to spin up your application it takes so much time. I think I understand your problem very well.
- download gem from internet
- install and spinup application
Possible solutions:
This is a performance of docker files. we have 2 areas which are creating the problems, and 2 different solutions
Solutions:
Download gem files locally put in a folder and in dockerfile copy those gem files inside the container and then install.
Create a base image for your application. Create a base image from Ruby/any other you like and install your gems either using the above method:
- copy
gems from the local folder and then paste inside the container
or
- Use the
RUN command to install the gems. Whatever you like.
This will be a one time process. With this, you can have your base image which already contains your time-consuming gems installed. Now inside your application dockerfile (which is a responsible for the startup the application), you just need to use your own created base image instead of Ruby or Linux from Docker Hub
We will see how to build your own base pre-configured image.
Let us see step by step.
Let's follow this GitHub repo: https://github.com/dupinder/docker-ruby-gem-game
Folder Structure (This will help to understand this article)
- application/dockerfile
- gems/download and place local gems
- dockerfile
- Create a base image and install local gems inside docker container.
dockerfile
FROM ruby:latest
RUN mkdir -p /gems
COPY /gems/grpc-1.28.0-universal-darwin.gem /gems/grpc-1.28.0-universal-darwin.gem
COPY /gems/sassc-2.2.1.gem /gems/sassc-2.2.1.gem
WORKDIR /gems
RUN gem install --force --local *.gem
Build an image from this dockerfile using follwing command
docker build --rm -f "dockerfile" -t ruby-gem-base-image:latest "."
Step 1:
I am using the base image as ruby, you can your whatever you want if you are using Linux then in next step you need to install Ruby
Step 2: Create a folder name gems in the container.
- Step 3 & 4: Copy the Gems you need to install inside the container from local directory to the directory inside
docker container.
- Step 5 & 6: Change the working directory to gems, because we want to install gems place inside this directory, So next command is
gem install --force --local *.gem which help to install gems inside a local directory.
With this, we solved 50% time-consumption. Now docker will never download gems from internet each time and install.
Now let us check is there any of our required gems installed our not. For that:
Run command docker images we will have our newly build image ruby-gem-base-image

Run container in detached mode, so that we can exec later on docker run -it -d ruby-gem-base-image
Run docker ps to get container ID.
- Run
exec as bash inside container docker exec -it d28234630343 bash.
- Run
gem list This will print a list of gems installed, and you will see your required gems there.

See your gems are installed from local directory.
If you follow these steps your problem is resolved. But Now you need if before starting your app docker container already have installed gems.
For this problem, we can use ruby-gem-base-image image as our ruby application base image. If you remember GitHub repo we have an application directory which has one dockerfile if we see that.
FROM ruby-gem-base-image:latest
CMD ["gem", "list"]
This is your dockerfile which can be used when you want to deploy an application, Use prebuilt docker image which has your gems.
I write the task gem list to check is this container have gems from parent image or not.
I think this is a bit clear. Your problem will be resolved with this.
If you need any other help or need help to understand this process, please ask.
---------Dupinder.