参考:https://docs.docker.com/get-started/06_bind_mounts/
参考:https://www.cnblogs.com/jasontarry/p/15516221.html
参考:https://stackoverflow.com/questions/69496662/are-bind-mounts-and-host-volumes-the-same-thing-in-docker
Contents
Use bind mounts
In the previous chapter, we talked about and used a volume mount to persist the data in our database. A volume mount is a great choice when you need somewhere persistent to store your application data.
A bind mount is another type of mount, which lets you share a directory from the host’s filesystem into the container. When working on an application, you can use a bind mount to mount source code into the container. The container sees the changes you make to the code immediately, as soon as you save a file. This means that you can run processes in the container that watch for filesystem changes and respond to them.
In this chapter, we’ll see how we can use bind mounts and a tool called nodemon to watch for file changes, and then restart the application automatically. There are equivalent tools in most other languages and frameworks.
Quick volume type comparisons
The following table outlines the main differences between volume mounts and bind mounts.
Named volumes | Bind mounts | |
---|---|---|
Host location | Docker chooses | You decide |
Mount example (using --mount ) |
type=volume,src=my-volume,target=/usr/local/data |
type=bind,src=/path/to/data,target=/usr/local/data |
Populates new volume with container contents | Yes | No |
Supports Volume Drivers | Yes | No |
注意这里Named volumes支持“Populates new volume with container contents”, 也就是用容器中的数据初始化一个volume。
Trying out bind mounts
Before looking at how we can use bind mounts for developing our application, let’s run a quick experiment to get a practical understanding of how bind mounts work.
If you’re following these steps on Windows, make sure to use PowerShell and not command prompt (cmd
).
-
Open a terminal and make sure your current working directory is in the
app
directory of the getting started repository. -
Run the following command to start
bash
in anubuntu
container with a bind mount.$ docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash
The
--mount
option tells Docker to create a bind mount, wheresrc
is the current working directory on your host machine (getting-started/app
), andtarget
is where that directory should appear inside the container (/src
). -
After running the command, Docker starts an interactive
bash
session in the root directory of the container’s filesystem.root@ac1237fad8db:/# pwd / root@ac1237fad8db:/# ls bin dev home media opt root sbin srv tmp var boot etc lib mnt proc run src sys usr
-
Now, change directory in the
src
directory.This is the directory that you mounted when starting the container. Listing the contents of this directory displays the same files as in the
getting-started/app
directory on your host machine.root@ac1237fad8db:/# cd src root@ac1237fad8db:/src# ls Dockerfile node_modules package.json spec src yarn.lock
-
Create a new file named
myfile.txt
.root@ac1237fad8db:/src# touch myfile.txt root@ac1237fad8db:/src# ls Dockerfile myfile.txt node_modules package.json spec src yarn.lock
-
Now if you open this directory on the host, you’ll see the
myfile.txt
file has been created in the directory.File viewer on the host machine that sees the file created from the container -
From the host, delete the
myfile.txt
file. -
In the container, list the contents of the
app
directory once more. You’ll see that the file is now gone.root@ac1237fad8db:/src# ls Dockerfile node_modules package.json spec src yarn.lock
-
Stop the interactive container session with
Ctrl
+D
.
And that’s all for a brief introduction to bind mounts. This procedure demonstrated how files are shared between the host and the container, and how changes are immediately reflected on both sides. Now let’s see how we can use bind mounts to develop software.
Run your app in a development container
The following steps describe how to run a development container with a bind mount that does the following:
- Mount our source code into the container
- Install all dependencies
- Start
nodemon
to watch for filesystem changes
So, let’s do it!
-
Make sure you don’t have any
getting-started
containers currently running. -
Run the following command from the
getting-started/app
directory.If you are using an Mac or Linux device, then use the following command.
$ docker run -dp 3000:3000 \ -w /app --mount type=bind,src="$(pwd)",target=/app \ node:18-alpine \ sh -c "yarn install && yarn run dev"
If you are using Windows, then use the following command in PowerShell.
$ docker run -dp 3000:3000 ` -w /app --mount type=bind,src="$(pwd)",target=/app ` node:18-alpine ` sh -c "yarn install && yarn run dev"
-dp 3000:3000
– same as before. Run in detached (background) mode and create a port mapping-w /app
– sets the “working directory” or the current directory that the command will run from--mount type=bind,src="$(pwd)",target=/app
– bind mount the current directory from the host into the/app
directory in the containernode:18-alpine
– the image to use. Note that this is the base image for our app from the Dockerfilesh -c "yarn install && yarn run dev"
– the command. We’re starting a shell usingsh
(alpine doesn’t havebash
) and runningyarn install
to install packages and then runningyarn run dev
to start the development server. If we look in thepackage.json
, we’ll see that thedev
script startsnodemon
.
-
You can watch the logs using
docker logs
. You’ll know you’re ready to go when you see this:$ docker logs -f <container-id> nodemon src/index.js [nodemon] 2.0.20 [nodemon] to restart at any time, enter `rs` [nodemon] watching dir(s): *.* [nodemon] starting `node src/index.js` Using sqlite database at /etc/todos/todo.db Listening on port 3000
When you’re done watching the logs, exit out by hitting
Ctrl
+C
. -
Now, make a change to the app. In the
src/static/js/app.js
file, on line 109, change the “Add Item” button to simply say “Add”:- {submitting ? 'Adding...' : 'Add Item'} + {submitting ? 'Adding...' : 'Add'}
Save the file.
-
Refresh the page in your web browser, and you should see the change reflected almost immediately. It might take a few seconds for the Node server to restart. If you get an error, try refreshing after a few seconds.
Screenshot of updated label for Add button -
Feel free to make any other changes you’d like to make. Each time you make a change and save a file, the
nodemon
process restarts the app inside the container automatically. When you’re done, stop the container and build your new image using:$ docker build -t getting-started .
Using bind mounts is common for local development setups. The advantage is that the development machine doesn’t need to have all of the build tools and environments installed. With a single docker run
command, dependencies and tools are pulled and ready to go. We’ll talk about Docker Compose in a future step, as this will help simplify our commands (we’re already getting a lot of flags).
In addition to volume mounts and bind mounts, Docker also supports other mount types and storage drivers for handling more complex and specialized use cases. To learn more about the advanced storage concepts, see Manage data in Docker.
发表回复