持久化应用数据
前面我们注意到,如果我们删除重建container的话,我们的todo-list应用的数据会被擦除。(但是停止重启不会擦除)
容器的文件系统
when a container runs, it uses the various layers from a image for its filesystem. Each container also gets its own “scratch space” to create/update/remove files. Any changes won’t be seen in another container, even if they are using the same image.
举个例子
-
Start an
ubuntu
container that will create a file named/data.txt
with a random number between 1 and 10000.docker run -d ubuntu:16.04 bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
In case you’re curious about the command, we’re starting a bash shell and invoking two commands (why we have the
&&
). The first portion picks a single random number and write it to/data.txt
. The second command is simply watching a file to keep the container running. -
Validate that you can see the output by accessing the terminal in the container. Use the command below:
docker exec <container-id> cat /data.txt
You should see a random number.
-
Now, let’s start another
ubuntu
container(the same image) and we’ll see we don’t have the same filedocker run -it ubuntu:16.04 ls /
And look! There is no
data.txt
file there. That’s beacase it was written to the scratch space for only the first container.
持久化 todo-app数据的方式
挂载卷、挂载命名挂载、使用外部数据库
By default, the todo app stores its data in a SQLite database at /etc/todos/todo.db
in the container’s filesystem. If you’re not familar with SQLite , no worries! It’s simply a relational database which all of the data is stored in a single file. While this isn’t the best for large-scale applications. it works for small demos. We’ll talk about switching this to a different database engine later.
With the database being a single file, if we can persist that file on the host and make it available to the next container, it should be able to pick up where the last on left off. By creating a volume aand attaching (often called “mounting”) it to the directory the data is stored in , we can persist the data. As our conatiner writes to the todo.db
file, it will be persisted to the host in the volume.
As mentioned, we are going to use a volume mount. Think of a volume mount as an opaque bucket of data. Docker fully manages the volume, incluing where it is stored on disk. You only need to remember the name of the volume.
-
Create a volume by using the
docker volume create
command.docker volume create todo-db
-
Stop and remove the todo app container once again (with
docker rm <container-id>
), as it is still running without using the persistent volume. -
Start the todo app container, but add the
--mount
option the specify a volume mount. We will give the volume a name, and mount it to/etc/todos
in the container, which will capture all files created at the path.docker run -dp 3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started
-
Once the container starts up, open the app and add a few items to your todo list.
-
Stop and remove the container for the todo app. Use the
docker ps
command to get the ID and thendocker rm -f <id>
to remove it. -
Start a new container using the same command from above.
-
Open the app. You should see your items still in your list!
-
Go ahead and remove the container when you’re done checking your list.
Hooray! You’ve now learned how to persist data!
Dive into the volume
A lot of people frequently ask “Where is Docker storing my data when I use a volume?” If you want to know, you can use the docker volume inspect
command.
$ docker volume inspect todo-db
[
{
"CreatedAt": "2019-09-26T02:18:36Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
"Name": "todo-db",
"Options": {},
"Scope": "local"
}
]
The Mountpoint
is the actual location on the disk where the data is stored. Note that on most machines, you will need to have root access to access this directory from the host. But, that’s where it is!
发表回复