Nav fixes

This commit is contained in:
John Mulhausen 2017-01-19 15:11:42 -08:00 committed by Misty Stanley-Jones
parent a2092986e4
commit d8fcf8ae85
10 changed files with 32 additions and 1352 deletions

View File

@ -3,6 +3,7 @@ redirect_from:
- /mac/step_four/
- /windows/step_four/
- /linux/step_four/
- /engine/tutorials/dockerimages/
description: Getting started with Docker
keywords: beginner, getting started, Docker
title: Build your own image

View File

@ -5,6 +5,7 @@ redirect_from:
- /mac/step_one/
- /windows/step_one/
- /linux/step_one/
- /engine/tutorials/dockerizing/
title: Install Docker and run hello-world
---

View File

@ -5,6 +5,7 @@ redirect_from:
- /mac/step_six/
- /windows/step_six/
- /linux/step_six/
- /engine/tutorials/dockerrepos/
title: Tag, push, and pull your image
---

View File

@ -5,6 +5,7 @@ redirect_from:
- /mac/step_three/
- /windows/step_three/
- /linux/step_three/
- /engine/tutorials/usingdocker/
title: Find and run the whalesay image
---
@ -66,15 +67,15 @@ Make sure Docker is running. On Docker for Mac and Docker for Windows, this is i
-----
\
\
\
## .
## ## ## ==
## ## ## ## ===
/""""""""""""""""___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/
\
## .
## ## ## ==
## ## ## ## ===
/""""""""""""""""___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/
The first time you run a software image, the `docker` command looks for it
on your local system. If the image isn't there, then `docker` gets it from
@ -108,15 +109,15 @@ Make sure Docker is running. On Docker for Mac and Docker for Windows, this is i
---------
\
\
\
## .
## ## ## ==
## ## ## ## ===
/""""""""""""""""___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/
\
## .
## ## ## ==
## ## ## ## ===
/""""""""""""""""___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/
## Where to go next

View File

