[Docker] How to build when the source code is bind-mounted on the container

Introduction

Premise

I will not touch on the basic operations of Docker. It is assumed that the source code of the application is mounted in the container and developed by using bind mount.

version information

Docker Engine: 19.03.13

Rough flow

  1. First conclusion
  2. What is a bind mount?
  3. Check the build method step by step
  4. Bonus
  5. Impressions

Goal of this article

Understand the characteristics of bind mount, and you will be able to build and image the entire source of the application.


First conclusion

It is a common technique to bind and mount the source code to a container during development, but it is necessary to devise a way to create an image including the source code when deploying. The method is simple enough to beat, but you can prepare a separate Dockerfile for build and explicitly COPY the source. (I was researching it myself, and I wondered, "Is this really such a simple story ...?")


What is a bind mount?

There are three main volume mount types that can be used with Docker. To explain each difference completely

--Volume --Mount for areas managed by Docker --Multiple containers can be shared --Bind mount --Mount on the path on the host --The host and container can read and write to each other --tmpfs mount --Saved in host memory --What the container uses only while the container is running --Save temporary status and confidential information

image.png

Volumes and bind mounts also have the following features: Quoted from Official Storage Overview

Tips for using bind mounts and volumes When using either bind mount or volume, keep the following in mind:

If you are trying to mount an empty volume on a directory inside a container and a file or directory exists in that directory, that file or directory will be copied into the volume. If the specified volume does not already exist when the container is started, an empty volume will be created. It is used as a method of providing data in advance at the request of the container.

If you are trying to mount a bind mount or a non-empty volume on a directory inside a container and the file or directory exists in that directory, the mount will hide the file or directory. It's the same as if you saved the file to / mnt on your Linux machine and then mounted the USB drive on / mnt. What was in / mnt is hidden by the contents of the USB drive and continues until the USB drive is unmounted. Hidden files are not deleted or modified. However, it cannot be accessed unless the bind mount or volume is unmounted.


Check the build method step by step

situation

It is assumed that you are developing by simply building an Nginx container and mounting the source code on the container. The sample directory structure and Dockerfile are shown below.

Directory structure


project-directory/
  └html/
    └index.html
  └Dockerfile

Dockerfile


FROM nginx
COPY ./html /usr/share/nginx/html
EXPOSE 80

index.html


<!DOCTYPE html>
<head>
<title>ContainerA</title>
</head>
<body>
    <h1>ContainerA!</h1>
</body>

Create a bind-mounted Nginx container with the source code with the following command


docker run --name containerA --mount type=bind,source=(pwd)/html,target=/usr/share/nginx/html -d -p 81:80 nginx

image.png

Command explanation

Create a container with the following options based on DockerHub official repository nginx image

--Specify the container name with --name --Mount the volume with --mount --Volume also has the old option -v or --volume, but officially recommends --mount, so follow it. --type specifies the mount type (this time it is a bind mount, so bind) --source specifies the mount source path (host) --target specifies the mount path (inside the container) --Detach mode with -d (start in background) --Set port forwarding with -p --Associate loclahost: 80 in the container with localhost: 81 of the host

Go to http: // localhost: 81 and try to display the screen

The following screen is displayed image.png

Add wording and make sure it is reflected in the container

index.html


<!DOCTYPE html>
~abridgement~
<body>
    <h1>ContainerA!</h1>
    <p>Add message at Host.</p>
</body>

When you load it again, the added wording is displayed. This also confirms that the host and container are securely bind mounted.

image.png

Build Dockerfile and image each source


docker build -t build_with_bind_data ./

Check the built image

docker image ls

The image build_with_bind_data is built as shown below

image.png

Create a container based on the built image and check if the source is also included


docker run --name containerB -d -p 82:80 build_with_bind_data

image.png

When you access http: // localhost: 82 I was able to confirm that it was exactly the same as what was displayed on Contaier A. image.png

For the time being, if you also check the source inside containerB


docker exec containerB bash -c "cat /usr/share/nginx/html/index.html"

At build time, you can see that the specified directory / file has been copied by the COPY command. image.png

bonus

The container can be imaged with the COMMIT command, but the volume mount data is not included.

