I learned about Docker when I was studying Rails on my own, but I already built a separate environment on my PC and I'm not sure what's good. I didn't know how to use it, but I needed to use it after joining the company, and I studied with the Udemy video below, so I would like to output it.
Building an application execution environment with Docker starting from scratch
I would like to roughly explain what Docker is and how to use it. Roughly.
There is no point in learning if you don't understand this in the first place.
If you've built a Rails environment, you'll know that you used homebrew (in the case of Mac) to add various things, and you chose a Ruby version.
As I will explain later, if you are using Docker, all you have to do is the command docker-compose up
. It's a moment. (Although you need to install Docker.)
Even if you want to use PostgreSQL, it is troublesome to put PostgreSQL locally, decide the version, pass through the path, etc. It ends with docker-compose up
.
You can build an environment like this with various libraries and frameworks, not limited to Rails. Personally, this is the biggest advantage.
If you want to try something, you need to install various software and it will use the storage of your PC. If you want to install multiple versions (Ruby 2.6, 2.7, etc.), use more storage.
What's more, if you forget what you put in, it will not be erased for the rest of your life, and it will just consume the capacity of your PC.
However, if you use Docker, the environment you used can be disposable, so you will not waste the capacity of your PC. (Docker itself needs to be installed, so that much space is required)
When building an environment locally, various things are built on Windows OS or Mac OS, but when deploying in production, if the virtual machine that builds the production environment is Linux, it was running locally due to the difference in the OS in the first place. Things may get stuck.
Also, if the members who make the same Rails app use different OS and version, it may work or stop working depending on the person.
By using Docker, you can use the same environment again, so if it works locally, it will work in production, and you can easily share the same environment with other people. (To be exact, it's not exactly the same environment, but for now, let's say it's the same environment.)
When I first studied Docker before watching the video, I stumbled upon it quite a bit, but to put it simply, the image is a template and the container is the actual execution environment.
For example, suppose you want to write a resume in Excel and download a template made in Excel on the net. This template is an image. It's a template that someone made using Excel.
Then, download the template and fill in various information locally. The file that you download locally and play around with is the container. The image doesn't change no matter how much you play with the container. Because it is a template on the net, even if you play with it locally, the local file will only change.
Of course, you can also create a template itself (image) and upload it on the net.
Dockerfile is a definition document that creates a template. Sometimes you've downloaded a resume template online, but want to customize it for yourself.
If you only write one, you can add more and more without permission, but since you have to write multiple resumes, you make your own template, then duplicate it and write another resume, right? ..
The Dockerfile creates this template for me.
For reference, the following code is a sample of Dockerfile borrowed from Docker documentation and slightly modified.
#ruby v2.Use 5 images
FROM ruby:2.5
#ruby:2.Add libraries not included in 5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
#Create a directory called myapp
RUN mkdir /myapp
#Move to a directory called myapp (cd myapp)
WORKDIR /myapp
#Copy local Gemfile to myapp
COPY Gemfile /myapp/Gemfile
#Local Gemfile.Copy lock to myapp
COPY Gemfile.lock /myapp/Gemfile.lock
#gem installation
RUN bundle install
#Copy local files to myapp
COPY . /myapp
#I will continue to write other processing.
The original image was only the environment of ruby version 2.5, but you can create a Rails environment by adding various things.
On the other hand, docker-compose is used when creating a container.
Use the following command to create a container (execution environment) from an image (template).
docker run [Image name]
If you add various options, the command will be as follows. (The command is borrowed from Docker documentation)
docker run -e MYVAR1 --env MYVAR2=foo --env-file ./env.list ubuntu bash
It's a hassle to enter this every time, so use docker-compose.
If you write this option in docker-compose.yml, just docker-compose up
will create a container that reflects that option.
In addition, docker-compose allows you to set up multiple containers at the same time. With docker run, you can only set up one container at a time, but if you write in docker-compose, you can set up as many containers as you want at the same time.
It also connects containers without permission.
For example, if you do not connect the rails container and the postgreSQL container, the rails container will not recognize the postgreSQL container and you will not be able to connect forever.
I also borrow a sample docker-compose.yml from the docker documentation (https://docs.docker.com/compose/rails/).
docker-compose.yml
version: "3.9" #Docker to use-compose version
services: #Define the components of the app, that is, the container
db: #Service name (name that appears in logs)
image: postgres #Image to use (postgres that can also be tagged:latest)
volumes: #Specifying a local storage location for persisting data (otherwise the data will be erased if the container is deleted)
- ./tmp/db:/var/lib/postgresql/data
environment: #Environment variable
POSTGRES_PASSWORD: password
web:
build: . #When using a Dockerfile defined by yourself, specify the save location of the Dockerfile
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" #Specify the command when starting the container
volumes:
- .:/myapp
ports: #Specify the port number
- "3000:3000"
depends_on: #Make sure to start this service after the db service has started.
- db
This docker-compose does not write the network settings, but it builds a network called directory name_default
and connects each service without permission.
Thanks to this, it becomes possible to send data from the db service to the web service.
I think it's okay to understand that you can easily set up multiple containers by using docker-compose like this.
In a situation where you study only Rails at the beginning, it is not very useful in the first place, but when you use another language or library, you can quickly build an environment, so it is worth remembering early. I think.
Also, since the Dockerfile itself is like a definition document for environment construction, even if you build the production environment without using Docker, you can basically create the production environment if you build it according to the Dockerfile, so it means learning how to create the production environment. But learning Docker is good.
Recommended Posts