‫All right. Volumes seem pretty simple up front, but there's actually a lot to it.
‫The first way you can tell a container that it needs to worry about a volume is in a Dockerfile.
‫Let's go check some of those out.
‫I'm just going to do what I do a lot.
‫I'm going to search for MySQL.
‫This is how I learned so much about Dockerfiles, and how to use them correctly, is the official repositories
‫have really sound defaults and best practices built into them.
‫When I go over here to MySQL one, I'm just going to click on the latest Dockerfile here. I
‫I bet you because it's a database, it's probably got a volume command in it.
‫There we go.
‫This is the default location of the MySQL databases. This image is programmed in a way to tell
‫Docker that when we start a new container from it, to actually create a new volume location and assign
‫it to this directory in the container. Which means any files that we put in there, in the container, will
‫outlive the container until we manually delete the volume.
‫And that's something we should point out here is that volumes need manual deletion.
‫You can't clean them up just by removing a container.
‫They're an extra step. That's just for insurance really, because the whole point of a volume command
‫is to say that this data is particularly important, at least much more important than the container itself.
‫If we do a docker pull on MySQL,
‫and then I do a docker image inspect on MySQL, we don't get to see the Dockerfile because the Docker
‫file isn't actually part of the image metadata, which you'll notice in this config area, that it specified
‫that volume there.
‫I can always tell that the config, that came from the Dockerfile when it was built, assigned a volume
‫to that path.
‫Let's run a container from it.
‫So docker container run -d --name mysql.
‫If you remember from earlier, the MySQL one is little special.
‫It now requires an environment variable
‫before it will work.
‫It's MYSQL_ALLOW_EMPTY_PASSWORD.
‫OK.
‫What you see is MySQL running. If we do a docker container
‫inspect mysql, we should see the same thing where it tells us in the config that there's a volume.
‫Here.
‫We can also see it up here under mounts. What this is, is this is actually the running container getting
‫its own unique location on the host, to store that data, and then it's in the background, mapped or mounted,
‫to that location in the container, so that the location in the container actually just thinks it's writing
‫to /var/lib/mysql.
‫In this case, we can see that the data is actually living in that location on the host. So let's
‫do a docker volume
‫ls, and we can see we have now one volume. Now we notice this has got that unique ID that we'll never
‫know what the heck that goes to,
‫Right?
‫So, let's do an inspect on that.
‫You don't have to type the whole thing out.
‫You can just type the first couple of characters and hit Tab to complete it. You'll get that similar
‫information about the volume itself.
‫If you're actually doing this on a Linux machine, you could navigate to that location on your hard
‫drive and see the data.
‫There will actually be some databases there.
‫If you're on a Mac or Windows, remember that Docker for Windows and Docker for Mac are actually doing
‫a little bit in the background that's hidden from us where it's actually creating a Linux VM.
‫So this data is technically inside that Linux VM. You're not going to be able to go to that path
‫on your Windows or Mac machine and see the data. It's actually inside that VM.
‫We'll see in a little bit, with mounted volumes, how we can get around that limitation as well.
‫By looking at this, you notice that it's not very user friendly in terms of telling us what's in it
‫or what this volume is assigned to.
‫We can see from the container's perspective what volume it's using, but we can't see from the volume perspective
‫what it's connected to.
‫Right?
‫If I were just to hit the Up Arrow and, let's see, create a mysql2.
‫That's now created another MySQL server running in the background.
‫If I do another docker volume ls, you'll see two of them.
‫You start to see the problem, right?
‫There's no real easy way here to tell one from the other.
‫If we just, to prove a point, do a docker container stop mysql, and a docker a container stop
‫mysql2.
‫We do a docker container ls, we'll not see any containers running. If we do an ls
‫-a, we get to see them all. And notice that they're stopped. And then we do a docker volume
‫ls, you notice we still have the two volumes.
‫If I do a docker container rm mysql, and then mysql2, because I can actually do both
‫of those in one command, it will remove both of my containers. If I now do a docker volume ls, my volumes
‫are still there. My data is still safe.
‫So, we've solved one problem.
‫The databases outlive the executable.
‫How do we make this a little more user friendly?
‫That's where named volumes come in and the ability for us to specify things on the docker run
‫command.
‫If I hit the Up Arrow a couple of times til I get to the docker container run, it doesn't really
‫matter which one you're going to run again.
‫In this case, we're going to actually throw in a -v command. A -v allows us to specify either
‫a new volume that we want to create for this container that's about to run, or it allows us two other
‫options.
‫One of them here is to create a named volume.
‫If I just did -v, and then the var lib mysql, that would do the same thing is what our volume
‫command in the Dockerfile did.
‫We don't really need to do that here. But what we can do is I can put a name in front of it
‫with a colon. That's known as a "named volume."
‫When I do that, and then do a docker volume ls, you'll see that my new container is using a new volume
‫and it's using a friendly name.
‫If we do a docker volume inspect on that mysql, you'll see that this is easier to use here.
‫If I deleted my container again,
‫and we have to put in a -f because it's still running, and then I run another one. And this time, I'll
‫give it a different name. And then we do another docker volume
‫ls, you'll see that it looks like we haven't created a new volume. It's still using the same volume.
‫Let's do a docker container inspect on the mysql3. Then what we'll see up here
‫is, yes, this is what was configured but what are we running?
‫This is our mounts up here.
‫We'll see here that not only is the name friendlier, but it actually changed the source location to
‫be a little friendlier as well.
‫For me, a little tip here is that when I am running for days or weeks at a time, a particular database,
‫in a particular container that I need to keep using over and over and I don't want a blank database
‫server, I'll end up creating my containers this way and naming them for the project so that I know what
‫that volume's for,
‫and that it needs to stick around.
‫One last thing here.
‫Why would you want to do docker volume create?
‫If we can create them from a docker container run command at runtime, and we can create them by specifying
‫them in the Dockerfile, there's only a few cases where you'd want to create it ahead of time. And you can
‫actually figure that out pretty quickly by using the help command.
‫Because here's the only way that we can actually specify a different driver.
‫Remember that plug-in stuff I'm going to talk about later?
‫Then any driver options that we want to use the -o on.
‫Then if we want to put labels on it, which we'll also talk about later in the production section.
‫Sometimes, in special cases, you do need to create the Docker volume ahead of time, but usually for
‫your local development purposes, just specifying it in a Dockerfile or at the run command is fine.