In this article, I will introduce how to build a development environment for Ruby on Rails (hereinafter, rails) 5.x series using Docker.
Most rails beginners usually install it directly on their machine to build a development environment. However, if you stumble due to a subtle environment (Ruby version, environment variables, etc.) I think it will take a lot of time to troubleshoot.
So, by building a rails environment on the virtual environment with Docker Equal behavior can be achieved in any development environment on any machine, avoiding errors due to environmental differences. It is also an advantage that you can reset once at worst when you mess with the environment too much.
Also, when trying to publish the created application to the outside as a production environment You can run it as a stable application by minimizing the difference between the development environment and the production environment. You may find it difficult to create a virtual environment with Docker and publish it, Recently, even cloud services such as AWS have services such as ECS that can execute Docker containers as they are. It's getting easier to publish the environment created with Docker.
You have Docker installed on your machine
If you don't have Docker installed, download the Docker installer from the official website and install it. → Docker Official
Also, create an arbitrary working folder. Here, we will create a folder called "rails-docker" and work in it.
$ mkdir rails-docker
$ cd rails-docker
Prepare the following four empty files in rails-docker. If you are using VScode, you can create it by creating a new file, You can also use the touch command from your Mac terminal.
.
├── Dockerfile #Create New
├── Gemfile #Create New
├── Gemfile.lock #Create New
└── docker-compose.yml #Create New
Docker builds the container based on a file called Dockerfile, A Docker Image (container template) will be created.
First, write the full text of the Dockerfile. The version of Ruby used is 2.7.0.
FROM ruby:2.7.0
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
Although it is a bullet point, I will explain the meaning of each.
In Ruby, you can define the gem you want to use in your environment with a file called Gemfile.
A gem is a Ruby library. gem is managed by a package management system for Ruby called RubyGems, and can be installed through the gem command provided by RubyGems.
source 'https://rubygems.org'
gem 'rails', '5.2.1'
I will explain a little again.
If you run the "bundle install" command in the directory where the Gemfile is, You can install the defined gem according to the definition in the Gemfile.
For the Docker file I mentioned earlier, copy the Gemfile to the working directory of the container. You specified to run bundle install in that folder, didn't you?
In fact, Gemfile.lock doesn't need to write anything at first. This is not a file that you edit directly After running bundle install based on Gemfile The installed gems will now be listed in Gemfile.lock.
To use it, refer to Gemfile.lock to find out the installed gem and version. You can also run bundle install from Gemfile.lock Gemfile.lock is used when you want to recreate the exact same environment or when developing with a large number of people.
Isn't it just a Gemfile? As a supplement to those who thought that it was sharp, one of the reasons is that Gemfile can actually be written in this way.
gem 'rails', '~> 5.2.1'
In this case, the version of rails installed by bundle install is 5.2.1 or higher The version that can actually be installed (published) depends on the time.
However, in Gemfile.lock, when you try to install according to Gemfile, the gem itself and the specific version actually installed It even records the packages that were installed for accompanying needs.
To summarize a little, Gemfile is a "list of gems needed by your app", On the other hand, Gemfile.lock will contain "information on the gem actually installed as a result of following the Gemfile".
This yml file is used by Docker Compose.
Docker Compose is about applications that consist of multiple containers It is a tool for managing such as building Docker image and starting / stopping each container.
In Docker Compose, definitions for multiple containers, including options for Docker build and container startup, are written in a file called docker-compose.yml. You can use it to build Docker images and start containers.
If you want to run Rails by itself like a development environment, you can just use Dockerfile. In addition to the application server for running Rails A web server for accepting access from the Internet when actually publishing, We may also prepare a database server for storing and processing data.
docker-compose.yml
version: '3'
services:
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/app
ports:
- 3000:3000
depends_on:
- db
tty: true
stdin_open: true
db:
image: mysql:5.7
volumes:
- db-volume:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
db-volume:
Since rails also requires a database, we will build a container for a database server using MySQL as well as a web server. Although it is not explained in detail here, the database server (container) with which rails is linked is specified by name in "depends_on" in the column called web.
Execute the following docker-compose command in the folder (rails-docker folder) where docker-compose.yml is located.
$ docker-compose run web rails new . --force --database=mysql
I will explain how to read the command, including options ↓
--docker-compose: Using a tool called docker-compose --run: Run the following command --web: in a web container --rails new: create a new project with rails --.: For the current directory ---- force: Overwrite existing files (here Gemfile, Gemfile.lock) ---- database = mysql: However, use MySQL for rails database
It has the meaning.
If you execute this one-line command, it will take a few minutes to process, so wait patiently while eating chocolate.
Installation of gem added to Gemfile, And run build to bring the created files into the container.
$ docker-compose build
After the build is complete, edit the settings in the database file used by rails. The target file is ** database.yml ** in the config directory.
config/database.yml
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: password #add to
host: db #Change
The password must match the password specified in docker-compose.yml.
docker-compose.yml
...
environment:
MYSQL_ROOT_PASSWORD: password #Match here
...
Also, the host field sets the MySQL container name.
To start the container, run the following command:
$ docker-compose up -d
docker-compose up is a command to start a container based on docker-compose.yml It can be started in the background with the option "-d".
Now that the container has just started and the database has not been created Run the following command to create the database.
$ docker-compose run web bundle exec rails db:create
It is a process to execute rails db: create (= create a new database) in the web container running rails.
You have successfully started the rails development server. Enter ** localhost: 3000 ** in the address bar of your browser and check the startup.
In rails, if you see the familiar screen, you're done.
To stop the development server, execute the following command to stop the containers at once.
$ docker-compose down
If you want to start it again, run docker-comopose up -d.
The set of files created by this is listed on Github. If you don't understand the folder structure, or if you want to compare and see if it works in your environment, please refer to it.
Recommended Posts