Skip to main content Link Search Menu Expand Document (external link)

Create new dockerized Ruby on Rails project.

This manual is intended for newcomers who wish to begin building their first Rails application. It makes no assumption that you have any prior knowledge of Rails and is beginner friendly.

Table of contents

  1. Before you start
  2. How to create a new dockerized rails project?
  3. Docker Configuration
    1. What is a Dockerfile?
    2. Dockerfile Instructions
    3. What is a Compose File?
    4. Compose File Directives and Attributes
    5. Database YML

Before you start

Please check the following:

  • Check if there’s already a docker application installed and check for the docker images.
  • You can check by running command docker -v docker images on your terminal.
  • Make sure you have docker-compose.yml file and docker folder that contains app/Dockerfile. If none, it can be downloaded here ~ Basic Composer.
  • Further explanation of Docker Configuration will be discussed at the end of this article.

How to create a new dockerized rails project?

  1. Open iTerm Application as your Terminal, it can be seen in the Dock (Taskbar).

  2. Make your your project folder: Type mkdir KodaCamp, hit enter.

     $~> mkdir KodaCamp
    
  3. Open Rubymine Application, it can be seen in Dock (Taskbar).

  4. Open your project in Rubymine by clicking Open then locate your project directory. Click trust project if a prompt appeared.

  5. Copy docker-compose.yml and docker folder to your new project (KodaCamp).
    # docker/app/Dockerfile
       
    FROM ruby:3.0.4
    RUN bundle config --global frozen 0
       
    RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
    curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
    curl -fsSL https://deb.nodesource.com/setup_lts.x | bash && \
    apt-get update && apt-get install -y python2.7 nodejs mariadb-client cron yarn --no-install-recommends && \
    rm -rf /var/lib/apt/lists/*
       
    ENV APP_PATH /usr/src/app
    RUN mkdir -p $APP_PATH
    WORKDIR $APP_PATH
       
    COPY Gemfile* $APP_PATH/
    RUN gem update --system && bundle install
    COPY . $APP_PATH/
       
    EXPOSE 3000
    
    # docker-compose.yml
       
    version: '3'
    services:
      db:
        image: mariadb:10.5.13
        restart: always
        ports:
          - 3306:3306
        environment:
          MYSQL_ROOT_PASSWORD: qwer4321
        command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-authentication-plugin=mysql_native_password
        volumes:
          - ./tmp/db:/var/lib/mysql
          - ./docker/db:/docker-entrypoint-initdb.d
       
      app:
        build:
          context: .
          dockerfile: ./docker/app/Dockerfile
        stdin_open: true
        tty: true
        restart: always
        volumes:
          - .:/usr/src/app
          - ~/.ssh:/root/.ssh:ro
          - bundle-volume:/usr/local/bundle
        ports:
          - "3000:3000"
          - "1234:1234"
        environment:
          - REDIS_URL_CACHING=redis://redis:6379/0
        depends_on:
          - db
          - redis
       
      # Redis
      redis:
        image: redis
        command: ["redis-server", "--appendonly", "yes"]
        ports:
          - "6379:6379"
       
    #Volumes
    volumes:
      bundle-volume:
    
  6. Create new Gemfile, touch Gemfile.
    Note: It will automatically create a Gemfile.lock file.

     $~/KodaCamp> touch Gemfile
    
  7. Add the following codes to Gemfile:

    # Gemfile
       
    source 'https://rubygems.org'
    gem 'rails', '~> 7.0.4'
    
  8. Type docker-compose build on your terminal and hit enter to build your project. Wait for it to finish.

     $~/KodaCamp> docker-compose build
    [+] Building 13.6s (13/13) FINISHED                                                                                                                                                                   
    => [internal] load build definition from Dockerfile                                                                                                                                             0.0s
    => => transferring dockerfile: 646B                                                                                                                                                             0.0s
    => [internal] load .dockerignore                                                                                                                                                                0.0s
    => => transferring context: 2B                                                                                                                                                                  0.0s
    => [internal] load metadata for docker.io/library/ruby:3.0.4                                                                                                                                    0.0s
    => [1/8] FROM docker.io/library/ruby:3.0.4                                                                                                                                                      0.0s
    => [internal] load build context                                                                                                                                                                0.0s
    => => transferring context: 4.11kB                                                                                                                                                              0.0s
    => CACHED [2/8] RUN bundle config --global frozen 0                                                                                                                                             0.0s
    => CACHED [3/8] RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list &&     curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - &&   0.0s
    => CACHED [4/8] RUN mkdir -p /usr/src/app                                                                                                                                                       0.0s
    => CACHED [5/8] WORKDIR /usr/src/app                                                                                                                                                            0.0s
    => [6/8] COPY Gemfile* /usr/src/app/                                                                                                                                                            0.0s
    => [7/8] RUN gem update --system && bundle install                                                                                                                                             12.8s
    => [8/8] COPY . /usr/src/app/                                                                                                                                                                   0.0s
    => exporting to image                                                                                                                                                                           0.6s
    => => exporting layers                                                                                                                                                                          0.6s
    => => writing image sha256:35e23afbbefda3207afc53ad75328bacfd5f10f37370a1e5abe9c97a8463c4c0                                                                                                     0.0s
    => => naming to docker.io/library/kodacamp-app
    
  9. Type docker-compose run app rails new . -d mysql -T -j esbuild -c bootstrap on your terminal and hit enter.
    After a second, it will ask for your Gemfile to be overwritten, type Y and hit enter.

     $~/KodaCamp> docker-compose run app rails new . -d mysql -T -j esbuild -c bootstrap
    [+] Running 2/2
     ⠿ Container kodacamp-redis-1  Created                                                                   0.0s
     ⠿ Container kodacamp-db-1     Recreated                                                                 0.1s
    [+] Running 2/2
     ⠿ Container kodacamp-redis-1  Started                                                                   0.4s
     ⠿ Container kodacamp-db-1     Started                                                                   0.4s
           exist  
          create  README.md
          create  Rakefile
          create  .ruby-version
          create  config.ru
          create  .gitignore
          create  .gitattributes
        conflict  Gemfile
    Overwrite /usr/src/app/Gemfile? (enter "h" for help) [Ynaqdhm] Y
    ...
    Done in 12.58s.
    
  10. Setup database.yml that contains your database config, change the content to:

    # config/database.yml
       
    default: &default
       adapter: mysql2
       encoding: utf8mb4
       pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
       username: root
    -  password:
    -  host: localhost
    +  password: qwer4321
    +  host: db
       
    development:
       <<: *default
    -  database: app
    +  database: kodacamp
       
    test:
       <<: *default
    -  database: app_test
    +  database: kodacamp_test
       
    production:
       <<: *default
    -  database: app_production
    +  database: kodacamp_production
       username: app
       password: <%= ENV["APP_DATABASE_PASSWORD"] %>
    
  11. Edit Procfile.dev, bind localhost IP.

    # Procfile.dev
       
    - web: bin/rails server -p 3000
    + web: bin/rails server -p 3000 -b '0.0.0.0'
      js: yarn build --watch
      css: yarn build:css --watch
    
  12. Type docker-compose up -d on your terminal and hit enter to up your container.

     $~/KodaCamp> docker-compose up -d
    [+] Running 3/3
     ⠿ Container kodacamp-redis-1  Running    0.0s
     ⠿ Container kodacamp-db-1     Running    0.0s
     ⠿ Container kodacamp-app-1    Started
    
  13. Open your terminal within container with docker-compose exec app bash.

     $~/KodaCamp> docker-compose exec app bash
     root@0122:/usr/src/app#
    
  14. Run bundle install in container to install the gems of your Gemfile project.

     root@0122:/usr/src/app# bundle install
    Using rake 13.0.6
    Using concurrent-ruby 1.1.10
    Using i18n 1.12.0
    ...
    Using web-console 4.2.0
    Bundle complete! 13 Gemfile dependencies, 61 gems now installed.
    Use `bundle info [gemname]` to see where a bundled gem is installed.
    
  15. On your container, run rails db:create to create database and rails db:migrate to run migration files.

     root@0122:/usr/src/app# rails db:create
    Created database 'kodacamp'
    Created database 'kodacamp_test'
     root@0122:/usr/src/app# rails db:migrate
    
  16. Run bin/dev to up your rails project.

     root@0122:/usr/src/app# bin/dev
    started with pid 666
    started with pid 668
    started with pid 672
    yarn run v1.22.19
    $ esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets --watch
    yarn run v1.22.19
    $ sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules --watch
    [watch] build finished, watching for changes...
    => Booting Puma
    => Rails 7.0.4 application starting in development
    => Run `bin/rails server --help` for more startup options
    Puma starting in single mode...
    * Puma version: 5.6.5 (ruby 3.0.4-p208) ("Birdie's Version")
    *  Min threads: 5
    *  Max threads: 5
    *  Environment: development
    *          PID: 667
    * Listening on http://0.0.0.0:3000
    Use Ctrl-C to stop
    Sass is watching for changes. Press Ctrl-C to stop.
    
  17. Try localhost:3000 on your browser and see if it works.

Docker Configuration

What is a Dockerfile?

Docker can build images automatically by reading the instructions from a Dockerfile.
The Dockerfile is essentially the build instructions to build the image.

Dockerfile Instructions

  1. FROM Instruction
    The first part is the FROM command, which tells us what image to base this off of. This is the multi-layered approach that makes Docker so efficient and powerful. In this instance, we are using the ruby:3.0.4 Docker image, which again references a Dockerfile to automate the build process.

  2. RUN Instruction
    The next set of calls are the RUN commands.
    This is what runs within the container at build time.

  3. ENV Instruction
    The ENV command sets the environment variable <key> to the value <value>.

  4. WORKDIR Instruction
    The WORKDIR instruction in the Dockerfile establishes the working directory for any RUN, CMD, ENTRYPOINT, COPY, and ADD instructions that come after it.
    WORKDIR will be created if it doesn’t already exist, regardless of not being used in any Dockerfile instructions.

  5. COPY Instruction
    The COPY command is simply as it sounds. It can copy a file (in the same directory as the Dockerfile) to the container.

  6. EXPOSE Instruction
    The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. You can specify whether the port listens on TCP or UDP, and the default is TCP if the protocol is not specified.

  7. CMD Instruction
    CMD is the default argument passed to the ENTRYPOINT.
    The main purpose of a CMD is to provide defaults for an executing container.
    These defaults can include an executable, or they can omit the executable, in which case you must specify an ENTRYPOINT instruction as well.

What is a Compose File?

A YAML file called Compose contains information about the version (DEPRECATED), services (REQUIRED), networks, volumes, configurations, and secrets. Compose files have a default path of compose.yaml (preferred) or compose.yml in the working directory.

Compose File Directives and Attributes

  1. Version
    A version is used for defining and mentioning the version of the schema.

  2. Services
    In a compose file, services represent the containers that will be created in the application. A typical compose file contains an app/web and db services.

  3. Image
    Attribute image is used for pulling a service Image that is already been published in the Docker Hub.

  4. Build
    Attribute build specifies the build configuration for creating container image from source.

  5. Ports
    ports keyword exposes container ports. It allows us to run different containers exposing the same ports without collisions.

  6. Environment
    The environment attribute is used to migrate the environment variable definitions.

  7. Command
    Attribute command is used for executing commands on your container.

  8. Volumes
    When you execute a docker-compose command, the volumes directive in compose file mounts source directories or volumes from your computer at target paths inside the container. Volumes are physical areas of disk space shared between the host and a container, or even between containers. In other words, a volume is a shared directory in the host, visible from some or all containers.

  9. Stdi Open
    Attribute stdin_open configures service containers to run with an allocated stdin.

  10. Tty
    A tty attribute configures service container to run with a TTY.

  11. Depends On
    The depends_on attribute creates a dependency chain between our services so that some services get loaded before (and unloaded after) other ones.

Database YML

In every new Rails applications, a file called database.yml is created in the /config directory that specifies the various database options your application will utilize. All the information required to access your database can be specified in the config/database.yml file.


Back to top

Copyright © 2020-2022 Secure Smarter Service, Inc. This site is powered by KodaCamp.