Building a Docker Development Environment (Part 2)
Tags: docker, devops, programming, tutorial
Published: 2024-04-30 14:00:00

## Introduction
Hello, I work as a system engineer in Tokyo and am now mainly developing web applications using Ruby and JavaScript.

I have been using Docker at my workplace for around 2 years now and almost all of my projects are developed using Docker these days. Docker technology has become so helpful that I believe it will be used for a long time.

In my [previous article](https://dev.to/weseek-inc/building-a-docker-development-environment-part-1-3i2e-temp-slug-2870976?preview=66c3d0de4257b518b013e65729031f9e4b7b0a27d03b0d5a7dc19ccff06758a9915755525f4349806eefa5af2003e6db9ac2441ee4d578bbc6dc50d6), I explained Docker Compose. **For this article, I would like to continue the discussion and explain more about Dockerfile.**

---

## What is Dockerfile?
A Dockerfile is a text file into which you can write the commands you want to run when creating an image.

Generally, you could pull the original image from the Docker Hub and then create a new image based on that image, customized to fit your project and development style.

---

## Merits of Dockerfile
First, let’s talk about creating a container without a Dockerfile.

Find and pull the source image of the container from the [Docker Hub](https://hub.docker.com/).

![docker_1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/86tf6rcpkaq94y16mwgx.png)

A container is then created from the pulled image.

![docker_2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iq0z0m673f2lsvjnw4vv.png)

The docker run command combines Docker Create and Docker Start into one command to create and run containers. Note that the -d option runs in the background (detached mode), and the -i and -t options leave it ready to accept commands.

Now you have successfully launched a Ruby container named my-container. If you are not particular about it, using the container you created is enough.

On the other hand, the advantage of using a Dockerfile is that you can write ALL the commands you want to execute in the file when you build the image. This allows you to pull images from DockerHub and customize them to fit your project and development style.

For example, when launching a Ruby container, you can use COPY or CMD in the Dockerfile to copy the Gemfile and Gemfile. lock into the container and run Bundle Install.

If you organize the Dockerfile well, you can also start the application by doing all the initial startup processes when the container is launched.

---

## Dockerfile Commands
In this case, I prepared the following Dockerfile:

![dockerfile](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7a4ssrpl98xkdlgrgy30.png)

### FROM
In the Dockerfile, we usually use FROM first. FROM sets up the base image to be used in subsequent instructions. When the Dockerfile is executed, it first looks for the image in the environment where it was executed. If the image is not found, it will look for the image in the Docker Hub and download it.

Subsequent instructions are executed sequentially for the image specified in FROM. The build stage can be named by adding “AS name” after FROM. You can use any name other than “name” here. By adding a name, the name can be referenced in subsequent like FROM and COPY, and multiple FROMs can be defined and managed in the Dockerfile.

### COPY
Copy files and folders. Note that only files and directories in the directory where the Dockerfile is placed can be copied.

### ADD
Adds files and folders. Unlike COPY, if the file is a compressed file, it would be automatically decompressed. In addition, by specifying a URL instead of a file name, a remote file can be downloaded and added.

### WORKDIR
Specifies the directory where RUN, CMD, ENTRYPOINT, COPY, and ADD are executed. If the directory specified in WORKDIR does not exist, a new directory will be created.

### RUN
The commands you specify will be executed at the time the image is built.
This is where you write the commands you want to run at the time of the image, such as installing packages, copying files, etc.

### CMD
This differs from RUN, with CMD specified command executed when the container is started. The main purpose of a CMD is to specify the initial configuration when the container is run, and it can only be used once in a Dockerfile. If multiple CMDs exist, the last CMD will take effect.

### ENTRYPOINT
Like CMD, this command is executed when the container is started. However, in the case of CMD, if a command is specified after the docker run, CMD will be overwritten and executed.

![entrypoint_1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/58a6mcc9eljjycm7dh5a.png)

Like the example, if the above command is used to launch a container, the CMD in the Dockerfile will be overwritten and the ls command will be executed.

If ENTRYPOINT is used instead of CMD, the command specified in ENTRYPOINT will be executed without overwriting. In other words, the command specified by ENTRYPOINT is always executed.

If ENTRYPOINT and CMD are used together, a command that is a combination of both will be executed.

![entrypoint_2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1tc7xz6wyb93byeqfuop.png)

For example, if you put such a description in the Dockerfile, “ls -a” will be executed when the container is started. The CMD part can be overwritten, so you can change -a to another option and have it run, but you will probably never use it.

### USER
Specifies the user who executes commands such as RUN and CMD. The command is automatically executed as the root user if USER is not specified.

### LABEL
Add metadata to the image. Specifically, you can describe the name, version, and producer information.

### ENV
Set environment variables. The set environment variables can be overwritten later.

---
## Summary
Use the docker-compose.yml we prepared last time and the Dockerfile this time and run the following code:

![docker-compose](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jokesfuoa2ob5z6tz97p.png)

Now we successfully built a Rails development environment.

---
## About Us💡

In addition, we want to introduce a little more about GROWI, an open software developed by **WESEEK, Inc**.

**GROWI** is a wiki service with features-rich support for efficient information storage within the company. It also boasts high security and various authentication methods are available to simplify authentication management, including **LDAP/OAuth/SAML**.

**GROWI** originated in Japan and GROWI OSS is **FREE** for anyone to [download](https://docs.growi.org/en/admin-guide/?utm_source=dev+community&utm_medium=referral&utm_campaign=Building_a_Docker_Development_Environment_Part_2) and use **in English**.

For more information, go to [GROWI.org](https://growi.org/en/?utm_source=dev+community&utm_medium=referral&utm_campaign=Building_a_Docker_Development_Environment_Part_2) to learn more about us. You can also follow our [Facebook](https://www.facebook.com/people/GROWIcloud/100089272547238/) to see updates about our service.

![GROWI.org](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1rhpa0qcdukeall2vfsj.png)