@ -1,593 +0,0 @@
---
description: How to work with Docker images.
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
redirect_from:
- /engine/userguide/containers/dockerimages/
- /engine/userguide/dockerimages/
title: Build your own images
---
Docker images are the basis of containers. Each time you've used `docker run`
you told it which image you wanted. In the previous sections of the guide you
used Docker images that already exist, for example the `ubuntu` image and the
`training/webapp` image.
You also discovered that Docker stores downloaded images on the Docker host. If
an image isn't already present on the host then it'll be downloaded from a
registry: by default the [Docker Hub Registry](https://hub.docker.com).
In this section you're going to explore Docker images a bit more
including:
* Managing and working with images locally on your Docker host.
* Creating basic images.
* Uploading images to [Docker Hub Registry](https://hub.docker.com).
## Listing images on the host
Let's start with listing the images you have locally on our host. You can
do this using the `docker images` command like so:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04 1d073211c498 3 days ago 187.9 MB
busybox latest 2c5ac3f849df 5 days ago 1.113 MB
training/webapp latest 54bb4e8718e8 5 months ago 348.7 MB
You can see the images you've previously used in the user guide.
Each has been downloaded from [Docker Hub](https://hub.docker.com) when you
launched a container using that image. When you list images, you get three crucial pieces of information in the listing.
* What repository they came from, for example `ubuntu`.
* The tags for each image, for example `14.04`.
* The image ID of each image.
> **Tip:**
> You can use [a third-party dockviz tool](https://github.com/justone/dockviz)
> or the [Image layers site](https://imagelayers.io/) to display
> visualizations of image data.
A repository potentially holds multiple variants of an image. In the case of
our `ubuntu` image you can see multiple variants covering Ubuntu 10.04, 12.04,
12.10, 13.04, 13.10 and 14.04. Each variant is identified by a tag and you can
refer to a tagged image like so:
ubuntu:14.04
So when you run a container you refer to a tagged image like so:
$ docker run -t -i ubuntu:14.04 /bin/bash
If instead you wanted to run an Ubuntu 12.04 image you'd use:
$ docker run -t -i ubuntu:12.04 /bin/bash
If you don't specify a variant, for example you just use `ubuntu`, then Docker
will default to using the `ubuntu:latest` image.
> **Tip:**
> You should always specify an image tag, for example `ubuntu:14.04`.
> That way, you always know exactly what variant of an image you are using.
> This is useful for troubleshooting and debugging.
## Getting a new image
So how do you get new images? Well Docker will automatically download any image
you use that isn't already present on the Docker host. But this can potentially
add some time to the launch of a container. If you want to pre-load an image you
can download it using the `docker pull` command. Suppose you'd like to
download the `centos` image.
$ docker pull centos
Using default tag: latest
latest: Pulling from library/centos
f1b10cd84249: Pull complete
c852f6d61e65: Pull complete
7322fbe74aa5: Pull complete
Digest: sha256:90305c9112250c7e3746425477f1c4ef112b03b4abe78c612e092037bfecc3b7
Status: Downloaded newer image for centos:latest
You can see that each layer of the image has been pulled down and now you
can run a container from this image and you won't have to wait to
download the image.
$ docker run -t -i centos /bin/bash
bash-4.1#
## Finding images
One of the features of Docker is that a lot of people have created Docker
images for a variety of purposes. Many of these have been uploaded to
[Docker Hub](https://hub.docker.com). You can search these images on the
[Docker Hub](https://hub.docker.com) website.
![indexsearch](search.png)
You can also search for images on the command line using the `docker search`
command. Suppose your team wants an image with Ruby and Sinatra installed on
which to do our web application development. You can search for a suitable image
by using the `docker search` command to find all the images that contain the
term `sinatra`.
$ docker search sinatra
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
training/sinatra Sinatra training image 0 [OK]
marceldegraaf/sinatra Sinatra test app 0
mattwarren/docker-sinatra-demo 0 [OK]
luisbebop/docker-sinatra-hello-world 0 [OK]
bmorearty/handson-sinatra handson-ruby + Sinatra for Hands on with D... 0
subwiz/sinatra 0
bmorearty/sinatra 0
. . .
You can see the command returns a lot of images that use the term `sinatra`.
You've received a list of image names, descriptions, Stars (which measure the
social popularity of images - if a user likes an image then they can "star" it),
and the Official and Automated build statuses. [Official
Repositories](/docker-hub/official_repos) are a carefully
curated set of Docker repositories supported by Docker, Inc. Automated
repositories are [Automated Builds](dockerrepos.md#automated-builds) that allow
you to validate the source and content of an image.
You've reviewed the images available to use and you decided to use the
`training/sinatra` image. So far you've seen two types of images repositories,
images like `ubuntu`, which are called base or root images. These base images
are provided by Docker Inc and are built, validated and supported. These can be
identified by their single word names.
You've also seen user images, for example the `training/sinatra` image you've
chosen. A user image belongs to a member of the Docker community and is built
and maintained by them. You can identify user images as they are always
prefixed with the user name, here `training`, of the user that created them.
## Pulling our image
You've identified a suitable image, `training/sinatra`, and now you can download it using the `docker pull` command.
$ docker pull training/sinatra
The team can now use this image by running their own containers.
$ docker run -t -i training/sinatra /bin/bash
root@a8cb6ce02d85:/#
## Creating our own images
The team has found the `training/sinatra` image pretty useful but it's not quite
what they need and you need to make some changes to it. There are two ways you
can update and create images.
1. You can update a container created from an image and commit the results to an image.
2. You can use a `Dockerfile` to specify instructions to create an image.
### Updating and committing an image
To update an image you first need to create a container from the image
you'd like to update.
$ docker run -t -i training/sinatra /bin/bash
root@0b2616b0e5a8:/#
> **Note:**
> Take note of the container ID that has been created, `0b2616b0e5a8`, as you'll
> need it in a moment.
Inside our running container first let's update Ruby:
root@0b2616b0e5a8:/# apt-get install -y ruby2.0-dev ruby2.0
Now let's add the `json` gem.
root@0b2616b0e5a8:/# gem2.0 install json
Once this has completed let's exit our container using the `exit`
command.
Now you have a container with the change you want to make. You can then
commit a copy of this container to an image using the `docker commit`
command.
$ docker commit -m "Added json gem" -a "Kate Smith" \
0b2616b0e5a8 ouruser/sinatra:v2
4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c
Here you've used the `docker commit` command. You've specified two flags: `-m`
and `-a`. The `-m` flag allows us to specify a commit message, much like you
would with a commit on a version control system. The `-a` flag allows us to
specify an author for our update.
You've also specified the container you want to create this new image from,
`0b2616b0e5a8` (the ID you recorded earlier) and you've specified a target for
the image:
ouruser/sinatra:v2
Break this target down. It consists of a new user, `ouruser`, that you're
writing this image to. You've also specified the name of the image, here you're
keeping the original image name `sinatra`. Finally you're specifying a tag for
the image: `v2`.
You can then look at our new `ouruser/sinatra` image using the `docker images`
command.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
training/sinatra latest 5bc342fa0b91 10 hours ago 446.7 MB
ouruser/sinatra v2 3c59e02ddd1a 10 hours ago 446.7 MB
ouruser/sinatra latest 5db5f8471261 10 hours ago 446.7 MB
To use our new image to create a container you can then:
$ docker run -t -i ouruser/sinatra:v2 /bin/bash
root@78e82f680994:/#
### Building an image from a `Dockerfile`
Using the `docker commit` command is a pretty simple way of extending an image
but it's a bit cumbersome and it's not easy to share a development process for
images amongst a team. Instead you can use a new command, `docker build`, to
build new images from scratch.
To do this you create a `Dockerfile` that contains a set of instructions that
tell Docker how to build our image.
First, create a directory and a `Dockerfile`.
$ mkdir sinatra
$ cd sinatra
$ touch Dockerfile
If you are using Docker Machine on Windows, you may access your host
directory by `cd` to `/c/Users/your_user_name`.
Each instruction creates a new layer of the image. Try a simple example now for
building your own Sinatra image for your fictitious development team.
# This is a comment
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y ruby ruby-dev
RUN gem install sinatra
Examine what your `Dockerfile` does. Each instruction prefixes a statement and
is capitalized.
INSTRUCTION statement
> **Note:** You use `#` to indicate a comment
The first instruction `FROM` tells Docker what the source of our image is, in
this case you're basing our new image on an Ubuntu 14.04 image.
Lastly, you've specified two `RUN` instructions. A `RUN` instruction executes
a command inside the image, for example installing a package. Here you're
updating our APT cache, installing Ruby and RubyGems and then installing the
Sinatra gem.
Now let's take our `Dockerfile` and use the `docker build` command to build an image.
$ docker build -t ouruser/sinatra:v2 .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 1 : FROM ubuntu:14.04
---> e54ca5efa2e9
Step 2 : RUN apt-get update && apt-get install -y ruby ruby-dev
---> Running in 3a2558904e9b
Selecting previously unselected package libasan0:amd64.
(Reading database ... 11518 files and directories currently installed.)
Preparing to unpack .../libasan0_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libasan0:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libatomic1:amd64.
Preparing to unpack .../libatomic1_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libatomic1:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libgmp10:amd64.
Preparing to unpack .../libgmp10_2%3a5.1.3+dfsg-1ubuntu1_amd64.deb ...
Unpacking libgmp10:amd64 (2:5.1.3+dfsg-1ubuntu1) ...
Selecting previously unselected package libisl10:amd64.
Preparing to unpack .../libisl10_0.12.2-1_amd64.deb ...
Unpacking libisl10:amd64 (0.12.2-1) ...
Selecting previously unselected package libcloog-isl4:amd64.
Preparing to unpack .../libcloog-isl4_0.18.2-1_amd64.deb ...
Unpacking libcloog-isl4:amd64 (0.18.2-1) ...
Selecting previously unselected package libgomp1:amd64.
Preparing to unpack .../libgomp1_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libgomp1:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libitm1:amd64.
Preparing to unpack .../libitm1_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libitm1:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libmpfr4:amd64.
Preparing to unpack .../libmpfr4_3.1.2-1_amd64.deb ...
Unpacking libmpfr4:amd64 (3.1.2-1) ...
Selecting previously unselected package libquadmath0:amd64.
Preparing to unpack .../libquadmath0_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libquadmath0:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libtsan0:amd64.
Preparing to unpack .../libtsan0_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libtsan0:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package libyaml-0-2:amd64.
Preparing to unpack .../libyaml-0-2_0.1.4-3ubuntu3_amd64.deb ...
Unpacking libyaml-0-2:amd64 (0.1.4-3ubuntu3) ...
Selecting previously unselected package libmpc3:amd64.
Preparing to unpack .../libmpc3_1.0.1-1ubuntu1_amd64.deb ...
Unpacking libmpc3:amd64 (1.0.1-1ubuntu1) ...
Selecting previously unselected package openssl.
Preparing to unpack .../openssl_1.0.1f-1ubuntu2.4_amd64.deb ...
Unpacking openssl (1.0.1f-1ubuntu2.4) ...
Selecting previously unselected package ca-certificates.
Preparing to unpack .../ca-certificates_20130906ubuntu2_all.deb ...
Unpacking ca-certificates (20130906ubuntu2) ...
Selecting previously unselected package manpages.
Preparing to unpack .../manpages_3.54-1ubuntu1_all.deb ...
Unpacking manpages (3.54-1ubuntu1) ...
Selecting previously unselected package binutils.
Preparing to unpack .../binutils_2.24-5ubuntu3_amd64.deb ...
Unpacking binutils (2.24-5ubuntu3) ...
Selecting previously unselected package cpp-4.8.
Preparing to unpack .../cpp-4.8_4.8.2-19ubuntu1_amd64.deb ...
Unpacking cpp-4.8 (4.8.2-19ubuntu1) ...
Selecting previously unselected package cpp.
Preparing to unpack .../cpp_4%3a4.8.2-1ubuntu6_amd64.deb ...
Unpacking cpp (4:4.8.2-1ubuntu6) ...
Selecting previously unselected package libgcc-4.8-dev:amd64.
Preparing to unpack .../libgcc-4.8-dev_4.8.2-19ubuntu1_amd64.deb ...
Unpacking libgcc-4.8-dev:amd64 (4.8.2-19ubuntu1) ...
Selecting previously unselected package gcc-4.8.
Preparing to unpack .../gcc-4.8_4.8.2-19ubuntu1_amd64.deb ...
Unpacking gcc-4.8 (4.8.2-19ubuntu1) ...
Selecting previously unselected package gcc.
Preparing to unpack .../gcc_4%3a4.8.2-1ubuntu6_amd64.deb ...
Unpacking gcc (4:4.8.2-1ubuntu6) ...
Selecting previously unselected package libc-dev-bin.
Preparing to unpack .../libc-dev-bin_2.19-0ubuntu6_amd64.deb ...
Unpacking libc-dev-bin (2.19-0ubuntu6) ...
Selecting previously unselected package linux-libc-dev:amd64.
Preparing to unpack .../linux-libc-dev_3.13.0-30.55_amd64.deb ...
Unpacking linux-libc-dev:amd64 (3.13.0-30.55) ...
Selecting previously unselected package libc6-dev:amd64.
Preparing to unpack .../libc6-dev_2.19-0ubuntu6_amd64.deb ...
Unpacking libc6-dev:amd64 (2.19-0ubuntu6) ...
Selecting previously unselected package ruby.
Preparing to unpack .../ruby_1%3a1.9.3.4_all.deb ...
Unpacking ruby (1:1.9.3.4) ...
Selecting previously unselected package ruby1.9.1.
Preparing to unpack .../ruby1.9.1_1.9.3.484-2ubuntu1_amd64.deb ...
Unpacking ruby1.9.1 (1.9.3.484-2ubuntu1) ...
Selecting previously unselected package libruby1.9.1.
Preparing to unpack .../libruby1.9.1_1.9.3.484-2ubuntu1_amd64.deb ...
Unpacking libruby1.9.1 (1.9.3.484-2ubuntu1) ...
Selecting previously unselected package manpages-dev.
Preparing to unpack .../manpages-dev_3.54-1ubuntu1_all.deb ...
Unpacking manpages-dev (3.54-1ubuntu1) ...
Selecting previously unselected package ruby1.9.1-dev.
Preparing to unpack .../ruby1.9.1-dev_1.9.3.484-2ubuntu1_amd64.deb ...
Unpacking ruby1.9.1-dev (1.9.3.484-2ubuntu1) ...
Selecting previously unselected package ruby-dev.
Preparing to unpack .../ruby-dev_1%3a1.9.3.4_all.deb ...
Unpacking ruby-dev (1:1.9.3.4) ...
Setting up libasan0:amd64 (4.8.2-19ubuntu1) ...
Setting up libatomic1:amd64 (4.8.2-19ubuntu1) ...
Setting up libgmp10:amd64 (2:5.1.3+dfsg-1ubuntu1) ...
Setting up libisl10:amd64 (0.12.2-1) ...
Setting up libcloog-isl4:amd64 (0.18.2-1) ...
Setting up libgomp1:amd64 (4.8.2-19ubuntu1) ...
Setting up libitm1:amd64 (4.8.2-19ubuntu1) ...
Setting up libmpfr4:amd64 (3.1.2-1) ...
Setting up libquadmath0:amd64 (4.8.2-19ubuntu1) ...
Setting up libtsan0:amd64 (4.8.2-19ubuntu1) ...
Setting up libyaml-0-2:amd64 (0.1.4-3ubuntu3) ...
Setting up libmpc3:amd64 (1.0.1-1ubuntu1) ...
Setting up openssl (1.0.1f-1ubuntu2.4) ...
Setting up ca-certificates (20130906ubuntu2) ...
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
Setting up manpages (3.54-1ubuntu1) ...
Setting up binutils (2.24-5ubuntu3) ...
Setting up cpp-4.8 (4.8.2-19ubuntu1) ...
Setting up cpp (4:4.8.2-1ubuntu6) ...
Setting up libgcc-4.8-dev:amd64 (4.8.2-19ubuntu1) ...
Setting up gcc-4.8 (4.8.2-19ubuntu1) ...
Setting up gcc (4:4.8.2-1ubuntu6) ...
Setting up libc-dev-bin (2.19-0ubuntu6) ...
Setting up linux-libc-dev:amd64 (3.13.0-30.55) ...
Setting up libc6-dev:amd64 (2.19-0ubuntu6) ...
Setting up manpages-dev (3.54-1ubuntu1) ...
Setting up libruby1.9.1 (1.9.3.484-2ubuntu1) ...
Setting up ruby1.9.1-dev (1.9.3.484-2ubuntu1) ...
Setting up ruby-dev (1:1.9.3.4) ...
Setting up ruby (1:1.9.3.4) ...
Setting up ruby1.9.1 (1.9.3.484-2ubuntu1) ...
Processing triggers for libc-bin (2.19-0ubuntu6) ...
Processing triggers for ca-certificates (20130906ubuntu2) ...
Updating certificates in /etc/ssl/certs... 164 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
---> c55c31703134
Removing intermediate container 3a2558904e9b
Step 3 : RUN gem install sinatra
---> Running in 6b81cb6313e5
unable to convert "\xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to US-ASCII for README.rdoc, skipping
unable to convert "\xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to US-ASCII for README.rdoc, skipping
Successfully installed rack-1.5.2
Successfully installed tilt-1.4.1
Successfully installed rack-protection-1.5.3
Successfully installed sinatra-1.4.5
4 gems installed
Installing ri documentation for rack-1.5.2...
Installing ri documentation for tilt-1.4.1...
Installing ri documentation for rack-protection-1.5.3...
Installing ri documentation for sinatra-1.4.5...
Installing RDoc documentation for rack-1.5.2...
Installing RDoc documentation for tilt-1.4.1...
Installing RDoc documentation for rack-protection-1.5.3...
Installing RDoc documentation for sinatra-1.4.5...
---> 97feabe5d2ed
Removing intermediate container 6b81cb6313e5
Successfully built 97feabe5d2ed
You've specified our `docker build` command and used the `-t` flag to identify
our new image as belonging to the user `ouruser`, the repository name `sinatra`
and given it the tag `v2`.
You've also specified the location of our `Dockerfile` using the `.` to
indicate a `Dockerfile` in the current directory.
> **Note:**
> You can also specify a path to a `Dockerfile`.
Now you can see the build process at work. The first thing Docker does is
upload the build context: basically the contents of the directory you're
building in. This is done because the Docker daemon does the actual
build of the image and it needs the local context to do it.
Next you can see each instruction in the `Dockerfile` being executed
step-by-step. You can see that each step creates a new container, runs
the instruction inside that container and then commits that change -
just like the `docker commit` work flow you saw earlier. When all the
instructions have executed you're left with the `97feabe5d2ed` image
(also helpfuly tagged as `ouruser/sinatra:v2`) and all intermediate
containers will get removed to clean things up.
> **Note:**
> An image can't have more than 127 layers regardless of the storage driver.
> This limitation is set globally to encourage optimization of the overall
> size of images.
You can then create a container from our new image.
$ docker run -t -i ouruser/sinatra:v2 /bin/bash
root@8196968dac35:/#
> **Note:**
> This is just a brief introduction to creating images. We've
> skipped a whole bunch of other instructions that you can use. We'll see more of
> those instructions in later sections of the Guide or you can refer to the
> [`Dockerfile`](../reference/builder.md) reference for a
> detailed description and examples of every instruction.
> To help you write a clear, readable, maintainable `Dockerfile`, we've also
> written a [`Dockerfile` Best Practices guide](../userguide/eng-image/dockerfile_best-practices.md).
## Setting tags on an image
You can also add a tag to an existing image after you commit or build it. We
can do this using the `docker tag` command. Now, add a new tag to your
`ouruser/sinatra` image.
$ docker tag 5db5f8471261 ouruser/sinatra:devel
The `docker tag` command takes the ID of the image, here `5db5f8471261`, and our
user name, the repository name and the new tag.
Now, see your new tag using the `docker images` command.
$ docker images ouruser/sinatra
REPOSITORY TAG IMAGE ID CREATED SIZE
ouruser/sinatra latest 5db5f8471261 11 hours ago 446.7 MB
ouruser/sinatra devel 5db5f8471261 11 hours ago 446.7 MB
ouruser/sinatra v2 5db5f8471261 11 hours ago 446.7 MB
## Image Digests
Images that use the v2 or later format have a content-addressable identifier
called a `digest`. As long as the input used to generate the image is
unchanged, the digest value is predictable. To list image digest values, use
the `--digests` flag:
$ docker images --digests | head
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
ouruser/sinatra latest sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf 5db5f8471261 11 hours ago 446.7 MB
When pushing or pulling to a 2.0 registry, the `push` or `pull` command
output includes the image digest. You can `pull` using a digest value.
$ docker pull ouruser/sinatra@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf
You can also reference by digest in `create`, `run`, and `rmi` commands, as well as the
`FROM` image reference in a Dockerfile.
## Push an image to Docker Hub
Once you've built or created a new image you can push it to [Docker
Hub](https://hub.docker.com) using the `docker push` command. This
allows you to share it with others, either publicly, or push it into [a
private repository](https://hub.docker.com/account/billing-plans/).
$ docker push ouruser/sinatra
The push refers to a repository [ouruser/sinatra] (len: 1)
Sending image list
Pushing repository ouruser/sinatra (3 tags)
. . .
## Remove an image from the host
You can also remove images on your Docker host in a way [similar to
containers](usingdocker.md) using the `docker rmi` command.
Delete the `training/sinatra` image as you don't need it anymore.
$ docker rmi training/sinatra
Untagged: training/sinatra:latest
Deleted: 5bc342fa0b91cabf65246837015197eecfa24b2213ed6a51a8974ae250fedd8d
Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f
Deleted: 5c58979d73ae448df5af1d8142436d81116187a7633082650549c52c3a2418f0
> **Note:** To remove an image from the host, please make sure
> that there are no containers actively based on it.
## Check size of images and containers
An image is
[stored in layers](../userguide/storagedriver/imagesandcontainers.md),
shared with other images on the host, so the real disk usage depends on
how much layer overlap is happening between images on a host.
A container runs on
[a writable layer](../userguide/storagedriver/imagesandcontainers.md#/container-and-layers)
on top of a readonly rootfs.
Use `docker history` to see the size of image layers on your host:
$ docker history centos:centos7
IMAGE CREATED CREATED BY SIZE
970633036444 6 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing> 6 weeks ago /bin/sh -c #(nop) LABEL name=CentOS Base Imag 0 B
<missing> 6 weeks ago /bin/sh -c #(nop) ADD file:44ef4e10b27d8c464a 196.7 MB
<missing> 10 weeks ago /bin/sh -c #(nop) MAINTAINER https://github.c 0 B
Check the size of containers with `docker ps -s`:
$ docker ps -s
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
cb7827c19ef7 docker-docs:is-11160-explain-image-container-size-prediction "hugo server --port=8" About a minute ago Up About a minute 0.0.0.0:8000->8000/tcp evil_hodgkin 0 B (virtual 949.2 MB)
# Next steps
Until now you've seen how to build individual applications inside Docker
containers. Now learn how to build whole application stacks with Docker
by networking together multiple Docker containers.
Go to [Network containers](networkingcontainers.md).

View File

@ -1,199 +0,0 @@
---
description: A simple 'Hello world' exercise that introduced you to Docker.
keywords: docker guide, docker, docker platform, how to, dockerize, dockerizing apps, dockerizing applications, container, containers
redirect_from:
- /engine/userguide/containers/dockerizing/
- /engine/userguide/dockerizing/
title: Hello world in a container
---
*So what's this Docker thing all about?*
Docker allows you to run applications, worlds you create, inside containers.
Running an application inside a container takes a single command: `docker run`.
>**Note**: Depending on your Docker system configuration, you may be required to
>preface each `docker` command on this page with `sudo`. To avoid this behavior,
>your system administrator can create a Unix group called `docker` and add users
>to it.
## Run a Hello world
Let's run a hello world container.
$ docker run ubuntu /bin/echo 'Hello world'
Hello world
You just launched your first container!
In this example:
* `docker run` runs a container.
* `ubuntu` is the image you run, for example the Ubuntu operating system image.
When you specify an image, Docker looks first for the image on your
Docker host. If the image does not exist locally, then the image is pulled from the public
image registry [Docker Hub](https://hub.docker.com).
* `/bin/echo` is the command to run inside the new container.
The container launches. Docker creates a new Ubuntu
environment and executes the `/bin/echo` command inside it and then prints out:
Hello world
So what happened to the container after that? Well, Docker containers
only run as long as the command you specify is active. Therefore, in the above example,
the container stops once the command is executed.
## Run an interactive container
Let's specify a new command to run in the container.
$ docker run -t -i ubuntu /bin/bash
root@af8bae53bdd3:/#
In this example:
* `docker run` runs a container.
* `ubuntu` is the image you would like to run.
* `-t` flag assigns a pseudo-tty or terminal inside the new container.
* `-i` flag allows you to make an interactive connection by
grabbing the standard input (`STDIN`) of the container.
* `/bin/bash` launches a Bash shell inside our container.
The container launches. We can see there is a
command prompt inside it:
root@af8bae53bdd3:/#
Let's try running some commands inside the container:
root@af8bae53bdd3:/# pwd
/
root@af8bae53bdd3:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
In this example:
* `pwd` displays the current directory, the `/` root directory.
* `ls` displays the directory listing of the root directory of a typical Linux file system.
Now, you can play around inside this container. When completed, run the `exit` command or enter Ctrl-D
to exit the interactive shell.
root@af8bae53bdd3:/# exit
>**Note:** As with our previous container, once the Bash shell process has
finished, the container stops.
## Start a daemonized Hello world
Let's create a container that runs as a daemon.
$ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147
In this example:
* `docker run` runs the container.
* `-d` flag runs the container in the background (to daemonize it).
* `ubuntu` is the image you would like to run.
Finally, we specify a command to run:
/bin/sh -c "while true; do echo hello world; sleep 1; done"
In the output, we do not see `hello world` but a long string:
1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147
This long string is called a *container ID*. It uniquely
identifies a container so we can work with it.
> **Note:**
> The container ID is a bit long and unwieldy. Later, we will cover the short
> ID and ways to name our containers to make
> working with them easier.
We can use this container ID to see what's happening with our `hello world` daemon.
First, let's make sure our container is running. Run the `docker ps` command.
The `docker ps` command queries the Docker daemon for information about all the containers it knows
about.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e5535038e28 ubuntu /bin/sh -c 'while tr 2 minutes ago Up 1 minute insane_babbage
In this example, we can see our daemonized container. The `docker ps` returns some useful
information:
* `1e5535038e28` is the shorter variant of the container ID.
* `ubuntu` is the used image.
* the command, status, and assigned name `insane_babbage`.
> **Note:**
> Docker automatically generates names for any containers started.
> We'll see how to specify your own names a bit later.
Now, we know the container is running. But is it doing what we asked it to do? To
see this we're going to look inside the container using the `docker logs`
command.
Let's use the container name `insane_babbage`.
$ docker logs insane_babbage
hello world
hello world
hello world
. . .
In this example:
* `docker logs` looks inside the container and returns `hello world`.
Awesome! The daemon is working and you have just created your first
Dockerized application!
Next, run the `docker stop` command to stop our detached container.
$ docker stop insane_babbage
insane_babbage
The `docker stop` command tells Docker to politely stop the running
container and returns the name of the container it stopped.
Let's check it worked with the `docker ps` command.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Excellent. Our container is stopped.
# Next steps
So far, you launched your 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:
* `docker ps` - Lists containers.
* `docker logs` - Shows the standard output of a container.
* `docker stop` - Stops running containers.
Now, you have the basis to learn more about Docker and how to do some more advanced
tasks. Go to ["*Run a simple application*"](usingdocker.md) to actually build a
web application with the Docker client.

View File

@ -1,185 +0,0 @@
---
description: Learn how to use the Docker Hub to manage Docker images and work flow
keywords: repo, Docker Hub, Docker Hub, registry, index, repositories, usage, pull image, push image, image, documentation
redirect_from:
- /engine/userguide/containers/dockerrepos/
- /engine/userguide/dockerrepos/
title: Store images on Docker Hub
---
So far you've learned how to use the command line to run Docker on your local
host. You've learned how to [pull down images](usingdocker.md) to build
containers from existing images and you've learned how to [create your own
images](dockerimages.md).
Next, you're going to learn how to use the [Docker Hub](https://hub.docker.com)
to simplify and enhance your Docker workflows.
The [Docker Hub](https://hub.docker.com) is a public registry maintained by
Docker, Inc. It contains images you can download and use to build
containers. It also provides authentication, work group structure, workflow
tools like webhooks and build triggers, and privacy tools like private
repositories for storing images you don't want to share publicly.
## Docker commands and Docker Hub
Docker itself provides access to Docker Hub services via the `docker search`,
`pull`, `login`, and `push` commands. This page will show you how these commands work.
### Account creation and login
Before you try an Engine CLI command, if you haven't already, create a Docker
ID. You can do this through [Docker Hub](https://hub.docker.com/). Once you have
a Docker ID, log into your account from the Engine CLI:
```bash
$ docker login
```
The `login` command stores your Docker ID authentication credentials in the
`$HOME/.docker/config.json` (Bash notation). For Windows `cmd` users the
notation for this file is `%HOME%\.docker\config.json` ; for PowerShell users
the notation is `$env:Home\.docker\config.json`.
Once you have logged in from the command line, you can `commit` and `push`
Engine subcommands to interact with your repos on Docker Hub.
## Searching for images
You can search the [Docker Hub](https://hub.docker.com) registry via its search
interface or by using the command line interface. Searching can find images by image
name, user name, or description:
$ docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS 1223 [OK]
tianon/centos CentOS 5 and 6, created using rinse instea... 33
...
There you can see two example results: `centos` and `tianon/centos`. The second
result shows that it comes from the public repository of a user, named
`tianon`, while the first result, `centos`, doesn't explicitly list a
repository which means that it comes from the trusted top-level namespace for
[Official Repositories](/docker-hub/official_repos/). The `/` character separates
a user's repository from the image name.
Once you've found the image you want, you can download it with `docker pull <imagename>`:
$ docker pull centos
Using default tag: latest
latest: Pulling from library/centos
f1b10cd84249: Pull complete
c852f6d61e65: Pull complete
7322fbe74aa5: Pull complete
Digest: sha256:90305c9112250c7e3746425477f1c4ef112b03b4abe78c612e092037bfecc3b7
Status: Downloaded newer image for centos:latest
You now have an image from which you can run containers.
### Specific Versions or Latest
Using `docker pull centos` is equivalent to using `docker pull centos:latest`.
To pull an image that is not the default latest image you can be more precise
with the image that you want.
For example, to pull version 5 of `centos` use `docker pull centos:centos5`.
In this example, `centos5` is the tag labeling an image in the `centos`
repository for a version of `centos`.
To find a list of tags pointing to currently available versions of a repository
see the [Docker Hub](https://hub.docker.com) registry.
## Contributing to Docker Hub
Anyone can pull public images from the [Docker Hub](https://hub.docker.com)
registry, but if you would like to share your own images, then you must
[register first](/docker-hub/accounts).
## Pushing a repository to Docker Hub
In order to push a repository to its registry, you need to have named an image
or committed your container to a named image as we saw
[here](dockerimages.md).
Now you can push this repository to the registry designated by its name or tag.
$ docker push yourname/newimage
The image will then be uploaded and available for use by your team-mates and/or the
community.
## Features of Docker Hub
Let's take a closer look at some of the features of Docker Hub. You can find more
information [here](/docker-hub/).
* Private repositories
* Organizations and teams
* Automated Builds
* Webhooks
### Private repositories
Sometimes you have images you don't want to make public and share with
everyone. So Docker Hub allows you to have private repositories. You can
sign up for a plan [here](https://hub.docker.com/account/billing-plans/).
### Organizations and teams
One of the useful aspects of private repositories is that you can share
them only with members of your organization or team. Docker Hub lets you
create organizations where you can collaborate with your colleagues and
manage private repositories. You can learn how to create and manage an organization
[here](https://hub.docker.com/organizations/).
### Automated Builds
Automated Builds automate the building and updating of images from
[GitHub](https://www.github.com) or [Bitbucket](http://bitbucket.com), directly on Docker
Hub. It works by adding a commit hook to your selected GitHub or Bitbucket repository,
triggering a build and update when you push a commit.
#### To setup an Automated Build
1. Create a [Docker Hub account](https://hub.docker.com/) and login.
2. Link your GitHub or Bitbucket account on the ["Linked Accounts &amp; Services"](https://hub.docker.com/account/authorized-services/) page.
3. Select "Create Automated Build" from the "Create" dropdown menu
4. Pick a GitHub or Bitbucket project that has a `Dockerfile` that you want to build.
5. Pick the branch you want to build (the default is the `master` branch).
6. Give the Automated Build a name.
7. Assign an optional Docker tag to the Build.
8. Specify where the `Dockerfile` is located. The default is `/`.
Once the Automated Build is configured it will automatically trigger a
build and, in a few minutes, you should see your new Automated Build on the [Docker Hub](https://hub.docker.com)
Registry. It will stay in sync with your GitHub and Bitbucket repository until you
deactivate the Automated Build.
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.
Once you've created an Automated Build you can deactivate or delete it. You
cannot, however, push to an Automated Build with the `docker push` command.
You can only manage it by committing code to your GitHub or Bitbucket
repository.
You can create multiple Automated Builds per repository and configure them
to point to specific `Dockerfile`'s or Git branches.
#### Build triggers
Automated Builds can also be triggered via a URL on Docker Hub. This
allows you to rebuild an Automated build image on demand.
### Webhooks
Webhooks are attached to your repositories and allow you to trigger an
event when an image or updated image is pushed to the repository. With
a webhook you can specify a target URL and a JSON payload that will be
delivered when the image is pushed.
See the Docker Hub documentation for [more information on
webhooks](/docker-hub/repos/#webhooks)
## Next steps
Go and use Docker!

View File

@ -1,347 +0,0 @@
---
redirect_from:
- /engine/userguide/containers/usingdocker/
description: Learn how to manage and operate Docker containers.
keywords: docker, the docker guide, documentation, docker.io, monitoring containers, docker top, docker inspect, docker port, ports, docker logs, log, logs
title: Run a simple application
---
In the ["*Hello world in a container*"](dockerizing.md) you launched your 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:
* `docker ps` - Lists containers.
* `docker logs` - Shows the standard output of a container.
* `docker stop` - Stops running containers.
## Learn about the Docker client
The `docker` program is called the Docker client. To control Docker using the
client, you use commands, flags, and arguments. Have a look at the following
example, which uses the `run` command, the `-i` and `-t` flags, and the `ubuntu`
and `/bin/bash` arguments.
```bash
$ docker run -i -t ubuntu /bin/bash
```
The `docker version` command shows information about the version of Docker the
client is using, as well as other version-specific information.
```bash
$ docker version
Client:
Version: 1.12.5
API version: 1.24
Go version: go1.6.4
Git commit: 7392c3b
Built: Fri Dec 16 02:42:17 2016
OS/Arch: windows/amd64
Server:
Version: 1.12.5
API version: 1.24
Go version: go1.6.4
Git commit: 7392c3b
Built: Fri Dec 16 02:42:17 2016
OS/Arch: linux/amd64
```
## Get Docker command help
Each Docker command has associated usage information, which you can see when you
use the `--help` flag. You can use `--help` for the `docker` command itself, or
for its sub-commands.
To see usage information for the entire `docker` command, including a list of
all the possible commands, use `docker --help`.
```bash
$ docker --help
```
To see usage for a specific command, add the `--help` flag after that specific
command. For instance, the following command shows the help text for the
`docker attach` command.
```bash
$ docker attach --help
Usage: docker attach [OPTIONS] CONTAINER
Attach to a running container
Options:
--detach-keys string Override the key sequence for detaching a container
--help Print usage
--no-stdin Do not attach STDIN
--sig-proxy Proxy all received signals to the process (default true)
```
> **Note:**
> For further details and examples of each command, see the
> [command reference](../reference/commandline/) in this guide.
## Run a web application in Docker
Now that you've learned a bit more about the Docker client, you can move onto
the important stuff: running more containers. First, run an example Python Flask
web application as a Docker container.
```bash
$ docker run -d -P --name my_webapp training/webapp python app.py
```
This command consists of the following parts:
* The `-d` flag runs the container in the background (as a so-called daemon).
* The `--name my_webapp` flag names the container `my_webapp`. If you do not
specify a name, Docker creates a random (and sometimes amusing) name for the
container. This name is guaranteed to be unique among all the containers
running on a given Docker host.
* The `-P` flag maps any required network ports inside the container to your
host. This lets you view the web application.
* The `training/webapp` image is a pre-built image that contains a simple Python
Flask web application.
* The remaining arguments make up the command that is run inside
the container. The `python app.py` command launches the web application.
> **Note:**
> You can see more detail on the `docker run` command
> in the [command reference](../reference/commandline/run.md)
> and the [docker run reference](../reference/run.md).
## View the web application container
To see information about your running container, use the `docker ps` command.
```bash
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp my_webapp
```
The `-l` flag shows only the details of the *last* container started.
> **Note:**
> By default, the `docker ps` command only shows information about running
> containers. If you want to see stopped containers too, use the `-a` flag.
In particular, have a look at the `PORTS` column.
```none
PORTS
0.0.0.0:49155->5000/tcp
```
When you passed the `-P` flag to the `docker run` command, Docker mapped any
ports exposed in the container to ports on your host machine. In this case,
port 5000 (the default port for Python Flask) is mapped to port 49155 on the
Docker host.
> **Note:**
> You'll learn more about how to expose ports in Docker images when
> [you learn how to build images](dockerimages.md).
Network port bindings are very configurable in Docker. In the last example the
`-P` flag is a shortcut for `-p 5000` that maps port 5000 inside the container
to a high port (from *ephemeral port range* which typically ranges from 32768
to 61000) on the local Docker host. You can also bind Docker containers to
specific ports using the `-p` flag, for example:
```bash
$ docker run -d --name my_other_webapp -p 80:5000 training/webapp python app.py
```
This would map port 5000 inside your container to port 80 on your local
host. You might be asking about now: why wouldn't we just want to always
use 1:1 port mappings in Docker containers rather than mapping to high
ports? Well, 1:1 mappings have the constraint of only being able to map
one of each port on your local host.
Suppose you want to test two Python applications: both bound to port 5000 inside
their own containers. Without Docker's port mapping you could only access one at
a time on the Docker host.
So you can now browse to port 80 in a web browser to see the application.
![Screenshot of the running web application](webapp1.png).
Your Python web application is live!
> **Note:**
> If you have been using a virtual machine on macOS, Windows or Linux,
> you'll need to get the IP of the virtual host instead of using localhost.
> You can do this by running `docker-machine ip` from the command line:
>
> $ docker-machine ip
> 192.168.99.100
>
> In this case you'd browse to `http://192.168.99.100:49155` for the above example.
## A network port shortcut
Using the `docker ps` command to return the mapped port is a bit clumsy,
so Docker has a useful shortcut you can use: `docker port`.
To use `docker port`, specify the ID or name of your container and then
the port for which you need the corresponding public-facing port.
```bash
$ docker port my_webapp 5000
0.0.0.0:49155
```
In this case you've looked up what port is mapped externally to port 5000 inside
the container.
## View the web application's logs
You can also find out a bit more about what's happening with your
application and use another of the commands you've learned, `docker logs`.
```basg
$ docker logs -f my_webapp
* Running on http://0.0.0.0:5000/
10.0.2.2 - - [06/Nov/2016 20:16:31] "GET / HTTP/1.1" 200 -
10.0.2.2 - - [06/Nov/2016 20:16:31] "GET /favicon.ico HTTP/1.1" 404 -
```
The `-f` flag causes the `docker logs` command to act like the `tail -f` command
and watch the container's standard output. You can see here the logs from Flask
showing the application running on port 5000 and the access log entries for it.
## Look at the web application container's processes
In addition to the container's logs you can also examine the processes
running inside it using the `docker top` command.
```bash
$ docker top my_webapp
PID USER COMMAND
854 root python app.py
```
Here you can see that the `python app.py` command is the only process
running inside the container.
## Inspect the web application container
Lastly, you can take a low-level dive into the Docker container using the
`docker inspect` command. It returns a JSON document containing useful
configuration and status information for the specified container.
```bash
$ docker inspect my_webapp
```
You can see a sample of that JSON output.
```none
[{
"ID": "bc533791f3f500b280a9626688bc79e342e3ea0d528efe3a86a51ecb28ea20",
"Created": "2014-05-26T05:52:40.808952951Z",
"Path": "python",
"Args": [
"app.py"
],
"Config": {
"Hostname": "bc533791f3f5",
"Domainname": "",
"User": "",
...
}]
```
You can also narrow down the information you want to return by requesting a
specific element, for example to return the container's IP address, you would:
```bash
{% raw %}
$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my_webapp
172.17.0.5
{% endraw %}
```
## Stop the web application container
The web application is still running inside the container. You can stop it using
the `docker stop` command and the name of the container: `my_webapp`.
```bash
$ docker stop my_webapp
my_webapp
```
You can now use the `docker ps` command to check if the container has
been stopped.
```bash
$ docker ps -l
```
## Restart the web application container
Oops! Just after you stopped the container you get a call to say another
developer needs the container back. From here you have two choices: you
can create a new container or restart the old one. Look at
starting your previous container back up.
```bash
$ docker start my_webapp
my_webapp
```
Now quickly run `docker ps -l` again to see the running container is
back up or browse to the container's URL to see if the application
responds.
> **Note:**
> The `docker restart` command is also available. It is the equivalent of
> running `docker stop` followed by `docker start`.
## Remove the web application container
Your colleague has let you know that they've now finished with the container
and won't need it again. Now, you can remove it using the `docker rm` command.
```bash
$ docker rm my_webapp
Error: Impossible to remove a running container, please stop it first or use -f
2014/05/24 08:12:56 Error: failed to remove one or more containers
```
What happened? You can't actually remove a running container. This protects
you from accidentally removing a running container you might need. You can try
this again by stopping the container first.
```bash
$ docker stop my_webapp
my_webapp
$ docker rm my_webapp
my_webapp
```
Now the container is stopped and deleted.
> **Note:**
> Always remember that removing a container is final!
# Next steps
Until now you've only used images that you've downloaded from Docker Hub. Next,
you can get introduced to building and sharing your own images.
Go to [Working with Docker Images](dockerimages.md).

View File

@ -8,15 +8,13 @@ title: Docker Documentation
Docker packages your app with its dependencies, freeing you from worrying about your
system configuration, and making your app more portable.
[Get Docker](/engine/installation/){: class="button darkblue-btn"}
<table><tr><td width="50%">
{% capture basics %}
## Learn the basics of Docker
The basic tutorial teaches you about how to build, push, and pull images, and
run them as containers. This tutorial stops short of teaching you how to deploy
applications.
The basic tutorial teaches you about how to build, push, and pull Docker images,
and run them as containers. This tutorial stops short of teaching you how to
deploy applications.
[Start the basic tutorial](/engine/getstarted/){: class="button darkblue-btn"}
{% endcapture %}{{ basics | markdownify }}
@ -25,7 +23,8 @@ applications.
## Define and deploy applications
The application tutorial teaches you how to relate containers to each other and
define them as part of an application that is ready to deploy at scale.
define them as part of an application that is ready to deploy at scale in a
production environment.
[Start the application tutorial](/engine/getstarted-voting-app/){: class="button darkblue-btn"}
{% endcapture %}{{ apps | markdownify }}

View File

@ -9,9 +9,9 @@ Docker workflows.
{% capture basics %}
## Learn the basics of Docker
The basic tutorial teaches you about how to build, push, and pull images, and
run them as containers. This tutorial stops short of teaching you how to deploy
applications.
The basic tutorial teaches you about how to build, push, and pull Docker images,
and run them as containers. This tutorial stops short of teaching you how to
deploy applications.
[Start the basic tutorial](/engine/getstarted/){: class="button darkblue-btn"}
{% endcapture %}{{ basics | markdownify }}
@ -20,7 +20,8 @@ applications.
## Define and deploy applications
The application tutorial teaches you how to relate containers to each other and
define them as part of an application that is ready to deploy at scale.
define them as part of an application that is ready to deploy at scale in a
production environment.
[Start the application tutorial](/engine/getstarted-voting-app/){: class="button darkblue-btn"}
{% endcapture %}{{ apps | markdownify }}