Step by step guide to dockerize Rails application
24 Jun 2023 - Chandan J
- Create
Dockerfile
in Rails application’s root directory# cd to application root directory $> touch Dockerfile
- Edit the
Dockerfile
. You can remove the comments, as they’re just for your understanding purpose.
# Install required image of Ruby
# Every Dockerfile start with "FROM" base image
FROM ruby:3.2.2
# Download latest package information
# -y : Yes to any prompt, -qq : Really queit mode
RUN apt-get update -yqq
# install nodejs and DO NOT install other recommended packages as we don't need them
# NOTE: nodejs is NOT required with Rails 7
RUN apt-get install -yqq --no-install-recommends nodejs
# Copy the all files in current folder (.) i.e. Application root to `/usr/src/app`
COPY . /usr/src/app
# docker run [OPTIONS] <our custom image> bin/rails server
# This command will fail, because by default container's working directory is `/`
# which doesn't have our rails application. Our rails application is IN `/usr/src/app`
# Thus change the working directory with WORKDIR
WORKDIR /usr/src/app
# Now we can run any command with `RUN`
RUN bundle install
3 Build the image
# docker build [options] path/to/build/directory
# In your application root directory, run docker build command
$> docker build .
[+] Building 32.4s (11/11) FINISHED
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 234B 0.0s
=> [internal] load metadata for docker.io/library/ruby:3.2.2 0.0s
=> [1/6] FROM docker.io/library/ruby:3.2.2 0.0s
=> [internal] load build context 1.4s
=> => transferring context: 21.90MB 1.4s
=> [2/6] RUN apt-get update -yqq 3.5s
=> [3/6] RUN apt-get install -yqq --no-install-recommends nodejs 2.9s
=> [4/6] COPY . /usr/src/app 0.7s
=> [5/6] WORKDIR /usr/src/app 0.0s
=> [6/6] RUN bundle install 24.7s
=> exporting to image 0.6s
=> => exporting layers 0.6s
=> => writing image sha256:e6ed3b8666fb59cwe9f9217549764af3cbd45d3b9b04e17f35eed04d0x7e14d21 0.0s
- Where is the image built?
# Notice the IMAGE ID (e6ed3b8666fb) and the last line of our `docker build .` image id.
$➜ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> e6ed3b8666fb 31 minutes ago 1.01GB
ambassador/telepresence-docker-extension 1.0.9 a3b57dd2c34f 11 days ago 418MB
- Run the image
$> docker run -p 3000:3000 e6ed3b8666fb \
bin/rails s -b 0.0.0.0
=> Booting Puma
=> Rails 7.0.5 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.6.6 (ruby 3.2.2-p53) ("Birdie's Version")
* Min threads: 5
* Max threads: 5
* Environment: development
* PID: 1
* Listening on http://0.0.0.0:3000
Use Ctrl-C to stop
Now go to localhost:3000
and you can see the Rails application’s homepage.
We need to start rails s
with binding -b 0.0.0.0
, because by default rails s - starts on localhost, i.e. 127.0.0.1.
This ip can be access only from the machine, where the rails server is running.
Our docker image is running on Linux distro, i.e. light-weight VM. So, our host machine can’t access this localhost
.
We’re binding to 0.0.0.0
, which is equivalent to all IPv4 address on this machine
.
The actual IP address of container can be found with following:
± ➜ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b95d7d9faae e6ed3b8666fb "bin/rails s -b 0.0.…" 15 minutes ago Up 15 minutes 0.0.0.0:3000->3000/tcp nostalgic_chatterjee
± ➜ docker inspect --format \
> '' 2b95d7d9faae
172.17.0.2
Give a name to your docker image:
$➜ docker tag e6ed3b8666fb orendaa
$➜ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
orendaa latest e6ed3b8666fb About an hour ago 1.01GB
$➜ docker tag e6ed3b8666fb orendaa:1.0.0
# Notice both latest and 1.0.0 has same IMAGE ID, as they're same image
$➜ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
orendaa 1.0.0 e6ed3b8666fb About an hour ago 1.01GB
orendaa latest e6ed3b8666fb About an hour ago 1.01GB
You can provide tag while building the image:
# Single tag - latest
$> docker build -t orendaa .
# Multiple tags
$> docker build -t orendaa -t orendaa:1.0.0 .
Now you can run your specific image:
$> docker run -p 3000:3000 orendaa:1.0.0 \
bin/rails s -b 0.0.0.0