fixing more links for the newly located tutorials
Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
| ... | ... |
@@ -19,4 +19,4 @@ This section contains the following: |
| 19 | 19 |
* [Dockerizing a CouchDB service](couchdb_data_volumes.md) |
| 20 | 20 |
* [Dockerizing a Redis service](running_redis_service.md) |
| 21 | 21 |
* [Dockerizing an apt-cacher-ng service](apt-cacher-ng.md) |
| 22 |
-* [Dockerizing applications: A 'Hello world'](../userguide/containers/dockerizing.md) |
|
| 22 |
+* [Dockerizing applications: A 'Hello world'](../tutorials/dockerizing.md) |
| ... | ... |
@@ -100,7 +100,7 @@ the `Using cache` message in the console output. |
| 100 | 100 |
Successfully built 7ea8aef582cc |
| 101 | 101 |
|
| 102 | 102 |
When you're done with your build, you're ready to look into [*Pushing a |
| 103 |
-repository to its registry*](../userguide/containers/dockerrepos.md#contributing-to-docker-hub). |
|
| 103 |
+repository to its registry*](../tutorials/dockerrepos.md#contributing-to-docker-hub). |
|
| 104 | 104 |
|
| 105 | 105 |
## Format |
| 106 | 106 |
|
| ... | ... |
@@ -474,7 +474,7 @@ Or |
| 474 | 474 |
The `FROM` instruction sets the [*Base Image*](glossary.md#base-image) |
| 475 | 475 |
for subsequent instructions. As such, a valid `Dockerfile` must have `FROM` as |
| 476 | 476 |
its first instruction. The image can be any valid image – it is especially easy |
| 477 |
-to start by **pulling an image** from the [*Public Repositories*](../userguide/containers/dockerrepos.md). |
|
| 477 |
+to start by **pulling an image** from the [*Public Repositories*](../tutorials/dockerrepos.md). |
|
| 478 | 478 |
|
| 479 | 479 |
- `FROM` must be the first non-comment instruction in the `Dockerfile`. |
| 480 | 480 |
|
| ... | ... |
@@ -1171,7 +1171,7 @@ containers. The value can be a JSON array, `VOLUME ["/var/log/"]`, or a plain |
| 1171 | 1171 |
string with multiple arguments, such as `VOLUME /var/log` or `VOLUME /var/log |
| 1172 | 1172 |
/var/db`. For more information/examples and mounting instructions via the |
| 1173 | 1173 |
Docker client, refer to |
| 1174 |
-[*Share Directories via Volumes*](../userguide/containers/dockervolumes.md#mount-a-host-directory-as-a-data-volume) |
|
| 1174 |
+[*Share Directories via Volumes*](../tutorials/dockervolumes.md#mount-a-host-directory-as-a-data-volume) |
|
| 1175 | 1175 |
documentation. |
| 1176 | 1176 |
|
| 1177 | 1177 |
The `docker run` command initializes the newly created volume with any data |
| ... | ... |
@@ -23,7 +23,7 @@ the container, `docker export` will export the contents of the *underlying* |
| 23 | 23 |
directory, not the contents of the volume. |
| 24 | 24 |
|
| 25 | 25 |
Refer to [Backup, restore, or migrate data |
| 26 |
-volumes](../../userguide/containers/dockervolumes.md#backup-restore-or-migrate-data-volumes) in |
|
| 26 |
+volumes](../../tutorials/dockervolumes.md#backup-restore-or-migrate-data-volumes) in |
|
| 27 | 27 |
the user guide for examples on exporting data in a volume. |
| 28 | 28 |
|
| 29 | 29 |
## Examples |
| ... | ... |
@@ -24,7 +24,7 @@ parent = "smn_cli" |
| 24 | 24 |
|
| 25 | 25 |
Search [Docker Hub](https://hub.docker.com) for images |
| 26 | 26 |
|
| 27 |
-See [*Find Public Images on Docker Hub*](../../userguide/containers/dockerrepos.md#searching-for-images) for |
|
| 27 |
+See [*Find Public Images on Docker Hub*](../../tutorials/dockerrepos.md#searching-for-images) for |
|
| 28 | 28 |
more details on finding shared images from the command line. |
| 29 | 29 |
|
| 30 | 30 |
> **Note:** |
| ... | ... |
@@ -124,5 +124,3 @@ This example displays images with a name containing 'busybox', at least |
| 124 | 124 |
NAME DESCRIPTION STARS OFFICIAL AUTOMATED |
| 125 | 125 |
progrium/busybox 50 [OK] |
| 126 | 126 |
radial/busyboxplus Full-chain, Internet enabled, busybox made... 8 [OK] |
| 127 |
- |
|
| 128 |
- |
| ... | ... |
@@ -19,10 +19,10 @@ parent = "smn_cli" |
| 19 | 19 |
An image name is made up of slash-separated name components, optionally prefixed |
| 20 | 20 |
by a registry hostname. The hostname must comply with standard DNS rules, but |
| 21 | 21 |
may not contain underscores. If a hostname is present, it may optionally be |
| 22 |
-followed by a port number in the format `:8080`. If not present, the command |
|
| 23 |
-uses Docker's public registry located at `registry-1.docker.io` by default. Name |
|
| 24 |
-components may contain lowercase characters, digits and separators. A separator |
|
| 25 |
-is defined as a period, one or two underscores, or one or more dashes. A name |
|
| 22 |
+followed by a port number in the format `:8080`. If not present, the command |
|
| 23 |
+uses Docker's public registry located at `registry-1.docker.io` by default. Name |
|
| 24 |
+components may contain lowercase characters, digits and separators. A separator |
|
| 25 |
+is defined as a period, one or two underscores, or one or more dashes. A name |
|
| 26 | 26 |
component may not start or end with a separator. |
| 27 | 27 |
|
| 28 | 28 |
A tag name may contain lowercase and uppercase characters, digits, underscores, |
| ... | ... |
@@ -30,20 +30,20 @@ periods and dashes. A tag name may not start with a period or a dash and may |
| 30 | 30 |
contain a maximum of 128 characters. |
| 31 | 31 |
|
| 32 | 32 |
You can group your images together using names and tags, and then upload them |
| 33 |
-to [*Share Images via Repositories*](../../userguide/containers/dockerrepos.md#contributing-to-docker-hub). |
|
| 33 |
+to [*Share Images via Repositories*](../../tutorials/dockerrepos.md#contributing-to-docker-hub). |
|
| 34 | 34 |
|
| 35 | 35 |
# Examples |
| 36 | 36 |
|
| 37 | 37 |
## Tagging an image referenced by ID |
| 38 | 38 |
|
| 39 |
-To tag a local image with ID "0e5574283393" into the "fedora" repository with |
|
| 39 |
+To tag a local image with ID "0e5574283393" into the "fedora" repository with |
|
| 40 | 40 |
"version1.0": |
| 41 | 41 |
|
| 42 | 42 |
docker tag 0e5574283393 fedora/httpd:version1.0 |
| 43 | 43 |
|
| 44 | 44 |
## Tagging an image referenced by Name |
| 45 | 45 |
|
| 46 |
-To tag a local image with name "httpd" into the "fedora" repository with |
|
| 46 |
+To tag a local image with name "httpd" into the "fedora" repository with |
|
| 47 | 47 |
"version1.0": |
| 48 | 48 |
|
| 49 | 49 |
docker tag httpd fedora/httpd:version1.0 |
| ... | ... |
@@ -73,4 +73,4 @@ $ docker volume create --driver local --opt type=btrfs --opt device=/dev/sda2 |
| 73 | 73 |
* [volume inspect](volume_inspect.md) |
| 74 | 74 |
* [volume ls](volume_ls.md) |
| 75 | 75 |
* [volume rm](volume_rm.md) |
| 76 |
-* [Understand Data Volumes](../../userguide/containers/dockervolumes.md) |
|
| 76 |
+* [Understand Data Volumes](../../tutorials/dockervolumes.md) |
| ... | ... |
@@ -81,4 +81,4 @@ The following filter matches all volumes with a name containing the `rose` strin |
| 81 | 81 |
* [volume create](volume_create.md) |
| 82 | 82 |
* [volume inspect](volume_inspect.md) |
| 83 | 83 |
* [volume rm](volume_rm.md) |
| 84 |
-* [Understand Data Volumes](../../userguide/containers/dockervolumes.md) |
|
| 84 |
+* [Understand Data Volumes](../../tutorials/dockervolumes.md) |
| ... | ... |
@@ -26,4 +26,4 @@ Removes one or more volumes. You cannot remove a volume that is in use by a cont |
| 26 | 26 |
* [volume create](volume_create.md) |
| 27 | 27 |
* [volume inspect](volume_inspect.md) |
| 28 | 28 |
* [volume ls](volume_ls.md) |
| 29 |
-* [Understand Data Volumes](../../userguide/containers/dockervolumes.md) |
|
| 30 | 29 |
\ No newline at end of file |
| 30 |
+* [Understand Data Volumes](../../tutorials/dockervolumes.md) |
| ... | ... |
@@ -1073,7 +1073,7 @@ Both flags take limits in the `<device-path>:<limit>` format. Both read and |
| 1073 | 1073 |
write rates must be a positive integer. |
| 1074 | 1074 |
|
| 1075 | 1075 |
## Additional groups |
| 1076 |
- --group-add: Add additional groups to run as |
|
| 1076 |
+ --group-add: Add additional groups to run as |
|
| 1077 | 1077 |
|
| 1078 | 1078 |
By default, the docker container process runs with the supplementary groups looked |
| 1079 | 1079 |
up for the specified user. If one wants to add more to that list of groups, then |
| ... | ... |
@@ -1497,8 +1497,8 @@ The example below mounts an empty tmpfs into the container with the `rw`, |
| 1497 | 1497 |
> a volume. |
| 1498 | 1498 |
|
| 1499 | 1499 |
The volumes commands are complex enough to have their own documentation |
| 1500 |
-in section [*Managing data in |
|
| 1501 |
-containers*](../userguide/containers/dockervolumes.md). A developer can define |
|
| 1500 |
+in section [*Manage data in |
|
| 1501 |
+containers*](../tutorials/dockervolumes.md). A developer can define |
|
| 1502 | 1502 |
one or more `VOLUME`'s associated with an image, but only the operator |
| 1503 | 1503 |
can give access from one container to another (or from a container to a |
| 1504 | 1504 |
volume mounted on the host). |
| ... | ... |
@@ -1527,7 +1527,7 @@ Dockerfile `USER` instruction. When starting a container, the operator can overr |
| 1527 | 1527 |
the `USER` instruction by passing the `-u` option. |
| 1528 | 1528 |
|
| 1529 | 1529 |
-u="", --user="": Sets the username or UID used and optionally the groupname or GID for the specified command. |
| 1530 |
- |
|
| 1530 |
+ |
|
| 1531 | 1531 |
The followings examples are all valid: |
| 1532 | 1532 |
--user=[ user | user:group | uid | uid:gid | user:gid | uid:group ] |
| 1533 | 1533 |
|
| 1534 | 1534 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,557 @@ |
| 0 |
+<!--[metadata]> |
|
| 1 |
+aliases = [ |
|
| 2 |
+"/engine/userguide/containers/dockerimages/", |
|
| 3 |
+"/engine/userguide/dockerimages/" |
|
| 4 |
+] |
|
| 5 |
+title = "Build your own images" |
|
| 6 |
+description = "How to work with Docker images." |
|
| 7 |
+keywords = ["documentation, docs, the docker guide, docker guide, docker, docker platform, docker.io, Docker images, Docker image, image management, Docker repos, Docker repositories, docker, docker tag, docker tags, Docker Hub, collaboration"] |
|
| 8 |
+[menu.main] |
|
| 9 |
+parent = "engine_learn" |
|
| 10 |
+weight = -4 |
|
| 11 |
+<![end-metadata]--> |
|
| 12 |
+ |
|
| 13 |
+# Build your own images |
|
| 14 |
+ |
|
| 15 |
+Docker images are the basis of containers. Each time you've used `docker run` |
|
| 16 |
+you told it which image you wanted. In the previous sections of the guide you |
|
| 17 |
+used Docker images that already exist, for example the `ubuntu` image and the |
|
| 18 |
+`training/webapp` image. |
|
| 19 |
+ |
|
| 20 |
+You also discovered that Docker stores downloaded images on the Docker host. If |
|
| 21 |
+an image isn't already present on the host then it'll be downloaded from a |
|
| 22 |
+registry: by default the [Docker Hub Registry](https://hub.docker.com). |
|
| 23 |
+ |
|
| 24 |
+In this section you're going to explore Docker images a bit more |
|
| 25 |
+including: |
|
| 26 |
+ |
|
| 27 |
+* Managing and working with images locally on your Docker host. |
|
| 28 |
+* Creating basic images. |
|
| 29 |
+* Uploading images to [Docker Hub Registry](https://hub.docker.com). |
|
| 30 |
+ |
|
| 31 |
+## Listing images on the host |
|
| 32 |
+ |
|
| 33 |
+Let's start with listing the images you have locally on our host. You can |
|
| 34 |
+do this using the `docker images` command like so: |
|
| 35 |
+ |
|
| 36 |
+ $ docker images |
|
| 37 |
+ REPOSITORY TAG IMAGE ID CREATED SIZE |
|
| 38 |
+ ubuntu 14.04 1d073211c498 3 days ago 187.9 MB |
|
| 39 |
+ busybox latest 2c5ac3f849df 5 days ago 1.113 MB |
|
| 40 |
+ training/webapp latest 54bb4e8718e8 5 months ago 348.7 MB |
|
| 41 |
+ |
|
| 42 |
+You can see the images you've previously used in the user guide. |
|
| 43 |
+Each has been downloaded from [Docker Hub](https://hub.docker.com) when you |
|
| 44 |
+launched a container using that image. When you list images, you get three crucial pieces of information in the listing. |
|
| 45 |
+ |
|
| 46 |
+* What repository they came from, for example `ubuntu`. |
|
| 47 |
+* The tags for each image, for example `14.04`. |
|
| 48 |
+* The image ID of each image. |
|
| 49 |
+ |
|
| 50 |
+> **Tip:** |
|
| 51 |
+> You can use [a third-party dockviz tool](https://github.com/justone/dockviz) |
|
| 52 |
+> or the [Image layers site](https://imagelayers.io/) to display |
|
| 53 |
+> visualizations of image data. |
|
| 54 |
+ |
|
| 55 |
+A repository potentially holds multiple variants of an image. In the case of |
|
| 56 |
+our `ubuntu` image you can see multiple variants covering Ubuntu 10.04, 12.04, |
|
| 57 |
+12.10, 13.04, 13.10 and 14.04. Each variant is identified by a tag and you can |
|
| 58 |
+refer to a tagged image like so: |
|
| 59 |
+ |
|
| 60 |
+ ubuntu:14.04 |
|
| 61 |
+ |
|
| 62 |
+So when you run a container you refer to a tagged image like so: |
|
| 63 |
+ |
|
| 64 |
+ $ docker run -t -i ubuntu:14.04 /bin/bash |
|
| 65 |
+ |
|
| 66 |
+If instead you wanted to run an Ubuntu 12.04 image you'd use: |
|
| 67 |
+ |
|
| 68 |
+ $ docker run -t -i ubuntu:12.04 /bin/bash |
|
| 69 |
+ |
|
| 70 |
+If you don't specify a variant, for example you just use `ubuntu`, then Docker |
|
| 71 |
+will default to using the `ubuntu:latest` image. |
|
| 72 |
+ |
|
| 73 |
+> **Tip:** |
|
| 74 |
+> You should always specify an image tag, for example `ubuntu:14.04`. |
|
| 75 |
+> That way, you always know exactly what variant of an image you are using. |
|
| 76 |
+> This is useful for troubleshooting and debugging. |
|
| 77 |
+ |
|
| 78 |
+## Getting a new image |
|
| 79 |
+ |
|
| 80 |
+So how do you get new images? Well Docker will automatically download any image |
|
| 81 |
+you use that isn't already present on the Docker host. But this can potentially |
|
| 82 |
+add some time to the launch of a container. If you want to pre-load an image you |
|
| 83 |
+can download it using the `docker pull` command. Suppose you'd like to |
|
| 84 |
+download the `centos` image. |
|
| 85 |
+ |
|
| 86 |
+ $ docker pull centos |
|
| 87 |
+ Pulling repository centos |
|
| 88 |
+ b7de3133ff98: Pulling dependent layers |
|
| 89 |
+ 5cc9e91966f7: Pulling fs layer |
|
| 90 |
+ 511136ea3c5a: Download complete |
|
| 91 |
+ ef52fb1fe610: Download complete |
|
| 92 |
+ . . . |
|
| 93 |
+ |
|
| 94 |
+ Status: Downloaded newer image for centos |
|
| 95 |
+ |
|
| 96 |
+You can see that each layer of the image has been pulled down and now you |
|
| 97 |
+can run a container from this image and you won't have to wait to |
|
| 98 |
+download the image. |
|
| 99 |
+ |
|
| 100 |
+ $ docker run -t -i centos /bin/bash |
|
| 101 |
+ bash-4.1# |
|
| 102 |
+ |
|
| 103 |
+## Finding images |
|
| 104 |
+ |
|
| 105 |
+One of the features of Docker is that a lot of people have created Docker |
|
| 106 |
+images for a variety of purposes. Many of these have been uploaded to |
|
| 107 |
+[Docker Hub](https://hub.docker.com). You can search these images on the |
|
| 108 |
+[Docker Hub](https://hub.docker.com) website. |
|
| 109 |
+ |
|
| 110 |
+ |
|
| 111 |
+ |
|
| 112 |
+You can also search for images on the command line using the `docker search` |
|
| 113 |
+command. Suppose your team wants an image with Ruby and Sinatra installed on |
|
| 114 |
+which to do our web application development. You can search for a suitable image |
|
| 115 |
+by using the `docker search` command to find all the images that contain the |
|
| 116 |
+term `sinatra`. |
|
| 117 |
+ |
|
| 118 |
+ $ docker search sinatra |
|
| 119 |
+ NAME DESCRIPTION STARS OFFICIAL AUTOMATED |
|
| 120 |
+ training/sinatra Sinatra training image 0 [OK] |
|
| 121 |
+ marceldegraaf/sinatra Sinatra test app 0 |
|
| 122 |
+ mattwarren/docker-sinatra-demo 0 [OK] |
|
| 123 |
+ luisbebop/docker-sinatra-hello-world 0 [OK] |
|
| 124 |
+ bmorearty/handson-sinatra handson-ruby + Sinatra for Hands on with D... 0 |
|
| 125 |
+ subwiz/sinatra 0 |
|
| 126 |
+ bmorearty/sinatra 0 |
|
| 127 |
+ . . . |
|
| 128 |
+ |
|
| 129 |
+You can see the command returns a lot of images that use the term `sinatra`. |
|
| 130 |
+You've received a list of image names, descriptions, Stars (which measure the |
|
| 131 |
+social popularity of images - if a user likes an image then they can "star" it), |
|
| 132 |
+and the Official and Automated build statuses. [Official |
|
| 133 |
+Repositories](https://docs.docker.com/docker-hub/official_repos) are a carefully |
|
| 134 |
+curated set of Docker repositories supported by Docker, Inc. Automated |
|
| 135 |
+repositories are [Automated Builds](dockerrepos.md#automated-builds) that allow |
|
| 136 |
+you to validate the source and content of an image. |
|
| 137 |
+ |
|
| 138 |
+You've reviewed the images available to use and you decided to use the |
|
| 139 |
+`training/sinatra` image. So far you've seen two types of images repositories, |
|
| 140 |
+images like `ubuntu`, which are called base or root images. These base images |
|
| 141 |
+are provided by Docker Inc and are built, validated and supported. These can be |
|
| 142 |
+identified by their single word names. |
|
| 143 |
+ |
|
| 144 |
+You've also seen user images, for example the `training/sinatra` image you've |
|
| 145 |
+chosen. A user image belongs to a member of the Docker community and is built |
|
| 146 |
+and maintained by them. You can identify user images as they are always |
|
| 147 |
+prefixed with the user name, here `training`, of the user that created them. |
|
| 148 |
+ |
|
| 149 |
+## Pulling our image |
|
| 150 |
+ |
|
| 151 |
+You've identified a suitable image, `training/sinatra`, and now you can download it using the `docker pull` command. |
|
| 152 |
+ |
|
| 153 |
+ $ docker pull training/sinatra |
|
| 154 |
+ |
|
| 155 |
+The team can now use this image by running their own containers. |
|
| 156 |
+ |
|
| 157 |
+ $ docker run -t -i training/sinatra /bin/bash |
|
| 158 |
+ root@a8cb6ce02d85:/# |
|
| 159 |
+ |
|
| 160 |
+## Creating our own images |
|
| 161 |
+ |
|
| 162 |
+The team has found the `training/sinatra` image pretty useful but it's not quite |
|
| 163 |
+what they need and you need to make some changes to it. There are two ways you |
|
| 164 |
+can update and create images. |
|
| 165 |
+ |
|
| 166 |
+1. You can update a container created from an image and commit the results to an image. |
|
| 167 |
+2. You can use a `Dockerfile` to specify instructions to create an image. |
|
| 168 |
+ |
|
| 169 |
+ |
|
| 170 |
+### Updating and committing an image |
|
| 171 |
+ |
|
| 172 |
+To update an image you first need to create a container from the image |
|
| 173 |
+you'd like to update. |
|
| 174 |
+ |
|
| 175 |
+ $ docker run -t -i training/sinatra /bin/bash |
|
| 176 |
+ root@0b2616b0e5a8:/# |
|
| 177 |
+ |
|
| 178 |
+> **Note:** |
|
| 179 |
+> Take note of the container ID that has been created, `0b2616b0e5a8`, as you'll |
|
| 180 |
+> need it in a moment. |
|
| 181 |
+ |
|
| 182 |
+Inside our running container let's add the `json` gem. |
|
| 183 |
+ |
|
| 184 |
+ root@0b2616b0e5a8:/# gem install json |
|
| 185 |
+ |
|
| 186 |
+Once this has completed let's exit our container using the `exit` |
|
| 187 |
+command. |
|
| 188 |
+ |
|
| 189 |
+Now you have a container with the change you want to make. You can then |
|
| 190 |
+commit a copy of this container to an image using the `docker commit` |
|
| 191 |
+command. |
|
| 192 |
+ |
|
| 193 |
+ $ docker commit -m "Added json gem" -a "Kate Smith" \ |
|
| 194 |
+ 0b2616b0e5a8 ouruser/sinatra:v2 |
|
| 195 |
+ 4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c |
|
| 196 |
+ |
|
| 197 |
+Here you've used the `docker commit` command. You've specified two flags: `-m` |
|
| 198 |
+and `-a`. The `-m` flag allows us to specify a commit message, much like you |
|
| 199 |
+would with a commit on a version control system. The `-a` flag allows us to |
|
| 200 |
+specify an author for our update. |
|
| 201 |
+ |
|
| 202 |
+You've also specified the container you want to create this new image from, |
|
| 203 |
+`0b2616b0e5a8` (the ID you recorded earlier) and you've specified a target for |
|
| 204 |
+the image: |
|
| 205 |
+ |
|
| 206 |
+ ouruser/sinatra:v2 |
|
| 207 |
+ |
|
| 208 |
+Break this target down. It consists of a new user, `ouruser`, that you're |
|
| 209 |
+writing this image to. You've also specified the name of the image, here you're |
|
| 210 |
+keeping the original image name `sinatra`. Finally you're specifying a tag for |
|
| 211 |
+the image: `v2`. |
|
| 212 |
+ |
|
| 213 |
+You can then look at our new `ouruser/sinatra` image using the `docker images` |
|
| 214 |
+command. |
|
| 215 |
+ |
|
| 216 |
+ $ docker images |
|
| 217 |
+ REPOSITORY TAG IMAGE ID CREATED SIZE |
|
| 218 |
+ training/sinatra latest 5bc342fa0b91 10 hours ago 446.7 MB |
|
| 219 |
+ ouruser/sinatra v2 3c59e02ddd1a 10 hours ago 446.7 MB |
|
| 220 |
+ ouruser/sinatra latest 5db5f8471261 10 hours ago 446.7 MB |
|
| 221 |
+ |
|
| 222 |
+To use our new image to create a container you can then: |
|
| 223 |
+ |
|
| 224 |
+ $ docker run -t -i ouruser/sinatra:v2 /bin/bash |
|
| 225 |
+ root@78e82f680994:/# |
|
| 226 |
+ |
|
| 227 |
+### Building an image from a `Dockerfile` |
|
| 228 |
+ |
|
| 229 |
+Using the `docker commit` command is a pretty simple way of extending an image |
|
| 230 |
+but it's a bit cumbersome and it's not easy to share a development process for |
|
| 231 |
+images amongst a team. Instead you can use a new command, `docker build`, to |
|
| 232 |
+build new images from scratch. |
|
| 233 |
+ |
|
| 234 |
+To do this you create a `Dockerfile` that contains a set of instructions that |
|
| 235 |
+tell Docker how to build our image. |
|
| 236 |
+ |
|
| 237 |
+First, create a directory and a `Dockerfile`. |
|
| 238 |
+ |
|
| 239 |
+ $ mkdir sinatra |
|
| 240 |
+ $ cd sinatra |
|
| 241 |
+ $ touch Dockerfile |
|
| 242 |
+ |
|
| 243 |
+If you are using Docker Machine on Windows, you may access your host |
|
| 244 |
+directory by `cd` to `/c/Users/your_user_name`. |
|
| 245 |
+ |
|
| 246 |
+Each instruction creates a new layer of the image. Try a simple example now for |
|
| 247 |
+building your own Sinatra image for your fictitious development team. |
|
| 248 |
+ |
|
| 249 |
+ # This is a comment |
|
| 250 |
+ FROM ubuntu:14.04 |
|
| 251 |
+ MAINTAINER Kate Smith <ksmith@example.com> |
|
| 252 |
+ RUN apt-get update && apt-get install -y ruby ruby-dev |
|
| 253 |
+ RUN gem install sinatra |
|
| 254 |
+ |
|
| 255 |
+Examine what your `Dockerfile` does. Each instruction prefixes a statement and |
|
| 256 |
+is capitalized. |
|
| 257 |
+ |
|
| 258 |
+ INSTRUCTION statement |
|
| 259 |
+ |
|
| 260 |
+> **Note:** You use `#` to indicate a comment |
|
| 261 |
+ |
|
| 262 |
+The first instruction `FROM` tells Docker what the source of our image is, in |
|
| 263 |
+this case you're basing our new image on an Ubuntu 14.04 image. The instruction uses the `MAINTAINER` instruction to specify who maintains the new image. |
|
| 264 |
+ |
|
| 265 |
+Lastly, you've specified two `RUN` instructions. A `RUN` instruction executes |
|
| 266 |
+a command inside the image, for example installing a package. Here you're |
|
| 267 |
+updating our APT cache, installing Ruby and RubyGems and then installing the |
|
| 268 |
+Sinatra gem. |
|
| 269 |
+ |
|
| 270 |
+ |
|
| 271 |
+ |
|
| 272 |
+Now let's take our `Dockerfile` and use the `docker build` command to build an image. |
|
| 273 |
+ |
|
| 274 |
+ $ docker build -t ouruser/sinatra:v2 . |
|
| 275 |
+ Sending build context to Docker daemon 2.048 kB |
|
| 276 |
+ Sending build context to Docker daemon |
|
| 277 |
+ Step 1 : FROM ubuntu:14.04 |
|
| 278 |
+ ---> e54ca5efa2e9 |
|
| 279 |
+ Step 2 : MAINTAINER Kate Smith <ksmith@example.com> |
|
| 280 |
+ ---> Using cache |
|
| 281 |
+ ---> 851baf55332b |
|
| 282 |
+ Step 3 : RUN apt-get update && apt-get install -y ruby ruby-dev |
|
| 283 |
+ ---> Running in 3a2558904e9b |
|
| 284 |
+ Selecting previously unselected package libasan0:amd64. |
|
| 285 |
+ (Reading database ... 11518 files and directories currently installed.) |
|
| 286 |
+ Preparing to unpack .../libasan0_4.8.2-19ubuntu1_amd64.deb ... |
|
| 287 |
+ Unpacking libasan0:amd64 (4.8.2-19ubuntu1) ... |
|
| 288 |
+ Selecting previously unselected package libatomic1:amd64. |
|
| 289 |
+ Preparing to unpack .../libatomic1_4.8.2-19ubuntu1_amd64.deb ... |
|
| 290 |
+ Unpacking libatomic1:amd64 (4.8.2-19ubuntu1) ... |
|
| 291 |
+ Selecting previously unselected package libgmp10:amd64. |
|
| 292 |
+ Preparing to unpack .../libgmp10_2%3a5.1.3+dfsg-1ubuntu1_amd64.deb ... |
|
| 293 |
+ Unpacking libgmp10:amd64 (2:5.1.3+dfsg-1ubuntu1) ... |
|
| 294 |
+ Selecting previously unselected package libisl10:amd64. |
|
| 295 |
+ Preparing to unpack .../libisl10_0.12.2-1_amd64.deb ... |
|
| 296 |
+ Unpacking libisl10:amd64 (0.12.2-1) ... |
|
| 297 |
+ Selecting previously unselected package libcloog-isl4:amd64. |
|
| 298 |
+ Preparing to unpack .../libcloog-isl4_0.18.2-1_amd64.deb ... |
|
| 299 |
+ Unpacking libcloog-isl4:amd64 (0.18.2-1) ... |
|
| 300 |
+ Selecting previously unselected package libgomp1:amd64. |
|
| 301 |
+ Preparing to unpack .../libgomp1_4.8.2-19ubuntu1_amd64.deb ... |
|
| 302 |
+ Unpacking libgomp1:amd64 (4.8.2-19ubuntu1) ... |
|
| 303 |
+ Selecting previously unselected package libitm1:amd64. |
|
| 304 |
+ Preparing to unpack .../libitm1_4.8.2-19ubuntu1_amd64.deb ... |
|
| 305 |
+ Unpacking libitm1:amd64 (4.8.2-19ubuntu1) ... |
|
| 306 |
+ Selecting previously unselected package libmpfr4:amd64. |
|
| 307 |
+ Preparing to unpack .../libmpfr4_3.1.2-1_amd64.deb ... |
|
| 308 |
+ Unpacking libmpfr4:amd64 (3.1.2-1) ... |
|
| 309 |
+ Selecting previously unselected package libquadmath0:amd64. |
|
| 310 |
+ Preparing to unpack .../libquadmath0_4.8.2-19ubuntu1_amd64.deb ... |
|
| 311 |
+ Unpacking libquadmath0:amd64 (4.8.2-19ubuntu1) ... |
|
| 312 |
+ Selecting previously unselected package libtsan0:amd64. |
|
| 313 |
+ Preparing to unpack .../libtsan0_4.8.2-19ubuntu1_amd64.deb ... |
|
| 314 |
+ Unpacking libtsan0:amd64 (4.8.2-19ubuntu1) ... |
|
| 315 |
+ Selecting previously unselected package libyaml-0-2:amd64. |
|
| 316 |
+ Preparing to unpack .../libyaml-0-2_0.1.4-3ubuntu3_amd64.deb ... |
|
| 317 |
+ Unpacking libyaml-0-2:amd64 (0.1.4-3ubuntu3) ... |
|
| 318 |
+ Selecting previously unselected package libmpc3:amd64. |
|
| 319 |
+ Preparing to unpack .../libmpc3_1.0.1-1ubuntu1_amd64.deb ... |
|
| 320 |
+ Unpacking libmpc3:amd64 (1.0.1-1ubuntu1) ... |
|
| 321 |
+ Selecting previously unselected package openssl. |
|
| 322 |
+ Preparing to unpack .../openssl_1.0.1f-1ubuntu2.4_amd64.deb ... |
|
| 323 |
+ Unpacking openssl (1.0.1f-1ubuntu2.4) ... |
|
| 324 |
+ Selecting previously unselected package ca-certificates. |
|
| 325 |
+ Preparing to unpack .../ca-certificates_20130906ubuntu2_all.deb ... |
|
| 326 |
+ Unpacking ca-certificates (20130906ubuntu2) ... |
|
| 327 |
+ Selecting previously unselected package manpages. |
|
| 328 |
+ Preparing to unpack .../manpages_3.54-1ubuntu1_all.deb ... |
|
| 329 |
+ Unpacking manpages (3.54-1ubuntu1) ... |
|
| 330 |
+ Selecting previously unselected package binutils. |
|
| 331 |
+ Preparing to unpack .../binutils_2.24-5ubuntu3_amd64.deb ... |
|
| 332 |
+ Unpacking binutils (2.24-5ubuntu3) ... |
|
| 333 |
+ Selecting previously unselected package cpp-4.8. |
|
| 334 |
+ Preparing to unpack .../cpp-4.8_4.8.2-19ubuntu1_amd64.deb ... |
|
| 335 |
+ Unpacking cpp-4.8 (4.8.2-19ubuntu1) ... |
|
| 336 |
+ Selecting previously unselected package cpp. |
|
| 337 |
+ Preparing to unpack .../cpp_4%3a4.8.2-1ubuntu6_amd64.deb ... |
|
| 338 |
+ Unpacking cpp (4:4.8.2-1ubuntu6) ... |
|
| 339 |
+ Selecting previously unselected package libgcc-4.8-dev:amd64. |
|
| 340 |
+ Preparing to unpack .../libgcc-4.8-dev_4.8.2-19ubuntu1_amd64.deb ... |
|
| 341 |
+ Unpacking libgcc-4.8-dev:amd64 (4.8.2-19ubuntu1) ... |
|
| 342 |
+ Selecting previously unselected package gcc-4.8. |
|
| 343 |
+ Preparing to unpack .../gcc-4.8_4.8.2-19ubuntu1_amd64.deb ... |
|
| 344 |
+ Unpacking gcc-4.8 (4.8.2-19ubuntu1) ... |
|
| 345 |
+ Selecting previously unselected package gcc. |
|
| 346 |
+ Preparing to unpack .../gcc_4%3a4.8.2-1ubuntu6_amd64.deb ... |
|
| 347 |
+ Unpacking gcc (4:4.8.2-1ubuntu6) ... |
|
| 348 |
+ Selecting previously unselected package libc-dev-bin. |
|
| 349 |
+ Preparing to unpack .../libc-dev-bin_2.19-0ubuntu6_amd64.deb ... |
|
| 350 |
+ Unpacking libc-dev-bin (2.19-0ubuntu6) ... |
|
| 351 |
+ Selecting previously unselected package linux-libc-dev:amd64. |
|
| 352 |
+ Preparing to unpack .../linux-libc-dev_3.13.0-30.55_amd64.deb ... |
|
| 353 |
+ Unpacking linux-libc-dev:amd64 (3.13.0-30.55) ... |
|
| 354 |
+ Selecting previously unselected package libc6-dev:amd64. |
|
| 355 |
+ Preparing to unpack .../libc6-dev_2.19-0ubuntu6_amd64.deb ... |
|
| 356 |
+ Unpacking libc6-dev:amd64 (2.19-0ubuntu6) ... |
|
| 357 |
+ Selecting previously unselected package ruby. |
|
| 358 |
+ Preparing to unpack .../ruby_1%3a1.9.3.4_all.deb ... |
|
| 359 |
+ Unpacking ruby (1:1.9.3.4) ... |
|
| 360 |
+ Selecting previously unselected package ruby1.9.1. |
|
| 361 |
+ Preparing to unpack .../ruby1.9.1_1.9.3.484-2ubuntu1_amd64.deb ... |
|
| 362 |
+ Unpacking ruby1.9.1 (1.9.3.484-2ubuntu1) ... |
|
| 363 |
+ Selecting previously unselected package libruby1.9.1. |
|
| 364 |
+ Preparing to unpack .../libruby1.9.1_1.9.3.484-2ubuntu1_amd64.deb ... |
|
| 365 |
+ Unpacking libruby1.9.1 (1.9.3.484-2ubuntu1) ... |
|
| 366 |
+ Selecting previously unselected package manpages-dev. |
|
| 367 |
+ Preparing to unpack .../manpages-dev_3.54-1ubuntu1_all.deb ... |
|
| 368 |
+ Unpacking manpages-dev (3.54-1ubuntu1) ... |
|
| 369 |
+ Selecting previously unselected package ruby1.9.1-dev. |
|
| 370 |
+ Preparing to unpack .../ruby1.9.1-dev_1.9.3.484-2ubuntu1_amd64.deb ... |
|
| 371 |
+ Unpacking ruby1.9.1-dev (1.9.3.484-2ubuntu1) ... |
|
| 372 |
+ Selecting previously unselected package ruby-dev. |
|
| 373 |
+ Preparing to unpack .../ruby-dev_1%3a1.9.3.4_all.deb ... |
|
| 374 |
+ Unpacking ruby-dev (1:1.9.3.4) ... |
|
| 375 |
+ Setting up libasan0:amd64 (4.8.2-19ubuntu1) ... |
|
| 376 |
+ Setting up libatomic1:amd64 (4.8.2-19ubuntu1) ... |
|
| 377 |
+ Setting up libgmp10:amd64 (2:5.1.3+dfsg-1ubuntu1) ... |
|
| 378 |
+ Setting up libisl10:amd64 (0.12.2-1) ... |
|
| 379 |
+ Setting up libcloog-isl4:amd64 (0.18.2-1) ... |
|
| 380 |
+ Setting up libgomp1:amd64 (4.8.2-19ubuntu1) ... |
|
| 381 |
+ Setting up libitm1:amd64 (4.8.2-19ubuntu1) ... |
|
| 382 |
+ Setting up libmpfr4:amd64 (3.1.2-1) ... |
|
| 383 |
+ Setting up libquadmath0:amd64 (4.8.2-19ubuntu1) ... |
|
| 384 |
+ Setting up libtsan0:amd64 (4.8.2-19ubuntu1) ... |
|
| 385 |
+ Setting up libyaml-0-2:amd64 (0.1.4-3ubuntu3) ... |
|
| 386 |
+ Setting up libmpc3:amd64 (1.0.1-1ubuntu1) ... |
|
| 387 |
+ Setting up openssl (1.0.1f-1ubuntu2.4) ... |
|
| 388 |
+ Setting up ca-certificates (20130906ubuntu2) ... |
|
| 389 |
+ debconf: unable to initialize frontend: Dialog |
|
| 390 |
+ debconf: (TERM is not set, so the dialog frontend is not usable.) |
|
| 391 |
+ debconf: falling back to frontend: Readline |
|
| 392 |
+ debconf: unable to initialize frontend: Readline |
|
| 393 |
+ debconf: (This frontend requires a controlling tty.) |
|
| 394 |
+ debconf: falling back to frontend: Teletype |
|
| 395 |
+ Setting up manpages (3.54-1ubuntu1) ... |
|
| 396 |
+ Setting up binutils (2.24-5ubuntu3) ... |
|
| 397 |
+ Setting up cpp-4.8 (4.8.2-19ubuntu1) ... |
|
| 398 |
+ Setting up cpp (4:4.8.2-1ubuntu6) ... |
|
| 399 |
+ Setting up libgcc-4.8-dev:amd64 (4.8.2-19ubuntu1) ... |
|
| 400 |
+ Setting up gcc-4.8 (4.8.2-19ubuntu1) ... |
|
| 401 |
+ Setting up gcc (4:4.8.2-1ubuntu6) ... |
|
| 402 |
+ Setting up libc-dev-bin (2.19-0ubuntu6) ... |
|
| 403 |
+ Setting up linux-libc-dev:amd64 (3.13.0-30.55) ... |
|
| 404 |
+ Setting up libc6-dev:amd64 (2.19-0ubuntu6) ... |
|
| 405 |
+ Setting up manpages-dev (3.54-1ubuntu1) ... |
|
| 406 |
+ Setting up libruby1.9.1 (1.9.3.484-2ubuntu1) ... |
|
| 407 |
+ Setting up ruby1.9.1-dev (1.9.3.484-2ubuntu1) ... |
|
| 408 |
+ Setting up ruby-dev (1:1.9.3.4) ... |
|
| 409 |
+ Setting up ruby (1:1.9.3.4) ... |
|
| 410 |
+ Setting up ruby1.9.1 (1.9.3.484-2ubuntu1) ... |
|
| 411 |
+ Processing triggers for libc-bin (2.19-0ubuntu6) ... |
|
| 412 |
+ Processing triggers for ca-certificates (20130906ubuntu2) ... |
|
| 413 |
+ Updating certificates in /etc/ssl/certs... 164 added, 0 removed; done. |
|
| 414 |
+ Running hooks in /etc/ca-certificates/update.d....done. |
|
| 415 |
+ ---> c55c31703134 |
|
| 416 |
+ Removing intermediate container 3a2558904e9b |
|
| 417 |
+ Step 4 : RUN gem install sinatra |
|
| 418 |
+ ---> Running in 6b81cb6313e5 |
|
| 419 |
+ unable to convert "\xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to US-ASCII for README.rdoc, skipping |
|
| 420 |
+ unable to convert "\xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to US-ASCII for README.rdoc, skipping |
|
| 421 |
+ Successfully installed rack-1.5.2 |
|
| 422 |
+ Successfully installed tilt-1.4.1 |
|
| 423 |
+ Successfully installed rack-protection-1.5.3 |
|
| 424 |
+ Successfully installed sinatra-1.4.5 |
|
| 425 |
+ 4 gems installed |
|
| 426 |
+ Installing ri documentation for rack-1.5.2... |
|
| 427 |
+ Installing ri documentation for tilt-1.4.1... |
|
| 428 |
+ Installing ri documentation for rack-protection-1.5.3... |
|
| 429 |
+ Installing ri documentation for sinatra-1.4.5... |
|
| 430 |
+ Installing RDoc documentation for rack-1.5.2... |
|
| 431 |
+ Installing RDoc documentation for tilt-1.4.1... |
|
| 432 |
+ Installing RDoc documentation for rack-protection-1.5.3... |
|
| 433 |
+ Installing RDoc documentation for sinatra-1.4.5... |
|
| 434 |
+ ---> 97feabe5d2ed |
|
| 435 |
+ Removing intermediate container 6b81cb6313e5 |
|
| 436 |
+ Successfully built 97feabe5d2ed |
|
| 437 |
+ |
|
| 438 |
+You've specified our `docker build` command and used the `-t` flag to identify |
|
| 439 |
+our new image as belonging to the user `ouruser`, the repository name `sinatra` |
|
| 440 |
+and given it the tag `v2`. |
|
| 441 |
+ |
|
| 442 |
+You've also specified the location of our `Dockerfile` using the `.` to |
|
| 443 |
+indicate a `Dockerfile` in the current directory. |
|
| 444 |
+ |
|
| 445 |
+> **Note:** |
|
| 446 |
+> You can also specify a path to a `Dockerfile`. |
|
| 447 |
+ |
|
| 448 |
+Now you can see the build process at work. The first thing Docker does is |
|
| 449 |
+upload the build context: basically the contents of the directory you're |
|
| 450 |
+building in. This is done because the Docker daemon does the actual |
|
| 451 |
+build of the image and it needs the local context to do it. |
|
| 452 |
+ |
|
| 453 |
+Next you can see each instruction in the `Dockerfile` being executed |
|
| 454 |
+step-by-step. You can see that each step creates a new container, runs |
|
| 455 |
+the instruction inside that container and then commits that change - |
|
| 456 |
+just like the `docker commit` work flow you saw earlier. When all the |
|
| 457 |
+instructions have executed you're left with the `97feabe5d2ed` image |
|
| 458 |
+(also helpfuly tagged as `ouruser/sinatra:v2`) and all intermediate |
|
| 459 |
+containers will get removed to clean things up. |
|
| 460 |
+ |
|
| 461 |
+> **Note:** |
|
| 462 |
+> An image can't have more than 127 layers regardless of the storage driver. |
|
| 463 |
+> This limitation is set globally to encourage optimization of the overall |
|
| 464 |
+> size of images. |
|
| 465 |
+ |
|
| 466 |
+You can then create a container from our new image. |
|
| 467 |
+ |
|
| 468 |
+ $ docker run -t -i ouruser/sinatra:v2 /bin/bash |
|
| 469 |
+ root@8196968dac35:/# |
|
| 470 |
+ |
|
| 471 |
+> **Note:** |
|
| 472 |
+> This is just a brief introduction to creating images. We've |
|
| 473 |
+> skipped a whole bunch of other instructions that you can use. We'll see more of |
|
| 474 |
+> those instructions in later sections of the Guide or you can refer to the |
|
| 475 |
+> [`Dockerfile`](../reference/builder.md) reference for a |
|
| 476 |
+> detailed description and examples of every instruction. |
|
| 477 |
+> To help you write a clear, readable, maintainable `Dockerfile`, we've also |
|
| 478 |
+> written a [`Dockerfile` Best Practices guide](../userguide/eng-image/dockerfile_best-practices.md). |
|
| 479 |
+ |
|
| 480 |
+ |
|
| 481 |
+## Setting tags on an image |
|
| 482 |
+ |
|
| 483 |
+You can also add a tag to an existing image after you commit or build it. We |
|
| 484 |
+can do this using the `docker tag` command. Now, add a new tag to your |
|
| 485 |
+`ouruser/sinatra` image. |
|
| 486 |
+ |
|
| 487 |
+ $ docker tag 5db5f8471261 ouruser/sinatra:devel |
|
| 488 |
+ |
|
| 489 |
+The `docker tag` command takes the ID of the image, here `5db5f8471261`, and our |
|
| 490 |
+user name, the repository name and the new tag. |
|
| 491 |
+ |
|
| 492 |
+Now, see your new tag using the `docker images` command. |
|
| 493 |
+ |
|
| 494 |
+ $ docker images ouruser/sinatra |
|
| 495 |
+ REPOSITORY TAG IMAGE ID CREATED SIZE |
|
| 496 |
+ ouruser/sinatra latest 5db5f8471261 11 hours ago 446.7 MB |
|
| 497 |
+ ouruser/sinatra devel 5db5f8471261 11 hours ago 446.7 MB |
|
| 498 |
+ ouruser/sinatra v2 5db5f8471261 11 hours ago 446.7 MB |
|
| 499 |
+ |
|
| 500 |
+## Image Digests |
|
| 501 |
+ |
|
| 502 |
+Images that use the v2 or later format have a content-addressable identifier |
|
| 503 |
+called a `digest`. As long as the input used to generate the image is |
|
| 504 |
+unchanged, the digest value is predictable. To list image digest values, use |
|
| 505 |
+the `--digests` flag: |
|
| 506 |
+ |
|
| 507 |
+ $ docker images --digests | head |
|
| 508 |
+ REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE |
|
| 509 |
+ ouruser/sinatra latest sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf 5db5f8471261 11 hours ago 446.7 MB |
|
| 510 |
+ |
|
| 511 |
+When pushing or pulling to a 2.0 registry, the `push` or `pull` command |
|
| 512 |
+output includes the image digest. You can `pull` using a digest value. |
|
| 513 |
+ |
|
| 514 |
+ $ docker pull ouruser/sinatra@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf |
|
| 515 |
+ |
|
| 516 |
+You can also reference by digest in `create`, `run`, and `rmi` commands, as well as the |
|
| 517 |
+`FROM` image reference in a Dockerfile. |
|
| 518 |
+ |
|
| 519 |
+## Push an image to Docker Hub |
|
| 520 |
+ |
|
| 521 |
+Once you've built or created a new image you can push it to [Docker |
|
| 522 |
+Hub](https://hub.docker.com) using the `docker push` command. This |
|
| 523 |
+allows you to share it with others, either publicly, or push it into [a |
|
| 524 |
+private repository](https://hub.docker.com/account/billing-plans/). |
|
| 525 |
+ |
|
| 526 |
+ $ docker push ouruser/sinatra |
|
| 527 |
+ The push refers to a repository [ouruser/sinatra] (len: 1) |
|
| 528 |
+ Sending image list |
|
| 529 |
+ Pushing repository ouruser/sinatra (3 tags) |
|
| 530 |
+ . . . |
|
| 531 |
+ |
|
| 532 |
+## Remove an image from the host |
|
| 533 |
+ |
|
| 534 |
+You can also remove images on your Docker host in a way [similar to |
|
| 535 |
+containers](usingdocker.md) using the `docker rmi` command. |
|
| 536 |
+ |
|
| 537 |
+Delete the `training/sinatra` image as you don't need it anymore. |
|
| 538 |
+ |
|
| 539 |
+ $ docker rmi training/sinatra |
|
| 540 |
+ Untagged: training/sinatra:latest |
|
| 541 |
+ Deleted: 5bc342fa0b91cabf65246837015197eecfa24b2213ed6a51a8974ae250fedd8d |
|
| 542 |
+ Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f |
|
| 543 |
+ Deleted: 5c58979d73ae448df5af1d8142436d81116187a7633082650549c52c3a2418f0 |
|
| 544 |
+ |
|
| 545 |
+> **Note:** To remove an image from the host, please make sure |
|
| 546 |
+> that there are no containers actively based on it. |
|
| 547 |
+ |
|
| 548 |
+# Next steps |
|
| 549 |
+ |
|
| 550 |
+Until now you've seen how to build individual applications inside Docker |
|
| 551 |
+containers. Now learn how to build whole application stacks with Docker |
|
| 552 |
+by networking together multiple Docker containers. |
|
| 553 |
+ |
|
| 554 |
+Go to [Network containers](networkingcontainers.md). |
| 0 | 555 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,197 @@ |
| 0 |
+<!--[metadata]> |
|
| 1 |
+aliases = [ |
|
| 2 |
+"/engine/userguide/containers/dockerizing/", |
|
| 3 |
+"/engine/userguide/dockerizing/" |
|
| 4 |
+] |
|
| 5 |
+title = "Hello world in a container" |
|
| 6 |
+description = "A simple 'Hello world' exercise that introduced you to Docker." |
|
| 7 |
+keywords = ["docker guide, docker, docker platform, how to, dockerize, dockerizing apps, dockerizing applications, container, containers"] |
|
| 8 |
+[menu.main] |
|
| 9 |
+parent = "engine_learn" |
|
| 10 |
+weight=-6 |
|
| 11 |
+<![end-metadata]--> |
|
| 12 |
+ |
|
| 13 |
+# Hello world in a container |
|
| 14 |
+ |
|
| 15 |
+*So what's this Docker thing all about?* |
|
| 16 |
+ |
|
| 17 |
+Docker allows you to run applications, worlds you create, inside containers. |
|
| 18 |
+Running an application inside a container takes a single command: `docker run`. |
|
| 19 |
+ |
|
| 20 |
+>**Note**: Depending on your Docker system configuration, you may be required to |
|
| 21 |
+>preface each `docker` command on this page with `sudo`. To avoid this behavior, |
|
| 22 |
+>your system administrator can create a Unix group called `docker` and add users |
|
| 23 |
+>to it. |
|
| 24 |
+ |
|
| 25 |
+## Run a Hello world |
|
| 26 |
+ |
|
| 27 |
+Let's run a hello world container. |
|
| 28 |
+ |
|
| 29 |
+ $ docker run ubuntu /bin/echo 'Hello world' |
|
| 30 |
+ Hello world |
|
| 31 |
+ |
|
| 32 |
+You just launched your first container! |
|
| 33 |
+ |
|
| 34 |
+In this example: |
|
| 35 |
+ |
|
| 36 |
+* `docker run` runs a container. |
|
| 37 |
+ |
|
| 38 |
+* `ubuntu` is the image you run, for example the Ubuntu operating system image. |
|
| 39 |
+ When you specify an image, Docker looks first for the image on your |
|
| 40 |
+ Docker host. If the image does not exist locally, then the image is pulled from the public |
|
| 41 |
+ image registry [Docker Hub](https://hub.docker.com). |
|
| 42 |
+ |
|
| 43 |
+* `/bin/echo` is the command to run inside the new container. |
|
| 44 |
+ |
|
| 45 |
+The container launches. Docker creates a new Ubuntu |
|
| 46 |
+environment and executes the `/bin/echo` command inside it and then prints out: |
|
| 47 |
+ |
|
| 48 |
+ Hello world |
|
| 49 |
+ |
|
| 50 |
+So what happened to the container after that? Well, Docker containers |
|
| 51 |
+only run as long as the command you specify is active. Therefore, in the above example, |
|
| 52 |
+the container stops once the command is executed. |
|
| 53 |
+ |
|
| 54 |
+## Run an interactive container |
|
| 55 |
+ |
|
| 56 |
+Let's specify a new command to run in the container. |
|
| 57 |
+ |
|
| 58 |
+ $ docker run -t -i ubuntu /bin/bash |
|
| 59 |
+ root@af8bae53bdd3:/# |
|
| 60 |
+ |
|
| 61 |
+In this example: |
|
| 62 |
+ |
|
| 63 |
+* `docker run` runs a container. |
|
| 64 |
+* `ubuntu` is the image you would like to run. |
|
| 65 |
+* `-t` flag assigns a pseudo-tty or terminal inside the new container. |
|
| 66 |
+* `-i` flag allows you to make an interactive connection by |
|
| 67 |
+grabbing the standard in (`STDIN`) of the container. |
|
| 68 |
+* `/bin/bash` launches a Bash shell inside our container. |
|
| 69 |
+ |
|
| 70 |
+The container launches. We can see there is a |
|
| 71 |
+command prompt inside it: |
|
| 72 |
+ |
|
| 73 |
+ root@af8bae53bdd3:/# |
|
| 74 |
+ |
|
| 75 |
+Let's try running some commands inside the container: |
|
| 76 |
+ |
|
| 77 |
+ root@af8bae53bdd3:/# pwd |
|
| 78 |
+ / |
|
| 79 |
+ root@af8bae53bdd3:/# ls |
|
| 80 |
+ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var |
|
| 81 |
+ |
|
| 82 |
+In this example: |
|
| 83 |
+ |
|
| 84 |
+* `pwd` displays the current directory, the `/` root directory. |
|
| 85 |
+* `ls` displays the directory listing of the root directory of a typical Linux file system. |
|
| 86 |
+ |
|
| 87 |
+Now, you can play around inside this container. When completed, run the `exit` command or enter Ctrl-D |
|
| 88 |
+to exit the interactive shell. |
|
| 89 |
+ |
|
| 90 |
+ root@af8bae53bdd3:/# exit |
|
| 91 |
+ |
|
| 92 |
+>**Note:** As with our previous container, once the Bash shell process has |
|
| 93 |
+finished, the container stops. |
|
| 94 |
+ |
|
| 95 |
+## Start a daemonized Hello world |
|
| 96 |
+ |
|
| 97 |
+Let's create a container that runs as a daemon. |
|
| 98 |
+ |
|
| 99 |
+ $ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done" |
|
| 100 |
+ 1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147 |
|
| 101 |
+ |
|
| 102 |
+In this example: |
|
| 103 |
+ |
|
| 104 |
+* `docker run` runs the container. |
|
| 105 |
+* `-d` flag runs the container in the background (to daemonize it). |
|
| 106 |
+* `ubuntu` is the image you would like to run. |
|
| 107 |
+ |
|
| 108 |
+Finally, we specify a command to run: |
|
| 109 |
+ |
|
| 110 |
+ /bin/sh -c "while true; do echo hello world; sleep 1; done" |
|
| 111 |
+ |
|
| 112 |
+ |
|
| 113 |
+In the output, we do not see `hello world` but a long string: |
|
| 114 |
+ |
|
| 115 |
+ 1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147 |
|
| 116 |
+ |
|
| 117 |
+This long string is called a *container ID*. It uniquely |
|
| 118 |
+identifies a container so we can work with it. |
|
| 119 |
+ |
|
| 120 |
+> **Note:** |
|
| 121 |
+> The container ID is a bit long and unwieldy. Later, we will cover the short |
|
| 122 |
+> ID and ways to name our containers to make |
|
| 123 |
+> working with them easier. |
|
| 124 |
+ |
|
| 125 |
+We can use this container ID to see what's happening with our `hello world` daemon. |
|
| 126 |
+ |
|
| 127 |
+First, let's make sure our container is running. Run the `docker ps` command. |
|
| 128 |
+The `docker ps` command queries the Docker daemon for information about all the containers it knows |
|
| 129 |
+about. |
|
| 130 |
+ |
|
| 131 |
+ $ docker ps |
|
| 132 |
+ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
|
| 133 |
+ 1e5535038e28 ubuntu /bin/sh -c 'while tr 2 minutes ago Up 1 minute insane_babbage |
|
| 134 |
+ |
|
| 135 |
+In this example, we can see our daemonized container. The `docker ps` returns some useful |
|
| 136 |
+information: |
|
| 137 |
+ |
|
| 138 |
+* `1e5535038e28` is the shorter variant of the container ID. |
|
| 139 |
+* `ubuntu` is the used image. |
|
| 140 |
+* the command, status, and assigned name `insane_babbage`. |
|
| 141 |
+ |
|
| 142 |
+ |
|
| 143 |
+> **Note:** |
|
| 144 |
+> Docker automatically generates names for any containers started. |
|
| 145 |
+> We'll see how to specify your own names a bit later. |
|
| 146 |
+ |
|
| 147 |
+Now, we know the container is running. But is it doing what we asked it to do? To |
|
| 148 |
+see this we're going to look inside the container using the `docker logs` |
|
| 149 |
+command. |
|
| 150 |
+ |
|
| 151 |
+Let's use the container name `insane_babbage`. |
|
| 152 |
+ |
|
| 153 |
+ $ docker logs insane_babbage |
|
| 154 |
+ hello world |
|
| 155 |
+ hello world |
|
| 156 |
+ hello world |
|
| 157 |
+ . . . |
|
| 158 |
+ |
|
| 159 |
+In this example: |
|
| 160 |
+ |
|
| 161 |
+* `docker logs` looks inside the container and returns `hello world`. |
|
| 162 |
+ |
|
| 163 |
+Awesome! The daemon is working and you have just created your first |
|
| 164 |
+Dockerized application! |
|
| 165 |
+ |
|
| 166 |
+Next, run the `docker stop` command to stop our detached container. |
|
| 167 |
+ |
|
| 168 |
+ $ docker stop insane_babbage |
|
| 169 |
+ insane_babbage |
|
| 170 |
+ |
|
| 171 |
+The `docker stop` command tells Docker to politely stop the running |
|
| 172 |
+container and returns the name of the container it stopped. |
|
| 173 |
+ |
|
| 174 |
+Let's check it worked with the `docker ps` command. |
|
| 175 |
+ |
|
| 176 |
+ $ docker ps |
|
| 177 |
+ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
|
| 178 |
+ |
|
| 179 |
+Excellent. Our container is stopped. |
|
| 180 |
+ |
|
| 181 |
+# Next steps |
|
| 182 |
+ |
|
| 183 |
+So far, you launched your first containers using the `docker run` command. You |
|
| 184 |
+ran an *interactive container* that ran in the foreground. You also ran a |
|
| 185 |
+*detached container* that ran in the background. In the process you learned |
|
| 186 |
+about several Docker commands: |
|
| 187 |
+ |
|
| 188 |
+* `docker ps` - Lists containers. |
|
| 189 |
+* `docker logs` - Shows us the standard output of a container. |
|
| 190 |
+* `docker stop` - Stops running containers. |
|
| 191 |
+ |
|
| 192 |
+Now, you have the basis learn more about Docker and how to do some more advanced |
|
| 193 |
+tasks. Go to ["*Run a simple application*"](usingdocker.md) to actually build a |
|
| 194 |
+web application with the Docker client. |
| 0 | 195 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,190 @@ |
| 0 |
+<!--[metadata]> |
|
| 1 |
+aliases = [ |
|
| 2 |
+"/engine/userguide/containers/dockerrepos/", |
|
| 3 |
+"/engine/userguide/dockerrepos/" |
|
| 4 |
+] |
|
| 5 |
+title = "Store images on Docker Hub" |
|
| 6 |
+description = "Learn how to use the Docker Hub to manage Docker images and work flow" |
|
| 7 |
+keywords = ["repo, Docker Hub, Docker Hub, registry, index, repositories, usage, pull image, push image, image, documentation"] |
|
| 8 |
+[menu.main] |
|
| 9 |
+parent = "engine_learn" |
|
| 10 |
+<![end-metadata]--> |
|
| 11 |
+ |
|
| 12 |
+# Store images on Docker Hub |
|
| 13 |
+ |
|
| 14 |
+So far you've learned how to use the command line to run Docker on your local |
|
| 15 |
+host. You've learned how to [pull down images](usingdocker.md) to build |
|
| 16 |
+containers from existing images and you've learned how to [create your own |
|
| 17 |
+images](dockerimages.md). |
|
| 18 |
+ |
|
| 19 |
+Next, you're going to learn how to use the [Docker Hub](https://hub.docker.com) |
|
| 20 |
+to simplify and enhance your Docker workflows. |
|
| 21 |
+ |
|
| 22 |
+The [Docker Hub](https://hub.docker.com) is a public registry maintained by |
|
| 23 |
+Docker, Inc. It contains images you can download and use to build |
|
| 24 |
+containers. It also provides authentication, work group structure, workflow |
|
| 25 |
+tools like webhooks and build triggers, and privacy tools like private |
|
| 26 |
+repositories for storing images you don't want to share publicly. |
|
| 27 |
+ |
|
| 28 |
+## Docker commands and Docker Hub |
|
| 29 |
+ |
|
| 30 |
+Docker itself provides access to Docker Hub services via the `docker search`, |
|
| 31 |
+`pull`, `login`, and `push` commands. This page will show you how these commands work. |
|
| 32 |
+ |
|
| 33 |
+### Account creation and login |
|
| 34 |
+Before you try an Engine CLI command, if you haven't already, create a Docker |
|
| 35 |
+ID. You can do this through [Docker Hub](https://hub.docker.com/). Once you have |
|
| 36 |
+a Docker ID, log into your account from the Engine CLI: |
|
| 37 |
+ |
|
| 38 |
+```bash |
|
| 39 |
+$ docker login |
|
| 40 |
+``` |
|
| 41 |
+ |
|
| 42 |
+The `login` command stores your Docker ID authentication credentials in the |
|
| 43 |
+`$HOME/.docker/config.json` (Bash notation). For Windows `cmd` users the |
|
| 44 |
+notation for this file is `%HOME%\.docker\config.json` ; for PowerShell users |
|
| 45 |
+the notation is `$env:Home\.docker\config.json`. |
|
| 46 |
+ |
|
| 47 |
+Once you have logged in from the command line, you can `commit` and `push` |
|
| 48 |
+Engine subcommands to interact with your repos on Docker Hub. |
|
| 49 |
+ |
|
| 50 |
+## Searching for images |
|
| 51 |
+ |
|
| 52 |
+You can search the [Docker Hub](https://hub.docker.com) registry via its search |
|
| 53 |
+interface or by using the command line interface. Searching can find images by image |
|
| 54 |
+name, user name, or description: |
|
| 55 |
+ |
|
| 56 |
+ $ docker search centos |
|
| 57 |
+ NAME DESCRIPTION STARS OFFICIAL AUTOMATED |
|
| 58 |
+ centos The official build of CentOS 1223 [OK] |
|
| 59 |
+ tianon/centos CentOS 5 and 6, created using rinse instea... 33 |
|
| 60 |
+ ... |
|
| 61 |
+ |
|
| 62 |
+There you can see two example results: `centos` and `tianon/centos`. The second |
|
| 63 |
+result shows that it comes from the public repository of a user, named |
|
| 64 |
+`tianon/`, while the first result, `centos`, doesn't explicitly list a |
|
| 65 |
+repository which means that it comes from the trusted top-level namespace for |
|
| 66 |
+[Official Repositories](https://docs.docker.com/docker-hub/official_repos/). The `/` character separates |
|
| 67 |
+a user's repository from the image name. |
|
| 68 |
+ |
|
| 69 |
+Once you've found the image you want, you can download it with `docker pull <imagename>`: |
|
| 70 |
+ |
|
| 71 |
+ $ docker pull centos |
|
| 72 |
+ Using default tag: latest |
|
| 73 |
+ latest: Pulling from library/centos |
|
| 74 |
+ f1b10cd84249: Pull complete |
|
| 75 |
+ c852f6d61e65: Pull complete |
|
| 76 |
+ 7322fbe74aa5: Pull complete |
|
| 77 |
+ Digest: sha256:90305c9112250c7e3746425477f1c4ef112b03b4abe78c612e092037bfecc3b7 |
|
| 78 |
+ Status: Downloaded newer image for centos:latest |
|
| 79 |
+ |
|
| 80 |
+You now have an image from which you can run containers. |
|
| 81 |
+ |
|
| 82 |
+### Specific Versions or Latest |
|
| 83 |
+Using `docker pull centos` is equivalent to using `docker pull centos:latest`. |
|
| 84 |
+To pull an image that is not the default latest image you can be more precise |
|
| 85 |
+with the image that you want. |
|
| 86 |
+ |
|
| 87 |
+For example, to pull version 5 of `centos` use `docker pull centos:centos5`. |
|
| 88 |
+In this example, `centos5` is the tag labeling an image in the `centos` |
|
| 89 |
+repository for a version of `centos`. |
|
| 90 |
+ |
|
| 91 |
+To find a list of tags pointing to currently available versions of a repository |
|
| 92 |
+see the [Docker Hub](https://hub.docker.com) registry. |
|
| 93 |
+ |
|
| 94 |
+## Contributing to Docker Hub |
|
| 95 |
+ |
|
| 96 |
+Anyone can pull public images from the [Docker Hub](https://hub.docker.com) |
|
| 97 |
+registry, but if you would like to share your own images, then you must |
|
| 98 |
+[register first](https://docs.docker.com/docker-hub/accounts). |
|
| 99 |
+ |
|
| 100 |
+## Pushing a repository to Docker Hub |
|
| 101 |
+ |
|
| 102 |
+In order to push a repository to its registry, you need to have named an image |
|
| 103 |
+or committed your container to a named image as we saw |
|
| 104 |
+[here](dockerimages.md). |
|
| 105 |
+ |
|
| 106 |
+Now you can push this repository to the registry designated by its name or tag. |
|
| 107 |
+ |
|
| 108 |
+ $ docker push yourname/newimage |
|
| 109 |
+ |
|
| 110 |
+The image will then be uploaded and available for use by your team-mates and/or the |
|
| 111 |
+community. |
|
| 112 |
+ |
|
| 113 |
+## Features of Docker Hub |
|
| 114 |
+ |
|
| 115 |
+Let's take a closer look at some of the features of Docker Hub. You can find more |
|
| 116 |
+information [here](https://docs.docker.com/docker-hub/). |
|
| 117 |
+ |
|
| 118 |
+* Private repositories |
|
| 119 |
+* Organizations and teams |
|
| 120 |
+* Automated Builds |
|
| 121 |
+* Webhooks |
|
| 122 |
+ |
|
| 123 |
+### Private repositories |
|
| 124 |
+ |
|
| 125 |
+Sometimes you have images you don't want to make public and share with |
|
| 126 |
+everyone. So Docker Hub allows you to have private repositories. You can |
|
| 127 |
+sign up for a plan [here](https://hub.docker.com/account/billing-plans/). |
|
| 128 |
+ |
|
| 129 |
+### Organizations and teams |
|
| 130 |
+ |
|
| 131 |
+One of the useful aspects of private repositories is that you can share |
|
| 132 |
+them only with members of your organization or team. Docker Hub lets you |
|
| 133 |
+create organizations where you can collaborate with your colleagues and |
|
| 134 |
+manage private repositories. You can learn how to create and manage an organization |
|
| 135 |
+[here](https://hub.docker.com/organizations/). |
|
| 136 |
+ |
|
| 137 |
+### Automated Builds |
|
| 138 |
+ |
|
| 139 |
+Automated Builds automate the building and updating of images from |
|
| 140 |
+[GitHub](https://www.github.com) or [Bitbucket](http://bitbucket.com), directly on Docker |
|
| 141 |
+Hub. It works by adding a commit hook to your selected GitHub or Bitbucket repository, |
|
| 142 |
+triggering a build and update when you push a commit. |
|
| 143 |
+ |
|
| 144 |
+#### To setup an Automated Build |
|
| 145 |
+ |
|
| 146 |
+1. Create a [Docker Hub account](https://hub.docker.com/) and login. |
|
| 147 |
+2. Link your GitHub or Bitbucket account on the ["Linked Accounts & Services"](https://hub.docker.com/account/authorized-services/) page. |
|
| 148 |
+3. Select "Create Automated Build" from the "Create" dropdown menu |
|
| 149 |
+4. Pick a GitHub or Bitbucket project that has a `Dockerfile` that you want to build. |
|
| 150 |
+5. Pick the branch you want to build (the default is the `master` branch). |
|
| 151 |
+6. Give the Automated Build a name. |
|
| 152 |
+7. Assign an optional Docker tag to the Build. |
|
| 153 |
+8. Specify where the `Dockerfile` is located. The default is `/`. |
|
| 154 |
+ |
|
| 155 |
+Once the Automated Build is configured it will automatically trigger a |
|
| 156 |
+build and, in a few minutes, you should see your new Automated Build on the [Docker Hub](https://hub.docker.com) |
|
| 157 |
+Registry. It will stay in sync with your GitHub and Bitbucket repository until you |
|
| 158 |
+deactivate the Automated Build. |
|
| 159 |
+ |
|
| 160 |
+To check the output and status of your Automated Build repositories, click on a repository name within the ["Your Repositories" page](https://registry.hub.docker.com/repos/). Automated Builds are indicated by a check-mark icon next to the repository name. Within the repository details page, you may click on the "Build Details" tab to view the status and output of all builds triggered by the Docker Hub. |
|
| 161 |
+ |
|
| 162 |
+Once you've created an Automated Build you can deactivate or delete it. You |
|
| 163 |
+cannot, however, push to an Automated Build with the `docker push` command. |
|
| 164 |
+You can only manage it by committing code to your GitHub or Bitbucket |
|
| 165 |
+repository. |
|
| 166 |
+ |
|
| 167 |
+You can create multiple Automated Builds per repository and configure them |
|
| 168 |
+to point to specific `Dockerfile`'s or Git branches. |
|
| 169 |
+ |
|
| 170 |
+#### Build triggers |
|
| 171 |
+ |
|
| 172 |
+Automated Builds can also be triggered via a URL on Docker Hub. This |
|
| 173 |
+allows you to rebuild an Automated build image on demand. |
|
| 174 |
+ |
|
| 175 |
+### Webhooks |
|
| 176 |
+ |
|
| 177 |
+Webhooks are attached to your repositories and allow you to trigger an |
|
| 178 |
+event when an image or updated image is pushed to the repository. With |
|
| 179 |
+a webhook you can specify a target URL and a JSON payload that will be |
|
| 180 |
+delivered when the image is pushed. |
|
| 181 |
+ |
|
| 182 |
+See the Docker Hub documentation for [more information on |
|
| 183 |
+webhooks](https://docs.docker.com/docker-hub/repos/#webhooks) |
|
| 184 |
+ |
|
| 185 |
+## Next steps |
|
| 186 |
+ |
|
| 187 |
+Go and use Docker! |
| 0 | 188 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,375 @@ |
| 0 |
+<!--[metadata]> |
|
| 1 |
+aliases = [ |
|
| 2 |
+"/engine/userguide/containers/dockervolumes/", |
|
| 3 |
+"/engine/userguide/dockervolumes/" |
|
| 4 |
+] |
|
| 5 |
+title = "Manage data in containers" |
|
| 6 |
+description = "How to manage data inside your Docker containers." |
|
| 7 |
+keywords = ["Examples, Usage, volume, docker, documentation, user guide, data, volumes"] |
|
| 8 |
+[menu.main] |
|
| 9 |
+parent = "engine_learn" |
|
| 10 |
+<![end-metadata]--> |
|
| 11 |
+ |
|
| 12 |
+# Manage data in containers |
|
| 13 |
+ |
|
| 14 |
+So far you've been introduced to some [basic Docker |
|
| 15 |
+concepts](usingdocker.md), seen how to work with [Docker |
|
| 16 |
+images](dockerimages.md) as well as learned about [networking and |
|
| 17 |
+links between containers](../userguide/networking/default_network/dockerlinks.md). In this |
|
| 18 |
+section you're going to learn how you can manage data inside and between your |
|
| 19 |
+Docker containers. |
|
| 20 |
+ |
|
| 21 |
+You're going to look at the two primary ways you can manage data with |
|
| 22 |
+Docker Engine. |
|
| 23 |
+ |
|
| 24 |
+* Data volumes |
|
| 25 |
+* Data volume containers |
|
| 26 |
+ |
|
| 27 |
+## Data volumes |
|
| 28 |
+ |
|
| 29 |
+A *data volume* is a specially-designated directory within one or more |
|
| 30 |
+containers that bypasses the [*Union File System*](../reference/glossary.md#union-file-system). Data volumes provide several useful features for persistent or shared data: |
|
| 31 |
+ |
|
| 32 |
+- Volumes are initialized when a container is created. If the container's |
|
| 33 |
+ base image contains data at the specified mount point, that existing data is |
|
| 34 |
+ copied into the new volume upon volume initialization. (Note that this does |
|
| 35 |
+ not apply when [mounting a host directory](#mount-a-host-directory-as-a-data-volume).) |
|
| 36 |
+- Data volumes can be shared and reused among containers. |
|
| 37 |
+- Changes to a data volume are made directly. |
|
| 38 |
+- Changes to a data volume will not be included when you update an image. |
|
| 39 |
+- Data volumes persist even if the container itself is deleted. |
|
| 40 |
+ |
|
| 41 |
+Data volumes are designed to persist data, independent of the container's life |
|
| 42 |
+cycle. Docker therefore *never* automatically deletes volumes when you remove |
|
| 43 |
+a container, nor will it "garbage collect" volumes that are no longer |
|
| 44 |
+referenced by a container. |
|
| 45 |
+ |
|
| 46 |
+### Adding a data volume |
|
| 47 |
+ |
|
| 48 |
+You can add a data volume to a container using the `-v` flag with the |
|
| 49 |
+`docker create` and `docker run` command. You can use the `-v` multiple times |
|
| 50 |
+to mount multiple data volumes. Now, mount a single volume in your web |
|
| 51 |
+application container. |
|
| 52 |
+ |
|
| 53 |
+```bash |
|
| 54 |
+$ docker run -d -P --name web -v /webapp training/webapp python app.py |
|
| 55 |
+``` |
|
| 56 |
+ |
|
| 57 |
+This will create a new volume inside a container at `/webapp`. |
|
| 58 |
+ |
|
| 59 |
+> **Note:** |
|
| 60 |
+> You can also use the `VOLUME` instruction in a `Dockerfile` to add one or |
|
| 61 |
+> more new volumes to any container created from that image. |
|
| 62 |
+ |
|
| 63 |
+### Locating a volume |
|
| 64 |
+ |
|
| 65 |
+You can locate the volume on the host by utilizing the `docker inspect` command. |
|
| 66 |
+ |
|
| 67 |
+```bash |
|
| 68 |
+$ docker inspect web |
|
| 69 |
+``` |
|
| 70 |
+ |
|
| 71 |
+The output will provide details on the container configurations including the |
|
| 72 |
+volumes. The output should look something similar to the following: |
|
| 73 |
+ |
|
| 74 |
+```json |
|
| 75 |
+... |
|
| 76 |
+"Mounts": [ |
|
| 77 |
+ {
|
|
| 78 |
+ "Name": "fac362...80535", |
|
| 79 |
+ "Source": "/var/lib/docker/volumes/fac362...80535/_data", |
|
| 80 |
+ "Destination": "/webapp", |
|
| 81 |
+ "Driver": "local", |
|
| 82 |
+ "Mode": "", |
|
| 83 |
+ "RW": true, |
|
| 84 |
+ "Propagation": "" |
|
| 85 |
+ } |
|
| 86 |
+] |
|
| 87 |
+... |
|
| 88 |
+``` |
|
| 89 |
+ |
|
| 90 |
+You will notice in the above `Source` is specifying the location on the host and |
|
| 91 |
+`Destination` is specifying the volume location inside the container. `RW` shows |
|
| 92 |
+if the volume is read/write. |
|
| 93 |
+ |
|
| 94 |
+### Mount a host directory as a data volume |
|
| 95 |
+ |
|
| 96 |
+In addition to creating a volume using the `-v` flag you can also mount a |
|
| 97 |
+directory from your Engine daemon's host into a container. |
|
| 98 |
+ |
|
| 99 |
+```bash |
|
| 100 |
+$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py |
|
| 101 |
+``` |
|
| 102 |
+ |
|
| 103 |
+This command mounts the host directory, `/src/webapp`, into the container at |
|
| 104 |
+`/opt/webapp`. If the path `/opt/webapp` already exists inside the container's |
|
| 105 |
+image, the `/src/webapp` mount overlays but does not remove the pre-existing |
|
| 106 |
+content. Once the mount is removed, the content is accessible again. This is |
|
| 107 |
+consistent with the expected behavior of the `mount` command. |
|
| 108 |
+ |
|
| 109 |
+The `container-dir` must always be an absolute path such as `/src/docs`. |
|
| 110 |
+The `host-dir` can either be an absolute path or a `name` value. If you |
|
| 111 |
+supply an absolute path for the `host-dir`, Docker bind-mounts to the path |
|
| 112 |
+you specify. If you supply a `name`, Docker creates a named volume by that `name`. |
|
| 113 |
+ |
|
| 114 |
+A `name` value must start with an alphanumeric character, |
|
| 115 |
+followed by `a-z0-9`, `_` (underscore), `.` (period) or `-` (hyphen). |
|
| 116 |
+An absolute path starts with a `/` (forward slash). |
|
| 117 |
+ |
|
| 118 |
+For example, you can specify either `/foo` or `foo` for a `host-dir` value. |
|
| 119 |
+If you supply the `/foo` value, Engine creates a bind-mount. If you supply |
|
| 120 |
+the `foo` specification, Engine creates a named volume. |
|
| 121 |
+ |
|
| 122 |
+If you are using Docker Machine on Mac or Windows, your Engine daemon has only |
|
| 123 |
+limited access to your OS X or Windows filesystem. Docker Machine tries to |
|
| 124 |
+auto-share your `/Users` (OS X) or `C:\Users` (Windows) directory. So, you can |
|
| 125 |
+mount files or directories on OS X using. |
|
| 126 |
+ |
|
| 127 |
+```bash |
|
| 128 |
+docker run -v /Users/<path>:/<container path> ... |
|
| 129 |
+``` |
|
| 130 |
+ |
|
| 131 |
+On Windows, mount directories using: |
|
| 132 |
+ |
|
| 133 |
+```bash |
|
| 134 |
+docker run -v /c/Users/<path>:/<container path> ...` |
|
| 135 |
+``` |
|
| 136 |
+ |
|
| 137 |
+All other paths come from your virtual machine's filesystem, so if you want |
|
| 138 |
+to make some other host folder available for sharing, you need to do |
|
| 139 |
+additional work. In the case of VirtualBox you need to make the host folder |
|
| 140 |
+available as a shared folder in VirtualBox. Then, you can mount it using the |
|
| 141 |
+Docker `-v` flag. |
|
| 142 |
+ |
|
| 143 |
+Mounting a host directory can be useful for testing. For example, you can mount |
|
| 144 |
+source code inside a container. Then, change the source code and see its effect |
|
| 145 |
+on the application in real time. The directory on the host must be specified as |
|
| 146 |
+an absolute path and if the directory doesn't exist the Engine daemon automatically |
|
| 147 |
+creates it for you. |
|
| 148 |
+ |
|
| 149 |
+Docker volumes default to mount in read-write mode, but you can also set it to |
|
| 150 |
+be mounted read-only. |
|
| 151 |
+ |
|
| 152 |
+```bash |
|
| 153 |
+$ docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py |
|
| 154 |
+``` |
|
| 155 |
+ |
|
| 156 |
+Here you've mounted the same `/src/webapp` directory but you've added the `ro` |
|
| 157 |
+option to specify that the mount should be read-only. |
|
| 158 |
+ |
|
| 159 |
+Because of [limitations in the `mount` |
|
| 160 |
+function](http://lists.linuxfoundation.org/pipermail/containers/2015-April/035788.html), |
|
| 161 |
+moving subdirectories within the host's source directory can give |
|
| 162 |
+access from the container to the host's file system. This requires a malicious |
|
| 163 |
+user with access to host and its mounted directory. |
|
| 164 |
+ |
|
| 165 |
+>**Note**: The host directory is, by its nature, host-dependent. For this |
|
| 166 |
+>reason, you can't mount a host directory from `Dockerfile` because built images |
|
| 167 |
+>should be portable. A host directory wouldn't be available on all potential |
|
| 168 |
+>hosts. |
|
| 169 |
+ |
|
| 170 |
+### Mount a shared-storage volume as a data volume |
|
| 171 |
+ |
|
| 172 |
+In addition to mounting a host directory in your container, some Docker |
|
| 173 |
+[volume plugins](../extend/plugins_volume.md) allow you to |
|
| 174 |
+provision and mount shared storage, such as iSCSI, NFS, or FC. |
|
| 175 |
+ |
|
| 176 |
+A benefit of using shared volumes is that they are host-independent. This |
|
| 177 |
+means that a volume can be made available on any host that a container is |
|
| 178 |
+started on as long as it has access to the shared storage backend, and has |
|
| 179 |
+the plugin installed. |
|
| 180 |
+ |
|
| 181 |
+One way to use volume drivers is through the `docker run` command. |
|
| 182 |
+Volume drivers create volumes by name, instead of by path like in |
|
| 183 |
+the other examples. |
|
| 184 |
+ |
|
| 185 |
+The following command creates a named volume, called `my-named-volume`, |
|
| 186 |
+using the `flocker` volume driver, and makes it available within the container |
|
| 187 |
+at `/opt/webapp`: |
|
| 188 |
+ |
|
| 189 |
+```bash |
|
| 190 |
+$ docker run -d -P \ |
|
| 191 |
+ --volume-driver=flocker \ |
|
| 192 |
+ -v my-named-volume:/opt/webapp \ |
|
| 193 |
+ --name web training/webapp python app.py |
|
| 194 |
+``` |
|
| 195 |
+ |
|
| 196 |
+You may also use the `docker volume create` command, to create a volume before |
|
| 197 |
+using it in a container. |
|
| 198 |
+ |
|
| 199 |
+The following example also creates the `my-named-volume` volume, this time |
|
| 200 |
+using the `docker volume create` command. |
|
| 201 |
+ |
|
| 202 |
+```bash |
|
| 203 |
+$ docker volume create -d flocker --name my-named-volume -o size=20GB |
|
| 204 |
+$ docker run -d -P \ |
|
| 205 |
+ -v my-named-volume:/opt/webapp \ |
|
| 206 |
+ --name web training/webapp python app.py |
|
| 207 |
+``` |
|
| 208 |
+ |
|
| 209 |
+A list of available plugins, including volume plugins, is available |
|
| 210 |
+[here](../extend/plugins.md). |
|
| 211 |
+ |
|
| 212 |
+### Volume labels |
|
| 213 |
+ |
|
| 214 |
+Labeling systems like SELinux require that proper labels are placed on volume |
|
| 215 |
+content mounted into a container. Without a label, the security system might |
|
| 216 |
+prevent the processes running inside the container from using the content. By |
|
| 217 |
+default, Docker does not change the labels set by the OS. |
|
| 218 |
+ |
|
| 219 |
+To change a label in the container context, you can add either of two suffixes |
|
| 220 |
+`:z` or `:Z` to the volume mount. These suffixes tell Docker to relabel file |
|
| 221 |
+objects on the shared volumes. The `z` option tells Docker that two containers |
|
| 222 |
+share the volume content. As a result, Docker labels the content with a shared |
|
| 223 |
+content label. Shared volume labels allow all containers to read/write content. |
|
| 224 |
+The `Z` option tells Docker to label the content with a private unshared label. |
|
| 225 |
+Only the current container can use a private volume. |
|
| 226 |
+ |
|
| 227 |
+### Mount a host file as a data volume |
|
| 228 |
+ |
|
| 229 |
+The `-v` flag can also be used to mount a single file - instead of *just* |
|
| 230 |
+directories - from the host machine. |
|
| 231 |
+ |
|
| 232 |
+```bash |
|
| 233 |
+$ docker run --rm -it -v ~/.bash_history:/root/.bash_history ubuntu /bin/bash |
|
| 234 |
+``` |
|
| 235 |
+ |
|
| 236 |
+This will drop you into a bash shell in a new container, you will have your bash |
|
| 237 |
+history from the host and when you exit the container, the host will have the |
|
| 238 |
+history of the commands typed while in the container. |
|
| 239 |
+ |
|
| 240 |
+> **Note:** |
|
| 241 |
+> Many tools used to edit files including `vi` and `sed --in-place` may result |
|
| 242 |
+> in an inode change. Since Docker v1.1.0, this will produce an error such as |
|
| 243 |
+> "*sed: cannot rename ./sedKdJ9Dy: Device or resource busy*". In the case where |
|
| 244 |
+> you want to edit the mounted file, it is often easiest to instead mount the |
|
| 245 |
+> parent directory. |
|
| 246 |
+ |
|
| 247 |
+## Creating and mounting a data volume container |
|
| 248 |
+ |
|
| 249 |
+If you have some persistent data that you want to share between |
|
| 250 |
+containers, or want to use from non-persistent containers, it's best to |
|
| 251 |
+create a named Data Volume Container, and then to mount the data from |
|
| 252 |
+it. |
|
| 253 |
+ |
|
| 254 |
+Let's create a new named container with a volume to share. |
|
| 255 |
+While this container doesn't run an application, it reuses the `training/postgres` |
|
| 256 |
+image so that all containers are using layers in common, saving disk space. |
|
| 257 |
+ |
|
| 258 |
+```bash |
|
| 259 |
+$ docker create -v /dbdata --name dbstore training/postgres /bin/true |
|
| 260 |
+``` |
|
| 261 |
+ |
|
| 262 |
+You can then use the `--volumes-from` flag to mount the `/dbdata` volume in another container. |
|
| 263 |
+ |
|
| 264 |
+```bash |
|
| 265 |
+$ docker run -d --volumes-from dbstore --name db1 training/postgres |
|
| 266 |
+``` |
|
| 267 |
+ |
|
| 268 |
+And another: |
|
| 269 |
+ |
|
| 270 |
+```bash |
|
| 271 |
+$ docker run -d --volumes-from dbstore --name db2 training/postgres |
|
| 272 |
+``` |
|
| 273 |
+ |
|
| 274 |
+In this case, if the `postgres` image contained a directory called `/dbdata` |
|
| 275 |
+then mounting the volumes from the `dbstore` container hides the |
|
| 276 |
+`/dbdata` files from the `postgres` image. The result is only the files |
|
| 277 |
+from the `dbstore` container are visible. |
|
| 278 |
+ |
|
| 279 |
+You can use multiple `--volumes-from` parameters to combine data volumes from |
|
| 280 |
+several containers. To find detailed information about `--volumes-from` see the |
|
| 281 |
+[Mount volumes from container](../reference/commandline/run.md#mount-volumes-from-container-volumes-from) |
|
| 282 |
+in the `run` command reference. |
|
| 283 |
+ |
|
| 284 |
+You can also extend the chain by mounting the volume that came from the |
|
| 285 |
+`dbstore` container in yet another container via the `db1` or `db2` containers. |
|
| 286 |
+ |
|
| 287 |
+```bash |
|
| 288 |
+$ docker run -d --name db3 --volumes-from db1 training/postgres |
|
| 289 |
+``` |
|
| 290 |
+ |
|
| 291 |
+If you remove containers that mount volumes, including the initial `dbstore` |
|
| 292 |
+container, or the subsequent containers `db1` and `db2`, the volumes will not |
|
| 293 |
+be deleted. To delete the volume from disk, you must explicitly call |
|
| 294 |
+`docker rm -v` against the last container with a reference to the volume. This |
|
| 295 |
+allows you to upgrade, or effectively migrate data volumes between containers. |
|
| 296 |
+ |
|
| 297 |
+> **Note:** Docker will not warn you when removing a container *without* |
|
| 298 |
+> providing the `-v` option to delete its volumes. If you remove containers |
|
| 299 |
+> without using the `-v` option, you may end up with "dangling" volumes; |
|
| 300 |
+> volumes that are no longer referenced by a container. |
|
| 301 |
+> You can use `docker volume ls -f dangling=true` to find dangling volumes, |
|
| 302 |
+> and use `docker volume rm <volume name>` to remove a volume that's |
|
| 303 |
+> no longer needed. |
|
| 304 |
+ |
|
| 305 |
+## Backup, restore, or migrate data volumes |
|
| 306 |
+ |
|
| 307 |
+Another useful function we can perform with volumes is use them for |
|
| 308 |
+backups, restores or migrations. You do this by using the |
|
| 309 |
+`--volumes-from` flag to create a new container that mounts that volume, |
|
| 310 |
+like so: |
|
| 311 |
+ |
|
| 312 |
+```bash |
|
| 313 |
+$ docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata |
|
| 314 |
+``` |
|
| 315 |
+ |
|
| 316 |
+Here you've launched a new container and mounted the volume from the |
|
| 317 |
+`dbstore` container. You've then mounted a local host directory as |
|
| 318 |
+`/backup`. Finally, you've passed a command that uses `tar` to backup the |
|
| 319 |
+contents of the `dbdata` volume to a `backup.tar` file inside our |
|
| 320 |
+`/backup` directory. When the command completes and the container stops |
|
| 321 |
+we'll be left with a backup of our `dbdata` volume. |
|
| 322 |
+ |
|
| 323 |
+You could then restore it to the same container, or another that you've made |
|
| 324 |
+elsewhere. Create a new container. |
|
| 325 |
+ |
|
| 326 |
+```bash |
|
| 327 |
+$ docker run -v /dbdata --name dbstore2 ubuntu /bin/bash |
|
| 328 |
+``` |
|
| 329 |
+ |
|
| 330 |
+Then un-tar the backup file in the new container`s data volume. |
|
| 331 |
+ |
|
| 332 |
+```bash |
|
| 333 |
+$ docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1" |
|
| 334 |
+``` |
|
| 335 |
+ |
|
| 336 |
+You can use the techniques above to automate backup, migration and |
|
| 337 |
+restore testing using your preferred tools. |
|
| 338 |
+ |
|
| 339 |
+## Removing volumes |
|
| 340 |
+ |
|
| 341 |
+A Docker data volume persists after a container is deleted. You can create named |
|
| 342 |
+or anonymous volumes. Named volumes have a specific source form outside the |
|
| 343 |
+container, for example `awesome:/bar`. Anonymous volumes have no specific |
|
| 344 |
+source. When the container is deleted, you should instruction the Engine daemon |
|
| 345 |
+to clean up anonymous volumes. To do this, use the `--rm` option, for example: |
|
| 346 |
+ |
|
| 347 |
+```bash |
|
| 348 |
+$ docker run --rm -v /foo -v awesome:/bar busybox top |
|
| 349 |
+``` |
|
| 350 |
+ |
|
| 351 |
+This command creates an anonymous `/foo` volume. When the container is removed, |
|
| 352 |
+Engine removes the `/foo` volume but not the `awesome` volume. |
|
| 353 |
+ |
|
| 354 |
+## Important tips on using shared volumes |
|
| 355 |
+ |
|
| 356 |
+Multiple containers can also share one or more data volumes. However, multiple |
|
| 357 |
+containers writing to a single shared volume can cause data corruption. Make |
|
| 358 |
+sure your applications are designed to write to shared data stores. |
|
| 359 |
+ |
|
| 360 |
+Data volumes are directly accessible from the Docker host. This means you can |
|
| 361 |
+read and write to them with normal Linux tools. In most cases you should not do |
|
| 362 |
+this as it can cause data corruption if your containers and applications are |
|
| 363 |
+unaware of your direct access. |
|
| 364 |
+ |
|
| 365 |
+# Next steps |
|
| 366 |
+ |
|
| 367 |
+Now you've learned a bit more about how to use Docker we're going to see how to |
|
| 368 |
+combine Docker with the services available on |
|
| 369 |
+[Docker Hub](https://hub.docker.com) including Automated Builds and private |
|
| 370 |
+repositories. |
|
| 371 |
+ |
|
| 372 |
+Go to [Store images in Docker Hub](dockerrepos.md). |
| 0 | 373 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,23 @@ |
| 0 |
+<!--[metadata]> |
|
| 1 |
+aliases = [ |
|
| 2 |
+"/engine/userguide/containers/", |
|
| 3 |
+] |
|
| 4 |
+title = "Learn by example" |
|
| 5 |
+description = "Explains how to work with containers" |
|
| 6 |
+keywords = ["docker, introduction, documentation, about, technology, docker.io, user, guide, user's, manual, platform, framework, home, intro"] |
|
| 7 |
+[menu.main] |
|
| 8 |
+identifier="engine_learn" |
|
| 9 |
+parent = "engine_use" |
|
| 10 |
+weight="-80" |
|
| 11 |
+<![end-metadata]--> |
|
| 12 |
+ |
|
| 13 |
+# Learn by example |
|
| 14 |
+ |
|
| 15 |
+* [Hello world in a container](dockerizing.md) |
|
| 16 |
+* [Run a simple application](usingdocker.md) |
|
| 17 |
+* [Build your own images](dockerimages.md) |
|
| 18 |
+* [Network containers](networkingcontainers.md) |
|
| 19 |
+* [Manage data in containers](dockervolumes.md) |
|
| 20 |
+* [Store images on Docker Hub](dockerrepos.md) |
| 0 | 21 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,250 @@ |
| 0 |
+<!--[metadata]> |
|
| 1 |
+aliases = [ |
|
| 2 |
+"/engine/userguide/containers/networkigncontainers/", |
|
| 3 |
+"/engine/userguide/networkigncontainers/" |
|
| 4 |
+] |
|
| 5 |
+title = "Network containers" |
|
| 6 |
+description = "How to network Docker containers." |
|
| 7 |
+keywords = ["Examples, Usage, volume, docker, documentation, user guide, data, volumes"] |
|
| 8 |
+[menu.main] |
|
| 9 |
+parent = "engine_learn" |
|
| 10 |
+weight = -3 |
|
| 11 |
+<![end-metadata]--> |
|
| 12 |
+ |
|
| 13 |
+ |
|
| 14 |
+# Network containers |
|
| 15 |
+ |
|
| 16 |
+If you are working your way through the user guide, you just built and ran a |
|
| 17 |
+simple application. You've also built in your own images. This section teaches |
|
| 18 |
+you how to network your containers. |
|
| 19 |
+ |
|
| 20 |
+## Name a container |
|
| 21 |
+ |
|
| 22 |
+You've already seen that each container you create has an automatically |
|
| 23 |
+created name; indeed you've become familiar with our old friend |
|
| 24 |
+`nostalgic_morse` during this guide. You can also name containers |
|
| 25 |
+yourself. This naming provides two useful functions: |
|
| 26 |
+ |
|
| 27 |
+* You can name containers that do specific functions in a way |
|
| 28 |
+ that makes it easier for you to remember them, for example naming a |
|
| 29 |
+ container containing a web application `web`. |
|
| 30 |
+ |
|
| 31 |
+* Names provide Docker with a reference point that allows it to refer to other |
|
| 32 |
+ containers. There are several commands that support this and you'll use one in an exercise later. |
|
| 33 |
+ |
|
| 34 |
+You name your container by using the `--name` flag, for example launch a new container called web: |
|
| 35 |
+ |
|
| 36 |
+ $ docker run -d -P --name web training/webapp python app.py |
|
| 37 |
+ |
|
| 38 |
+Use the `docker ps` command to check the name: |
|
| 39 |
+ |
|
| 40 |
+ $ docker ps -l |
|
| 41 |
+ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
|
| 42 |
+ aed84ee21bde training/webapp:latest python app.py 12 hours ago Up 2 seconds 0.0.0.0:49154->5000/tcp web |
|
| 43 |
+ |
|
| 44 |
+You can also use `docker inspect` with the container's name. |
|
| 45 |
+ |
|
| 46 |
+ $ docker inspect web |
|
| 47 |
+ [ |
|
| 48 |
+ {
|
|
| 49 |
+ "Id": "3ce51710b34f5d6da95e0a340d32aa2e6cf64857fb8cdb2a6c38f7c56f448143", |
|
| 50 |
+ "Created": "2015-10-25T22:44:17.854367116Z", |
|
| 51 |
+ "Path": "python", |
|
| 52 |
+ "Args": [ |
|
| 53 |
+ "app.py" |
|
| 54 |
+ ], |
|
| 55 |
+ "State": {
|
|
| 56 |
+ "Status": "running", |
|
| 57 |
+ "Running": true, |
|
| 58 |
+ "Paused": false, |
|
| 59 |
+ "Restarting": false, |
|
| 60 |
+ "OOMKilled": false, |
|
| 61 |
+ ... |
|
| 62 |
+ |
|
| 63 |
+Container names must be unique. That means you can only call one container |
|
| 64 |
+`web`. If you want to re-use a container name you must delete the old container |
|
| 65 |
+(with `docker rm`) before you can reuse the name with a new container. Go ahead and stop and remove your old `web` container. |
|
| 66 |
+ |
|
| 67 |
+ $ docker stop web |
|
| 68 |
+ web |
|
| 69 |
+ $ docker rm web |
|
| 70 |
+ web |
|
| 71 |
+ |
|
| 72 |
+ |
|
| 73 |
+## Launch a container on the default network |
|
| 74 |
+ |
|
| 75 |
+Docker includes support for networking containers through the use of **network |
|
| 76 |
+drivers**. By default, Docker provides two network drivers for you, the |
|
| 77 |
+`bridge` and the `overlay` drivers. You can also write a network driver plugin so |
|
| 78 |
+that you can create your own drivers but that is an advanced task. |
|
| 79 |
+ |
|
| 80 |
+Every installation of the Docker Engine automatically includes three default networks. You can list them: |
|
| 81 |
+ |
|
| 82 |
+ $ docker network ls |
|
| 83 |
+ NETWORK ID NAME DRIVER |
|
| 84 |
+ 18a2866682b8 none null |
|
| 85 |
+ c288470c46f6 host host |
|
| 86 |
+ 7b369448dccb bridge bridge |
|
| 87 |
+ |
|
| 88 |
+The network named `bridge` is a special network. Unless you tell it otherwise, Docker always launches your containers in this network. Try this now: |
|
| 89 |
+ |
|
| 90 |
+ $ docker run -itd --name=networktest ubuntu |
|
| 91 |
+ 74695c9cea6d9810718fddadc01a727a5dd3ce6a69d09752239736c030599741 |
|
| 92 |
+ |
|
| 93 |
+Inspecting the network is an easy way to find out the container's IP address. |
|
| 94 |
+ |
|
| 95 |
+```bash |
|
| 96 |
+$ docker network inspect bridge |
|
| 97 |
+[ |
|
| 98 |
+ {
|
|
| 99 |
+ "Name": "bridge", |
|
| 100 |
+ "Id": "f7ab26d71dbd6f557852c7156ae0574bbf62c42f539b50c8ebde0f728a253b6f", |
|
| 101 |
+ "Scope": "local", |
|
| 102 |
+ "Driver": "bridge", |
|
| 103 |
+ "IPAM": {
|
|
| 104 |
+ "Driver": "default", |
|
| 105 |
+ "Config": [ |
|
| 106 |
+ {
|
|
| 107 |
+ "Subnet": "172.17.0.1/16", |
|
| 108 |
+ "Gateway": "172.17.0.1" |
|
| 109 |
+ } |
|
| 110 |
+ ] |
|
| 111 |
+ }, |
|
| 112 |
+ "Containers": {
|
|
| 113 |
+ "3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c": {
|
|
| 114 |
+ "EndpointID": "647c12443e91faf0fd508b6edfe59c30b642abb60dfab890b4bdccee38750bc1", |
|
| 115 |
+ "MacAddress": "02:42:ac:11:00:02", |
|
| 116 |
+ "IPv4Address": "172.17.0.2/16", |
|
| 117 |
+ "IPv6Address": "" |
|
| 118 |
+ }, |
|
| 119 |
+ "94447ca479852d29aeddca75c28f7104df3c3196d7b6d83061879e339946805c": {
|
|
| 120 |
+ "EndpointID": "b047d090f446ac49747d3c37d63e4307be745876db7f0ceef7b311cbba615f48", |
|
| 121 |
+ "MacAddress": "02:42:ac:11:00:03", |
|
| 122 |
+ "IPv4Address": "172.17.0.3/16", |
|
| 123 |
+ "IPv6Address": "" |
|
| 124 |
+ } |
|
| 125 |
+ }, |
|
| 126 |
+ "Options": {
|
|
| 127 |
+ "com.docker.network.bridge.default_bridge": "true", |
|
| 128 |
+ "com.docker.network.bridge.enable_icc": "true", |
|
| 129 |
+ "com.docker.network.bridge.enable_ip_masquerade": "true", |
|
| 130 |
+ "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", |
|
| 131 |
+ "com.docker.network.bridge.name": "docker0", |
|
| 132 |
+ "com.docker.network.driver.mtu": "9001" |
|
| 133 |
+ } |
|
| 134 |
+ } |
|
| 135 |
+] |
|
| 136 |
+``` |
|
| 137 |
+ |
|
| 138 |
+You can remove a container from a network by disconnecting the container. To do this, you supply both the network name and the container name. You can also use the container id. In this example, though, the name is faster. |
|
| 139 |
+ |
|
| 140 |
+ $ docker network disconnect bridge networktest |
|
| 141 |
+ |
|
| 142 |
+While you can disconnect a container from a network, you cannot remove the builtin `bridge` network named `bridge`. Networks are natural ways to isolate containers from other containers or other networks. So, as you get more experienced with Docker, you'll want to create your own networks. |
|
| 143 |
+ |
|
| 144 |
+## Create your own bridge network |
|
| 145 |
+ |
|
| 146 |
+Docker Engine natively supports both bridge networks and overlay networks. A bridge network is limited to a single host running Docker Engine. An overlay network can include multiple hosts and is a more advanced topic. For this example, you'll create a bridge network: |
|
| 147 |
+ |
|
| 148 |
+ $ docker network create -d bridge my-bridge-network |
|
| 149 |
+ |
|
| 150 |
+The `-d` flag tells Docker to use the `bridge` driver for the new network. You could have left this flag off as `bridge` is the default value for this flag. Go ahead and list the networks on your machine: |
|
| 151 |
+ |
|
| 152 |
+ $ docker network ls |
|
| 153 |
+ NETWORK ID NAME DRIVER |
|
| 154 |
+ 7b369448dccb bridge bridge |
|
| 155 |
+ 615d565d498c my-bridge-network bridge |
|
| 156 |
+ 18a2866682b8 none null |
|
| 157 |
+ c288470c46f6 host host |
|
| 158 |
+ |
|
| 159 |
+If you inspect the network, you'll find that it has nothing in it. |
|
| 160 |
+ |
|
| 161 |
+ $ docker network inspect my-bridge-network |
|
| 162 |
+ [ |
|
| 163 |
+ {
|
|
| 164 |
+ "Name": "my-bridge-network", |
|
| 165 |
+ "Id": "5a8afc6364bccb199540e133e63adb76a557906dd9ff82b94183fc48c40857ac", |
|
| 166 |
+ "Scope": "local", |
|
| 167 |
+ "Driver": "bridge", |
|
| 168 |
+ "IPAM": {
|
|
| 169 |
+ "Driver": "default", |
|
| 170 |
+ "Config": [ |
|
| 171 |
+ {
|
|
| 172 |
+ "Subnet": "172.18.0.0/16", |
|
| 173 |
+ "Gateway": "172.18.0.1/16" |
|
| 174 |
+ } |
|
| 175 |
+ ] |
|
| 176 |
+ }, |
|
| 177 |
+ "Containers": {},
|
|
| 178 |
+ "Options": {}
|
|
| 179 |
+ } |
|
| 180 |
+ ] |
|
| 181 |
+ |
|
| 182 |
+## Add containers to a network |
|
| 183 |
+ |
|
| 184 |
+To build web applications that act in concert but do so securely, create a |
|
| 185 |
+network. Networks, by definition, provide complete isolation for containers. You |
|
| 186 |
+can add containers to a network when you first run a container. |
|
| 187 |
+ |
|
| 188 |
+Launch a container running a PostgreSQL database and pass it the `--net=my-bridge-network` flag to connect it to your new network: |
|
| 189 |
+ |
|
| 190 |
+ $ docker run -d --net=my-bridge-network --name db training/postgres |
|
| 191 |
+ |
|
| 192 |
+If you inspect your `my-bridge-network` you'll see it has a container attached. |
|
| 193 |
+You can also inspect your container to see where it is connected: |
|
| 194 |
+ |
|
| 195 |
+ $ docker inspect --format='{{json .NetworkSettings.Networks}}' db
|
|
| 196 |
+ {"my-bridge-network":{"NetworkID":"7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99",
|
|
| 197 |
+ "EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"172.18.0.1","IPAddress":"172.18.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}} |
|
| 198 |
+ |
|
| 199 |
+Now, go ahead and start your by now familiar web application. This time leave off the `-P` flag and also don't specify a network. |
|
| 200 |
+ |
|
| 201 |
+ $ docker run -d --name web training/webapp python app.py |
|
| 202 |
+ |
|
| 203 |
+Which network is your `web` application running under? Inspect the application and you'll find it is running in the default `bridge` network. |
|
| 204 |
+ |
|
| 205 |
+ $ docker inspect --format='{{json .NetworkSettings.Networks}}' web
|
|
| 206 |
+ {"bridge":{"NetworkID":"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812",
|
|
| 207 |
+ "EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"172.17.0.1","IPAddress":"172.17.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}} |
|
| 208 |
+ |
|
| 209 |
+Then, get the IP address of your `web` |
|
| 210 |
+ |
|
| 211 |
+ $ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
|
|
| 212 |
+ 172.17.0.2 |
|
| 213 |
+ |
|
| 214 |
+Now, open a shell to your running `db` container: |
|
| 215 |
+ |
|
| 216 |
+ $ docker exec -it db bash |
|
| 217 |
+ root@a205f0dd33b2:/# ping 172.17.0.2 |
|
| 218 |
+ ping 172.17.0.2 |
|
| 219 |
+ PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. |
|
| 220 |
+ ^C |
|
| 221 |
+ --- 172.17.0.2 ping statistics --- |
|
| 222 |
+ 44 packets transmitted, 0 received, 100% packet loss, time 43185ms |
|
| 223 |
+ |
|
| 224 |
+After a bit, use `CTRL-C` to end the `ping` and you'll find the ping failed. That is because the two containers are running on different networks. You can fix that. Then, use the `exit` command to close the container. |
|
| 225 |
+ |
|
| 226 |
+Docker networking allows you to attach a container to as many networks as you like. You can also attach an already running container. Go ahead and attach your running `web` app to the `my-bridge-network`. |
|
| 227 |
+ |
|
| 228 |
+ $ docker network connect my-bridge-network web |
|
| 229 |
+ |
|
| 230 |
+Open a shell into the `db` application again and try the ping command. This time just use the container name `web` rather than the IP Address. |
|
| 231 |
+ |
|
| 232 |
+ $ docker exec -it db bash |
|
| 233 |
+ root@a205f0dd33b2:/# ping web |
|
| 234 |
+ PING web (172.18.0.3) 56(84) bytes of data. |
|
| 235 |
+ 64 bytes from web (172.18.0.3): icmp_seq=1 ttl=64 time=0.095 ms |
|
| 236 |
+ 64 bytes from web (172.18.0.3): icmp_seq=2 ttl=64 time=0.060 ms |
|
| 237 |
+ 64 bytes from web (172.18.0.3): icmp_seq=3 ttl=64 time=0.066 ms |
|
| 238 |
+ ^C |
|
| 239 |
+ --- web ping statistics --- |
|
| 240 |
+ 3 packets transmitted, 3 received, 0% packet loss, time 2000ms |
|
| 241 |
+ rtt min/avg/max/mdev = 0.060/0.073/0.095/0.018 ms |
|
| 242 |
+ |
|
| 243 |
+The `ping` shows it is contacting a different IP address, the address on the `my-bridge-network` which is different from its address on the `bridge` network. |
|
| 244 |
+ |
|
| 245 |
+## Next steps |
|
| 246 |
+ |
|
| 247 |
+Now that you know how to network containers, see [how to manage data in containers](dockervolumes.md). |
| 2 | 250 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,309 @@ |
| 0 |
+<!--[metadata]> |
|
| 1 |
+aliases = [ |
|
| 2 |
+"/engine/userguide/containers/usingdocker/", |
|
| 3 |
+] |
|
| 4 |
+title = "Run a simple application" |
|
| 5 |
+description = "Learn how to manage and operate Docker containers." |
|
| 6 |
+keywords = ["docker, the docker guide, documentation, docker.io, monitoring containers, docker top, docker inspect, docker port, ports, docker logs, log, Logs"] |
|
| 7 |
+[menu.main] |
|
| 8 |
+parent = "engine_learn" |
|
| 9 |
+weight=-5 |
|
| 10 |
+<![end-metadata]--> |
|
| 11 |
+ |
|
| 12 |
+# Run a simple application |
|
| 13 |
+ |
|
| 14 |
+In the ["*Hello world in a container*"](dockerizing.md) you launched your |
|
| 15 |
+first containers using the `docker run` command. You ran an *interactive container* that ran in the foreground. You also ran a *detached container* that ran in the background. In the process you learned about several Docker commands: |
|
| 16 |
+ |
|
| 17 |
+* `docker ps` - Lists containers. |
|
| 18 |
+* `docker logs` - Shows us the standard output of a container. |
|
| 19 |
+* `docker stop` - Stops running containers. |
|
| 20 |
+ |
|
| 21 |
+## Learn about the Docker client |
|
| 22 |
+ |
|
| 23 |
+If you didn't realize it yet, you've been using the Docker client each time you |
|
| 24 |
+typed `docker` in your Bash terminal. The client is a simple command line client |
|
| 25 |
+also known as a command-line interface (CLI). Each action you can take with |
|
| 26 |
+the client is a command and each command can take a series of flags and arguments. |
|
| 27 |
+ |
|
| 28 |
+ # Usage: [sudo] docker [subcommand] [flags] [arguments] .. |
|
| 29 |
+ # Example: |
|
| 30 |
+ $ docker run -i -t ubuntu /bin/bash |
|
| 31 |
+ |
|
| 32 |
+You can see this in action by using the `docker version` command to return |
|
| 33 |
+version information on the currently installed Docker client and daemon. |
|
| 34 |
+ |
|
| 35 |
+ $ docker version |
|
| 36 |
+ |
|
| 37 |
+This command will not only provide you the version of Docker client and |
|
| 38 |
+daemon you are using, but also the version of Go (the programming |
|
| 39 |
+language powering Docker). |
|
| 40 |
+ |
|
| 41 |
+ Client: |
|
| 42 |
+ Version: 1.8.1 |
|
| 43 |
+ API version: 1.20 |
|
| 44 |
+ Go version: go1.4.2 |
|
| 45 |
+ Git commit: d12ea79 |
|
| 46 |
+ Built: Thu Aug 13 02:35:49 UTC 2015 |
|
| 47 |
+ OS/Arch: linux/amd64 |
|
| 48 |
+ |
|
| 49 |
+ Server: |
|
| 50 |
+ Version: 1.8.1 |
|
| 51 |
+ API version: 1.20 |
|
| 52 |
+ Go version: go1.4.2 |
|
| 53 |
+ Git commit: d12ea79 |
|
| 54 |
+ Built: Thu Aug 13 02:35:49 UTC 2015 |
|
| 55 |
+ OS/Arch: linux/amd64 |
|
| 56 |
+ |
|
| 57 |
+## Get Docker command help |
|
| 58 |
+ |
|
| 59 |
+You can display the help for specific Docker commands. The help details the |
|
| 60 |
+options and their usage. To see a list of all the possible commands, use the |
|
| 61 |
+following: |
|
| 62 |
+ |
|
| 63 |
+ $ docker --help |
|
| 64 |
+ |
|
| 65 |
+To see usage for a specific command, specify the command with the `--help` flag: |
|
| 66 |
+ |
|
| 67 |
+ $ docker attach --help |
|
| 68 |
+ |
|
| 69 |
+ Usage: docker attach [OPTIONS] CONTAINER |
|
| 70 |
+ |
|
| 71 |
+ Attach to a running container |
|
| 72 |
+ |
|
| 73 |
+ --help Print usage |
|
| 74 |
+ --no-stdin Do not attach stdin |
|
| 75 |
+ --sig-proxy=true Proxy all received signals to the process |
|
| 76 |
+ |
|
| 77 |
+> **Note:** |
|
| 78 |
+> For further details and examples of each command, see the |
|
| 79 |
+> [command reference](../reference/commandline/cli.md) in this guide. |
|
| 80 |
+ |
|
| 81 |
+## Running a web application in Docker |
|
| 82 |
+ |
|
| 83 |
+So now you've learned a bit more about the `docker` client you can move onto |
|
| 84 |
+the important stuff: running more containers. So far none of the |
|
| 85 |
+containers you've run did anything particularly useful, so you can |
|
| 86 |
+change that by running an example web application in Docker. |
|
| 87 |
+ |
|
| 88 |
+For our web application we're going to run a Python Flask application. |
|
| 89 |
+Start with a `docker run` command. |
|
| 90 |
+ |
|
| 91 |
+ $ docker run -d -P training/webapp python app.py |
|
| 92 |
+ |
|
| 93 |
+Review what the command did. You've specified two flags: `-d` and |
|
| 94 |
+`-P`. You've already seen the `-d` flag which tells Docker to run the |
|
| 95 |
+container in the background. The `-P` flag is new and tells Docker to |
|
| 96 |
+map any required network ports inside our container to our host. This |
|
| 97 |
+lets us view our web application. |
|
| 98 |
+ |
|
| 99 |
+You've specified an image: `training/webapp`. This image is a |
|
| 100 |
+pre-built image you've created that contains a simple Python Flask web |
|
| 101 |
+application. |
|
| 102 |
+ |
|
| 103 |
+Lastly, you've specified a command for our container to run: `python app.py`. This launches our web application. |
|
| 104 |
+ |
|
| 105 |
+> **Note:** |
|
| 106 |
+> You can see more detail on the `docker run` command in the [command |
|
| 107 |
+> reference](../reference/commandline/run.md) and the [Docker Run |
|
| 108 |
+> Reference](../reference/run.md). |
|
| 109 |
+ |
|
| 110 |
+## Viewing our web application container |
|
| 111 |
+ |
|
| 112 |
+Now you can see your running container using the `docker ps` command. |
|
| 113 |
+ |
|
| 114 |
+ $ docker ps -l |
|
| 115 |
+ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
|
| 116 |
+ bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse |
|
| 117 |
+ |
|
| 118 |
+You can see you've specified a new flag, `-l`, for the `docker ps` |
|
| 119 |
+command. This tells the `docker ps` command to return the details of the |
|
| 120 |
+*last* container started. |
|
| 121 |
+ |
|
| 122 |
+> **Note:** |
|
| 123 |
+> By default, the `docker ps` command only shows information about running |
|
| 124 |
+> containers. If you want to see stopped containers too use the `-a` flag. |
|
| 125 |
+ |
|
| 126 |
+We can see the same details we saw [when we first Dockerized a |
|
| 127 |
+container](dockerizing.md) with one important addition in the `PORTS` |
|
| 128 |
+column. |
|
| 129 |
+ |
|
| 130 |
+ PORTS |
|
| 131 |
+ 0.0.0.0:49155->5000/tcp |
|
| 132 |
+ |
|
| 133 |
+When we passed the `-P` flag to the `docker run` command Docker mapped any |
|
| 134 |
+ports exposed in our image to our host. |
|
| 135 |
+ |
|
| 136 |
+> **Note:** |
|
| 137 |
+> We'll learn more about how to expose ports in Docker images when |
|
| 138 |
+> [we learn how to build images](dockerimages.md). |
|
| 139 |
+ |
|
| 140 |
+In this case Docker has exposed port 5000 (the default Python Flask |
|
| 141 |
+port) on port 49155. |
|
| 142 |
+ |
|
| 143 |
+Network port bindings are very configurable in Docker. In our last example the |
|
| 144 |
+`-P` flag is a shortcut for `-p 5000` that maps port 5000 inside the container |
|
| 145 |
+to a high port (from *ephemeral port range* which typically ranges from 32768 |
|
| 146 |
+to 61000) on the local Docker host. We can also bind Docker containers to |
|
| 147 |
+specific ports using the `-p` flag, for example: |
|
| 148 |
+ |
|
| 149 |
+ $ docker run -d -p 80:5000 training/webapp python app.py |
|
| 150 |
+ |
|
| 151 |
+This would map port 5000 inside our container to port 80 on our local |
|
| 152 |
+host. You might be asking about now: why wouldn't we just want to always |
|
| 153 |
+use 1:1 port mappings in Docker containers rather than mapping to high |
|
| 154 |
+ports? Well 1:1 mappings have the constraint of only being able to map |
|
| 155 |
+one of each port on your local host. |
|
| 156 |
+ |
|
| 157 |
+Suppose you want to test two Python applications: both bound to port 5000 inside |
|
| 158 |
+their own containers. Without Docker's port mapping you could only access one at |
|
| 159 |
+a time on the Docker host. |
|
| 160 |
+ |
|
| 161 |
+So you can now browse to port 49155 in a web browser to |
|
| 162 |
+see the application. |
|
| 163 |
+ |
|
| 164 |
+. |
|
| 165 |
+ |
|
| 166 |
+Our Python application is live! |
|
| 167 |
+ |
|
| 168 |
+> **Note:** |
|
| 169 |
+> If you have been using a virtual machine on OS X, Windows or Linux, |
|
| 170 |
+> you'll need to get the IP of the virtual host instead of using localhost. |
|
| 171 |
+> You can do this by running the `docker-machine ip your_vm_name` from your command line or terminal application, for example: |
|
| 172 |
+> |
|
| 173 |
+> $ docker-machine ip my-docker-vm |
|
| 174 |
+> 192.168.99.100 |
|
| 175 |
+> |
|
| 176 |
+> In this case you'd browse to `http://192.168.99.100:49155` for the above example. |
|
| 177 |
+ |
|
| 178 |
+## A network port shortcut |
|
| 179 |
+ |
|
| 180 |
+Using the `docker ps` command to return the mapped port is a bit clumsy so |
|
| 181 |
+Docker has a useful shortcut we can use: `docker port`. To use `docker port` we |
|
| 182 |
+specify the ID or name of our container and then the port for which we need the |
|
| 183 |
+corresponding public-facing port. |
|
| 184 |
+ |
|
| 185 |
+ $ docker port nostalgic_morse 5000 |
|
| 186 |
+ 0.0.0.0:49155 |
|
| 187 |
+ |
|
| 188 |
+In this case you've looked up what port is mapped externally to port 5000 inside |
|
| 189 |
+the container. |
|
| 190 |
+ |
|
| 191 |
+## Viewing the web application's logs |
|
| 192 |
+ |
|
| 193 |
+You can also find out a bit more about what's happening with our application and |
|
| 194 |
+use another of the commands you've learned, `docker logs`. |
|
| 195 |
+ |
|
| 196 |
+ $ docker logs -f nostalgic_morse |
|
| 197 |
+ * Running on http://0.0.0.0:5000/ |
|
| 198 |
+ 10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 - |
|
| 199 |
+ 10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 - |
|
| 200 |
+ |
|
| 201 |
+This time though you've added a new flag, `-f`. This causes the `docker |
|
| 202 |
+logs` command to act like the `tail -f` command and watch the |
|
| 203 |
+container's standard out. We can see here the logs from Flask showing |
|
| 204 |
+the application running on port 5000 and the access log entries for it. |
|
| 205 |
+ |
|
| 206 |
+## Looking at our web application container's processes |
|
| 207 |
+ |
|
| 208 |
+In addition to the container's logs we can also examine the processes |
|
| 209 |
+running inside it using the `docker top` command. |
|
| 210 |
+ |
|
| 211 |
+ $ docker top nostalgic_morse |
|
| 212 |
+ PID USER COMMAND |
|
| 213 |
+ 854 root python app.py |
|
| 214 |
+ |
|
| 215 |
+Here we can see our `python app.py` command is the only process running inside |
|
| 216 |
+the container. |
|
| 217 |
+ |
|
| 218 |
+## Inspecting our web application container |
|
| 219 |
+ |
|
| 220 |
+Lastly, we can take a low-level dive into our Docker container using the |
|
| 221 |
+`docker inspect` command. It returns a JSON document containing useful |
|
| 222 |
+configuration and status information for the specified container. |
|
| 223 |
+ |
|
| 224 |
+ $ docker inspect nostalgic_morse |
|
| 225 |
+ |
|
| 226 |
+You can see a sample of that JSON output. |
|
| 227 |
+ |
|
| 228 |
+ [{
|
|
| 229 |
+ "ID": "bc533791f3f500b280a9626688bc79e342e3ea0d528efe3a86a51ecb28ea20", |
|
| 230 |
+ "Created": "2014-05-26T05:52:40.808952951Z", |
|
| 231 |
+ "Path": "python", |
|
| 232 |
+ "Args": [ |
|
| 233 |
+ "app.py" |
|
| 234 |
+ ], |
|
| 235 |
+ "Config": {
|
|
| 236 |
+ "Hostname": "bc533791f3f5", |
|
| 237 |
+ "Domainname": "", |
|
| 238 |
+ "User": "", |
|
| 239 |
+ . . . |
|
| 240 |
+ |
|
| 241 |
+We can also narrow down the information we want to return by requesting a |
|
| 242 |
+specific element, for example to return the container's IP address we would: |
|
| 243 |
+ |
|
| 244 |
+ $ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nostalgic_morse
|
|
| 245 |
+ 172.17.0.5 |
|
| 246 |
+ |
|
| 247 |
+## Stopping our web application container |
|
| 248 |
+ |
|
| 249 |
+Okay you've seen web application working. Now you can stop it using the |
|
| 250 |
+`docker stop` command and the name of our container: `nostalgic_morse`. |
|
| 251 |
+ |
|
| 252 |
+ $ docker stop nostalgic_morse |
|
| 253 |
+ nostalgic_morse |
|
| 254 |
+ |
|
| 255 |
+We can now use the `docker ps` command to check if the container has |
|
| 256 |
+been stopped. |
|
| 257 |
+ |
|
| 258 |
+ $ docker ps -l |
|
| 259 |
+ |
|
| 260 |
+## Restarting our web application container |
|
| 261 |
+ |
|
| 262 |
+Oops! Just after you stopped the container you get a call to say another |
|
| 263 |
+developer needs the container back. From here you have two choices: you |
|
| 264 |
+can create a new container or restart the old one. Look at |
|
| 265 |
+starting your previous container back up. |
|
| 266 |
+ |
|
| 267 |
+ $ docker start nostalgic_morse |
|
| 268 |
+ nostalgic_morse |
|
| 269 |
+ |
|
| 270 |
+Now quickly run `docker ps -l` again to see the running container is |
|
| 271 |
+back up or browse to the container's URL to see if the application |
|
| 272 |
+responds. |
|
| 273 |
+ |
|
| 274 |
+> **Note:** |
|
| 275 |
+> Also available is the `docker restart` command that runs a stop and |
|
| 276 |
+> then start on the container. |
|
| 277 |
+ |
|
| 278 |
+## Removing our web application container |
|
| 279 |
+ |
|
| 280 |
+Your colleague has let you know that they've now finished with the container |
|
| 281 |
+and won't need it again. Now, you can remove it using the `docker rm` command. |
|
| 282 |
+ |
|
| 283 |
+ $ docker rm nostalgic_morse |
|
| 284 |
+ Error: Impossible to remove a running container, please stop it first or use -f |
|
| 285 |
+ 2014/05/24 08:12:56 Error: failed to remove one or more containers |
|
| 286 |
+ |
|
| 287 |
+What happened? We can't actually remove a running container. This protects |
|
| 288 |
+you from accidentally removing a running container you might need. You can try |
|
| 289 |
+this again by stopping the container first. |
|
| 290 |
+ |
|
| 291 |
+ $ docker stop nostalgic_morse |
|
| 292 |
+ nostalgic_morse |
|
| 293 |
+ $ docker rm nostalgic_morse |
|
| 294 |
+ nostalgic_morse |
|
| 295 |
+ |
|
| 296 |
+And now our container is stopped and deleted. |
|
| 297 |
+ |
|
| 298 |
+> **Note:** |
|
| 299 |
+> Always remember that removing a container is final! |
|
| 300 |
+ |
|
| 301 |
+# Next steps |
|
| 302 |
+ |
|
| 303 |
+Until now you've only used images that you've downloaded from Docker Hub. Next, |
|
| 304 |
+you can get introduced to building and sharing our own images. |
|
| 305 |
+ |
|
| 306 |
+Go to [Working with Docker Images](dockerimages.md). |
| 2 | 309 |
deleted file mode 100644 |
| ... | ... |
@@ -1,554 +0,0 @@ |
| 1 |
-<!--[metadata]> |
|
| 2 |
-+++ |
|
| 3 |
-aliases = ["/engine/userguide/dockerimages/"] |
|
| 4 |
-title = "Build your own images" |
|
| 5 |
-description = "How to work with Docker images." |
|
| 6 |
-keywords = ["documentation, docs, the docker guide, docker guide, docker, docker platform, docker.io, Docker images, Docker image, image management, Docker repos, Docker repositories, docker, docker tag, docker tags, Docker Hub, collaboration"] |
|
| 7 |
-[menu.main] |
|
| 8 |
-parent = "engine_learn" |
|
| 9 |
-weight = -4 |
|
| 10 |
-+++ |
|
| 11 |
-<![end-metadata]--> |
|
| 12 |
- |
|
| 13 |
-# Build your own images |
|
| 14 |
- |
|
| 15 |
-Docker images are the basis of containers. Each time you've used `docker run` |
|
| 16 |
-you told it which image you wanted. In the previous sections of the guide you |
|
| 17 |
-used Docker images that already exist, for example the `ubuntu` image and the |
|
| 18 |
-`training/webapp` image. |
|
| 19 |
- |
|
| 20 |
-You also discovered that Docker stores downloaded images on the Docker host. If |
|
| 21 |
-an image isn't already present on the host then it'll be downloaded from a |
|
| 22 |
-registry: by default the [Docker Hub Registry](https://hub.docker.com). |
|
| 23 |
- |
|
| 24 |
-In this section you're going to explore Docker images a bit more |
|
| 25 |
-including: |
|
| 26 |
- |
|
| 27 |
-* Managing and working with images locally on your Docker host. |
|
| 28 |
-* Creating basic images. |
|
| 29 |
-* Uploading images to [Docker Hub Registry](https://hub.docker.com). |
|
| 30 |
- |
|
| 31 |
-## Listing images on the host |
|
| 32 |
- |
|
| 33 |
-Let's start with listing the images you have locally on our host. You can |
|
| 34 |
-do this using the `docker images` command like so: |
|
| 35 |
- |
|
| 36 |
- $ docker images |
|
| 37 |
- REPOSITORY TAG IMAGE ID CREATED SIZE |
|
| 38 |
- ubuntu 14.04 1d073211c498 3 days ago 187.9 MB |
|
| 39 |
- busybox latest 2c5ac3f849df 5 days ago 1.113 MB |
|
| 40 |
- training/webapp latest 54bb4e8718e8 5 months ago 348.7 MB |
|
| 41 |
- |
|
| 42 |
-You can see the images you've previously used in the user guide. |
|
| 43 |
-Each has been downloaded from [Docker Hub](https://hub.docker.com) when you |
|
| 44 |
-launched a container using that image. When you list images, you get three crucial pieces of information in the listing. |
|
| 45 |
- |
|
| 46 |
-* What repository they came from, for example `ubuntu`. |
|
| 47 |
-* The tags for each image, for example `14.04`. |
|
| 48 |
-* The image ID of each image. |
|
| 49 |
- |
|
| 50 |
-> **Tip:** |
|
| 51 |
-> You can use [a third-party dockviz tool](https://github.com/justone/dockviz) |
|
| 52 |
-> or the [Image layers site](https://imagelayers.io/) to display |
|
| 53 |
-> visualizations of image data. |
|
| 54 |
- |
|
| 55 |
-A repository potentially holds multiple variants of an image. In the case of |
|
| 56 |
-our `ubuntu` image you can see multiple variants covering Ubuntu 10.04, 12.04, |
|
| 57 |
-12.10, 13.04, 13.10 and 14.04. Each variant is identified by a tag and you can |
|
| 58 |
-refer to a tagged image like so: |
|
| 59 |
- |
|
| 60 |
- ubuntu:14.04 |
|
| 61 |
- |
|
| 62 |
-So when you run a container you refer to a tagged image like so: |
|
| 63 |
- |
|
| 64 |
- $ docker run -t -i ubuntu:14.04 /bin/bash |
|
| 65 |
- |
|
| 66 |
-If instead you wanted to run an Ubuntu 12.04 image you'd use: |
|
| 67 |
- |
|
| 68 |
- $ docker run -t -i ubuntu:12.04 /bin/bash |
|
| 69 |
- |
|
| 70 |
-If you don't specify a variant, for example you just use `ubuntu`, then Docker |
|
| 71 |
-will default to using the `ubuntu:latest` image. |
|
| 72 |
- |
|
| 73 |
-> **Tip:** |
|
| 74 |
-> You should always specify an image tag, for example `ubuntu:14.04`. |
|
| 75 |
-> That way, you always know exactly what variant of an image you are using. |
|
| 76 |
-> This is useful for troubleshooting and debugging. |
|
| 77 |
- |
|
| 78 |
-## Getting a new image |
|
| 79 |
- |
|
| 80 |
-So how do you get new images? Well Docker will automatically download any image |
|
| 81 |
-you use that isn't already present on the Docker host. But this can potentially |
|
| 82 |
-add some time to the launch of a container. If you want to pre-load an image you |
|
| 83 |
-can download it using the `docker pull` command. Suppose you'd like to |
|
| 84 |
-download the `centos` image. |
|
| 85 |
- |
|
| 86 |
- $ docker pull centos |
|
| 87 |
- Pulling repository centos |
|
| 88 |
- b7de3133ff98: Pulling dependent layers |
|
| 89 |
- 5cc9e91966f7: Pulling fs layer |
|
| 90 |
- 511136ea3c5a: Download complete |
|
| 91 |
- ef52fb1fe610: Download complete |
|
| 92 |
- . . . |
|
| 93 |
- |
|
| 94 |
- Status: Downloaded newer image for centos |
|
| 95 |
- |
|
| 96 |
-You can see that each layer of the image has been pulled down and now you |
|
| 97 |
-can run a container from this image and you won't have to wait to |
|
| 98 |
-download the image. |
|
| 99 |
- |
|
| 100 |
- $ docker run -t -i centos /bin/bash |
|
| 101 |
- bash-4.1# |
|
| 102 |
- |
|
| 103 |
-## Finding images |
|
| 104 |
- |
|
| 105 |
-One of the features of Docker is that a lot of people have created Docker |
|
| 106 |
-images for a variety of purposes. Many of these have been uploaded to |
|
| 107 |
-[Docker Hub](https://hub.docker.com). You can search these images on the |
|
| 108 |
-[Docker Hub](https://hub.docker.com) website. |
|
| 109 |
- |
|
| 110 |
- |
|
| 111 |
- |
|
| 112 |
-You can also search for images on the command line using the `docker search` |
|
| 113 |
-command. Suppose your team wants an image with Ruby and Sinatra installed on |
|
| 114 |
-which to do our web application development. You can search for a suitable image |
|
| 115 |
-by using the `docker search` command to find all the images that contain the |
|
| 116 |
-term `sinatra`. |
|
| 117 |
- |
|
| 118 |
- $ docker search sinatra |
|
| 119 |
- NAME DESCRIPTION STARS OFFICIAL AUTOMATED |
|
| 120 |
- training/sinatra Sinatra training image 0 [OK] |
|
| 121 |
- marceldegraaf/sinatra Sinatra test app 0 |
|
| 122 |
- mattwarren/docker-sinatra-demo 0 [OK] |
|
| 123 |
- luisbebop/docker-sinatra-hello-world 0 [OK] |
|
| 124 |
- bmorearty/handson-sinatra handson-ruby + Sinatra for Hands on with D... 0 |
|
| 125 |
- subwiz/sinatra 0 |
|
| 126 |
- bmorearty/sinatra 0 |
|
| 127 |
- . . . |
|
| 128 |
- |
|
| 129 |
-You can see the command returns a lot of images that use the term `sinatra`. |
|
| 130 |
-You've received a list of image names, descriptions, Stars (which measure the |
|
| 131 |
-social popularity of images - if a user likes an image then they can "star" it), |
|
| 132 |
-and the Official and Automated build statuses. [Official |
|
| 133 |
-Repositories](https://docs.docker.com/docker-hub/official_repos) are a carefully |
|
| 134 |
-curated set of Docker repositories supported by Docker, Inc. Automated |
|
| 135 |
-repositories are [Automated Builds](dockerrepos.md#automated-builds) that allow |
|
| 136 |
-you to validate the source and content of an image. |
|
| 137 |
- |
|
| 138 |
-You've reviewed the images available to use and you decided to use the |
|
| 139 |
-`training/sinatra` image. So far you've seen two types of images repositories, |
|
| 140 |
-images like `ubuntu`, which are called base or root images. These base images |
|
| 141 |
-are provided by Docker Inc and are built, validated and supported. These can be |
|
| 142 |
-identified by their single word names. |
|
| 143 |
- |
|
| 144 |
-You've also seen user images, for example the `training/sinatra` image you've |
|
| 145 |
-chosen. A user image belongs to a member of the Docker community and is built |
|
| 146 |
-and maintained by them. You can identify user images as they are always |
|
| 147 |
-prefixed with the user name, here `training`, of the user that created them. |
|
| 148 |
- |
|
| 149 |
-## Pulling our image |
|
| 150 |
- |
|
| 151 |
-You've identified a suitable image, `training/sinatra`, and now you can download it using the `docker pull` command. |
|
| 152 |
- |
|
| 153 |
- $ docker pull training/sinatra |
|
| 154 |
- |
|
| 155 |
-The team can now use this image by running their own containers. |
|
| 156 |
- |
|
| 157 |
- $ docker run -t -i training/sinatra /bin/bash |
|
| 158 |
- root@a8cb6ce02d85:/# |
|
| 159 |
- |
|
| 160 |
-## Creating our own images |
|
| 161 |
- |
|
| 162 |
-The team has found the `training/sinatra` image pretty useful but it's not quite |
|
| 163 |
-what they need and you need to make some changes to it. There are two ways you |
|
| 164 |
-can update and create images. |
|
| 165 |
- |
|
| 166 |
-1. You can update a container created from an image and commit the results to an image. |
|
| 167 |
-2. You can use a `Dockerfile` to specify instructions to create an image. |
|
| 168 |
- |
|
| 169 |
- |
|
| 170 |
-### Updating and committing an image |
|
| 171 |
- |
|
| 172 |
-To update an image you first need to create a container from the image |
|
| 173 |
-you'd like to update. |
|
| 174 |
- |
|
| 175 |
- $ docker run -t -i training/sinatra /bin/bash |
|
| 176 |
- root@0b2616b0e5a8:/# |
|
| 177 |
- |
|
| 178 |
-> **Note:** |
|
| 179 |
-> Take note of the container ID that has been created, `0b2616b0e5a8`, as you'll |
|
| 180 |
-> need it in a moment. |
|
| 181 |
- |
|
| 182 |
-Inside our running container let's add the `json` gem. |
|
| 183 |
- |
|
| 184 |
- root@0b2616b0e5a8:/# gem install json |
|
| 185 |
- |
|
| 186 |
-Once this has completed let's exit our container using the `exit` |
|
| 187 |
-command. |
|
| 188 |
- |
|
| 189 |
-Now you have a container with the change you want to make. You can then |
|
| 190 |
-commit a copy of this container to an image using the `docker commit` |
|
| 191 |
-command. |
|
| 192 |
- |
|
| 193 |
- $ docker commit -m "Added json gem" -a "Kate Smith" \ |
|
| 194 |
- 0b2616b0e5a8 ouruser/sinatra:v2 |
|
| 195 |
- 4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c |
|
| 196 |
- |
|
| 197 |
-Here you've used the `docker commit` command. You've specified two flags: `-m` |
|
| 198 |
-and `-a`. The `-m` flag allows us to specify a commit message, much like you |
|
| 199 |
-would with a commit on a version control system. The `-a` flag allows us to |
|
| 200 |
-specify an author for our update. |
|
| 201 |
- |
|
| 202 |
-You've also specified the container you want to create this new image from, |
|
| 203 |
-`0b2616b0e5a8` (the ID you recorded earlier) and you've specified a target for |
|
| 204 |
-the image: |
|
| 205 |
- |
|
| 206 |
- ouruser/sinatra:v2 |
|
| 207 |
- |
|
| 208 |
-Break this target down. It consists of a new user, `ouruser`, that you're |
|
| 209 |
-writing this image to. You've also specified the name of the image, here you're |
|
| 210 |
-keeping the original image name `sinatra`. Finally you're specifying a tag for |
|
| 211 |
-the image: `v2`. |
|
| 212 |
- |
|
| 213 |
-You can then look at our new `ouruser/sinatra` image using the `docker images` |
|
| 214 |
-command. |
|
| 215 |
- |
|
| 216 |
- $ docker images |
|
| 217 |
- REPOSITORY TAG IMAGE ID CREATED SIZE |
|
| 218 |
- training/sinatra latest 5bc342fa0b91 10 hours ago 446.7 MB |
|
| 219 |
- ouruser/sinatra v2 3c59e02ddd1a 10 hours ago 446.7 MB |
|
| 220 |
- ouruser/sinatra latest 5db5f8471261 10 hours ago 446.7 MB |
|
| 221 |
- |
|
| 222 |
-To use our new image to create a container you can then: |
|
| 223 |
- |
|
| 224 |
- $ docker run -t -i ouruser/sinatra:v2 /bin/bash |
|
| 225 |
- root@78e82f680994:/# |
|
| 226 |
- |
|
| 227 |
-### Building an image from a `Dockerfile` |
|
| 228 |
- |
|
| 229 |
-Using the `docker commit` command is a pretty simple way of extending an image |
|
| 230 |
-but it's a bit cumbersome and it's not easy to share a development process for |
|
| 231 |
-images amongst a team. Instead you can use a new command, `docker build`, to |
|
| 232 |
-build new images from scratch. |
|
| 233 |
- |
|
| 234 |
-To do this you create a `Dockerfile` that contains a set of instructions that |
|
| 235 |
-tell Docker how to build our image. |
|
| 236 |
- |
|
| 237 |
-First, create a directory and a `Dockerfile`. |
|
| 238 |
- |
|
| 239 |
- $ mkdir sinatra |
|
| 240 |
- $ cd sinatra |
|
| 241 |
- $ touch Dockerfile |
|
| 242 |
- |
|
| 243 |
-If you are using Docker Machine on Windows, you may access your host |
|
| 244 |
-directory by `cd` to `/c/Users/your_user_name`. |
|
| 245 |
- |
|
| 246 |
-Each instruction creates a new layer of the image. Try a simple example now for |
|
| 247 |
-building your own Sinatra image for your fictitious development team. |
|
| 248 |
- |
|
| 249 |
- # This is a comment |
|
| 250 |
- FROM ubuntu:14.04 |
|
| 251 |
- MAINTAINER Kate Smith <ksmith@example.com> |
|
| 252 |
- RUN apt-get update && apt-get install -y ruby ruby-dev |
|
| 253 |
- RUN gem install sinatra |
|
| 254 |
- |
|
| 255 |
-Examine what your `Dockerfile` does. Each instruction prefixes a statement and |
|
| 256 |
-is capitalized. |
|
| 257 |
- |
|
| 258 |
- INSTRUCTION statement |
|
| 259 |
- |
|
| 260 |
-> **Note:** You use `#` to indicate a comment |
|
| 261 |
- |
|
| 262 |
-The first instruction `FROM` tells Docker what the source of our image is, in |
|
| 263 |
-this case you're basing our new image on an Ubuntu 14.04 image. The instruction uses the `MAINTAINER` instruction to specify who maintains the new image. |
|
| 264 |
- |
|
| 265 |
-Lastly, you've specified two `RUN` instructions. A `RUN` instruction executes |
|
| 266 |
-a command inside the image, for example installing a package. Here you're |
|
| 267 |
-updating our APT cache, installing Ruby and RubyGems and then installing the |
|
| 268 |
-Sinatra gem. |
|
| 269 |
- |
|
| 270 |
- |
|
| 271 |
- |
|
| 272 |
-Now let's take our `Dockerfile` and use the `docker build` command to build an image. |
|
| 273 |
- |
|
| 274 |
- $ docker build -t ouruser/sinatra:v2 . |
|
| 275 |
- Sending build context to Docker daemon 2.048 kB |
|
| 276 |
- Sending build context to Docker daemon |
|
| 277 |
- Step 1 : FROM ubuntu:14.04 |
|
| 278 |
- ---> e54ca5efa2e9 |
|
| 279 |
- Step 2 : MAINTAINER Kate Smith <ksmith@example.com> |
|
| 280 |
- ---> Using cache |
|
| 281 |
- ---> 851baf55332b |
|
| 282 |
- Step 3 : RUN apt-get update && apt-get install -y ruby ruby-dev |
|
| 283 |
- ---> Running in 3a2558904e9b |
|
| 284 |
- Selecting previously unselected package libasan0:amd64. |
|
| 285 |
- (Reading database ... 11518 files and directories currently installed.) |
|
| 286 |
- Preparing to unpack .../libasan0_4.8.2-19ubuntu1_amd64.deb ... |
|
| 287 |
- Unpacking libasan0:amd64 (4.8.2-19ubuntu1) ... |
|
| 288 |
- Selecting previously unselected package libatomic1:amd64. |
|
| 289 |
- Preparing to unpack .../libatomic1_4.8.2-19ubuntu1_amd64.deb ... |
|
| 290 |
- Unpacking libatomic1:amd64 (4.8.2-19ubuntu1) ... |
|
| 291 |
- Selecting previously unselected package libgmp10:amd64. |
|
| 292 |
- Preparing to unpack .../libgmp10_2%3a5.1.3+dfsg-1ubuntu1_amd64.deb ... |
|
| 293 |
- Unpacking libgmp10:amd64 (2:5.1.3+dfsg-1ubuntu1) ... |
|
| 294 |
- Selecting previously unselected package libisl10:amd64. |
|
| 295 |
- Preparing to unpack .../libisl10_0.12.2-1_amd64.deb ... |
|
| 296 |
- Unpacking libisl10:amd64 (0.12.2-1) ... |
|
| 297 |
- Selecting previously unselected package libcloog-isl4:amd64. |
|
| 298 |
- Preparing to unpack .../libcloog-isl4_0.18.2-1_amd64.deb ... |
|
| 299 |
- Unpacking libcloog-isl4:amd64 (0.18.2-1) ... |
|
| 300 |
- Selecting previously unselected package libgomp1:amd64. |
|
| 301 |
- Preparing to unpack .../libgomp1_4.8.2-19ubuntu1_amd64.deb ... |
|
| 302 |
- Unpacking libgomp1:amd64 (4.8.2-19ubuntu1) ... |
|
| 303 |
- Selecting previously unselected package libitm1:amd64. |
|
| 304 |
- Preparing to unpack .../libitm1_4.8.2-19ubuntu1_amd64.deb ... |
|
| 305 |
- Unpacking libitm1:amd64 (4.8.2-19ubuntu1) ... |
|
| 306 |
- Selecting previously unselected package libmpfr4:amd64. |
|
| 307 |
- Preparing to unpack .../libmpfr4_3.1.2-1_amd64.deb ... |
|
| 308 |
- Unpacking libmpfr4:amd64 (3.1.2-1) ... |
|
| 309 |
- Selecting previously unselected package libquadmath0:amd64. |
|
| 310 |
- Preparing to unpack .../libquadmath0_4.8.2-19ubuntu1_amd64.deb ... |
|
| 311 |
- Unpacking libquadmath0:amd64 (4.8.2-19ubuntu1) ... |
|
| 312 |
- Selecting previously unselected package libtsan0:amd64. |
|
| 313 |
- Preparing to unpack .../libtsan0_4.8.2-19ubuntu1_amd64.deb ... |
|
| 314 |
- Unpacking libtsan0:amd64 (4.8.2-19ubuntu1) ... |
|
| 315 |
- Selecting previously unselected package libyaml-0-2:amd64. |
|
| 316 |
- Preparing to unpack .../libyaml-0-2_0.1.4-3ubuntu3_amd64.deb ... |
|
| 317 |
- Unpacking libyaml-0-2:amd64 (0.1.4-3ubuntu3) ... |
|
| 318 |
- Selecting previously unselected package libmpc3:amd64. |
|
| 319 |
- Preparing to unpack .../libmpc3_1.0.1-1ubuntu1_amd64.deb ... |
|
| 320 |
- Unpacking libmpc3:amd64 (1.0.1-1ubuntu1) ... |
|
| 321 |
- Selecting previously unselected package openssl. |
|
| 322 |
- Preparing to unpack .../openssl_1.0.1f-1ubuntu2.4_amd64.deb ... |
|
| 323 |
- Unpacking openssl (1.0.1f-1ubuntu2.4) ... |
|
| 324 |
- Selecting previously unselected package ca-certificates. |
|
| 325 |
- Preparing to unpack .../ca-certificates_20130906ubuntu2_all.deb ... |
|
| 326 |
- Unpacking ca-certificates (20130906ubuntu2) ... |
|
| 327 |
- Selecting previously unselected package manpages. |
|
| 328 |
- Preparing to unpack .../manpages_3.54-1ubuntu1_all.deb ... |
|
| 329 |
- Unpacking manpages (3.54-1ubuntu1) ... |
|
| 330 |
- Selecting previously unselected package binutils. |
|
| 331 |
- Preparing to unpack .../binutils_2.24-5ubuntu3_amd64.deb ... |
|
| 332 |
- Unpacking binutils (2.24-5ubuntu3) ... |
|
| 333 |
- Selecting previously unselected package cpp-4.8. |
|
| 334 |
- Preparing to unpack .../cpp-4.8_4.8.2-19ubuntu1_amd64.deb ... |
|
| 335 |
- Unpacking cpp-4.8 (4.8.2-19ubuntu1) ... |
|
| 336 |
- Selecting previously unselected package cpp. |
|
| 337 |
- Preparing to unpack .../cpp_4%3a4.8.2-1ubuntu6_amd64.deb ... |
|
| 338 |
- Unpacking cpp (4:4.8.2-1ubuntu6) ... |
|
| 339 |
- Selecting previously unselected package libgcc-4.8-dev:amd64. |
|
| 340 |
- Preparing to unpack .../libgcc-4.8-dev_4.8.2-19ubuntu1_amd64.deb ... |
|
| 341 |
- Unpacking libgcc-4.8-dev:amd64 (4.8.2-19ubuntu1) ... |
|
| 342 |
- Selecting previously unselected package gcc-4.8. |
|
| 343 |
- Preparing to unpack .../gcc-4.8_4.8.2-19ubuntu1_amd64.deb ... |
|
| 344 |
- Unpacking gcc-4.8 (4.8.2-19ubuntu1) ... |
|
| 345 |
- Selecting previously unselected package gcc. |
|
| 346 |
- Preparing to unpack .../gcc_4%3a4.8.2-1ubuntu6_amd64.deb ... |
|
| 347 |
- Unpacking gcc (4:4.8.2-1ubuntu6) ... |
|
| 348 |
- Selecting previously unselected package libc-dev-bin. |
|
| 349 |
- Preparing to unpack .../libc-dev-bin_2.19-0ubuntu6_amd64.deb ... |
|
| 350 |
- Unpacking libc-dev-bin (2.19-0ubuntu6) ... |
|
| 351 |
- Selecting previously unselected package linux-libc-dev:amd64. |
|
| 352 |
- Preparing to unpack .../linux-libc-dev_3.13.0-30.55_amd64.deb ... |
|
| 353 |
- Unpacking linux-libc-dev:amd64 (3.13.0-30.55) ... |
|
| 354 |
- Selecting previously unselected package libc6-dev:amd64. |
|
| 355 |
- Preparing to unpack .../libc6-dev_2.19-0ubuntu6_amd64.deb ... |
|
| 356 |
- Unpacking libc6-dev:amd64 (2.19-0ubuntu6) ... |
|
| 357 |
- Selecting previously unselected package ruby. |
|
| 358 |
- Preparing to unpack .../ruby_1%3a1.9.3.4_all.deb ... |
|
| 359 |
- Unpacking ruby (1:1.9.3.4) ... |
|
| 360 |
- Selecting previously unselected package ruby1.9.1. |
|
| 361 |
- Preparing to unpack .../ruby1.9.1_1.9.3.484-2ubuntu1_amd64.deb ... |
|
| 362 |
- Unpacking ruby1.9.1 (1.9.3.484-2ubuntu1) ... |
|
| 363 |
- Selecting previously unselected package libruby1.9.1. |
|
| 364 |
- Preparing to unpack .../libruby1.9.1_1.9.3.484-2ubuntu1_amd64.deb ... |
|
| 365 |
- Unpacking libruby1.9.1 (1.9.3.484-2ubuntu1) ... |
|
| 366 |
- Selecting previously unselected package manpages-dev. |
|
| 367 |
- Preparing to unpack .../manpages-dev_3.54-1ubuntu1_all.deb ... |
|
| 368 |
- Unpacking manpages-dev (3.54-1ubuntu1) ... |
|
| 369 |
- Selecting previously unselected package ruby1.9.1-dev. |
|
| 370 |
- Preparing to unpack .../ruby1.9.1-dev_1.9.3.484-2ubuntu1_amd64.deb ... |
|
| 371 |
- Unpacking ruby1.9.1-dev (1.9.3.484-2ubuntu1) ... |
|
| 372 |
- Selecting previously unselected package ruby-dev. |
|
| 373 |
- Preparing to unpack .../ruby-dev_1%3a1.9.3.4_all.deb ... |
|
| 374 |
- Unpacking ruby-dev (1:1.9.3.4) ... |
|
| 375 |
- Setting up libasan0:amd64 (4.8.2-19ubuntu1) ... |
|
| 376 |
- Setting up libatomic1:amd64 (4.8.2-19ubuntu1) ... |
|
| 377 |
- Setting up libgmp10:amd64 (2:5.1.3+dfsg-1ubuntu1) ... |
|
| 378 |
- Setting up libisl10:amd64 (0.12.2-1) ... |
|
| 379 |
- Setting up libcloog-isl4:amd64 (0.18.2-1) ... |
|
| 380 |
- Setting up libgomp1:amd64 (4.8.2-19ubuntu1) ... |
|
| 381 |
- Setting up libitm1:amd64 (4.8.2-19ubuntu1) ... |
|
| 382 |
- Setting up libmpfr4:amd64 (3.1.2-1) ... |
|
| 383 |
- Setting up libquadmath0:amd64 (4.8.2-19ubuntu1) ... |
|
| 384 |
- Setting up libtsan0:amd64 (4.8.2-19ubuntu1) ... |
|
| 385 |
- Setting up libyaml-0-2:amd64 (0.1.4-3ubuntu3) ... |
|
| 386 |
- Setting up libmpc3:amd64 (1.0.1-1ubuntu1) ... |
|
| 387 |
- Setting up openssl (1.0.1f-1ubuntu2.4) ... |
|
| 388 |
- Setting up ca-certificates (20130906ubuntu2) ... |
|
| 389 |
- debconf: unable to initialize frontend: Dialog |
|
| 390 |
- debconf: (TERM is not set, so the dialog frontend is not usable.) |
|
| 391 |
- debconf: falling back to frontend: Readline |
|
| 392 |
- debconf: unable to initialize frontend: Readline |
|
| 393 |
- debconf: (This frontend requires a controlling tty.) |
|
| 394 |
- debconf: falling back to frontend: Teletype |
|
| 395 |
- Setting up manpages (3.54-1ubuntu1) ... |
|
| 396 |
- Setting up binutils (2.24-5ubuntu3) ... |
|
| 397 |
- Setting up cpp-4.8 (4.8.2-19ubuntu1) ... |
|
| 398 |
- Setting up cpp (4:4.8.2-1ubuntu6) ... |
|
| 399 |
- Setting up libgcc-4.8-dev:amd64 (4.8.2-19ubuntu1) ... |
|
| 400 |
- Setting up gcc-4.8 (4.8.2-19ubuntu1) ... |
|
| 401 |
- Setting up gcc (4:4.8.2-1ubuntu6) ... |
|
| 402 |
- Setting up libc-dev-bin (2.19-0ubuntu6) ... |
|
| 403 |
- Setting up linux-libc-dev:amd64 (3.13.0-30.55) ... |
|
| 404 |
- Setting up libc6-dev:amd64 (2.19-0ubuntu6) ... |
|
| 405 |
- Setting up manpages-dev (3.54-1ubuntu1) ... |
|
| 406 |
- Setting up libruby1.9.1 (1.9.3.484-2ubuntu1) ... |
|
| 407 |
- Setting up ruby1.9.1-dev (1.9.3.484-2ubuntu1) ... |
|
| 408 |
- Setting up ruby-dev (1:1.9.3.4) ... |
|
| 409 |
- Setting up ruby (1:1.9.3.4) ... |
|
| 410 |
- Setting up ruby1.9.1 (1.9.3.484-2ubuntu1) ... |
|
| 411 |
- Processing triggers for libc-bin (2.19-0ubuntu6) ... |
|
| 412 |
- Processing triggers for ca-certificates (20130906ubuntu2) ... |
|
| 413 |
- Updating certificates in /etc/ssl/certs... 164 added, 0 removed; done. |
|
| 414 |
- Running hooks in /etc/ca-certificates/update.d....done. |
|
| 415 |
- ---> c55c31703134 |
|
| 416 |
- Removing intermediate container 3a2558904e9b |
|
| 417 |
- Step 4 : RUN gem install sinatra |
|
| 418 |
- ---> Running in 6b81cb6313e5 |
|
| 419 |
- unable to convert "\xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to US-ASCII for README.rdoc, skipping |
|
| 420 |
- unable to convert "\xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to US-ASCII for README.rdoc, skipping |
|
| 421 |
- Successfully installed rack-1.5.2 |
|
| 422 |
- Successfully installed tilt-1.4.1 |
|
| 423 |
- Successfully installed rack-protection-1.5.3 |
|
| 424 |
- Successfully installed sinatra-1.4.5 |
|
| 425 |
- 4 gems installed |
|
| 426 |
- Installing ri documentation for rack-1.5.2... |
|
| 427 |
- Installing ri documentation for tilt-1.4.1... |
|
| 428 |
- Installing ri documentation for rack-protection-1.5.3... |
|
| 429 |
- Installing ri documentation for sinatra-1.4.5... |
|
| 430 |
- Installing RDoc documentation for rack-1.5.2... |
|
| 431 |
- Installing RDoc documentation for tilt-1.4.1... |
|
| 432 |
- Installing RDoc documentation for rack-protection-1.5.3... |
|
| 433 |
- Installing RDoc documentation for sinatra-1.4.5... |
|
| 434 |
- ---> 97feabe5d2ed |
|
| 435 |
- Removing intermediate container 6b81cb6313e5 |
|
| 436 |
- Successfully built 97feabe5d2ed |
|
| 437 |
- |
|
| 438 |
-You've specified our `docker build` command and used the `-t` flag to identify |
|
| 439 |
-our new image as belonging to the user `ouruser`, the repository name `sinatra` |
|
| 440 |
-and given it the tag `v2`. |
|
| 441 |
- |
|
| 442 |
-You've also specified the location of our `Dockerfile` using the `.` to |
|
| 443 |
-indicate a `Dockerfile` in the current directory. |
|
| 444 |
- |
|
| 445 |
-> **Note:** |
|
| 446 |
-> You can also specify a path to a `Dockerfile`. |
|
| 447 |
- |
|
| 448 |
-Now you can see the build process at work. The first thing Docker does is |
|
| 449 |
-upload the build context: basically the contents of the directory you're |
|
| 450 |
-building in. This is done because the Docker daemon does the actual |
|
| 451 |
-build of the image and it needs the local context to do it. |
|
| 452 |
- |
|
| 453 |
-Next you can see each instruction in the `Dockerfile` being executed |
|
| 454 |
-step-by-step. You can see that each step creates a new container, runs |
|
| 455 |
-the instruction inside that container and then commits that change - |
|
| 456 |
-just like the `docker commit` work flow you saw earlier. When all the |
|
| 457 |
-instructions have executed you're left with the `97feabe5d2ed` image |
|
| 458 |
-(also helpfuly tagged as `ouruser/sinatra:v2`) and all intermediate |
|
| 459 |
-containers will get removed to clean things up. |
|
| 460 |
- |
|
| 461 |
-> **Note:** |
|
| 462 |
-> An image can't have more than 127 layers regardless of the storage driver. |
|
| 463 |
-> This limitation is set globally to encourage optimization of the overall |
|
| 464 |
-> size of images. |
|
| 465 |
- |
|
| 466 |
-You can then create a container from our new image. |
|
| 467 |
- |
|
| 468 |
- $ docker run -t -i ouruser/sinatra:v2 /bin/bash |
|
| 469 |
- root@8196968dac35:/# |
|
| 470 |
- |
|
| 471 |
-> **Note:** |
|
| 472 |
-> This is just a brief introduction to creating images. We've |
|
| 473 |
-> skipped a whole bunch of other instructions that you can use. We'll see more of |
|
| 474 |
-> those instructions in later sections of the Guide or you can refer to the |
|
| 475 |
-> [`Dockerfile`](../../reference/builder.md) reference for a |
|
| 476 |
-> detailed description and examples of every instruction. |
|
| 477 |
-> To help you write a clear, readable, maintainable `Dockerfile`, we've also |
|
| 478 |
-> written a [`Dockerfile` Best Practices guide](../eng-image/dockerfile_best-practices.md). |
|
| 479 |
- |
|
| 480 |
- |
|
| 481 |
-## Setting tags on an image |
|
| 482 |
- |
|
| 483 |
-You can also add a tag to an existing image after you commit or build it. We |
|
| 484 |
-can do this using the `docker tag` command. Now, add a new tag to your |
|
| 485 |
-`ouruser/sinatra` image. |
|
| 486 |
- |
|
| 487 |
- $ docker tag 5db5f8471261 ouruser/sinatra:devel |
|
| 488 |
- |
|
| 489 |
-The `docker tag` command takes the ID of the image, here `5db5f8471261`, and our |
|
| 490 |
-user name, the repository name and the new tag. |
|
| 491 |
- |
|
| 492 |
-Now, see your new tag using the `docker images` command. |
|
| 493 |
- |
|
| 494 |
- $ docker images ouruser/sinatra |
|
| 495 |
- REPOSITORY TAG IMAGE ID CREATED SIZE |
|
| 496 |
- ouruser/sinatra latest 5db5f8471261 11 hours ago 446.7 MB |
|
| 497 |
- ouruser/sinatra devel 5db5f8471261 11 hours ago 446.7 MB |
|
| 498 |
- ouruser/sinatra v2 5db5f8471261 11 hours ago 446.7 MB |
|
| 499 |
- |
|
| 500 |
-## Image Digests |
|
| 501 |
- |
|
| 502 |
-Images that use the v2 or later format have a content-addressable identifier |
|
| 503 |
-called a `digest`. As long as the input used to generate the image is |
|
| 504 |
-unchanged, the digest value is predictable. To list image digest values, use |
|
| 505 |
-the `--digests` flag: |
|
| 506 |
- |
|
| 507 |
- $ docker images --digests | head |
|
| 508 |
- REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE |
|
| 509 |
- ouruser/sinatra latest sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf 5db5f8471261 11 hours ago 446.7 MB |
|
| 510 |
- |
|
| 511 |
-When pushing or pulling to a 2.0 registry, the `push` or `pull` command |
|
| 512 |
-output includes the image digest. You can `pull` using a digest value. |
|
| 513 |
- |
|
| 514 |
- $ docker pull ouruser/sinatra@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf |
|
| 515 |
- |
|
| 516 |
-You can also reference by digest in `create`, `run`, and `rmi` commands, as well as the |
|
| 517 |
-`FROM` image reference in a Dockerfile. |
|
| 518 |
- |
|
| 519 |
-## Push an image to Docker Hub |
|
| 520 |
- |
|
| 521 |
-Once you've built or created a new image you can push it to [Docker |
|
| 522 |
-Hub](https://hub.docker.com) using the `docker push` command. This |
|
| 523 |
-allows you to share it with others, either publicly, or push it into [a |
|
| 524 |
-private repository](https://hub.docker.com/account/billing-plans/). |
|
| 525 |
- |
|
| 526 |
- $ docker push ouruser/sinatra |
|
| 527 |
- The push refers to a repository [ouruser/sinatra] (len: 1) |
|
| 528 |
- Sending image list |
|
| 529 |
- Pushing repository ouruser/sinatra (3 tags) |
|
| 530 |
- . . . |
|
| 531 |
- |
|
| 532 |
-## Remove an image from the host |
|
| 533 |
- |
|
| 534 |
-You can also remove images on your Docker host in a way [similar to |
|
| 535 |
-containers](usingdocker.md) using the `docker rmi` command. |
|
| 536 |
- |
|
| 537 |
-Delete the `training/sinatra` image as you don't need it anymore. |
|
| 538 |
- |
|
| 539 |
- $ docker rmi training/sinatra |
|
| 540 |
- Untagged: training/sinatra:latest |
|
| 541 |
- Deleted: 5bc342fa0b91cabf65246837015197eecfa24b2213ed6a51a8974ae250fedd8d |
|
| 542 |
- Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f |
|
| 543 |
- Deleted: 5c58979d73ae448df5af1d8142436d81116187a7633082650549c52c3a2418f0 |
|
| 544 |
- |
|
| 545 |
-> **Note:** To remove an image from the host, please make sure |
|
| 546 |
-> that there are no containers actively based on it. |
|
| 547 |
- |
|
| 548 |
-# Next steps |
|
| 549 |
- |
|
| 550 |
-Until now you've seen how to build individual applications inside Docker |
|
| 551 |
-containers. Now learn how to build whole application stacks with Docker |
|
| 552 |
-by networking together multiple Docker containers. |
|
| 553 |
- |
|
| 554 |
-Go to [Network containers](networkingcontainers.md). |
| 555 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,194 +0,0 @@ |
| 1 |
-<!--[metadata]> |
|
| 2 |
-+++ |
|
| 3 |
-aliases = ["/engine/userguide/dockerizing/"] |
|
| 4 |
-title = "Hello world in a container" |
|
| 5 |
-description = "A simple 'Hello world' exercise that introduced you to Docker." |
|
| 6 |
-keywords = ["docker guide, docker, docker platform, how to, dockerize, dockerizing apps, dockerizing applications, container, containers"] |
|
| 7 |
-[menu.main] |
|
| 8 |
-parent="engine_learn" |
|
| 9 |
-weight=-6 |
|
| 10 |
-+++ |
|
| 11 |
-<![end-metadata]--> |
|
| 12 |
- |
|
| 13 |
-# Hello world in a container |
|
| 14 |
- |
|
| 15 |
-*So what's this Docker thing all about?* |
|
| 16 |
- |
|
| 17 |
-Docker allows you to run applications, worlds you create, inside containers. |
|
| 18 |
-Running an application inside a container takes a single command: `docker run`. |
|
| 19 |
- |
|
| 20 |
->**Note**: Depending on your Docker system configuration, you may be required to |
|
| 21 |
->preface each `docker` command on this page with `sudo`. To avoid this behavior, |
|
| 22 |
->your system administrator can create a Unix group called `docker` and add users |
|
| 23 |
->to it. |
|
| 24 |
- |
|
| 25 |
-## Run a Hello world |
|
| 26 |
- |
|
| 27 |
-Let's run a hello world container. |
|
| 28 |
- |
|
| 29 |
- $ docker run ubuntu /bin/echo 'Hello world' |
|
| 30 |
- Hello world |
|
| 31 |
- |
|
| 32 |
-You just launched your first container! |
|
| 33 |
- |
|
| 34 |
-In this example: |
|
| 35 |
- |
|
| 36 |
-* `docker run` runs a container. |
|
| 37 |
- |
|
| 38 |
-* `ubuntu` is the image you run, for example the Ubuntu operating system image. |
|
| 39 |
- When you specify an image, Docker looks first for the image on your |
|
| 40 |
- Docker host. If the image does not exist locally, then the image is pulled from the public |
|
| 41 |
- image registry [Docker Hub](https://hub.docker.com). |
|
| 42 |
- |
|
| 43 |
-* `/bin/echo` is the command to run inside the new container. |
|
| 44 |
- |
|
| 45 |
-The container launches. Docker creates a new Ubuntu |
|
| 46 |
-environment and executes the `/bin/echo` command inside it and then prints out: |
|
| 47 |
- |
|
| 48 |
- Hello world |
|
| 49 |
- |
|
| 50 |
-So what happened to the container after that? Well, Docker containers |
|
| 51 |
-only run as long as the command you specify is active. Therefore, in the above example, |
|
| 52 |
-the container stops once the command is executed. |
|
| 53 |
- |
|
| 54 |
-## Run an interactive container |
|
| 55 |
- |
|
| 56 |
-Let's specify a new command to run in the container. |
|
| 57 |
- |
|
| 58 |
- $ docker run -t -i ubuntu /bin/bash |
|
| 59 |
- root@af8bae53bdd3:/# |
|
| 60 |
- |
|
| 61 |
-In this example: |
|
| 62 |
- |
|
| 63 |
-* `docker run` runs a container. |
|
| 64 |
-* `ubuntu` is the image you would like to run. |
|
| 65 |
-* `-t` flag assigns a pseudo-tty or terminal inside the new container. |
|
| 66 |
-* `-i` flag allows you to make an interactive connection by |
|
| 67 |
-grabbing the standard in (`STDIN`) of the container. |
|
| 68 |
-* `/bin/bash` launches a Bash shell inside our container. |
|
| 69 |
- |
|
| 70 |
-The container launches. We can see there is a |
|
| 71 |
-command prompt inside it: |
|
| 72 |
- |
|
| 73 |
- root@af8bae53bdd3:/# |
|
| 74 |
- |
|
| 75 |
-Let's try running some commands inside the container: |
|
| 76 |
- |
|
| 77 |
- root@af8bae53bdd3:/# pwd |
|
| 78 |
- / |
|
| 79 |
- root@af8bae53bdd3:/# ls |
|
| 80 |
- bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var |
|
| 81 |
- |
|
| 82 |
-In this example: |
|
| 83 |
- |
|
| 84 |
-* `pwd` displays the current directory, the `/` root directory. |
|
| 85 |
-* `ls` displays the directory listing of the root directory of a typical Linux file system. |
|
| 86 |
- |
|
| 87 |
-Now, you can play around inside this container. When completed, run the `exit` command or enter Ctrl-D |
|
| 88 |
-to exit the interactive shell. |
|
| 89 |
- |
|
| 90 |
- root@af8bae53bdd3:/# exit |
|
| 91 |
- |
|
| 92 |
->**Note:** As with our previous container, once the Bash shell process has |
|
| 93 |
-finished, the container stops. |
|
| 94 |
- |
|
| 95 |
-## Start a daemonized Hello world |
|
| 96 |
- |
|
| 97 |
-Let's create a container that runs as a daemon. |
|
| 98 |
- |
|
| 99 |
- $ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done" |
|
| 100 |
- 1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147 |
|
| 101 |
- |
|
| 102 |
-In this example: |
|
| 103 |
- |
|
| 104 |
-* `docker run` runs the container. |
|
| 105 |
-* `-d` flag runs the container in the background (to daemonize it). |
|
| 106 |
-* `ubuntu` is the image you would like to run. |
|
| 107 |
- |
|
| 108 |
-Finally, we specify a command to run: |
|
| 109 |
- |
|
| 110 |
- /bin/sh -c "while true; do echo hello world; sleep 1; done" |
|
| 111 |
- |
|
| 112 |
- |
|
| 113 |
-In the output, we do not see `hello world` but a long string: |
|
| 114 |
- |
|
| 115 |
- 1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147 |
|
| 116 |
- |
|
| 117 |
-This long string is called a *container ID*. It uniquely |
|
| 118 |
-identifies a container so we can work with it. |
|
| 119 |
- |
|
| 120 |
-> **Note:** |
|
| 121 |
-> The container ID is a bit long and unwieldy. Later, we will cover the short |
|
| 122 |
-> ID and ways to name our containers to make |
|
| 123 |
-> working with them easier. |
|
| 124 |
- |
|
| 125 |
-We can use this container ID to see what's happening with our `hello world` daemon. |
|
| 126 |
- |
|
| 127 |
-First, let's make sure our container is running. Run the `docker ps` command. |
|
| 128 |
-The `docker ps` command queries the Docker daemon for information about all the containers it knows |
|
| 129 |
-about. |
|
| 130 |
- |
|
| 131 |
- $ docker ps |
|
| 132 |
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
|
| 133 |
- 1e5535038e28 ubuntu /bin/sh -c 'while tr 2 minutes ago Up 1 minute insane_babbage |
|
| 134 |
- |
|
| 135 |
-In this example, we can see our daemonized container. The `docker ps` returns some useful |
|
| 136 |
-information: |
|
| 137 |
- |
|
| 138 |
-* `1e5535038e28` is the shorter variant of the container ID. |
|
| 139 |
-* `ubuntu` is the used image. |
|
| 140 |
-* the command, status, and assigned name `insane_babbage`. |
|
| 141 |
- |
|
| 142 |
- |
|
| 143 |
-> **Note:** |
|
| 144 |
-> Docker automatically generates names for any containers started. |
|
| 145 |
-> We'll see how to specify your own names a bit later. |
|
| 146 |
- |
|
| 147 |
-Now, we know the container is running. But is it doing what we asked it to do? To |
|
| 148 |
-see this we're going to look inside the container using the `docker logs` |
|
| 149 |
-command. |
|
| 150 |
- |
|
| 151 |
-Let's use the container name `insane_babbage`. |
|
| 152 |
- |
|
| 153 |
- $ docker logs insane_babbage |
|
| 154 |
- hello world |
|
| 155 |
- hello world |
|
| 156 |
- hello world |
|
| 157 |
- . . . |
|
| 158 |
- |
|
| 159 |
-In this example: |
|
| 160 |
- |
|
| 161 |
-* `docker logs` looks inside the container and returns `hello world`. |
|
| 162 |
- |
|
| 163 |
-Awesome! The daemon is working and you have just created your first |
|
| 164 |
-Dockerized application! |
|
| 165 |
- |
|
| 166 |
-Next, run the `docker stop` command to stop our detached container. |
|
| 167 |
- |
|
| 168 |
- $ docker stop insane_babbage |
|
| 169 |
- insane_babbage |
|
| 170 |
- |
|
| 171 |
-The `docker stop` command tells Docker to politely stop the running |
|
| 172 |
-container and returns the name of the container it stopped. |
|
| 173 |
- |
|
| 174 |
-Let's check it worked with the `docker ps` command. |
|
| 175 |
- |
|
| 176 |
- $ docker ps |
|
| 177 |
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
|
| 178 |
- |
|
| 179 |
-Excellent. Our container is stopped. |
|
| 180 |
- |
|
| 181 |
-# Next steps |
|
| 182 |
- |
|
| 183 |
-So far, you launched your first containers using the `docker run` command. You |
|
| 184 |
-ran an *interactive container* that ran in the foreground. You also ran a |
|
| 185 |
-*detached container* that ran in the background. In the process you learned |
|
| 186 |
-about several Docker commands: |
|
| 187 |
- |
|
| 188 |
-* `docker ps` - Lists containers. |
|
| 189 |
-* `docker logs` - Shows us the standard output of a container. |
|
| 190 |
-* `docker stop` - Stops running containers. |
|
| 191 |
- |
|
| 192 |
-Now, you have the basis learn more about Docker and how to do some more advanced |
|
| 193 |
-tasks. Go to ["*Run a simple application*"](usingdocker.md) to actually build a |
|
| 194 |
-web application with the Docker client. |
| 195 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,187 +0,0 @@ |
| 1 |
-<!--[metadata]> |
|
| 2 |
-+++ |
|
| 3 |
-aliases = ["/engine/userguide/dockerrepos/"] |
|
| 4 |
-title = "Store images on Docker Hub" |
|
| 5 |
-description = "Learn how to use the Docker Hub to manage Docker images and work flow" |
|
| 6 |
-keywords = ["repo, Docker Hub, Docker Hub, registry, index, repositories, usage, pull image, push image, image, documentation"] |
|
| 7 |
-[menu.main] |
|
| 8 |
-parent = "engine_learn" |
|
| 9 |
-+++ |
|
| 10 |
-<![end-metadata]--> |
|
| 11 |
- |
|
| 12 |
-# Store images on Docker Hub |
|
| 13 |
- |
|
| 14 |
-So far you've learned how to use the command line to run Docker on your local |
|
| 15 |
-host. You've learned how to [pull down images](usingdocker.md) to build |
|
| 16 |
-containers from existing images and you've learned how to [create your own |
|
| 17 |
-images](dockerimages.md). |
|
| 18 |
- |
|
| 19 |
-Next, you're going to learn how to use the [Docker Hub](https://hub.docker.com) |
|
| 20 |
-to simplify and enhance your Docker workflows. |
|
| 21 |
- |
|
| 22 |
-The [Docker Hub](https://hub.docker.com) is a public registry maintained by |
|
| 23 |
-Docker, Inc. It contains images you can download and use to build |
|
| 24 |
-containers. It also provides authentication, work group structure, workflow |
|
| 25 |
-tools like webhooks and build triggers, and privacy tools like private |
|
| 26 |
-repositories for storing images you don't want to share publicly. |
|
| 27 |
- |
|
| 28 |
-## Docker commands and Docker Hub |
|
| 29 |
- |
|
| 30 |
-Docker itself provides access to Docker Hub services via the `docker search`, |
|
| 31 |
-`pull`, `login`, and `push` commands. This page will show you how these commands work. |
|
| 32 |
- |
|
| 33 |
-### Account creation and login |
|
| 34 |
-Before you try an Engine CLI command, if you haven't already, create a Docker |
|
| 35 |
-ID. You can do this through [Docker Hub](https://hub.docker.com/). Once you have |
|
| 36 |
-a Docker ID, log into your account from the Engine CLI: |
|
| 37 |
- |
|
| 38 |
-```bash |
|
| 39 |
-$ docker login |
|
| 40 |
-``` |
|
| 41 |
- |
|
| 42 |
-The `login` command stores your Docker ID authentication credentials in the |
|
| 43 |
-`$HOME/.docker/config.json` (Bash notation). For Windows `cmd` users the |
|
| 44 |
-notation for this file is `%HOME%\.docker\config.json` ; for PowerShell users |
|
| 45 |
-the notation is `$env:Home\.docker\config.json`. |
|
| 46 |
- |
|
| 47 |
-Once you have logged in from the command line, you can `commit` and `push` |
|
| 48 |
-Engine subcommands to interact with your repos on Docker Hub. |
|
| 49 |
- |
|
| 50 |
-## Searching for images |
|
| 51 |
- |
|
| 52 |
-You can search the [Docker Hub](https://hub.docker.com) registry via its search |
|
| 53 |
-interface or by using the command line interface. Searching can find images by image |
|
| 54 |
-name, user name, or description: |
|
| 55 |
- |
|
| 56 |
- $ docker search centos |
|
| 57 |
- NAME DESCRIPTION STARS OFFICIAL AUTOMATED |
|
| 58 |
- centos The official build of CentOS 1223 [OK] |
|
| 59 |
- tianon/centos CentOS 5 and 6, created using rinse instea... 33 |
|
| 60 |
- ... |
|
| 61 |
- |
|
| 62 |
-There you can see two example results: `centos` and `tianon/centos`. The second |
|
| 63 |
-result shows that it comes from the public repository of a user, named |
|
| 64 |
-`tianon/`, while the first result, `centos`, doesn't explicitly list a |
|
| 65 |
-repository which means that it comes from the trusted top-level namespace for |
|
| 66 |
-[Official Repositories](https://docs.docker.com/docker-hub/official_repos/). The `/` character separates |
|
| 67 |
-a user's repository from the image name. |
|
| 68 |
- |
|
| 69 |
-Once you've found the image you want, you can download it with `docker pull <imagename>`: |
|
| 70 |
- |
|
| 71 |
- $ docker pull centos |
|
| 72 |
- Using default tag: latest |
|
| 73 |
- latest: Pulling from library/centos |
|
| 74 |
- f1b10cd84249: Pull complete |
|
| 75 |
- c852f6d61e65: Pull complete |
|
| 76 |
- 7322fbe74aa5: Pull complete |
|
| 77 |
- Digest: sha256:90305c9112250c7e3746425477f1c4ef112b03b4abe78c612e092037bfecc3b7 |
|
| 78 |
- Status: Downloaded newer image for centos:latest |
|
| 79 |
- |
|
| 80 |
-You now have an image from which you can run containers. |
|
| 81 |
- |
|
| 82 |
-### Specific Versions or Latest |
|
| 83 |
-Using `docker pull centos` is equivalent to using `docker pull centos:latest`. |
|
| 84 |
-To pull an image that is not the default latest image you can be more precise |
|
| 85 |
-with the image that you want. |
|
| 86 |
- |
|
| 87 |
-For example, to pull version 5 of `centos` use `docker pull centos:centos5`. |
|
| 88 |
-In this example, `centos5` is the tag labeling an image in the `centos` |
|
| 89 |
-repository for a version of `centos`. |
|
| 90 |
- |
|
| 91 |
-To find a list of tags pointing to currently available versions of a repository |
|
| 92 |
-see the [Docker Hub](https://hub.docker.com) registry. |
|
| 93 |
- |
|
| 94 |
-## Contributing to Docker Hub |
|
| 95 |
- |
|
| 96 |
-Anyone can pull public images from the [Docker Hub](https://hub.docker.com) |
|
| 97 |
-registry, but if you would like to share your own images, then you must |
|
| 98 |
-[register first](https://docs.docker.com/docker-hub/accounts). |
|
| 99 |
- |
|
| 100 |
-## Pushing a repository to Docker Hub |
|
| 101 |
- |
|
| 102 |
-In order to push a repository to its registry, you need to have named an image |
|
| 103 |
-or committed your container to a named image as we saw |
|
| 104 |
-[here](dockerimages.md). |
|
| 105 |
- |
|
| 106 |
-Now you can push this repository to the registry designated by its name or tag. |
|
| 107 |
- |
|
| 108 |
- $ docker push yourname/newimage |
|
| 109 |
- |
|
| 110 |
-The image will then be uploaded and available for use by your team-mates and/or the |
|
| 111 |
-community. |
|
| 112 |
- |
|
| 113 |
-## Features of Docker Hub |
|
| 114 |
- |
|
| 115 |
-Let's take a closer look at some of the features of Docker Hub. You can find more |
|
| 116 |
-information [here](https://docs.docker.com/docker-hub/). |
|
| 117 |
- |
|
| 118 |
-* Private repositories |
|
| 119 |
-* Organizations and teams |
|
| 120 |
-* Automated Builds |
|
| 121 |
-* Webhooks |
|
| 122 |
- |
|
| 123 |
-### Private repositories |
|
| 124 |
- |
|
| 125 |
-Sometimes you have images you don't want to make public and share with |
|
| 126 |
-everyone. So Docker Hub allows you to have private repositories. You can |
|
| 127 |
-sign up for a plan [here](https://hub.docker.com/account/billing-plans/). |
|
| 128 |
- |
|
| 129 |
-### Organizations and teams |
|
| 130 |
- |
|
| 131 |
-One of the useful aspects of private repositories is that you can share |
|
| 132 |
-them only with members of your organization or team. Docker Hub lets you |
|
| 133 |
-create organizations where you can collaborate with your colleagues and |
|
| 134 |
-manage private repositories. You can learn how to create and manage an organization |
|
| 135 |
-[here](https://hub.docker.com/organizations/). |
|
| 136 |
- |
|
| 137 |
-### Automated Builds |
|
| 138 |
- |
|
| 139 |
-Automated Builds automate the building and updating of images from |
|
| 140 |
-[GitHub](https://www.github.com) or [Bitbucket](http://bitbucket.com), directly on Docker |
|
| 141 |
-Hub. It works by adding a commit hook to your selected GitHub or Bitbucket repository, |
|
| 142 |
-triggering a build and update when you push a commit. |
|
| 143 |
- |
|
| 144 |
-#### To setup an Automated Build |
|
| 145 |
- |
|
| 146 |
-1. Create a [Docker Hub account](https://hub.docker.com/) and login. |
|
| 147 |
-2. Link your GitHub or Bitbucket account on the ["Linked Accounts & Services"](https://hub.docker.com/account/authorized-services/) page. |
|
| 148 |
-3. Select "Create Automated Build" from the "Create" dropdown menu |
|
| 149 |
-4. Pick a GitHub or Bitbucket project that has a `Dockerfile` that you want to build. |
|
| 150 |
-5. Pick the branch you want to build (the default is the `master` branch). |
|
| 151 |
-6. Give the Automated Build a name. |
|
| 152 |
-7. Assign an optional Docker tag to the Build. |
|
| 153 |
-8. Specify where the `Dockerfile` is located. The default is `/`. |
|
| 154 |
- |
|
| 155 |
-Once the Automated Build is configured it will automatically trigger a |
|
| 156 |
-build and, in a few minutes, you should see your new Automated Build on the [Docker Hub](https://hub.docker.com) |
|
| 157 |
-Registry. It will stay in sync with your GitHub and Bitbucket repository until you |
|
| 158 |
-deactivate the Automated Build. |
|
| 159 |
- |
|
| 160 |
-To check the output and status of your Automated Build repositories, click on a repository name within the ["Your Repositories" page](https://registry.hub.docker.com/repos/). Automated Builds are indicated by a check-mark icon next to the repository name. Within the repository details page, you may click on the "Build Details" tab to view the status and output of all builds triggered by the Docker Hub. |
|
| 161 |
- |
|
| 162 |
-Once you've created an Automated Build you can deactivate or delete it. You |
|
| 163 |
-cannot, however, push to an Automated Build with the `docker push` command. |
|
| 164 |
-You can only manage it by committing code to your GitHub or Bitbucket |
|
| 165 |
-repository. |
|
| 166 |
- |
|
| 167 |
-You can create multiple Automated Builds per repository and configure them |
|
| 168 |
-to point to specific `Dockerfile`'s or Git branches. |
|
| 169 |
- |
|
| 170 |
-#### Build triggers |
|
| 171 |
- |
|
| 172 |
-Automated Builds can also be triggered via a URL on Docker Hub. This |
|
| 173 |
-allows you to rebuild an Automated build image on demand. |
|
| 174 |
- |
|
| 175 |
-### Webhooks |
|
| 176 |
- |
|
| 177 |
-Webhooks are attached to your repositories and allow you to trigger an |
|
| 178 |
-event when an image or updated image is pushed to the repository. With |
|
| 179 |
-a webhook you can specify a target URL and a JSON payload that will be |
|
| 180 |
-delivered when the image is pushed. |
|
| 181 |
- |
|
| 182 |
-See the Docker Hub documentation for [more information on |
|
| 183 |
-webhooks](https://docs.docker.com/docker-hub/repos/#webhooks) |
|
| 184 |
- |
|
| 185 |
-## Next steps |
|
| 186 |
- |
|
| 187 |
-Go and use Docker! |
| 188 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,372 +0,0 @@ |
| 1 |
-<!--[metadata]> |
|
| 2 |
-+++ |
|
| 3 |
-aliases = ["/engine/userguide/dockervolumes/"] |
|
| 4 |
-title = "Manage data in containers" |
|
| 5 |
-description = "How to manage data inside your Docker containers." |
|
| 6 |
-keywords = ["Examples, Usage, volume, docker, documentation, user guide, data, volumes"] |
|
| 7 |
-[menu.main] |
|
| 8 |
-parent = "engine_learn" |
|
| 9 |
-+++ |
|
| 10 |
-<![end-metadata]--> |
|
| 11 |
- |
|
| 12 |
-# Manage data in containers |
|
| 13 |
- |
|
| 14 |
-So far you've been introduced to some [basic Docker |
|
| 15 |
-concepts](../containers/usingdocker.md), seen how to work with [Docker |
|
| 16 |
-images](../containers/dockerimages.md) as well as learned about [networking and |
|
| 17 |
-links between containers](../networking/default_network/dockerlinks.md). In this |
|
| 18 |
-section you're going to learn how you can manage data inside and between your |
|
| 19 |
-Docker containers. |
|
| 20 |
- |
|
| 21 |
-You're going to look at the two primary ways you can manage data with |
|
| 22 |
-Docker Engine. |
|
| 23 |
- |
|
| 24 |
-* Data volumes |
|
| 25 |
-* Data volume containers |
|
| 26 |
- |
|
| 27 |
-## Data volumes |
|
| 28 |
- |
|
| 29 |
-A *data volume* is a specially-designated directory within one or more |
|
| 30 |
-containers that bypasses the [*Union File System*](../../reference/glossary.md#union-file-system). Data volumes provide several useful features for persistent or shared data: |
|
| 31 |
- |
|
| 32 |
-- Volumes are initialized when a container is created. If the container's |
|
| 33 |
- base image contains data at the specified mount point, that existing data is |
|
| 34 |
- copied into the new volume upon volume initialization. (Note that this does |
|
| 35 |
- not apply when [mounting a host directory](#mount-a-host-directory-as-a-data-volume).) |
|
| 36 |
-- Data volumes can be shared and reused among containers. |
|
| 37 |
-- Changes to a data volume are made directly. |
|
| 38 |
-- Changes to a data volume will not be included when you update an image. |
|
| 39 |
-- Data volumes persist even if the container itself is deleted. |
|
| 40 |
- |
|
| 41 |
-Data volumes are designed to persist data, independent of the container's life |
|
| 42 |
-cycle. Docker therefore *never* automatically deletes volumes when you remove |
|
| 43 |
-a container, nor will it "garbage collect" volumes that are no longer |
|
| 44 |
-referenced by a container. |
|
| 45 |
- |
|
| 46 |
-### Adding a data volume |
|
| 47 |
- |
|
| 48 |
-You can add a data volume to a container using the `-v` flag with the |
|
| 49 |
-`docker create` and `docker run` command. You can use the `-v` multiple times |
|
| 50 |
-to mount multiple data volumes. Now, mount a single volume in your web |
|
| 51 |
-application container. |
|
| 52 |
- |
|
| 53 |
-```bash |
|
| 54 |
-$ docker run -d -P --name web -v /webapp training/webapp python app.py |
|
| 55 |
-``` |
|
| 56 |
- |
|
| 57 |
-This will create a new volume inside a container at `/webapp`. |
|
| 58 |
- |
|
| 59 |
-> **Note:** |
|
| 60 |
-> You can also use the `VOLUME` instruction in a `Dockerfile` to add one or |
|
| 61 |
-> more new volumes to any container created from that image. |
|
| 62 |
- |
|
| 63 |
-### Locating a volume |
|
| 64 |
- |
|
| 65 |
-You can locate the volume on the host by utilizing the `docker inspect` command. |
|
| 66 |
- |
|
| 67 |
-```bash |
|
| 68 |
-$ docker inspect web |
|
| 69 |
-``` |
|
| 70 |
- |
|
| 71 |
-The output will provide details on the container configurations including the |
|
| 72 |
-volumes. The output should look something similar to the following: |
|
| 73 |
- |
|
| 74 |
-```json |
|
| 75 |
-... |
|
| 76 |
-"Mounts": [ |
|
| 77 |
- {
|
|
| 78 |
- "Name": "fac362...80535", |
|
| 79 |
- "Source": "/var/lib/docker/volumes/fac362...80535/_data", |
|
| 80 |
- "Destination": "/webapp", |
|
| 81 |
- "Driver": "local", |
|
| 82 |
- "Mode": "", |
|
| 83 |
- "RW": true, |
|
| 84 |
- "Propagation": "" |
|
| 85 |
- } |
|
| 86 |
-] |
|
| 87 |
-... |
|
| 88 |
-``` |
|
| 89 |
- |
|
| 90 |
-You will notice in the above `Source` is specifying the location on the host and |
|
| 91 |
-`Destination` is specifying the volume location inside the container. `RW` shows |
|
| 92 |
-if the volume is read/write. |
|
| 93 |
- |
|
| 94 |
-### Mount a host directory as a data volume |
|
| 95 |
- |
|
| 96 |
-In addition to creating a volume using the `-v` flag you can also mount a |
|
| 97 |
-directory from your Engine daemon's host into a container. |
|
| 98 |
- |
|
| 99 |
-```bash |
|
| 100 |
-$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py |
|
| 101 |
-``` |
|
| 102 |
- |
|
| 103 |
-This command mounts the host directory, `/src/webapp`, into the container at |
|
| 104 |
-`/opt/webapp`. If the path `/opt/webapp` already exists inside the container's |
|
| 105 |
-image, the `/src/webapp` mount overlays but does not remove the pre-existing |
|
| 106 |
-content. Once the mount is removed, the content is accessible again. This is |
|
| 107 |
-consistent with the expected behavior of the `mount` command. |
|
| 108 |
- |
|
| 109 |
-The `container-dir` must always be an absolute path such as `/src/docs`. |
|
| 110 |
-The `host-dir` can either be an absolute path or a `name` value. If you |
|
| 111 |
-supply an absolute path for the `host-dir`, Docker bind-mounts to the path |
|
| 112 |
-you specify. If you supply a `name`, Docker creates a named volume by that `name`. |
|
| 113 |
- |
|
| 114 |
-A `name` value must start with an alphanumeric character, |
|
| 115 |
-followed by `a-z0-9`, `_` (underscore), `.` (period) or `-` (hyphen). |
|
| 116 |
-An absolute path starts with a `/` (forward slash). |
|
| 117 |
- |
|
| 118 |
-For example, you can specify either `/foo` or `foo` for a `host-dir` value. |
|
| 119 |
-If you supply the `/foo` value, Engine creates a bind-mount. If you supply |
|
| 120 |
-the `foo` specification, Engine creates a named volume. |
|
| 121 |
- |
|
| 122 |
-If you are using Docker Machine on Mac or Windows, your Engine daemon has only |
|
| 123 |
-limited access to your OS X or Windows filesystem. Docker Machine tries to |
|
| 124 |
-auto-share your `/Users` (OS X) or `C:\Users` (Windows) directory. So, you can |
|
| 125 |
-mount files or directories on OS X using. |
|
| 126 |
- |
|
| 127 |
-```bash |
|
| 128 |
-docker run -v /Users/<path>:/<container path> ... |
|
| 129 |
-``` |
|
| 130 |
- |
|
| 131 |
-On Windows, mount directories using: |
|
| 132 |
- |
|
| 133 |
-```bash |
|
| 134 |
-docker run -v /c/Users/<path>:/<container path> ...` |
|
| 135 |
-``` |
|
| 136 |
- |
|
| 137 |
-All other paths come from your virtual machine's filesystem, so if you want |
|
| 138 |
-to make some other host folder available for sharing, you need to do |
|
| 139 |
-additional work. In the case of VirtualBox you need to make the host folder |
|
| 140 |
-available as a shared folder in VirtualBox. Then, you can mount it using the |
|
| 141 |
-Docker `-v` flag. |
|
| 142 |
- |
|
| 143 |
-Mounting a host directory can be useful for testing. For example, you can mount |
|
| 144 |
-source code inside a container. Then, change the source code and see its effect |
|
| 145 |
-on the application in real time. The directory on the host must be specified as |
|
| 146 |
-an absolute path and if the directory doesn't exist the Engine daemon automatically |
|
| 147 |
-creates it for you. |
|
| 148 |
- |
|
| 149 |
-Docker volumes default to mount in read-write mode, but you can also set it to |
|
| 150 |
-be mounted read-only. |
|
| 151 |
- |
|
| 152 |
-```bash |
|
| 153 |
-$ docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py |
|
| 154 |
-``` |
|
| 155 |
- |
|
| 156 |
-Here you've mounted the same `/src/webapp` directory but you've added the `ro` |
|
| 157 |
-option to specify that the mount should be read-only. |
|
| 158 |
- |
|
| 159 |
-Because of [limitations in the `mount` |
|
| 160 |
-function](http://lists.linuxfoundation.org/pipermail/containers/2015-April/035788.html), |
|
| 161 |
-moving subdirectories within the host's source directory can give |
|
| 162 |
-access from the container to the host's file system. This requires a malicious |
|
| 163 |
-user with access to host and its mounted directory. |
|
| 164 |
- |
|
| 165 |
->**Note**: The host directory is, by its nature, host-dependent. For this |
|
| 166 |
->reason, you can't mount a host directory from `Dockerfile` because built images |
|
| 167 |
->should be portable. A host directory wouldn't be available on all potential |
|
| 168 |
->hosts. |
|
| 169 |
- |
|
| 170 |
-### Mount a shared-storage volume as a data volume |
|
| 171 |
- |
|
| 172 |
-In addition to mounting a host directory in your container, some Docker |
|
| 173 |
-[volume plugins](../../extend/plugins_volume.md) allow you to |
|
| 174 |
-provision and mount shared storage, such as iSCSI, NFS, or FC. |
|
| 175 |
- |
|
| 176 |
-A benefit of using shared volumes is that they are host-independent. This |
|
| 177 |
-means that a volume can be made available on any host that a container is |
|
| 178 |
-started on as long as it has access to the shared storage backend, and has |
|
| 179 |
-the plugin installed. |
|
| 180 |
- |
|
| 181 |
-One way to use volume drivers is through the `docker run` command. |
|
| 182 |
-Volume drivers create volumes by name, instead of by path like in |
|
| 183 |
-the other examples. |
|
| 184 |
- |
|
| 185 |
-The following command creates a named volume, called `my-named-volume`, |
|
| 186 |
-using the `flocker` volume driver, and makes it available within the container |
|
| 187 |
-at `/opt/webapp`: |
|
| 188 |
- |
|
| 189 |
-```bash |
|
| 190 |
-$ docker run -d -P \ |
|
| 191 |
- --volume-driver=flocker \ |
|
| 192 |
- -v my-named-volume:/opt/webapp \ |
|
| 193 |
- --name web training/webapp python app.py |
|
| 194 |
-``` |
|
| 195 |
- |
|
| 196 |
-You may also use the `docker volume create` command, to create a volume before |
|
| 197 |
-using it in a container. |
|
| 198 |
- |
|
| 199 |
-The following example also creates the `my-named-volume` volume, this time |
|
| 200 |
-using the `docker volume create` command. |
|
| 201 |
- |
|
| 202 |
-```bash |
|
| 203 |
-$ docker volume create -d flocker --name my-named-volume -o size=20GB |
|
| 204 |
-$ docker run -d -P \ |
|
| 205 |
- -v my-named-volume:/opt/webapp \ |
|
| 206 |
- --name web training/webapp python app.py |
|
| 207 |
-``` |
|
| 208 |
- |
|
| 209 |
-A list of available plugins, including volume plugins, is available |
|
| 210 |
-[here](../../extend/plugins.md). |
|
| 211 |
- |
|
| 212 |
-### Volume labels |
|
| 213 |
- |
|
| 214 |
-Labeling systems like SELinux require that proper labels are placed on volume |
|
| 215 |
-content mounted into a container. Without a label, the security system might |
|
| 216 |
-prevent the processes running inside the container from using the content. By |
|
| 217 |
-default, Docker does not change the labels set by the OS. |
|
| 218 |
- |
|
| 219 |
-To change a label in the container context, you can add either of two suffixes |
|
| 220 |
-`:z` or `:Z` to the volume mount. These suffixes tell Docker to relabel file |
|
| 221 |
-objects on the shared volumes. The `z` option tells Docker that two containers |
|
| 222 |
-share the volume content. As a result, Docker labels the content with a shared |
|
| 223 |
-content label. Shared volume labels allow all containers to read/write content. |
|
| 224 |
-The `Z` option tells Docker to label the content with a private unshared label. |
|
| 225 |
-Only the current container can use a private volume. |
|
| 226 |
- |
|
| 227 |
-### Mount a host file as a data volume |
|
| 228 |
- |
|
| 229 |
-The `-v` flag can also be used to mount a single file - instead of *just* |
|
| 230 |
-directories - from the host machine. |
|
| 231 |
- |
|
| 232 |
-```bash |
|
| 233 |
-$ docker run --rm -it -v ~/.bash_history:/root/.bash_history ubuntu /bin/bash |
|
| 234 |
-``` |
|
| 235 |
- |
|
| 236 |
-This will drop you into a bash shell in a new container, you will have your bash |
|
| 237 |
-history from the host and when you exit the container, the host will have the |
|
| 238 |
-history of the commands typed while in the container. |
|
| 239 |
- |
|
| 240 |
-> **Note:** |
|
| 241 |
-> Many tools used to edit files including `vi` and `sed --in-place` may result |
|
| 242 |
-> in an inode change. Since Docker v1.1.0, this will produce an error such as |
|
| 243 |
-> "*sed: cannot rename ./sedKdJ9Dy: Device or resource busy*". In the case where |
|
| 244 |
-> you want to edit the mounted file, it is often easiest to instead mount the |
|
| 245 |
-> parent directory. |
|
| 246 |
- |
|
| 247 |
-## Creating and mounting a data volume container |
|
| 248 |
- |
|
| 249 |
-If you have some persistent data that you want to share between |
|
| 250 |
-containers, or want to use from non-persistent containers, it's best to |
|
| 251 |
-create a named Data Volume Container, and then to mount the data from |
|
| 252 |
-it. |
|
| 253 |
- |
|
| 254 |
-Let's create a new named container with a volume to share. |
|
| 255 |
-While this container doesn't run an application, it reuses the `training/postgres` |
|
| 256 |
-image so that all containers are using layers in common, saving disk space. |
|
| 257 |
- |
|
| 258 |
-```bash |
|
| 259 |
-$ docker create -v /dbdata --name dbstore training/postgres /bin/true |
|
| 260 |
-``` |
|
| 261 |
- |
|
| 262 |
-You can then use the `--volumes-from` flag to mount the `/dbdata` volume in another container. |
|
| 263 |
- |
|
| 264 |
-```bash |
|
| 265 |
-$ docker run -d --volumes-from dbstore --name db1 training/postgres |
|
| 266 |
-``` |
|
| 267 |
- |
|
| 268 |
-And another: |
|
| 269 |
- |
|
| 270 |
-```bash |
|
| 271 |
-$ docker run -d --volumes-from dbstore --name db2 training/postgres |
|
| 272 |
-``` |
|
| 273 |
- |
|
| 274 |
-In this case, if the `postgres` image contained a directory called `/dbdata` |
|
| 275 |
-then mounting the volumes from the `dbstore` container hides the |
|
| 276 |
-`/dbdata` files from the `postgres` image. The result is only the files |
|
| 277 |
-from the `dbstore` container are visible. |
|
| 278 |
- |
|
| 279 |
-You can use multiple `--volumes-from` parameters to combine data volumes from |
|
| 280 |
-several containers. To find detailed information about `--volumes-from` see the |
|
| 281 |
-[Mount volumes from container](../../reference/commandline/run.md#mount-volumes-from-container-volumes-from) |
|
| 282 |
-in the `run` command reference. |
|
| 283 |
- |
|
| 284 |
-You can also extend the chain by mounting the volume that came from the |
|
| 285 |
-`dbstore` container in yet another container via the `db1` or `db2` containers. |
|
| 286 |
- |
|
| 287 |
-```bash |
|
| 288 |
-$ docker run -d --name db3 --volumes-from db1 training/postgres |
|
| 289 |
-``` |
|
| 290 |
- |
|
| 291 |
-If you remove containers that mount volumes, including the initial `dbstore` |
|
| 292 |
-container, or the subsequent containers `db1` and `db2`, the volumes will not |
|
| 293 |
-be deleted. To delete the volume from disk, you must explicitly call |
|
| 294 |
-`docker rm -v` against the last container with a reference to the volume. This |
|
| 295 |
-allows you to upgrade, or effectively migrate data volumes between containers. |
|
| 296 |
- |
|
| 297 |
-> **Note:** Docker will not warn you when removing a container *without* |
|
| 298 |
-> providing the `-v` option to delete its volumes. If you remove containers |
|
| 299 |
-> without using the `-v` option, you may end up with "dangling" volumes; |
|
| 300 |
-> volumes that are no longer referenced by a container. |
|
| 301 |
-> You can use `docker volume ls -f dangling=true` to find dangling volumes, |
|
| 302 |
-> and use `docker volume rm <volume name>` to remove a volume that's |
|
| 303 |
-> no longer needed. |
|
| 304 |
- |
|
| 305 |
-## Backup, restore, or migrate data volumes |
|
| 306 |
- |
|
| 307 |
-Another useful function we can perform with volumes is use them for |
|
| 308 |
-backups, restores or migrations. You do this by using the |
|
| 309 |
-`--volumes-from` flag to create a new container that mounts that volume, |
|
| 310 |
-like so: |
|
| 311 |
- |
|
| 312 |
-```bash |
|
| 313 |
-$ docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata |
|
| 314 |
-``` |
|
| 315 |
- |
|
| 316 |
-Here you've launched a new container and mounted the volume from the |
|
| 317 |
-`dbstore` container. You've then mounted a local host directory as |
|
| 318 |
-`/backup`. Finally, you've passed a command that uses `tar` to backup the |
|
| 319 |
-contents of the `dbdata` volume to a `backup.tar` file inside our |
|
| 320 |
-`/backup` directory. When the command completes and the container stops |
|
| 321 |
-we'll be left with a backup of our `dbdata` volume. |
|
| 322 |
- |
|
| 323 |
-You could then restore it to the same container, or another that you've made |
|
| 324 |
-elsewhere. Create a new container. |
|
| 325 |
- |
|
| 326 |
-```bash |
|
| 327 |
-$ docker run -v /dbdata --name dbstore2 ubuntu /bin/bash |
|
| 328 |
-``` |
|
| 329 |
- |
|
| 330 |
-Then un-tar the backup file in the new container`s data volume. |
|
| 331 |
- |
|
| 332 |
-```bash |
|
| 333 |
-$ docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1" |
|
| 334 |
-``` |
|
| 335 |
- |
|
| 336 |
-You can use the techniques above to automate backup, migration and |
|
| 337 |
-restore testing using your preferred tools. |
|
| 338 |
- |
|
| 339 |
-## Removing volumes |
|
| 340 |
- |
|
| 341 |
-A Docker data volume persists after a container is deleted. You can create named |
|
| 342 |
-or anonymous volumes. Named volumes have a specific source form outside the |
|
| 343 |
-container, for example `awesome:/bar`. Anonymous volumes have no specific |
|
| 344 |
-source. When the container is deleted, you should instruction the Engine daemon |
|
| 345 |
-to clean up anonymous volumes. To do this, use the `--rm` option, for example: |
|
| 346 |
- |
|
| 347 |
-```bash |
|
| 348 |
-$ docker run --rm -v /foo -v awesome:/bar busybox top |
|
| 349 |
-``` |
|
| 350 |
- |
|
| 351 |
-This command creates an anonymous `/foo` volume. When the container is removed, |
|
| 352 |
-Engine removes the `/foo` volume but not the `awesome` volume. |
|
| 353 |
- |
|
| 354 |
-## Important tips on using shared volumes |
|
| 355 |
- |
|
| 356 |
-Multiple containers can also share one or more data volumes. However, multiple |
|
| 357 |
-containers writing to a single shared volume can cause data corruption. Make |
|
| 358 |
-sure your applications are designed to write to shared data stores. |
|
| 359 |
- |
|
| 360 |
-Data volumes are directly accessible from the Docker host. This means you can |
|
| 361 |
-read and write to them with normal Linux tools. In most cases you should not do |
|
| 362 |
-this as it can cause data corruption if your containers and applications are |
|
| 363 |
-unaware of your direct access. |
|
| 364 |
- |
|
| 365 |
-# Next steps |
|
| 366 |
- |
|
| 367 |
-Now you've learned a bit more about how to use Docker we're going to see how to |
|
| 368 |
-combine Docker with the services available on |
|
| 369 |
-[Docker Hub](https://hub.docker.com) including Automated Builds and private |
|
| 370 |
-repositories. |
|
| 371 |
- |
|
| 372 |
-Go to [Working with Docker Hub](../containers/dockerrepos.md). |
| 373 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,19 +0,0 @@ |
| 1 |
-<!--[metadata]> |
|
| 2 |
-+++ |
|
| 3 |
-title = "Learn by example" |
|
| 4 |
-description = "Explains how to work with containers" |
|
| 5 |
-keywords = ["docker, introduction, documentation, about, technology, docker.io, user, guide, user's, manual, platform, framework, home, intro"] |
|
| 6 |
-[menu.main] |
|
| 7 |
-identifier="engine_learn" |
|
| 8 |
-parent = "engine_guide" |
|
| 9 |
-+++ |
|
| 10 |
-<![end-metadata]--> |
|
| 11 |
- |
|
| 12 |
-# Learn by example |
|
| 13 |
- |
|
| 14 |
-* [Hello world in a container](dockerizing.md) |
|
| 15 |
-* [Run a simple application](usingdocker.md) |
|
| 16 |
-* [Build your own images](dockerimages.md) |
|
| 17 |
-* [Network containers](networkingcontainers.md) |
|
| 18 |
-* [Manage data in containers](dockervolumes.md) |
|
| 19 |
-* [Store images on Docker Hub](dockerrepos.md) |
| 20 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,247 +0,0 @@ |
| 1 |
-<!--[metadata]> |
|
| 2 |
-+++ |
|
| 3 |
-aliases = ["/engine/userguide/networkigncontainers/"] |
|
| 4 |
-title = "Network containers" |
|
| 5 |
-description = "How to network Docker containers." |
|
| 6 |
-keywords = ["Examples, Usage, volume, docker, documentation, user guide, data, volumes"] |
|
| 7 |
-[menu.main] |
|
| 8 |
-parent = "engine_learn" |
|
| 9 |
-weight = -3 |
|
| 10 |
-+++ |
|
| 11 |
-<![end-metadata]--> |
|
| 12 |
- |
|
| 13 |
- |
|
| 14 |
-# Network containers |
|
| 15 |
- |
|
| 16 |
-If you are working your way through the user guide, you just built and ran a |
|
| 17 |
-simple application. You've also built in your own images. This section teaches |
|
| 18 |
-you how to network your containers. |
|
| 19 |
- |
|
| 20 |
-## Name a container |
|
| 21 |
- |
|
| 22 |
-You've already seen that each container you create has an automatically |
|
| 23 |
-created name; indeed you've become familiar with our old friend |
|
| 24 |
-`nostalgic_morse` during this guide. You can also name containers |
|
| 25 |
-yourself. This naming provides two useful functions: |
|
| 26 |
- |
|
| 27 |
-* You can name containers that do specific functions in a way |
|
| 28 |
- that makes it easier for you to remember them, for example naming a |
|
| 29 |
- container containing a web application `web`. |
|
| 30 |
- |
|
| 31 |
-* Names provide Docker with a reference point that allows it to refer to other |
|
| 32 |
- containers. There are several commands that support this and you'll use one in an exercise later. |
|
| 33 |
- |
|
| 34 |
-You name your container by using the `--name` flag, for example launch a new container called web: |
|
| 35 |
- |
|
| 36 |
- $ docker run -d -P --name web training/webapp python app.py |
|
| 37 |
- |
|
| 38 |
-Use the `docker ps` command to check the name: |
|
| 39 |
- |
|
| 40 |
- $ docker ps -l |
|
| 41 |
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
|
| 42 |
- aed84ee21bde training/webapp:latest python app.py 12 hours ago Up 2 seconds 0.0.0.0:49154->5000/tcp web |
|
| 43 |
- |
|
| 44 |
-You can also use `docker inspect` with the container's name. |
|
| 45 |
- |
|
| 46 |
- $ docker inspect web |
|
| 47 |
- [ |
|
| 48 |
- {
|
|
| 49 |
- "Id": "3ce51710b34f5d6da95e0a340d32aa2e6cf64857fb8cdb2a6c38f7c56f448143", |
|
| 50 |
- "Created": "2015-10-25T22:44:17.854367116Z", |
|
| 51 |
- "Path": "python", |
|
| 52 |
- "Args": [ |
|
| 53 |
- "app.py" |
|
| 54 |
- ], |
|
| 55 |
- "State": {
|
|
| 56 |
- "Status": "running", |
|
| 57 |
- "Running": true, |
|
| 58 |
- "Paused": false, |
|
| 59 |
- "Restarting": false, |
|
| 60 |
- "OOMKilled": false, |
|
| 61 |
- ... |
|
| 62 |
- |
|
| 63 |
-Container names must be unique. That means you can only call one container |
|
| 64 |
-`web`. If you want to re-use a container name you must delete the old container |
|
| 65 |
-(with `docker rm`) before you can reuse the name with a new container. Go ahead and stop and remove your old `web` container. |
|
| 66 |
- |
|
| 67 |
- $ docker stop web |
|
| 68 |
- web |
|
| 69 |
- $ docker rm web |
|
| 70 |
- web |
|
| 71 |
- |
|
| 72 |
- |
|
| 73 |
-## Launch a container on the default network |
|
| 74 |
- |
|
| 75 |
-Docker includes support for networking containers through the use of **network |
|
| 76 |
-drivers**. By default, Docker provides two network drivers for you, the |
|
| 77 |
-`bridge` and the `overlay` drivers. You can also write a network driver plugin so |
|
| 78 |
-that you can create your own drivers but that is an advanced task. |
|
| 79 |
- |
|
| 80 |
-Every installation of the Docker Engine automatically includes three default networks. You can list them: |
|
| 81 |
- |
|
| 82 |
- $ docker network ls |
|
| 83 |
- NETWORK ID NAME DRIVER |
|
| 84 |
- 18a2866682b8 none null |
|
| 85 |
- c288470c46f6 host host |
|
| 86 |
- 7b369448dccb bridge bridge |
|
| 87 |
- |
|
| 88 |
-The network named `bridge` is a special network. Unless you tell it otherwise, Docker always launches your containers in this network. Try this now: |
|
| 89 |
- |
|
| 90 |
- $ docker run -itd --name=networktest ubuntu |
|
| 91 |
- 74695c9cea6d9810718fddadc01a727a5dd3ce6a69d09752239736c030599741 |
|
| 92 |
- |
|
| 93 |
-Inspecting the network is an easy way to find out the container's IP address. |
|
| 94 |
- |
|
| 95 |
-```bash |
|
| 96 |
-$ docker network inspect bridge |
|
| 97 |
-[ |
|
| 98 |
- {
|
|
| 99 |
- "Name": "bridge", |
|
| 100 |
- "Id": "f7ab26d71dbd6f557852c7156ae0574bbf62c42f539b50c8ebde0f728a253b6f", |
|
| 101 |
- "Scope": "local", |
|
| 102 |
- "Driver": "bridge", |
|
| 103 |
- "IPAM": {
|
|
| 104 |
- "Driver": "default", |
|
| 105 |
- "Config": [ |
|
| 106 |
- {
|
|
| 107 |
- "Subnet": "172.17.0.1/16", |
|
| 108 |
- "Gateway": "172.17.0.1" |
|
| 109 |
- } |
|
| 110 |
- ] |
|
| 111 |
- }, |
|
| 112 |
- "Containers": {
|
|
| 113 |
- "3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c": {
|
|
| 114 |
- "EndpointID": "647c12443e91faf0fd508b6edfe59c30b642abb60dfab890b4bdccee38750bc1", |
|
| 115 |
- "MacAddress": "02:42:ac:11:00:02", |
|
| 116 |
- "IPv4Address": "172.17.0.2/16", |
|
| 117 |
- "IPv6Address": "" |
|
| 118 |
- }, |
|
| 119 |
- "94447ca479852d29aeddca75c28f7104df3c3196d7b6d83061879e339946805c": {
|
|
| 120 |
- "EndpointID": "b047d090f446ac49747d3c37d63e4307be745876db7f0ceef7b311cbba615f48", |
|
| 121 |
- "MacAddress": "02:42:ac:11:00:03", |
|
| 122 |
- "IPv4Address": "172.17.0.3/16", |
|
| 123 |
- "IPv6Address": "" |
|
| 124 |
- } |
|
| 125 |
- }, |
|
| 126 |
- "Options": {
|
|
| 127 |
- "com.docker.network.bridge.default_bridge": "true", |
|
| 128 |
- "com.docker.network.bridge.enable_icc": "true", |
|
| 129 |
- "com.docker.network.bridge.enable_ip_masquerade": "true", |
|
| 130 |
- "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", |
|
| 131 |
- "com.docker.network.bridge.name": "docker0", |
|
| 132 |
- "com.docker.network.driver.mtu": "9001" |
|
| 133 |
- } |
|
| 134 |
- } |
|
| 135 |
-] |
|
| 136 |
-``` |
|
| 137 |
- |
|
| 138 |
-You can remove a container from a network by disconnecting the container. To do this, you supply both the network name and the container name. You can also use the container id. In this example, though, the name is faster. |
|
| 139 |
- |
|
| 140 |
- $ docker network disconnect bridge networktest |
|
| 141 |
- |
|
| 142 |
-While you can disconnect a container from a network, you cannot remove the builtin `bridge` network named `bridge`. Networks are natural ways to isolate containers from other containers or other networks. So, as you get more experienced with Docker, you'll want to create your own networks. |
|
| 143 |
- |
|
| 144 |
-## Create your own bridge network |
|
| 145 |
- |
|
| 146 |
-Docker Engine natively supports both bridge networks and overlay networks. A bridge network is limited to a single host running Docker Engine. An overlay network can include multiple hosts and is a more advanced topic. For this example, you'll create a bridge network: |
|
| 147 |
- |
|
| 148 |
- $ docker network create -d bridge my-bridge-network |
|
| 149 |
- |
|
| 150 |
-The `-d` flag tells Docker to use the `bridge` driver for the new network. You could have left this flag off as `bridge` is the default value for this flag. Go ahead and list the networks on your machine: |
|
| 151 |
- |
|
| 152 |
- $ docker network ls |
|
| 153 |
- NETWORK ID NAME DRIVER |
|
| 154 |
- 7b369448dccb bridge bridge |
|
| 155 |
- 615d565d498c my-bridge-network bridge |
|
| 156 |
- 18a2866682b8 none null |
|
| 157 |
- c288470c46f6 host host |
|
| 158 |
- |
|
| 159 |
-If you inspect the network, you'll find that it has nothing in it. |
|
| 160 |
- |
|
| 161 |
- $ docker network inspect my-bridge-network |
|
| 162 |
- [ |
|
| 163 |
- {
|
|
| 164 |
- "Name": "my-bridge-network", |
|
| 165 |
- "Id": "5a8afc6364bccb199540e133e63adb76a557906dd9ff82b94183fc48c40857ac", |
|
| 166 |
- "Scope": "local", |
|
| 167 |
- "Driver": "bridge", |
|
| 168 |
- "IPAM": {
|
|
| 169 |
- "Driver": "default", |
|
| 170 |
- "Config": [ |
|
| 171 |
- {
|
|
| 172 |
- "Subnet": "172.18.0.0/16", |
|
| 173 |
- "Gateway": "172.18.0.1/16" |
|
| 174 |
- } |
|
| 175 |
- ] |
|
| 176 |
- }, |
|
| 177 |
- "Containers": {},
|
|
| 178 |
- "Options": {}
|
|
| 179 |
- } |
|
| 180 |
- ] |
|
| 181 |
- |
|
| 182 |
-## Add containers to a network |
|
| 183 |
- |
|
| 184 |
-To build web applications that act in concert but do so securely, create a |
|
| 185 |
-network. Networks, by definition, provide complete isolation for containers. You |
|
| 186 |
-can add containers to a network when you first run a container. |
|
| 187 |
- |
|
| 188 |
-Launch a container running a PostgreSQL database and pass it the `--net=my-bridge-network` flag to connect it to your new network: |
|
| 189 |
- |
|
| 190 |
- $ docker run -d --net=my-bridge-network --name db training/postgres |
|
| 191 |
- |
|
| 192 |
-If you inspect your `my-bridge-network` you'll see it has a container attached. |
|
| 193 |
-You can also inspect your container to see where it is connected: |
|
| 194 |
- |
|
| 195 |
- $ docker inspect --format='{{json .NetworkSettings.Networks}}' db
|
|
| 196 |
- {"my-bridge-network":{"NetworkID":"7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99",
|
|
| 197 |
- "EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"172.18.0.1","IPAddress":"172.18.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}} |
|
| 198 |
- |
|
| 199 |
-Now, go ahead and start your by now familiar web application. This time leave off the `-P` flag and also don't specify a network. |
|
| 200 |
- |
|
| 201 |
- $ docker run -d --name web training/webapp python app.py |
|
| 202 |
- |
|
| 203 |
-Which network is your `web` application running under? Inspect the application and you'll find it is running in the default `bridge` network. |
|
| 204 |
- |
|
| 205 |
- $ docker inspect --format='{{json .NetworkSettings.Networks}}' web
|
|
| 206 |
- {"bridge":{"NetworkID":"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812",
|
|
| 207 |
- "EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"172.17.0.1","IPAddress":"172.17.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}} |
|
| 208 |
- |
|
| 209 |
-Then, get the IP address of your `web` |
|
| 210 |
- |
|
| 211 |
- $ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
|
|
| 212 |
- 172.17.0.2 |
|
| 213 |
- |
|
| 214 |
-Now, open a shell to your running `db` container: |
|
| 215 |
- |
|
| 216 |
- $ docker exec -it db bash |
|
| 217 |
- root@a205f0dd33b2:/# ping 172.17.0.2 |
|
| 218 |
- ping 172.17.0.2 |
|
| 219 |
- PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. |
|
| 220 |
- ^C |
|
| 221 |
- --- 172.17.0.2 ping statistics --- |
|
| 222 |
- 44 packets transmitted, 0 received, 100% packet loss, time 43185ms |
|
| 223 |
- |
|
| 224 |
-After a bit, use `CTRL-C` to end the `ping` and you'll find the ping failed. That is because the two containers are running on different networks. You can fix that. Then, use the `exit` command to close the container. |
|
| 225 |
- |
|
| 226 |
-Docker networking allows you to attach a container to as many networks as you like. You can also attach an already running container. Go ahead and attach your running `web` app to the `my-bridge-network`. |
|
| 227 |
- |
|
| 228 |
- $ docker network connect my-bridge-network web |
|
| 229 |
- |
|
| 230 |
-Open a shell into the `db` application again and try the ping command. This time just use the container name `web` rather than the IP Address. |
|
| 231 |
- |
|
| 232 |
- $ docker exec -it db bash |
|
| 233 |
- root@a205f0dd33b2:/# ping web |
|
| 234 |
- PING web (172.18.0.3) 56(84) bytes of data. |
|
| 235 |
- 64 bytes from web (172.18.0.3): icmp_seq=1 ttl=64 time=0.095 ms |
|
| 236 |
- 64 bytes from web (172.18.0.3): icmp_seq=2 ttl=64 time=0.060 ms |
|
| 237 |
- 64 bytes from web (172.18.0.3): icmp_seq=3 ttl=64 time=0.066 ms |
|
| 238 |
- ^C |
|
| 239 |
- --- web ping statistics --- |
|
| 240 |
- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms |
|
| 241 |
- rtt min/avg/max/mdev = 0.060/0.073/0.095/0.018 ms |
|
| 242 |
- |
|
| 243 |
-The `ping` shows it is contacting a different IP address, the address on the `my-bridge-network` which is different from its address on the `bridge` network. |
|
| 244 |
- |
|
| 245 |
-## Next steps |
|
| 246 |
- |
|
| 247 |
-Now that you know how to network containers, see [how to manage data in containers](dockervolumes.md). |
| 250 | 3 |
deleted file mode 100644 |
| ... | ... |
@@ -1,306 +0,0 @@ |
| 1 |
-<!--[metadata]> |
|
| 2 |
-+++ |
|
| 3 |
-title = "Run a simple application" |
|
| 4 |
-description = "Learn how to manage and operate Docker containers." |
|
| 5 |
-keywords = ["docker, the docker guide, documentation, docker.io, monitoring containers, docker top, docker inspect, docker port, ports, docker logs, log, Logs"] |
|
| 6 |
-[menu.main] |
|
| 7 |
-parent="engine_learn" |
|
| 8 |
-weight=-5 |
|
| 9 |
-+++ |
|
| 10 |
-<![end-metadata]--> |
|
| 11 |
- |
|
| 12 |
-# Run a simple application |
|
| 13 |
- |
|
| 14 |
-In the ["*Hello world in a container*"](dockerizing.md) you launched your |
|
| 15 |
-first containers using the `docker run` command. You ran an *interactive container* that ran in the foreground. You also ran a *detached container* that ran in the background. In the process you learned about several Docker commands: |
|
| 16 |
- |
|
| 17 |
-* `docker ps` - Lists containers. |
|
| 18 |
-* `docker logs` - Shows us the standard output of a container. |
|
| 19 |
-* `docker stop` - Stops running containers. |
|
| 20 |
- |
|
| 21 |
-## Learn about the Docker client |
|
| 22 |
- |
|
| 23 |
-If you didn't realize it yet, you've been using the Docker client each time you |
|
| 24 |
-typed `docker` in your Bash terminal. The client is a simple command line client |
|
| 25 |
-also known as a command-line interface (CLI). Each action you can take with |
|
| 26 |
-the client is a command and each command can take a series of flags and arguments. |
|
| 27 |
- |
|
| 28 |
- # Usage: [sudo] docker [subcommand] [flags] [arguments] .. |
|
| 29 |
- # Example: |
|
| 30 |
- $ docker run -i -t ubuntu /bin/bash |
|
| 31 |
- |
|
| 32 |
-You can see this in action by using the `docker version` command to return |
|
| 33 |
-version information on the currently installed Docker client and daemon. |
|
| 34 |
- |
|
| 35 |
- $ docker version |
|
| 36 |
- |
|
| 37 |
-This command will not only provide you the version of Docker client and |
|
| 38 |
-daemon you are using, but also the version of Go (the programming |
|
| 39 |
-language powering Docker). |
|
| 40 |
- |
|
| 41 |
- Client: |
|
| 42 |
- Version: 1.8.1 |
|
| 43 |
- API version: 1.20 |
|
| 44 |
- Go version: go1.4.2 |
|
| 45 |
- Git commit: d12ea79 |
|
| 46 |
- Built: Thu Aug 13 02:35:49 UTC 2015 |
|
| 47 |
- OS/Arch: linux/amd64 |
|
| 48 |
- |
|
| 49 |
- Server: |
|
| 50 |
- Version: 1.8.1 |
|
| 51 |
- API version: 1.20 |
|
| 52 |
- Go version: go1.4.2 |
|
| 53 |
- Git commit: d12ea79 |
|
| 54 |
- Built: Thu Aug 13 02:35:49 UTC 2015 |
|
| 55 |
- OS/Arch: linux/amd64 |
|
| 56 |
- |
|
| 57 |
-## Get Docker command help |
|
| 58 |
- |
|
| 59 |
-You can display the help for specific Docker commands. The help details the |
|
| 60 |
-options and their usage. To see a list of all the possible commands, use the |
|
| 61 |
-following: |
|
| 62 |
- |
|
| 63 |
- $ docker --help |
|
| 64 |
- |
|
| 65 |
-To see usage for a specific command, specify the command with the `--help` flag: |
|
| 66 |
- |
|
| 67 |
- $ docker attach --help |
|
| 68 |
- |
|
| 69 |
- Usage: docker attach [OPTIONS] CONTAINER |
|
| 70 |
- |
|
| 71 |
- Attach to a running container |
|
| 72 |
- |
|
| 73 |
- --help Print usage |
|
| 74 |
- --no-stdin Do not attach stdin |
|
| 75 |
- --sig-proxy=true Proxy all received signals to the process |
|
| 76 |
- |
|
| 77 |
-> **Note:** |
|
| 78 |
-> For further details and examples of each command, see the |
|
| 79 |
-> [command reference](../../reference/commandline/cli.md) in this guide. |
|
| 80 |
- |
|
| 81 |
-## Running a web application in Docker |
|
| 82 |
- |
|
| 83 |
-So now you've learned a bit more about the `docker` client you can move onto |
|
| 84 |
-the important stuff: running more containers. So far none of the |
|
| 85 |
-containers you've run did anything particularly useful, so you can |
|
| 86 |
-change that by running an example web application in Docker. |
|
| 87 |
- |
|
| 88 |
-For our web application we're going to run a Python Flask application. |
|
| 89 |
-Start with a `docker run` command. |
|
| 90 |
- |
|
| 91 |
- $ docker run -d -P training/webapp python app.py |
|
| 92 |
- |
|
| 93 |
-Review what the command did. You've specified two flags: `-d` and |
|
| 94 |
-`-P`. You've already seen the `-d` flag which tells Docker to run the |
|
| 95 |
-container in the background. The `-P` flag is new and tells Docker to |
|
| 96 |
-map any required network ports inside our container to our host. This |
|
| 97 |
-lets us view our web application. |
|
| 98 |
- |
|
| 99 |
-You've specified an image: `training/webapp`. This image is a |
|
| 100 |
-pre-built image you've created that contains a simple Python Flask web |
|
| 101 |
-application. |
|
| 102 |
- |
|
| 103 |
-Lastly, you've specified a command for our container to run: `python app.py`. This launches our web application. |
|
| 104 |
- |
|
| 105 |
-> **Note:** |
|
| 106 |
-> You can see more detail on the `docker run` command in the [command |
|
| 107 |
-> reference](../../reference/commandline/run.md) and the [Docker Run |
|
| 108 |
-> Reference](../../reference/run.md). |
|
| 109 |
- |
|
| 110 |
-## Viewing our web application container |
|
| 111 |
- |
|
| 112 |
-Now you can see your running container using the `docker ps` command. |
|
| 113 |
- |
|
| 114 |
- $ docker ps -l |
|
| 115 |
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
|
| 116 |
- bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse |
|
| 117 |
- |
|
| 118 |
-You can see you've specified a new flag, `-l`, for the `docker ps` |
|
| 119 |
-command. This tells the `docker ps` command to return the details of the |
|
| 120 |
-*last* container started. |
|
| 121 |
- |
|
| 122 |
-> **Note:** |
|
| 123 |
-> By default, the `docker ps` command only shows information about running |
|
| 124 |
-> containers. If you want to see stopped containers too use the `-a` flag. |
|
| 125 |
- |
|
| 126 |
-We can see the same details we saw [when we first Dockerized a |
|
| 127 |
-container](dockerizing.md) with one important addition in the `PORTS` |
|
| 128 |
-column. |
|
| 129 |
- |
|
| 130 |
- PORTS |
|
| 131 |
- 0.0.0.0:49155->5000/tcp |
|
| 132 |
- |
|
| 133 |
-When we passed the `-P` flag to the `docker run` command Docker mapped any |
|
| 134 |
-ports exposed in our image to our host. |
|
| 135 |
- |
|
| 136 |
-> **Note:** |
|
| 137 |
-> We'll learn more about how to expose ports in Docker images when |
|
| 138 |
-> [we learn how to build images](dockerimages.md). |
|
| 139 |
- |
|
| 140 |
-In this case Docker has exposed port 5000 (the default Python Flask |
|
| 141 |
-port) on port 49155. |
|
| 142 |
- |
|
| 143 |
-Network port bindings are very configurable in Docker. In our last example the |
|
| 144 |
-`-P` flag is a shortcut for `-p 5000` that maps port 5000 inside the container |
|
| 145 |
-to a high port (from *ephemeral port range* which typically ranges from 32768 |
|
| 146 |
-to 61000) on the local Docker host. We can also bind Docker containers to |
|
| 147 |
-specific ports using the `-p` flag, for example: |
|
| 148 |
- |
|
| 149 |
- $ docker run -d -p 80:5000 training/webapp python app.py |
|
| 150 |
- |
|
| 151 |
-This would map port 5000 inside our container to port 80 on our local |
|
| 152 |
-host. You might be asking about now: why wouldn't we just want to always |
|
| 153 |
-use 1:1 port mappings in Docker containers rather than mapping to high |
|
| 154 |
-ports? Well 1:1 mappings have the constraint of only being able to map |
|
| 155 |
-one of each port on your local host. |
|
| 156 |
- |
|
| 157 |
-Suppose you want to test two Python applications: both bound to port 5000 inside |
|
| 158 |
-their own containers. Without Docker's port mapping you could only access one at |
|
| 159 |
-a time on the Docker host. |
|
| 160 |
- |
|
| 161 |
-So you can now browse to port 49155 in a web browser to |
|
| 162 |
-see the application. |
|
| 163 |
- |
|
| 164 |
-. |
|
| 165 |
- |
|
| 166 |
-Our Python application is live! |
|
| 167 |
- |
|
| 168 |
-> **Note:** |
|
| 169 |
-> If you have been using a virtual machine on OS X, Windows or Linux, |
|
| 170 |
-> you'll need to get the IP of the virtual host instead of using localhost. |
|
| 171 |
-> You can do this by running the `docker-machine ip your_vm_name` from your command line or terminal application, for example: |
|
| 172 |
-> |
|
| 173 |
-> $ docker-machine ip my-docker-vm |
|
| 174 |
-> 192.168.99.100 |
|
| 175 |
-> |
|
| 176 |
-> In this case you'd browse to `http://192.168.99.100:49155` for the above example. |
|
| 177 |
- |
|
| 178 |
-## A network port shortcut |
|
| 179 |
- |
|
| 180 |
-Using the `docker ps` command to return the mapped port is a bit clumsy so |
|
| 181 |
-Docker has a useful shortcut we can use: `docker port`. To use `docker port` we |
|
| 182 |
-specify the ID or name of our container and then the port for which we need the |
|
| 183 |
-corresponding public-facing port. |
|
| 184 |
- |
|
| 185 |
- $ docker port nostalgic_morse 5000 |
|
| 186 |
- 0.0.0.0:49155 |
|
| 187 |
- |
|
| 188 |
-In this case you've looked up what port is mapped externally to port 5000 inside |
|
| 189 |
-the container. |
|
| 190 |
- |
|
| 191 |
-## Viewing the web application's logs |
|
| 192 |
- |
|
| 193 |
-You can also find out a bit more about what's happening with our application and |
|
| 194 |
-use another of the commands you've learned, `docker logs`. |
|
| 195 |
- |
|
| 196 |
- $ docker logs -f nostalgic_morse |
|
| 197 |
- * Running on http://0.0.0.0:5000/ |
|
| 198 |
- 10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 - |
|
| 199 |
- 10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 - |
|
| 200 |
- |
|
| 201 |
-This time though you've added a new flag, `-f`. This causes the `docker |
|
| 202 |
-logs` command to act like the `tail -f` command and watch the |
|
| 203 |
-container's standard out. We can see here the logs from Flask showing |
|
| 204 |
-the application running on port 5000 and the access log entries for it. |
|
| 205 |
- |
|
| 206 |
-## Looking at our web application container's processes |
|
| 207 |
- |
|
| 208 |
-In addition to the container's logs we can also examine the processes |
|
| 209 |
-running inside it using the `docker top` command. |
|
| 210 |
- |
|
| 211 |
- $ docker top nostalgic_morse |
|
| 212 |
- PID USER COMMAND |
|
| 213 |
- 854 root python app.py |
|
| 214 |
- |
|
| 215 |
-Here we can see our `python app.py` command is the only process running inside |
|
| 216 |
-the container. |
|
| 217 |
- |
|
| 218 |
-## Inspecting our web application container |
|
| 219 |
- |
|
| 220 |
-Lastly, we can take a low-level dive into our Docker container using the |
|
| 221 |
-`docker inspect` command. It returns a JSON document containing useful |
|
| 222 |
-configuration and status information for the specified container. |
|
| 223 |
- |
|
| 224 |
- $ docker inspect nostalgic_morse |
|
| 225 |
- |
|
| 226 |
-You can see a sample of that JSON output. |
|
| 227 |
- |
|
| 228 |
- [{
|
|
| 229 |
- "ID": "bc533791f3f500b280a9626688bc79e342e3ea0d528efe3a86a51ecb28ea20", |
|
| 230 |
- "Created": "2014-05-26T05:52:40.808952951Z", |
|
| 231 |
- "Path": "python", |
|
| 232 |
- "Args": [ |
|
| 233 |
- "app.py" |
|
| 234 |
- ], |
|
| 235 |
- "Config": {
|
|
| 236 |
- "Hostname": "bc533791f3f5", |
|
| 237 |
- "Domainname": "", |
|
| 238 |
- "User": "", |
|
| 239 |
- . . . |
|
| 240 |
- |
|
| 241 |
-We can also narrow down the information we want to return by requesting a |
|
| 242 |
-specific element, for example to return the container's IP address we would: |
|
| 243 |
- |
|
| 244 |
- $ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nostalgic_morse
|
|
| 245 |
- 172.17.0.5 |
|
| 246 |
- |
|
| 247 |
-## Stopping our web application container |
|
| 248 |
- |
|
| 249 |
-Okay you've seen web application working. Now you can stop it using the |
|
| 250 |
-`docker stop` command and the name of our container: `nostalgic_morse`. |
|
| 251 |
- |
|
| 252 |
- $ docker stop nostalgic_morse |
|
| 253 |
- nostalgic_morse |
|
| 254 |
- |
|
| 255 |
-We can now use the `docker ps` command to check if the container has |
|
| 256 |
-been stopped. |
|
| 257 |
- |
|
| 258 |
- $ docker ps -l |
|
| 259 |
- |
|
| 260 |
-## Restarting our web application container |
|
| 261 |
- |
|
| 262 |
-Oops! Just after you stopped the container you get a call to say another |
|
| 263 |
-developer needs the container back. From here you have two choices: you |
|
| 264 |
-can create a new container or restart the old one. Look at |
|
| 265 |
-starting your previous container back up. |
|
| 266 |
- |
|
| 267 |
- $ docker start nostalgic_morse |
|
| 268 |
- nostalgic_morse |
|
| 269 |
- |
|
| 270 |
-Now quickly run `docker ps -l` again to see the running container is |
|
| 271 |
-back up or browse to the container's URL to see if the application |
|
| 272 |
-responds. |
|
| 273 |
- |
|
| 274 |
-> **Note:** |
|
| 275 |
-> Also available is the `docker restart` command that runs a stop and |
|
| 276 |
-> then start on the container. |
|
| 277 |
- |
|
| 278 |
-## Removing our web application container |
|
| 279 |
- |
|
| 280 |
-Your colleague has let you know that they've now finished with the container |
|
| 281 |
-and won't need it again. Now, you can remove it using the `docker rm` command. |
|
| 282 |
- |
|
| 283 |
- $ docker rm nostalgic_morse |
|
| 284 |
- Error: Impossible to remove a running container, please stop it first or use -f |
|
| 285 |
- 2014/05/24 08:12:56 Error: failed to remove one or more containers |
|
| 286 |
- |
|
| 287 |
-What happened? We can't actually remove a running container. This protects |
|
| 288 |
-you from accidentally removing a running container you might need. You can try |
|
| 289 |
-this again by stopping the container first. |
|
| 290 |
- |
|
| 291 |
- $ docker stop nostalgic_morse |
|
| 292 |
- nostalgic_morse |
|
| 293 |
- $ docker rm nostalgic_morse |
|
| 294 |
- nostalgic_morse |
|
| 295 |
- |
|
| 296 |
-And now our container is stopped and deleted. |
|
| 297 |
- |
|
| 298 |
-> **Note:** |
|
| 299 |
-> Always remember that removing a container is final! |
|
| 300 |
- |
|
| 301 |
-# Next steps |
|
| 302 |
- |
|
| 303 |
-Until now you've only used images that you've downloaded from Docker Hub. Next, |
|
| 304 |
-you can get introduced to building and sharing our own images. |
|
| 305 |
- |
|
| 306 |
-Go to [Working with Docker Images](dockerimages.md). |
| ... | ... |
@@ -6,7 +6,7 @@ keywords = ["engine, introduction, documentation, about, technology, docker, use |
| 6 | 6 |
[menu.main] |
| 7 | 7 |
parent="engine_use" |
| 8 | 8 |
identifier = "engine_guide" |
| 9 |
-weight="-80" |
|
| 9 |
+weight="-79" |
|
| 10 | 10 |
+++ |
| 11 | 11 |
<![end-metadata]--> |
| 12 | 12 |
|
| ... | ... |
@@ -18,12 +18,12 @@ This guide helps users learn how to use Docker Engine. |
| 18 | 18 |
|
| 19 | 19 |
## Learn by example |
| 20 | 20 |
|
| 21 |
-- [Hello world in a container](containers/dockerizing.md) |
|
| 22 |
-- [Build your own images](containers/dockerimages.md) |
|
| 23 |
-- [Network containers](containers/networkingcontainers.md) |
|
| 24 |
-- [Run a simple application](containers/usingdocker.md) |
|
| 25 |
-- [Manage data in containers](containers/dockervolumes.md) |
|
| 26 |
-- [Store images on Docker Hub](containers/dockerrepos.md) |
|
| 21 |
+- [Hello world in a container](../tutorials/dockerizing.md) |
|
| 22 |
+- [Build your own images](../tutorials/dockerimages.md) |
|
| 23 |
+- [Network containers](../tutorials/networkingcontainers.md) |
|
| 24 |
+- [Run a simple application](../tutorials/usingdocker.md) |
|
| 25 |
+- [Manage data in containers](../tutorials/dockervolumes.md) |
|
| 26 |
+- [Store images on Docker Hub](../tutorials/dockerrepos.md) |
|
| 27 | 27 |
|
| 28 | 28 |
## Work with images |
| 29 | 29 |
|
| ... | ... |
@@ -28,7 +28,7 @@ This guide is broken into major sections that take you through learning the basi |
| 28 | 28 |
Docker Engine offers a containerization platform to power your applications. To |
| 29 | 29 |
learn how to Dockerize applications and run them: |
| 30 | 30 |
|
| 31 |
-Go to [Dockerizing Applications](containers/dockerizing.md). |
|
| 31 |
+Go to [Dockerizing Applications](../tutorials/dockerizing.md). |
|
| 32 | 32 |
|
| 33 | 33 |
|
| 34 | 34 |
## Working with containers |
| ... | ... |
@@ -38,7 +38,7 @@ Go to [Dockerizing Applications](containers/dockerizing.md). |
| 38 | 38 |
Once you get a grip on running your applications in Docker containers, you'll learn how to manage those containers. To find out |
| 39 | 39 |
about how to inspect, monitor and manage containers: |
| 40 | 40 |
|
| 41 |
-Go to [Working with Containers](containers/usingdocker.md). |
|
| 41 |
+Go to [Working with Containers](../tutorials/usingdocker.md). |
|
| 42 | 42 |
|
| 43 | 43 |
## Working with Docker images |
| 44 | 44 |
|
| ... | ... |
@@ -47,7 +47,7 @@ Go to [Working with Containers](containers/usingdocker.md). |
| 47 | 47 |
Once you've learnt how to use Docker it's time to take the next step and |
| 48 | 48 |
learn how to build your own application images with Docker. |
| 49 | 49 |
|
| 50 |
-Go to [Working with Docker Images](containers/dockerimages.md). |
|
| 50 |
+Go to [Working with Docker Images](../tutorials/dockerimages.md). |
|
| 51 | 51 |
|
| 52 | 52 |
## Networking containers |
| 53 | 53 |
|
| ... | ... |
@@ -55,14 +55,14 @@ Until now we've seen how to build individual applications inside Docker |
| 55 | 55 |
containers. Now learn how to build whole application stacks with Docker |
| 56 | 56 |
networking. |
| 57 | 57 |
|
| 58 |
-Go to [Networking Containers](containers/networkingcontainers.md). |
|
| 58 |
+Go to [Networking Containers](../tutorials/networkingcontainers.md). |
|
| 59 | 59 |
|
| 60 | 60 |
## Managing data in containers |
| 61 | 61 |
|
| 62 | 62 |
Now we know how to link Docker containers together the next step is |
| 63 | 63 |
learning how to manage data, volumes and mounts inside our containers. |
| 64 | 64 |
|
| 65 |
-Go to [Managing Data in Containers](containers/dockervolumes.md). |
|
| 65 |
+Go to [Managing Data in Containers](../tutorials/dockervolumes.md). |
|
| 66 | 66 |
|
| 67 | 67 |
## Docker products that complement Engine |
| 68 | 68 |
|
| ... | ... |
@@ -11,7 +11,7 @@ weight=-2 |
| 11 | 11 |
|
| 12 | 12 |
# Legacy container links |
| 13 | 13 |
|
| 14 |
-The information in this section explains legacy container links within the Docker default bridge. This is a `bridge` network named `bridge` created automatically when you install Docker. |
|
| 14 |
+The information in this section explains legacy container links within the Docker default bridge. This is a `bridge` network named `bridge` created automatically when you install Docker. |
|
| 15 | 15 |
|
| 16 | 16 |
Before the [Docker networks feature](../dockernetworks.md), you could use the |
| 17 | 17 |
Docker link feature to allow containers to discover each other and securely |
| ... | ... |
@@ -25,7 +25,7 @@ detail on container linking in default `bridge` network. |
| 25 | 25 |
|
| 26 | 26 |
## Connect using network port mapping |
| 27 | 27 |
|
| 28 |
-In [the Using Docker section](../../containers/usingdocker.md), you created a |
|
| 28 |
+In [Run a simple application](../../../tutorials/usingdocker.md), you created a |
|
| 29 | 29 |
container that ran a Python Flask application: |
| 30 | 30 |
|
| 31 | 31 |
$ docker run -d -P training/webapp python app.py |
| ... | ... |
@@ -33,7 +33,7 @@ container that ran a Python Flask application: |
| 33 | 33 |
> **Note:** |
| 34 | 34 |
> Containers have an internal network and an IP address |
| 35 | 35 |
> (as we saw when we used the `docker inspect` command to show the container's |
| 36 |
-> IP address in the [Using Docker](../../containers/usingdocker.md) section). |
|
| 36 |
+> IP address in [Run a simple application](../../../tutorials/usingdocker.md) section). |
|
| 37 | 37 |
> Docker can have a variety of network configurations. You can see more |
| 38 | 38 |
> information on Docker networking [here](../index.md). |
| 39 | 39 |
|
| ... | ... |
@@ -95,7 +95,7 @@ worth looking at the default `bridge` network a bit. |
| 95 | 95 |
|
| 96 | 96 |
|
| 97 | 97 |
### The default bridge network in detail |
| 98 |
-The default `bridge` network is present on all Docker hosts. The `docker network inspect` |
|
| 98 |
+The default `bridge` network is present on all Docker hosts. The `docker network inspect` |
|
| 99 | 99 |
command returns information about a network: |
| 100 | 100 |
|
| 101 | 101 |
``` |
| ... | ... |
@@ -519,7 +519,7 @@ functionality in user-defined networks. |
| 519 | 519 |
|
| 520 | 520 |
- [Work with network commands](work-with-networks.md) |
| 521 | 521 |
- [Get started with multi-host networking](get-started-overlay.md) |
| 522 |
-- [Managing Data in Containers](../containers/dockervolumes.md) |
|
| 522 |
+- [Managing Data in Containers](../../tutorials/dockervolumes.md) |
|
| 523 | 523 |
- [Docker Machine overview](https://docs.docker.com/machine) |
| 524 | 524 |
- [Docker Swarm overview](https://docs.docker.com/swarm) |
| 525 | 525 |
- [Investigate the LibNetwork project](https://github.com/docker/libnetwork) |