I want to solidify the image with the COMMIT command, but this is just an image of the settings and changes inside the container, and the volume was mounted [^ 1] on the __ container. Note that the data is not included in the image created by the commit __ </ font>. Therefore, it is necessary to place the source code of the application with the COPY command at build time.

[^ 1]: The mount type is either volume / bind mount / tmpfs mount.


Impressions

Maybe the content is rudimentary. As an experience of using Docker so far, I did not have the opportunity to build and manage images, so I had a hard time because I did not know the specific method of image conversion including the source. I didn't notice the characteristics of the COMMIT command, and was surprised by the wind," Why doesn't the source be included even if I commit? " However, I read the official commentary carefully and deepened my understanding, so I left it in the article so as not to forget it.

Recommended Posts

[Docker] How to build when the source code is bind-mounted on the container
How to check the logs in the Docker container
[Java] Memo on how to write the source
[IntelliJ IDEA] How to format only local changes when saving the source code
When reading the source code
Time is wrong with the application launched on the Docker container
[Docker] How to access the host from inside the container. http://host.docker.internal:
How to solve when you cannot connect to DB with a new container because the port is assigned to the existing docker container
How to build a Jenkins server with a Docker container on CentOS 7 of VirtualBox and access the Jenkins server from a local PC
How to build vim on Ubuntu 20.04
How to build CloudStack using Docker
When requested access to the resource is denied when pushing with Docker
Install Ubuntu20.04 on RaspberryPi 4 and build Kubernetes to run the container
How to write the view when Vue is introduced in Rails?
How to build an environment with Docker, which is the minimum required to start a Rails application
How the website is displayed on the screen
Docker container build fails to install php-radis
Build Redmine code reading environment on Docker
How to build Rails 6 environment with Docker
How to build a Ruby on Rails environment using Docker (for Docker beginners)
How to build a Ruby on Rails development environment with Docker (Rails 6.x)
How to build a Ruby on Rails development environment with Docker (Rails 5.x)
[Ruby] How to prevent errors when nil is included in the operation
Pg_resetwal can be used to start the PostgreSQL Docker container when WAL is broken and cannot be started.
[swift] How to control the behavior when the back button of NavigationBar is pressed
When I pushed to Docker Hub, I got requested access to the resource is denied
How to deploy a container on AWS Lambda
Add the JDK to the TeamCity build agent container
How to mount the batch file location via WSL2 and start the Docker container
How to get a heapdump from a Docker container
How to display the amount of disk used by Docker container for each container
[Ruby] Meaning of &. How to avoid the error when the receiver (object) is nil
How to delete the database when recreating the application
How to update pre-built files in docker container
[Heroku] How to solve when an error is displayed on git push heroku master
How to set when "The constructor Empty () is not visible" occurs in junit
[Rails] How to build an environment with Docker
How Docker works ~ Implement the container in 60 lines
How to build a Pytorch environment on Ubuntu
How to build the simplest blockchain in Ruby
[Rails] [Docker] Copy and paste is OK! How to build a Rails development environment with Docker
[Docker] How to update using a container on Heroku and how to deal with Migrate Error
How to change the process depending on the list pressed when there are multiple ListViews
[Docker] How to see the contents of Volumes. Start a container with root privileges.
How to deal with `Cannot connect to the Docker daemon at unix: /// var/run/docker.sock. Is the docker daemon running?`
How to fix the problem that the upper half is cut off when using UITabBar
How to identify the cause when GC occurs frequently and CPU usage is high
[Java] How to get the URL of the transition source
When the hover of Eclipse is hard to see
How to build Docker + Springboot app (for basic learning)
How far is the correct answer to divide the process?
How to figure out how much disk Docker is using
How to build docker environment with Gradle for intelliJ
[Ruby on Rails] How to change the column name
Create a Docker container to convert EPS to PGF source
[Docker] Build an Apache container on EC2 using dockerfile
How to build Java development environment with VS Code
[swift5] How to execute processing when tabBar is tapped
Install MySQL 5.6 on CentOS6 [How to specify the version]
BasicDataSourceFactory is ClassNotFoundException when connecting to DB on Tomcat 8
How to install Docker