mirror of
https://github.com/clearlinux/docker.git
synced 2026-09-07 06:22:03 +00:00
retooling for hugo
Tweaking for Hugo Updating the Dockerfile with new sed; fix broken link on Kitematic Fixing image pull for Dockerfile Removing docs targets Signed-off-by: Mary Anthony <mary@docker.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Getting started with Docker Hub"
|
||||
description = "Introductory guide to getting an account on Docker Hub"
|
||||
keywords = ["documentation, docs, the docker guide, docker guide, docker, docker platform, virtualization framework, docker.io, central service, services, how to, container, containers, automation, collaboration, collaborators, registry, repo, repository, technology, github webhooks, trusted builds"]
|
||||
[menu.main]
|
||||
parent = "smn_pubhub"
|
||||
weight = 1
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Getting started with Docker Hub
|
||||
|
||||
|
||||
This section provides a quick introduction to the [Docker Hub](https://hub.docker.com),
|
||||
including how to create an account.
|
||||
|
||||
The [Docker Hub](https://hub.docker.com) is a centralized resource for working with
|
||||
Docker and its components. Docker Hub helps you collaborate with colleagues and get the
|
||||
most out of Docker. To do this, it provides services such as:
|
||||
|
||||
* Docker image hosting.
|
||||
* User authentication.
|
||||
* Automated image builds and work-flow tools such as build triggers and web
|
||||
hooks.
|
||||
* Integration with GitHub and Bitbucket.
|
||||
|
||||
In order to use Docker Hub, you will first need to register and create an account. Don't
|
||||
worry, creating an account is simple and free.
|
||||
|
||||
## Creating a Docker Hub account
|
||||
|
||||
There are two ways for you to register and create an account:
|
||||
|
||||
1. Via the web, or
|
||||
2. Via the command line.
|
||||
|
||||
### Register via the web
|
||||
|
||||
Fill in the [sign-up form](https://hub.docker.com/account/signup/) by
|
||||
choosing your user name and password and entering a valid email address. You can also
|
||||
sign up for the Docker Weekly mailing list, which has lots of information about what's
|
||||
going on in the world of Docker.
|
||||
|
||||

|
||||
|
||||
### Register via the command line
|
||||
|
||||
You can also create a Docker Hub account via the command line with the
|
||||
`docker login` command.
|
||||
|
||||
$ docker login
|
||||
|
||||
### Confirm your email
|
||||
|
||||
Once you've filled in the form, check your email for a welcome message asking for
|
||||
confirmation so we can activate your account.
|
||||
|
||||
|
||||
### Login
|
||||
|
||||
After you complete the confirmation process, you can login using the web console:
|
||||
|
||||

|
||||
|
||||
Or via the command line with the `docker login` command:
|
||||
|
||||
$ docker login
|
||||
|
||||
Your Docker Hub account is now active and ready to use.
|
||||
|
||||
## Next steps
|
||||
|
||||
Next, let's start learning how to Dockerize applications with our "Hello world"
|
||||
exercise.
|
||||
|
||||
Go to [Dockerizing Applications](/userguide/dockerizing).
|
||||
|
||||
@@ -0,0 +1,582 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Get started with images"
|
||||
description = "How to work with Docker images."
|
||||
keywords = ["documentation, docs, the docker guide, docker guide, docker, docker platform, virtualization framework, docker.io, Docker images, Docker image, image management, Docker repos, Docker repositories, docker, docker tag, docker tags, Docker Hub, collaboration"]
|
||||
[menu.main]
|
||||
parent = "smn_images"
|
||||
weight = 1
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Get started with images
|
||||
|
||||
In the [introduction](/introduction/understanding-docker/) we've discovered that Docker
|
||||
images are the basis of containers. In the
|
||||
[previous](/userguide/dockerizing/) [sections](/userguide/usingdocker/)
|
||||
we've used Docker images that already exist, for example the `ubuntu`
|
||||
image and the `training/webapp` image.
|
||||
|
||||
We've 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://registry.hub.docker.com).
|
||||
|
||||
In this section we'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://registry.hub.docker.com).
|
||||
|
||||
## Listing images on the host
|
||||
|
||||
Let's start with listing the images we have locally on our host. You can
|
||||
do this using the `docker images` command like so:
|
||||
|
||||
$ docker images
|
||||
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
|
||||
training/webapp latest fc77f57ad303 3 weeks ago 280.5 MB
|
||||
ubuntu 13.10 5e019ab7bf6d 4 weeks ago 180 MB
|
||||
ubuntu saucy 5e019ab7bf6d 4 weeks ago 180 MB
|
||||
ubuntu 12.04 74fe38d11401 4 weeks ago 209.6 MB
|
||||
ubuntu precise 74fe38d11401 4 weeks ago 209.6 MB
|
||||
ubuntu 12.10 a7cf8ae4e998 4 weeks ago 171.3 MB
|
||||
ubuntu quantal a7cf8ae4e998 4 weeks ago 171.3 MB
|
||||
ubuntu 14.04 99ec81b80c55 4 weeks ago 266 MB
|
||||
ubuntu latest 99ec81b80c55 4 weeks ago 266 MB
|
||||
ubuntu trusty 99ec81b80c55 4 weeks ago 266 MB
|
||||
ubuntu 13.04 316b678ddf48 4 weeks ago 169.4 MB
|
||||
ubuntu raring 316b678ddf48 4 weeks ago 169.4 MB
|
||||
ubuntu 10.04 3db9c44f4520 4 weeks ago 183 MB
|
||||
ubuntu lucid 3db9c44f4520 4 weeks ago 183 MB
|
||||
|
||||
We can see the images we've previously used in our [user guide](/userguide/).
|
||||
Each has been downloaded from [Docker Hub](https://hub.docker.com) when we
|
||||
launched a container using that image.
|
||||
|
||||
We can see three crucial pieces of information about our images 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.
|
||||
|
||||
> **Note:**
|
||||
> Previously, the `docker images` command supported the `--tree` and `--dot`
|
||||
> arguments, which displayed different visualizations of the image data. Docker
|
||||
> core removed this functionality in the 1.7 version. If you liked this
|
||||
> functionality, you can still find it in
|
||||
> [the third-party dockviz tool](https://github.com/justone/dockviz).
|
||||
|
||||
A repository potentially holds multiple variants of an image. In the case of
|
||||
our `ubuntu` image we 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 we run a container we refer to a tagged image like so:
|
||||
|
||||
$ docker run -t -i ubuntu:14.04 /bin/bash
|
||||
|
||||
If instead we wanted to run an Ubuntu 12.04 image we'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:**
|
||||
> We recommend you always use a specific tagged image, for example
|
||||
> `ubuntu:12.04`. That way you always know exactly what variant of an image is
|
||||
> being used.
|
||||
|
||||
## Getting a new image
|
||||
|
||||
So how do we get new images? Well Docker will automatically download any image
|
||||
we use that isn't already present on the Docker host. But this can potentially
|
||||
add some time to the launch of a container. If we want to pre-load an image we
|
||||
can download it using the `docker pull` command. Let's say we'd like to
|
||||
download the `centos` image.
|
||||
|
||||
$ docker pull centos
|
||||
Pulling repository centos
|
||||
b7de3133ff98: Pulling dependent layers
|
||||
5cc9e91966f7: Pulling fs layer
|
||||
511136ea3c5a: Download complete
|
||||
ef52fb1fe610: Download complete
|
||||
. . .
|
||||
|
||||
Status: Downloaded newer image for centos
|
||||
|
||||
We can see that each layer of the image has been pulled down and now we
|
||||
can run a container from this image and we 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). We can search these images on the
|
||||
[Docker Hub](https://hub.docker.com) website.
|
||||
|
||||

|
||||
|
||||
We can also search for images on the command line using the `docker search`
|
||||
command. Let's say our team wants an image with Ruby and Sinatra installed on
|
||||
which to do our web application development. We 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
|
||||
. . .
|
||||
|
||||
We can see we've returned a lot of images that use the term `sinatra`. We've
|
||||
returned 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](/userguide/dockerrepos/#automated-builds) that allow you to
|
||||
validate the source and content of an image.
|
||||
|
||||
We've reviewed the images available to use and we decided to use the
|
||||
`training/sinatra` image. So far we'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.
|
||||
|
||||
We've also seen user images, for example the `training/sinatra` image we'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
|
||||
|
||||
We've identified a suitable image, `training/sinatra`, and now we 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 we need to make some changes to it. There are two ways we can
|
||||
update and create images.
|
||||
|
||||
1. We can update a container created from an image and commit the results to an image.
|
||||
2. We can use a `Dockerfile` to specify instructions to create an image.
|
||||
|
||||
|
||||
### Updating and committing an image
|
||||
|
||||
To update an image we first need to create a container from the image
|
||||
we'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 we'll
|
||||
> need it in a moment.
|
||||
|
||||
Inside our running container let's add the `json` gem.
|
||||
|
||||
root@0b2616b0e5a8:/# gem install json
|
||||
|
||||
Once this has completed let's exit our container using the `exit`
|
||||
command.
|
||||
|
||||
Now we have a container with the change we want to make. We 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 we've used the `docker commit` command. We'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.
|
||||
|
||||
We've also specified the container we want to create this new image from,
|
||||
`0b2616b0e5a8` (the ID we recorded earlier) and we've specified a target for
|
||||
the image:
|
||||
|
||||
ouruser/sinatra:v2
|
||||
|
||||
Let's break this target down. It consists of a new user, `ouruser`, that we're
|
||||
writing this image to. We've also specified the name of the image, here we're
|
||||
keeping the original image name `sinatra`. Finally we're specifying a tag for
|
||||
the image: `v2`.
|
||||
|
||||
We can then look at our new `ouruser/sinatra` image using the `docker images`
|
||||
command.
|
||||
|
||||
$ docker images
|
||||
REPOSITORY TAG IMAGE ID CREATED VIRTUAL 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 we 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 we can use a new command, `docker build`, to
|
||||
build new images from scratch.
|
||||
|
||||
To do this we create a `Dockerfile` that contains a set of instructions that
|
||||
tell Docker how to build our image.
|
||||
|
||||
Let's create a directory and a `Dockerfile` first.
|
||||
|
||||
$ mkdir sinatra
|
||||
$ cd sinatra
|
||||
$ touch Dockerfile
|
||||
|
||||
If you are using Boot2Docker 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. Let's look at a simple
|
||||
example now for building our own Sinatra image for our development team.
|
||||
|
||||
# This is a comment
|
||||
FROM ubuntu:14.04
|
||||
MAINTAINER Kate Smith <ksmith@example.com>
|
||||
RUN apt-get update && apt-get install -y ruby ruby-dev
|
||||
RUN gem install sinatra
|
||||
|
||||
Let's look at what our `Dockerfile` does. Each instruction prefixes a statement and is capitalized.
|
||||
|
||||
INSTRUCTION statement
|
||||
|
||||
> **Note:**
|
||||
> We use `#` to indicate a comment
|
||||
|
||||
The first instruction `FROM` tells Docker what the source of our image is, in
|
||||
this case we're basing our new image on an Ubuntu 14.04 image.
|
||||
|
||||
Next we use the `MAINTAINER` instruction to specify who maintains our new image.
|
||||
|
||||
Lastly, we've specified two `RUN` instructions. A `RUN` instruction executes
|
||||
a command inside the image, for example installing a package. Here we're
|
||||
updating our APT cache, installing Ruby and RubyGems and then installing the
|
||||
Sinatra gem.
|
||||
|
||||
> **Note:**
|
||||
> There are [a lot more instructions available to us in a Dockerfile](/reference/builder).
|
||||
|
||||
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 0 : FROM ubuntu:14.04
|
||||
---> e54ca5efa2e9
|
||||
Step 1 : MAINTAINER Kate Smith <ksmith@example.com>
|
||||
---> Using cache
|
||||
---> 851baf55332b
|
||||
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
|
||||
|
||||
We'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`.
|
||||
|
||||
We'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 we 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 we can see each instruction in the `Dockerfile` being executed
|
||||
step-by-step. We 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 we saw earlier. When all the
|
||||
instructions have executed we're left with the `97feabe5d2ed` image
|
||||
(also helpfully 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.
|
||||
|
||||
We 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/) 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](/articles/dockerfile_best-practices).
|
||||
|
||||
### More
|
||||
|
||||
To learn more, check out the [Dockerfile tutorial](/userguide/level1).
|
||||
|
||||
## 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. Let's add a new tag to our
|
||||
`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.
|
||||
|
||||
Let's see our new tag using the `docker images` command.
|
||||
|
||||
$ docker images ouruser/sinatra
|
||||
REPOSITORY TAG IMAGE ID CREATED VIRTUAL 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 VIRTUAL 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@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://registry.hub.docker.com/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](
|
||||
/userguide/usingdocker) using the `docker rmi` command.
|
||||
|
||||
Let's delete the `training/sinatra` image as we don't need it anymore.
|
||||
|
||||
$ docker rmi training/sinatra
|
||||
Untagged: training/sinatra:latest
|
||||
Deleted: 5bc342fa0b91cabf65246837015197eecfa24b2213ed6a51a8974ae250fedd8d
|
||||
Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f
|
||||
Deleted: 5c58979d73ae448df5af1d8142436d81116187a7633082650549c52c3a2418f0
|
||||
|
||||
> **Note:** In order to remove an image from the host, please make sure
|
||||
> that there are no containers actively based on it.
|
||||
|
||||
# Next steps
|
||||
|
||||
Until now we've seen how to build individual applications inside Docker
|
||||
containers. Now learn how to build whole application stacks with Docker
|
||||
by linking together multiple Docker containers.
|
||||
|
||||
Test your Dockerfile knowledge with the
|
||||
[Dockerfile tutorial](/userguide/level1).
|
||||
|
||||
Go to [Linking Containers Together](/userguide/dockerlinks).
|
||||
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Dockerizing applications: A 'Hello world'"
|
||||
description = "A simple 'Hello world' exercise that introduced you to Docker."
|
||||
keywords = ["docker guide, docker, docker platform, virtualization framework, how to, dockerize, dockerizing apps, dockerizing applications, container, containers"]
|
||||
[menu.main]
|
||||
parent = "smn_applied"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Dockerizing applications: A "Hello world"
|
||||
|
||||
*So what's this Docker thing all about?*
|
||||
|
||||
Docker allows you to run applications inside containers. Running an
|
||||
application inside a container takes a single command: `docker run`.
|
||||
|
||||
{{ include "no-remote-sudo.md" }}
|
||||
|
||||
## Hello world
|
||||
|
||||
Let's try it now.
|
||||
|
||||
$ docker run ubuntu:14.04 /bin/echo 'Hello world'
|
||||
Hello world
|
||||
|
||||
And you just launched your first container!
|
||||
|
||||
So what just happened? Let's step through what the `docker run` command
|
||||
did.
|
||||
|
||||
First we specified the `docker` binary and the command we wanted to
|
||||
execute, `run`. The `docker run` combination *runs* containers.
|
||||
|
||||
Next we specified an image: `ubuntu:14.04`. This is the source of the container
|
||||
we ran. Docker calls this an image. In this case we used an Ubuntu 14.04
|
||||
operating system image.
|
||||
|
||||
When you specify an image, Docker looks first for the image on your
|
||||
Docker host. If it can't find it then it downloads the image from the public
|
||||
image registry: [Docker Hub](https://hub.docker.com).
|
||||
|
||||
Next we told Docker what command to run inside our new container:
|
||||
|
||||
/bin/echo 'Hello world'
|
||||
|
||||
When our container was launched Docker created a new Ubuntu 14.04
|
||||
environment and then executed the `/bin/echo` command inside it. We saw
|
||||
the result on the command line:
|
||||
|
||||
Hello world
|
||||
|
||||
So what happened to our container after that? Well Docker containers
|
||||
only run as long as the command you specify is active. Here, as soon as
|
||||
`Hello world` was echoed, the container stopped.
|
||||
|
||||
## An interactive container
|
||||
|
||||
Let's try the `docker run` command again, this time specifying a new
|
||||
command to run in our container.
|
||||
|
||||
$ docker run -t -i ubuntu:14.04 /bin/bash
|
||||
root@af8bae53bdd3:/#
|
||||
|
||||
Here we've again specified the `docker run` command and launched an
|
||||
`ubuntu:14.04` image. But we've also passed in two flags: `-t` and `-i`.
|
||||
The `-t` flag assigns a pseudo-tty or terminal inside our new container
|
||||
and the `-i` flag allows us to make an interactive connection by
|
||||
grabbing the standard in (`STDIN`) of the container.
|
||||
|
||||
We've also specified a new command for our container to run:
|
||||
`/bin/bash`. This will launch a Bash shell inside our container.
|
||||
|
||||
So now when our container is launched we can see that we've got a
|
||||
command prompt inside it:
|
||||
|
||||
root@af8bae53bdd3:/#
|
||||
|
||||
Let's try running some commands inside our 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
|
||||
|
||||
You can see we've run the `pwd` to show our current directory and can
|
||||
see we're in the `/` root directory. We've also done a directory listing
|
||||
of the root directory which shows us what looks like a typical Linux
|
||||
file system.
|
||||
|
||||
You can play around inside this container and when you're done you can
|
||||
use the `exit` command or enter Ctrl-D to finish.
|
||||
|
||||
root@af8bae53bdd3:/# exit
|
||||
|
||||
As with our previous container, once the Bash shell process has
|
||||
finished, the container is stopped.
|
||||
|
||||
## A daemonized Hello world
|
||||
|
||||
Now a container that runs a command and then exits has some uses but
|
||||
it's not overly helpful. Let's create a container that runs as a daemon,
|
||||
like most of the applications we're probably going to run with Docker.
|
||||
|
||||
Again we can do this with the `docker run` command:
|
||||
|
||||
$ docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
|
||||
1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147
|
||||
|
||||
Wait, what? Where's our "hello world" output? Let's look at what we've run here.
|
||||
It should look pretty familiar. We ran `docker run` but this time we
|
||||
specified a flag: `-d`. The `-d` flag tells Docker to run the container
|
||||
and put it in the background, to daemonize it.
|
||||
|
||||
We also specified the same image: `ubuntu:14.04`.
|
||||
|
||||
Finally, we specified a command to run:
|
||||
|
||||
/bin/sh -c "while true; do echo hello world; sleep 1; done"
|
||||
|
||||
This is the (hello) world's silliest daemon: a shell script that echoes
|
||||
`hello world` forever.
|
||||
|
||||
So why aren't we seeing any `hello world`'s? Instead Docker has returned
|
||||
a really long string:
|
||||
|
||||
1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147
|
||||
|
||||
This really 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 and a bit later
|
||||
> on we'll see a shorter ID and some 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.
|
||||
|
||||
Firstly let's make sure our container is running. We can
|
||||
do that with 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:14.04 /bin/sh -c 'while tr 2 minutes ago Up 1 minute insane_babbage
|
||||
|
||||
Here we can see our daemonized container. The `docker ps` has returned some useful
|
||||
information about it, starting with a shorter variant of its container ID:
|
||||
`1e5535038e28`.
|
||||
|
||||
We can also see the image we used to build it, `ubuntu:14.04`, the command it
|
||||
is running, its status and an automatically assigned name,
|
||||
`insane_babbage`.
|
||||
|
||||
> **Note:**
|
||||
> Docker automatically names any containers you start, a
|
||||
> little later on we'll see how you can specify your own names.
|
||||
|
||||
Okay, so we now know it's 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 Docker assigned.
|
||||
|
||||
$ docker logs insane_babbage
|
||||
hello world
|
||||
hello world
|
||||
hello world
|
||||
. . .
|
||||
|
||||
The `docker logs` command looks inside the container and returns its standard
|
||||
output: in this case the output of our command `hello world`.
|
||||
|
||||
Awesome! Our daemon is working and we've just created our first
|
||||
Dockerized application!
|
||||
|
||||
Now we've established we can create our own containers let's tidy up
|
||||
after ourselves and stop our daemonized container. To do this we use the
|
||||
`docker stop` command.
|
||||
|
||||
$ docker stop insane_babbage
|
||||
insane_babbage
|
||||
|
||||
The `docker stop` command tells Docker to politely stop the running
|
||||
container. If it succeeds it will return the name of the container it
|
||||
has just stopped.
|
||||
|
||||
Let's check it worked with the `docker ps` command.
|
||||
|
||||
$ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
|
||||
Excellent. Our container has been stopped.
|
||||
|
||||
# Next steps
|
||||
|
||||
Now we've seen how simple it is to get started with Docker. Let's learn how to
|
||||
do some more advanced tasks.
|
||||
|
||||
Go to [Working With Containers](/userguide/usingdocker).
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Linking containers together"
|
||||
description = "Learn how to connect Docker containers together."
|
||||
keywords = ["Examples, Usage, user guide, links, linking, docker, documentation, examples, names, name, container naming, port, map, network port, network"]
|
||||
[menu.main]
|
||||
parent = "smn_containers"
|
||||
weight = 4
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Linking containers together
|
||||
|
||||
In [the Using Docker section](/userguide/usingdocker), you saw how you can
|
||||
connect to a service running inside a Docker container via a network
|
||||
port. But a port connection is only one way you can interact with services and
|
||||
applications running inside Docker containers. In this section, we'll briefly revisit
|
||||
connecting via a network port and then we'll introduce you to another method of access:
|
||||
container linking.
|
||||
|
||||
## Connect using network port mapping
|
||||
|
||||
In [the Using Docker section](/userguide/usingdocker), you created a
|
||||
container that ran a Python Flask application:
|
||||
|
||||
$ docker run -d -P training/webapp python app.py
|
||||
|
||||
> **Note:**
|
||||
> Containers have an internal network and an IP address
|
||||
> (as we saw when we used the `docker inspect` command to show the container's
|
||||
> IP address in the [Using Docker](/userguide/usingdocker/) section).
|
||||
> Docker can have a variety of network configurations. You can see more
|
||||
> information on Docker networking [here](/articles/networking/).
|
||||
|
||||
When that container was created, the `-P` flag was used to automatically map
|
||||
any network port inside it to a random high port within an *ephemeral port
|
||||
range* on your Docker host. Next, when `docker ps` was run, you saw that port
|
||||
5000 in the container was bound to port 49155 on the host.
|
||||
|
||||
$ docker ps nostalgic_morse
|
||||
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 nostalgic_morse
|
||||
|
||||
You also saw how you can bind a container's ports to a specific port using
|
||||
the `-p` flag. Here port 80 of the host is mapped to port 5000 of the
|
||||
container:
|
||||
|
||||
$ docker run -d -p 80:5000 training/webapp python app.py
|
||||
|
||||
And you saw why this isn't such a great idea because it constrains you to
|
||||
only one container on that specific port.
|
||||
|
||||
There are also a few other ways you can configure the `-p` flag. By
|
||||
default the `-p` flag will bind the specified port to all interfaces on
|
||||
the host machine. But you can also specify a binding to a specific
|
||||
interface, for example only to the `localhost`.
|
||||
|
||||
$ docker run -d -p 127.0.0.1:80:5000 training/webapp python app.py
|
||||
|
||||
This would bind port 5000 inside the container to port 80 on the
|
||||
`localhost` or `127.0.0.1` interface on the host machine.
|
||||
|
||||
Or, to bind port 5000 of the container to a dynamic port but only on the
|
||||
`localhost`, you could use:
|
||||
|
||||
$ docker run -d -p 127.0.0.1::5000 training/webapp python app.py
|
||||
|
||||
You can also bind UDP ports by adding a trailing `/udp`. For example:
|
||||
|
||||
$ docker run -d -p 127.0.0.1:80:5000/udp training/webapp python app.py
|
||||
|
||||
You also learned about the useful `docker port` shortcut which showed us the
|
||||
current port bindings. This is also useful for showing you specific port
|
||||
configurations. For example, if you've bound the container port to the
|
||||
`localhost` on the host machine, then the `docker port` output will reflect that.
|
||||
|
||||
$ docker port nostalgic_morse 5000
|
||||
127.0.0.1:49155
|
||||
|
||||
> **Note:**
|
||||
> The `-p` flag can be used multiple times to configure multiple ports.
|
||||
|
||||
## Connect with the linking system
|
||||
|
||||
Network port mappings are not the only way Docker containers can connect
|
||||
to one another. Docker also has a linking system that allows you to link
|
||||
multiple containers together and send connection information from one to another.
|
||||
When containers are linked, information about a source container can be sent to a
|
||||
recipient container. This allows the recipient to see selected data describing
|
||||
aspects of the source container.
|
||||
|
||||
### The importance of naming
|
||||
|
||||
To establish links, Docker relies on the names of your containers.
|
||||
You've already seen that each container you create has an automatically
|
||||
created name; indeed you've become familiar with our old friend
|
||||
`nostalgic_morse` during this guide. You can also name containers
|
||||
yourself. This naming provides two useful functions:
|
||||
|
||||
1. It can be useful to name containers that do specific functions in a way
|
||||
that makes it easier for you to remember them, for example naming a
|
||||
container containing a web application `web`.
|
||||
|
||||
2. It provides Docker with a reference point that allows it to refer to other
|
||||
containers, for example, you can specify to link the container `web` to container `db`.
|
||||
|
||||
You can name your container by using the `--name` flag, for example:
|
||||
|
||||
$ docker run -d -P --name web training/webapp python app.py
|
||||
|
||||
This launches a new container and uses the `--name` flag to
|
||||
name the container `web`. You can see the container's name using the
|
||||
`docker ps` command.
|
||||
|
||||
$ docker ps -l
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
aed84ee21bde training/webapp:latest python app.py 12 hours ago Up 2 seconds 0.0.0.0:49154->5000/tcp web
|
||||
|
||||
You can also use `docker inspect` to return the container's name.
|
||||
|
||||
|
||||
> **Note:**
|
||||
> Container names have to be unique. That means you can only call
|
||||
> one container `web`. If you want to re-use a container name you must delete
|
||||
> the old container (with `docker rm`) before you can create a new
|
||||
> container with the same name. As an alternative you can use the `--rm`
|
||||
> flag with the `docker run` command. This will delete the container
|
||||
> immediately after it is stopped.
|
||||
|
||||
## Communication across links
|
||||
|
||||
Links allow containers to discover each other and securely transfer information about one
|
||||
container to another container. When you set up a link, you create a conduit between a
|
||||
source container and a recipient container. The recipient can then access select data
|
||||
about the source. To create a link, you use the `--link` flag. First, create a new
|
||||
container, this time one containing a database.
|
||||
|
||||
$ docker run -d --name db training/postgres
|
||||
|
||||
This creates a new container called `db` from the `training/postgres`
|
||||
image, which contains a PostgreSQL database.
|
||||
|
||||
Now, you need to delete the `web` container you created previously so you can replace it
|
||||
with a linked one:
|
||||
|
||||
$ docker rm -f web
|
||||
|
||||
Now, create a new `web` container and link it with your `db` container.
|
||||
|
||||
$ docker run -d -P --name web --link db:db training/webapp python app.py
|
||||
|
||||
This will link the new `web` container with the `db` container you created
|
||||
earlier. The `--link` flag takes the form:
|
||||
|
||||
--link <name or id>:alias
|
||||
|
||||
Where `name` is the name of the container we're linking to and `alias` is an
|
||||
alias for the link name. You'll see how that alias gets used shortly.
|
||||
The `--link` flag also takes the form:
|
||||
|
||||
--link <name or id>
|
||||
|
||||
In which case the alias will match the name. You could have written the previous
|
||||
example as:
|
||||
|
||||
$ docker run -d -P --name web --link db training/webapp python app.py
|
||||
|
||||
Next, inspect your linked containers with `docker inspect`:
|
||||
|
||||
$ docker inspect -f "{{ .HostConfig.Links }}" web
|
||||
[/db:/web/db]
|
||||
|
||||
You can see that the `web` container is now linked to the `db` container
|
||||
`web/db`. Which allows it to access information about the `db` container.
|
||||
|
||||
So what does linking the containers actually do? You've learned that a link allows a
|
||||
source container to provide information about itself to a recipient container. In
|
||||
our example, the recipient, `web`, can access information about the source `db`. To do
|
||||
this, Docker creates a secure tunnel between the containers that doesn't need to
|
||||
expose any ports externally on the container; you'll note when we started the
|
||||
`db` container we did not use either the `-P` or `-p` flags. That's a big benefit of
|
||||
linking: we don't need to expose the source container, here the PostgreSQL database, to
|
||||
the network.
|
||||
|
||||
Docker exposes connectivity information for the source container to the
|
||||
recipient container in two ways:
|
||||
|
||||
* Environment variables,
|
||||
* Updating the `/etc/hosts` file.
|
||||
|
||||
### Environment variables
|
||||
|
||||
Docker creates several environment variables when you link containers. Docker
|
||||
automatically creates environment variables in the target container based on
|
||||
the `--link` parameters. It will also expose all environment variables
|
||||
originating from Docker from the source container. These include variables from:
|
||||
|
||||
* the `ENV` commands in the source container's Dockerfile
|
||||
* the `-e`, `--env` and `--env-file` options on the `docker run`
|
||||
command when the source container is started
|
||||
|
||||
These environment variables enable programmatic discovery from within the
|
||||
target container of information related to the source container.
|
||||
|
||||
> **Warning**:
|
||||
> It is important to understand that *all* environment variables originating
|
||||
> from Docker within a container are made available to *any* container
|
||||
> that links to it. This could have serious security implications if sensitive
|
||||
> data is stored in them.
|
||||
|
||||
Docker sets an `<alias>_NAME` environment variable for each target container
|
||||
listed in the `--link` parameter. For example, if a new container called
|
||||
`web` is linked to a database container called `db` via `--link db:webdb`,
|
||||
then Docker creates a `WEBDB_NAME=/web/webdb` variable in the `web` container.
|
||||
|
||||
Docker also defines a set of environment variables for each port exposed by the
|
||||
source container. Each variable has a unique prefix in the form:
|
||||
|
||||
`<name>_PORT_<port>_<protocol>`
|
||||
|
||||
The components in this prefix are:
|
||||
|
||||
* the alias `<name>` specified in the `--link` parameter (for example, `webdb`)
|
||||
* the `<port>` number exposed
|
||||
* a `<protocol>` which is either TCP or UDP
|
||||
|
||||
Docker uses this prefix format to define three distinct environment variables:
|
||||
|
||||
* The `prefix_ADDR` variable contains the IP Address from the URL, for
|
||||
example `WEBDB_PORT_8080_TCP_ADDR=172.17.0.82`.
|
||||
* The `prefix_PORT` variable contains just the port number from the URL for
|
||||
example `WEBDB_PORT_8080_TCP_PORT=8080`.
|
||||
* The `prefix_PROTO` variable contains just the protocol from the URL for
|
||||
example `WEBDB_PORT_8080_TCP_PROTO=tcp`.
|
||||
|
||||
If the container exposes multiple ports, an environment variable set is
|
||||
defined for each one. This means, for example, if a container exposes 4 ports
|
||||
that Docker creates 12 environment variables, 3 for each port.
|
||||
|
||||
Additionally, Docker creates an environment variable called `<alias>_PORT`.
|
||||
This variable contains the URL of the source container's first exposed port.
|
||||
The 'first' port is defined as the exposed port with the lowest number.
|
||||
For example, consider the `WEBDB_PORT=tcp://172.17.0.82:8080` variable. If
|
||||
that port is used for both tcp and udp, then the tcp one is specified.
|
||||
|
||||
Finally, Docker also exposes each Docker originated environment variable
|
||||
from the source container as an environment variable in the target. For each
|
||||
variable Docker creates an `<alias>_ENV_<name>` variable in the target
|
||||
container. The variable's value is set to the value Docker used when it
|
||||
started the source container.
|
||||
|
||||
Returning back to our database example, you can run the `env`
|
||||
command to list the specified container's environment variables.
|
||||
|
||||
```
|
||||
$ docker run --rm --name web2 --link db:db training/webapp env
|
||||
. . .
|
||||
DB_NAME=/web2/db
|
||||
DB_PORT=tcp://172.17.0.5:5432
|
||||
DB_PORT_5432_TCP=tcp://172.17.0.5:5432
|
||||
DB_PORT_5432_TCP_PROTO=tcp
|
||||
DB_PORT_5432_TCP_PORT=5432
|
||||
DB_PORT_5432_TCP_ADDR=172.17.0.5
|
||||
. . .
|
||||
```
|
||||
|
||||
You can see that Docker has created a series of environment variables with
|
||||
useful information about the source `db` container. Each variable is prefixed
|
||||
with
|
||||
`DB_`, which is populated from the `alias` you specified above. If the `alias`
|
||||
were `db1`, the variables would be prefixed with `DB1_`. You can use these
|
||||
environment variables to configure your applications to connect to the database
|
||||
on the `db` container. The connection will be secure and private; only the
|
||||
linked `web` container will be able to talk to the `db` container.
|
||||
|
||||
### Important notes on Docker environment variables
|
||||
|
||||
Unlike host entries in the [`/etc/hosts` file](#updating-the-etchosts-file),
|
||||
IP addresses stored in the environment variables are not automatically updated
|
||||
if the source container is restarted. We recommend using the host entries in
|
||||
`/etc/hosts` to resolve the IP address of linked containers.
|
||||
|
||||
These environment variables are only set for the first process in the
|
||||
container. Some daemons, such as `sshd`, will scrub them when spawning shells
|
||||
for connection.
|
||||
|
||||
### Updating the `/etc/hosts` file
|
||||
|
||||
In addition to the environment variables, Docker adds a host entry for the
|
||||
source container to the `/etc/hosts` file. Here's an entry for the `web`
|
||||
container:
|
||||
|
||||
$ docker run -t -i --rm --link db:webdb training/webapp /bin/bash
|
||||
root@aed84ee21bde:/opt/webapp# cat /etc/hosts
|
||||
172.17.0.7 aed84ee21bde
|
||||
. . .
|
||||
172.17.0.5 webdb 6e5cdeb2d300 db
|
||||
|
||||
You can see two relevant host entries. The first is an entry for the `web`
|
||||
container that uses the Container ID as a host name. The second entry uses the
|
||||
link alias to reference the IP address of the `db` container. In addition to
|
||||
the alias you provide, the linked container's name--if unique from the alias
|
||||
provided to the `--link` parameter--and the linked container's hostname will
|
||||
also be added in `/etc/hosts` for the linked container's IP address. You can ping
|
||||
that host now via any of these entries:
|
||||
|
||||
root@aed84ee21bde:/opt/webapp# apt-get install -yqq inetutils-ping
|
||||
root@aed84ee21bde:/opt/webapp# ping webdb
|
||||
PING webdb (172.17.0.5): 48 data bytes
|
||||
56 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.267 ms
|
||||
56 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.250 ms
|
||||
56 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.256 ms
|
||||
|
||||
> **Note:**
|
||||
> In the example, you'll note you had to install `ping` because it was not included
|
||||
> in the container initially.
|
||||
|
||||
Here, you used the `ping` command to ping the `db` container using its host entry,
|
||||
which resolves to `172.17.0.5`. You can use this host entry to configure an application
|
||||
to make use of your `db` container.
|
||||
|
||||
> **Note:**
|
||||
> You can link multiple recipient containers to a single source. For
|
||||
> example, you could have multiple (differently named) web containers attached to your
|
||||
>`db` container.
|
||||
|
||||
If you restart the source container, the linked containers `/etc/hosts` files
|
||||
will be automatically updated with the source container's new IP address,
|
||||
allowing linked communication to continue.
|
||||
|
||||
$ docker restart db
|
||||
db
|
||||
$ docker run -t -i --rm --link db:db training/webapp /bin/bash
|
||||
root@aed84ee21bde:/opt/webapp# cat /etc/hosts
|
||||
172.17.0.7 aed84ee21bde
|
||||
. . .
|
||||
172.17.0.9 db
|
||||
|
||||
# Next step
|
||||
|
||||
Now that you know how to link Docker containers together, the next step is
|
||||
learning how to manage data, volumes and mounts inside your containers.
|
||||
|
||||
Go to [Managing Data in Containers](/userguide/dockervolumes).
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Get started with Docker Hub"
|
||||
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"]
|
||||
[menu.main]
|
||||
parent = "smn_images"
|
||||
weight = 2
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Get started with 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](/userguide/usingdocker/) to build containers
|
||||
from existing images and you've learned how to [create your own images](/userguide/dockerimages).
|
||||
|
||||
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 over 15,000 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
|
||||
Typically, you'll want to start by creating an account on Docker Hub (if you haven't
|
||||
already) and logging in. You can create your account directly on
|
||||
[Docker Hub](https://hub.docker.com/account/signup/), or by running:
|
||||
|
||||
$ docker login
|
||||
|
||||
This will prompt you for a user name, which will become the public namespace for your
|
||||
public repositories.
|
||||
If your user name is available, Docker will prompt you to enter a password and your
|
||||
e-mail address. It will then automatically log you in. You can now commit and
|
||||
push your own images up to your repos on Docker Hub.
|
||||
|
||||
> **Note:**
|
||||
> Your authentication credentials will be stored in the `.dockercfg`
|
||||
> authentication file in your home directory.
|
||||
|
||||
## 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 TRUSTED
|
||||
centos Official CentOS 6 Image as of 12 April 2014 88
|
||||
tianon/centos CentOS 5 and 6, created using rinse instea... 21
|
||||
...
|
||||
|
||||
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
|
||||
Pulling repository centos
|
||||
0b443ba03958: Download complete
|
||||
539c0211cd76: Download complete
|
||||
511136ea3c5a: Download complete
|
||||
7064731afe90: Download complete
|
||||
|
||||
Status: Downloaded newer image for centos
|
||||
|
||||
You now have an image from which you can run containers.
|
||||
|
||||
## 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, as we saw in the [first section of the Docker User
|
||||
Guide](/userguide/dockerhub/).
|
||||
|
||||
## 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](/userguide/dockerimages).
|
||||
|
||||
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](https://docs.docker.com/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://registry.hub.docker.com/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://registry.hub.docker.com/account/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 through the ["Link Accounts"](https://registry.hub.docker.com/account/accounts/) menu.
|
||||
3. [Configure an Automated Build](https://registry.hub.docker.com/builds/add/).
|
||||
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.
|
||||
|
||||
If you want to see the status of your Automated Builds, you can go to your
|
||||
[Automated Builds page](https://registry.hub.docker.com/builds/) on the Docker Hub,
|
||||
and it will show you the status of your builds and their build history.
|
||||
|
||||
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](https://docs.docker.com/docker-hub/repos/#webhooks)
|
||||
|
||||
## Next steps
|
||||
|
||||
Go and use Docker!
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Managing data in containers"
|
||||
description = "How to manage data inside your Docker containers."
|
||||
keywords = ["Examples, Usage, volume, docker, documentation, user guide, data, volumes"]
|
||||
[menu.main]
|
||||
parent = "smn_containers"
|
||||
weight = 3
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Managing data in containers
|
||||
|
||||
So far we've been introduced to some [basic Docker
|
||||
concepts](/userguide/usingdocker/), seen how to work with [Docker
|
||||
images](/userguide/dockerimages/) as well as learned about [networking
|
||||
and links between containers](/userguide/dockerlinks/). In this section
|
||||
we're going to discuss how you can manage data inside and between your
|
||||
Docker containers.
|
||||
|
||||
We're going to look at the two primary ways you can manage data in
|
||||
Docker.
|
||||
|
||||
* Data volumes, and
|
||||
* Data volume containers.
|
||||
|
||||
## Data volumes
|
||||
|
||||
A *data volume* is a specially-designated directory within one or more
|
||||
containers that bypasses the [*Union File
|
||||
System*](/terms/layer/#union-file-system). Data volumes provide several
|
||||
useful features for persistent or shared data:
|
||||
|
||||
- Volumes are initialized when a container is created. If the container's
|
||||
base image contains data at the specified mount point, that existing data is
|
||||
copied into the new volume upon volume initialization.
|
||||
- Data volumes can be shared and reused among containers.
|
||||
- Changes to a data volume are made directly.
|
||||
- Changes to a data volume will not be included when you update an image.
|
||||
- Data volumes persist even if the container itself is deleted.
|
||||
|
||||
Data volumes are designed to persist data, independent of the container's life
|
||||
cycle. Docker therefore *never* automatically delete volumes when you remove
|
||||
a container, nor will it "garbage collect" volumes that are no longer
|
||||
referenced by a container.
|
||||
|
||||
### Adding a data volume
|
||||
|
||||
You can add a data volume to a container using the `-v` flag with the
|
||||
`docker create` and `docker run` command. You can use the `-v` multiple times
|
||||
to mount multiple data volumes. Let's mount a single volume now in our web
|
||||
application container.
|
||||
|
||||
$ docker run -d -P --name web -v /webapp training/webapp python app.py
|
||||
|
||||
This will create a new volume inside a container at `/webapp`.
|
||||
|
||||
> **Note:**
|
||||
> You can also use the `VOLUME` instruction in a `Dockerfile` to add one or
|
||||
> more new volumes to any container created from that image.
|
||||
|
||||
### Locating a volume
|
||||
|
||||
You can locate the volume on the host by utilizing the 'docker inspect' command.
|
||||
|
||||
$ docker inspect web
|
||||
|
||||
The output will provide details on the container configurations including the
|
||||
volumes. The output should look something similar to the following:
|
||||
|
||||
...
|
||||
"Volumes": {
|
||||
"/webapp": "/var/lib/docker/volumes/fac362...80535"
|
||||
},
|
||||
"VolumesRW": {
|
||||
"/webapp": true
|
||||
}
|
||||
...
|
||||
|
||||
You will notice in the above 'Volumes' is specifying the location on the host and
|
||||
'VolumesRW' is specifying that the volume is read/write.
|
||||
|
||||
### Mount a host directory as a data volume
|
||||
|
||||
In addition to creating a volume using the `-v` flag you can also mount a
|
||||
directory from your Docker daemon's host into a container.
|
||||
|
||||
> **Note:**
|
||||
> If you are using Boot2Docker, your Docker daemon only has limited access to
|
||||
> your OS X/Windows filesystem. Boot2Docker tries to auto-share your `/Users`
|
||||
> (OS X) or `C:\Users` (Windows) directory - and so you can mount files or directories
|
||||
> using `docker run -v /Users/<path>:/<container path> ...` (OS X) or
|
||||
> `docker run -v /c/Users/<path>:/<container path ...` (Windows). All other paths
|
||||
> come from the Boot2Docker virtual machine's filesystem.
|
||||
|
||||
$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
|
||||
|
||||
This will mount the host directory, `/src/webapp`, into the container at
|
||||
`/opt/webapp`.
|
||||
|
||||
> **Note:**
|
||||
> If the path `/opt/webapp` already exists inside the container's image, its
|
||||
> contents will be replaced by the contents of `/src/webapp` on the host to stay
|
||||
> consistent with the expected behavior of `mount`
|
||||
|
||||
This is very useful for testing, for example we can
|
||||
mount our source code inside the container and see our application at work as
|
||||
we change the source code. The directory on the host must be specified as an
|
||||
absolute path and if the directory doesn't exist Docker will automatically
|
||||
create it for you.
|
||||
|
||||
> **Note:**
|
||||
> This is not available from a `Dockerfile` due to the portability
|
||||
> and sharing purpose of built images. The host directory is, by its nature,
|
||||
> host-dependent, so a host directory specified in a `Dockerfile` probably
|
||||
> wouldn't work on all hosts.
|
||||
|
||||
Docker defaults to a read-write volume but we can also mount a directory
|
||||
read-only.
|
||||
|
||||
$ docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py
|
||||
|
||||
Here we've mounted the same `/src/webapp` directory but we've added the `ro`
|
||||
option to specify that the mount should be read-only.
|
||||
|
||||
### Mount a host file as a data volume
|
||||
|
||||
The `-v` flag can also be used to mount a single file - instead of *just*
|
||||
directories - from the host machine.
|
||||
|
||||
$ docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
|
||||
|
||||
This will drop you into a bash shell in a new container, you will have your bash
|
||||
history from the host and when you exit the container, the host will have the
|
||||
history of the commands typed while in the container.
|
||||
|
||||
> **Note:**
|
||||
> Many tools used to edit files including `vi` and `sed --in-place` may result
|
||||
> in an inode change. Since Docker v1.1.0, this will produce an error such as
|
||||
> "*sed: cannot rename ./sedKdJ9Dy: Device or resource busy*". In the case where
|
||||
> you want to edit the mounted file, it is often easiest to instead mount the
|
||||
> parent directory.
|
||||
|
||||
## Creating and mounting a data volume container
|
||||
|
||||
If you have some persistent data that you want to share between
|
||||
containers, or want to use from non-persistent containers, it's best to
|
||||
create a named Data Volume Container, and then to mount the data from
|
||||
it.
|
||||
|
||||
Let's create a new named container with a volume to share.
|
||||
While this container doesn't run an application, it reuses the `training/postgres`
|
||||
image so that all containers are using layers in common, saving disk space.
|
||||
|
||||
$ docker create -v /dbdata --name dbdata training/postgres /bin/true
|
||||
|
||||
You can then use the `--volumes-from` flag to mount the `/dbdata` volume in another container.
|
||||
|
||||
$ docker run -d --volumes-from dbdata --name db1 training/postgres
|
||||
|
||||
And another:
|
||||
|
||||
$ docker run -d --volumes-from dbdata --name db2 training/postgres
|
||||
|
||||
In this case, if the `postgres` image contained a directory called `/dbdata`
|
||||
then mounting the volumes from the `dbdata` container hides the
|
||||
`/dbdata` files from the `postgres` image. The result is only the files
|
||||
from the `dbdata` container are visible.
|
||||
|
||||
You can use multiple `--volumes-from` parameters to bring together multiple data
|
||||
volumes from multiple containers.
|
||||
|
||||
You can also extend the chain by mounting the volume that came from the
|
||||
`dbdata` container in yet another container via the `db1` or `db2` containers.
|
||||
|
||||
$ docker run -d --name db3 --volumes-from db1 training/postgres
|
||||
|
||||
If you remove containers that mount volumes, including the initial `dbdata`
|
||||
container, or the subsequent containers `db1` and `db2`, the volumes will not
|
||||
be deleted. To delete the volume from disk, you must explicitly call
|
||||
`docker rm -v` against the last container with a reference to the volume. This
|
||||
allows you to upgrade, or effectively migrate data volumes between containers.
|
||||
|
||||
> **Note:** Docker will not warn you when removing a container *without*
|
||||
> providing the `-v` option to delete its volumes. If you remove containers
|
||||
> without using the `-v` option, you may end up with "dangling" volumes;
|
||||
> volumes that are no longer referenced by a container.
|
||||
> Dangling volumes are difficult to get rid of and can take up a large amount
|
||||
> of disk space. We're working on improving volume management and you can check
|
||||
> progress on this in [pull request #8484](https://github.com/docker/docker/pull/8484)
|
||||
|
||||
## Backup, restore, or migrate data volumes
|
||||
|
||||
Another useful function we can perform with volumes is use them for
|
||||
backups, restores or migrations. We do this by using the
|
||||
`--volumes-from` flag to create a new container that mounts that volume,
|
||||
like so:
|
||||
|
||||
$ docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
|
||||
|
||||
Here we've launched a new container and mounted the volume from the
|
||||
`dbdata` container. We've then mounted a local host directory as
|
||||
`/backup`. Finally, we've passed a command that uses `tar` to backup the
|
||||
contents of the `dbdata` volume to a `backup.tar` file inside our
|
||||
`/backup` directory. When the command completes and the container stops
|
||||
we'll be left with a backup of our `dbdata` volume.
|
||||
|
||||
You could then restore it to the same container, or another that you've made
|
||||
elsewhere. Create a new container.
|
||||
|
||||
$ docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
|
||||
|
||||
Then un-tar the backup file in the new container's data volume.
|
||||
|
||||
$ docker run --volumes-from dbdata2 -v $(pwd):/backup ubuntu cd /dbdata && tar xvf /backup/backup.tar
|
||||
|
||||
You can use the techniques above to automate backup, migration and
|
||||
restore testing using your preferred tools.
|
||||
|
||||
# Next steps
|
||||
|
||||
Now we've learned a bit more about how to use Docker we're going to see how to
|
||||
combine Docker with the services available on
|
||||
[Docker Hub](https://hub.docker.com) including Automated Builds and private
|
||||
repositories.
|
||||
|
||||
Go to [Working with Docker Hub](/userguide/dockerrepos).
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
draft = true
|
||||
title = "The Docker user guide"
|
||||
description = "The Docker user guide home page"
|
||||
keywords = ["docker, introduction, documentation, about, technology, docker.io, user, guide, user's, manual, platform, framework, virtualization, home, intro"]
|
||||
[menu.main]
|
||||
parent = "mn_fun_docker"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Welcome to the Docker user guide
|
||||
|
||||
In the [Introduction](/) you got a taste of what Docker is and how it
|
||||
works. In this guide we're going to take you through the fundamentals of
|
||||
using Docker and integrating it into your environment.
|
||||
|
||||
We’ll teach you how to use Docker to:
|
||||
|
||||
* Dockerize your applications.
|
||||
* Run your own containers.
|
||||
* Build Docker images.
|
||||
* Share your Docker images with others.
|
||||
* And a whole lot more!
|
||||
|
||||
We've broken this guide into major sections that take you through
|
||||
the Docker life cycle:
|
||||
|
||||
## Getting started with Docker Hub
|
||||
|
||||
*How do I use Docker Hub?*
|
||||
|
||||
Docker Hub is the central hub for Docker. It hosts public Docker images
|
||||
and provides services to help you build and manage your Docker
|
||||
environment. To learn more:
|
||||
|
||||
Go to [Using Docker Hub](/userguide/dockerhub).
|
||||
|
||||
## Dockerizing applications: A "Hello world"
|
||||
|
||||
*How do I run applications inside containers?*
|
||||
|
||||
Docker offers a *container-based* virtualization platform to power your
|
||||
applications. To learn how to Dockerize applications and run them:
|
||||
|
||||
Go to [Dockerizing Applications](/userguide/dockerizing).
|
||||
|
||||
## Working with containers
|
||||
|
||||
*How do I manage my containers?*
|
||||
|
||||
Once you get a grip on running your applications in Docker containers
|
||||
we're going to show you how to manage those containers. To find out
|
||||
about how to inspect, monitor and manage containers:
|
||||
|
||||
Go to [Working With Containers](/userguide/usingdocker).
|
||||
|
||||
## Working with Docker images
|
||||
|
||||
*How can I access, share and build my own images?*
|
||||
|
||||
Once you've learnt how to use Docker it's time to take the next step and
|
||||
learn how to build your own application images with Docker.
|
||||
|
||||
Go to [Working with Docker Images](/userguide/dockerimages).
|
||||
|
||||
## Linking containers together
|
||||
|
||||
Until now we've seen how to build individual applications inside Docker
|
||||
containers. Now learn how to build whole application stacks with Docker
|
||||
by linking together multiple Docker containers.
|
||||
|
||||
Go to [Linking Containers Together](/userguide/dockerlinks).
|
||||
|
||||
## Managing data in containers
|
||||
|
||||
Now we know how to link Docker containers together the next step is
|
||||
learning how to manage data, volumes and mounts inside our containers.
|
||||
|
||||
Go to [Managing Data in Containers](/userguide/dockervolumes).
|
||||
|
||||
## Working with Docker Hub
|
||||
|
||||
Now we've learned a bit more about how to use Docker we're going to see
|
||||
how to combine Docker with the services available on Docker Hub including
|
||||
Trusted Builds and private repositories.
|
||||
|
||||
Go to [Working with Docker Hub](/userguide/dockerrepos).
|
||||
|
||||
## Docker Compose
|
||||
|
||||
Docker Compose allows you to define a application's components -- their containers,
|
||||
configuration, links and volumes -- in a single file. Then a single command
|
||||
will set everything up and start your application running.
|
||||
|
||||
Go to [Docker Compose user guide](/compose/).
|
||||
|
||||
## Docker Machine
|
||||
|
||||
Docker Machine helps you get Docker Engines up and running quickly. Machine
|
||||
can set up hosts for Docker Engines on your computer, on cloud providers,
|
||||
and/or in your data center, and then configure your Docker client to securely
|
||||
talk to them.
|
||||
|
||||
Go to [Docker Machine user guide](/machine/).
|
||||
|
||||
## Docker Swarm
|
||||
|
||||
Docker Swarm pools several Docker Engines together and exposes them as a single
|
||||
virtual Docker Engine. It serves the standard Docker API, so any tool that already
|
||||
works with Docker can now transparently scale up to multiple hosts.
|
||||
|
||||
Go to [Docker Swarm user guide](/swarm/).
|
||||
|
||||
## Getting help
|
||||
|
||||
* [Docker homepage](http://www.docker.com/)
|
||||
* [Docker Hub](https://hub.docker.com)
|
||||
* [Docker blog](http://blog.docker.com/)
|
||||
* [Docker documentation](https://docs.docker.com/)
|
||||
* [Docker Getting Started Guide](http://www.docker.com/gettingstarted/)
|
||||
* [Docker code on GitHub](https://github.com/docker/docker)
|
||||
* [Docker mailing
|
||||
list](https://groups.google.com/forum/#!forum/docker-user)
|
||||
* Docker on IRC: irc.freenode.net and channel #docker
|
||||
* [Docker on Twitter](http://twitter.com/docker)
|
||||
* Get [Docker help](http://stackoverflow.com/search?q=docker) on
|
||||
StackOverflow
|
||||
* [Docker.com](http://www.docker.com/)
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Apply custom metadata"
|
||||
description = "Learn how to work with custom metadata in Docker, using labels."
|
||||
keywords = ["Usage, user guide, labels, metadata, docker, documentation, examples, annotating"]
|
||||
[menu.main]
|
||||
parent = "mn_use_docker"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Apply custom metadata
|
||||
|
||||
You can apply metadata to your images, containers, or daemons via
|
||||
labels. Metadata can serve a wide range of uses. Use labels to add notes or
|
||||
licensing information to an image or to identify a host.
|
||||
|
||||
A label is a `<key>` / `<value>` pair. Docker stores the label values as
|
||||
*strings*. You can specify multiple labels but each `<key>` / `<value>` must be
|
||||
unique to avoid overwriting. If you specify the same `key` several times but with
|
||||
different values, newer labels overwrite previous labels. Docker uses
|
||||
the last `key=value` you supply.
|
||||
|
||||
>**Note:** Support for daemon-labels was added in Docker 1.4.1. Labels on
|
||||
>containers and images are new in Docker 1.6.0
|
||||
|
||||
## Label keys (namespaces)
|
||||
|
||||
Docker puts no hard restrictions on the label `key` you. However, labels with
|
||||
simple keys can conflict. For example, you can categorize your images by using a
|
||||
chip "architecture" label:
|
||||
|
||||
LABEL architecture="amd64"
|
||||
|
||||
LABEL architecture="ARMv7"
|
||||
|
||||
But a user can label images by building architectural style:
|
||||
|
||||
LABEL architecture="Art Nouveau"
|
||||
|
||||
To prevent naming conflicts, Docker namespaces label keys using a reverse domain
|
||||
notation. Use the following guidelines to name your keys:
|
||||
|
||||
- All (third-party) tools should prefix their keys with the
|
||||
reverse DNS notation of a domain controlled by the author. For
|
||||
example, `com.example.some-label`.
|
||||
|
||||
- The `com.docker.*`, `io.docker.*` and `org.dockerproject.*` namespaces are
|
||||
reserved for Docker's internal use.
|
||||
|
||||
- Keys should only consist of lower-cased alphanumeric characters,
|
||||
dots and dashes (for example, `[a-z0-9-.]`)
|
||||
|
||||
- Keys should start *and* end with an alpha numeric character
|
||||
|
||||
- Keys may not contain consecutive dots or dashes.
|
||||
|
||||
- Keys *without* namespace (dots) are reserved for CLI use. This allows end-
|
||||
users to add metadata to their containers and images without having to type
|
||||
cumbersome namespaces on the command-line.
|
||||
|
||||
|
||||
These are guidelines and Docker does not *enforce* them. Failing following these
|
||||
guidelines can result in conflicting labels. If you're building a tool that uses
|
||||
labels, you *should* use namespaces for your label keys.
|
||||
|
||||
|
||||
## Store structured data in labels
|
||||
|
||||
Label values can contain any data type that can be stored as a string. For
|
||||
example, consider this JSON:
|
||||
|
||||
|
||||
{
|
||||
"Description": "A containerized foobar",
|
||||
"Usage": "docker run --rm example/foobar [args]",
|
||||
"License": "GPL",
|
||||
"Version": "0.0.1-beta",
|
||||
"aBoolean": true,
|
||||
"aNumber" : 0.01234,
|
||||
"aNestedArray": ["a", "b", "c"]
|
||||
}
|
||||
|
||||
You can store this struct in a label by serializing it to a string first:
|
||||
|
||||
LABEL com.example.image-specs="{\"Description\":\"A containerized foobar\",\"Usage\":\"docker run --rm example\\/foobar [args]\",\"License\":\"GPL\",\"Version\":\"0.0.1-beta\",\"aBoolean\":true,\"aNumber\":0.01234,\"aNestedArray\":[\"a\",\"b\",\"c\"]}"
|
||||
|
||||
While it is *possible* to store structured data in label values, Docker treats
|
||||
this data as a 'regular' string. This means that Docker doesn't offer ways to
|
||||
query (filter) based on nested properties. If your tool needs to filter on
|
||||
nested properties, the tool itself should implement this.
|
||||
|
||||
|
||||
## Add labels to images; the `LABEL` instruction
|
||||
|
||||
Adding labels to an image:
|
||||
|
||||
|
||||
LABEL [<namespace>.]<key>[=<value>] ...
|
||||
|
||||
The `LABEL` instruction adds a label to your image, optionally setting its value.
|
||||
Use surrounding quotes or backslashes for labels that contain
|
||||
white space character:
|
||||
|
||||
LABEL vendor=ACME\ Incorporated
|
||||
LABEL com.example.version.is-beta
|
||||
LABEL com.example.version="0.0.1-beta"
|
||||
LABEL com.example.release-date="2015-02-12"
|
||||
|
||||
The `LABEL` instruction supports setting multiple labels in a single instruction
|
||||
using this notation:
|
||||
|
||||
LABEL com.example.version="0.0.1-beta" com.example.release-date="2015-02-12"
|
||||
|
||||
Wrapping is allowed by using a backslash (`\`) as continuation marker:
|
||||
|
||||
LABEL vendor=ACME\ Incorporated \
|
||||
com.example.is-beta \
|
||||
com.example.version="0.0.1-beta" \
|
||||
com.example.release-date="2015-02-12"
|
||||
|
||||
Docker recommends you add multiple labels in a single `LABEL` instruction. Using
|
||||
individual instructions for each label can result in an inefficient image. This
|
||||
is because each `LABEL` instruction in a Dockerfile produces a new IMAGE layer.
|
||||
|
||||
You can view the labels via the `docker inspect` command:
|
||||
|
||||
$ docker inspect 4fa6e0f0c678
|
||||
|
||||
...
|
||||
"Labels": {
|
||||
"vendor": "ACME Incorporated",
|
||||
"com.example.is-beta": "",
|
||||
"com.example.version": "0.0.1-beta",
|
||||
"com.example.release-date": "2015-02-12"
|
||||
}
|
||||
...
|
||||
|
||||
# Inspect labels on container
|
||||
$ docker inspect -f "{{json .Config.Labels }}" 4fa6e0f0c678
|
||||
|
||||
{"Vendor":"ACME Incorporated","com.example.is-beta":"","com.example.version":"0.0.1-beta","com.example.release-date":"2015-02-12"}
|
||||
|
||||
# Inspect labels on images
|
||||
$ docker inspect -f "{{json .ContainerConfig.Labels }}" myimage
|
||||
|
||||
|
||||
## Query labels
|
||||
|
||||
Besides storing metadata, you can filter images and containers by label. To list all
|
||||
running containers that the `com.example.is-beta` label:
|
||||
|
||||
# List all running containers that have a `com.example.is-beta` label
|
||||
$ docker ps --filter "label=com.example.is-beta"
|
||||
|
||||
List all running containers with a `color` label of `blue`:
|
||||
|
||||
$ docker ps --filter "label=color=blue"
|
||||
|
||||
List all images with `vendor` `ACME`:
|
||||
|
||||
$ docker images --filter "label=vendor=ACME"
|
||||
|
||||
|
||||
## Daemon labels
|
||||
|
||||
|
||||
docker -d \
|
||||
--dns 8.8.8.8 \
|
||||
--dns 8.8.4.4 \
|
||||
-H unix:///var/run/docker.sock \
|
||||
--label com.example.environment="production" \
|
||||
--label com.example.storage="ssd"
|
||||
|
||||
These labels appear as part of the `docker info` output for the daemon:
|
||||
|
||||
docker -D info
|
||||
Containers: 12
|
||||
Images: 672
|
||||
Storage Driver: aufs
|
||||
Root Dir: /var/lib/docker/aufs
|
||||
Backing Filesystem: extfs
|
||||
Dirs: 697
|
||||
Execution Driver: native-0.2
|
||||
Logging Driver: json-file
|
||||
Kernel Version: 3.13.0-32-generic
|
||||
Operating System: Ubuntu 14.04.1 LTS
|
||||
CPUs: 1
|
||||
Total Memory: 994.1 MiB
|
||||
Name: docker.example.com
|
||||
ID: RC3P:JTCT:32YS:XYSB:YUBG:VFED:AAJZ:W3YW:76XO:D7NN:TEVU:UCRW
|
||||
Debug mode (server): false
|
||||
Debug mode (client): true
|
||||
File Descriptors: 11
|
||||
Goroutines: 14
|
||||
EventsListeners: 0
|
||||
Init Path: /usr/bin/docker
|
||||
Docker Root Dir: /var/lib/docker
|
||||
WARNING: No swap limit support
|
||||
Labels:
|
||||
com.example.environment=production
|
||||
com.example.storage=ssd
|
||||
@@ -0,0 +1,79 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
draft = true
|
||||
title = "Docker images test"
|
||||
description = "How to work with Docker images."
|
||||
keywords = ["documentation, docs, the docker guide, docker guide, docker, docker platform, virtualization framework, docker.io, Docker images, Docker image, image management, Docker repos, Docker repositories, docker, docker tag, docker tags, Docker Hub, collaboration"]
|
||||
[menu.main]
|
||||
parent = "identifier"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
<a title="back" class="dockerfile back" href="/userguide/dockerimages/#creating-our-own-images">Back</a>
|
||||
|
||||
# Dockerfile tutorial
|
||||
|
||||
## Test your Dockerfile knowledge - Level 1
|
||||
|
||||
### Questions
|
||||
|
||||
<div name="level1_questions">
|
||||
What is the Dockerfile instruction to specify the base image ?<br />
|
||||
<input type="text" class="level" id="level1_q0"/>
|
||||
<div class="alert alert-error level_error" id="level1_error0" style="display:none;">The right answer was <code>FROM</code></div>
|
||||
<br>
|
||||
What is the Dockerfile instruction to execute any commands on the current image and commit the results?<br />
|
||||
<input type="text" class="level" id="level1_q1"/>
|
||||
<div class="alert alert-error level_error" id="level1_error1" style="display:none;">The right answer was <code>RUN</code></div>
|
||||
<br>
|
||||
What is the Dockerfile instruction to specify the maintainer of the Dockerfile?<br />
|
||||
<input type="text" class="level" id="level1_q2"/>
|
||||
<div class="alert alert-error level_error" id="level1_error2" style="display:none;">The right answer was <code>MAINTAINER</code></div>
|
||||
<br>
|
||||
What is the character used to add comment in Dockerfiles?<br />
|
||||
<input type="text" class="level" id="level1_q3"/>
|
||||
<div class="alert alert-error level_error" id="level1_error3" style="display:none;">The right answer was <code>#</code></div>
|
||||
<p>
|
||||
<div class="alert alert-success" id="all_good" style="display:none;">Congratulations, you made no mistake!<br />
|
||||
Tell the world <a href="https://twitter.com/share" class="twitter-share-button" data-url="http://www.docker.io/learn/dockerfile/level1/" data-text="I just successfully answered questions of the #Dockerfile tutorial Level 1. What's your score?" data-via="docker" >Tweet</a><br />
|
||||
And try the next challenge: <a href="#fill-the-dockerfile">Fill the Dockerfile</a>
|
||||
</div>
|
||||
<div class="alert alert-error" id="no_good" style="display:none;">Your Dockerfile skills are not yet perfect, try to take the time to read this tutorial again.</div>
|
||||
<div class="alert alert-block" id="some_good" style="display:none;">You're almost there! Read carefully the sections corresponding to your errors, and take the test again!</div>
|
||||
</p>
|
||||
<button class="btn btn-primary" id="check_level1_questions">Check your answers</button>
|
||||
</div>
|
||||
|
||||
### Fill the Dockerfile
|
||||
Your best friend Eric Bardin sent you a Dockerfile, but some parts were lost in the ocean. Can you find the missing parts?
|
||||
<div class="form-inline">
|
||||
<pre>
|
||||
# This is a Dockerfile to create an image with Memcached and Emacs installed. <br>
|
||||
# VERSION 1.0<br>
|
||||
# use the ubuntu base image provided by dotCloud
|
||||
<input type="text" class="l_fill" id="from" /> ub<input type="text" class="l_fill" id="ubuntu" /><br>
|
||||
<input type="text" class="l_fill" id="maintainer" /> E<input type="text" class="l_fill" id="eric" /> B<input type="text" class="l_fill" id="bardin" />, eric.bardin@dotcloud.com<br>
|
||||
# make sure the package repository is up to date
|
||||
<input type="text" class="l_fill" id="run0"/> echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
|
||||
<input type="text" class="l_fill" id="run1" /> apt-get update<br>
|
||||
# install memcached
|
||||
RUN apt-get install -y <input type="text" class="l_fill" id="memcached" /><br>
|
||||
# install emacs
|
||||
<input type="text" class="l_fill" id="run2"/> apt-get install -y emacs23
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-success" id="dockerfile_ok" style="display:none;">Congratulations, you successfully restored Eric's Dockerfile! You are ready to containerize the world!.<br />
|
||||
Tell the world! <a href="https://twitter.com/share" class="twitter-share-button" data-url="https://www.docker.io/learn/dockerfile/level1/" data-text="I just successfully completed the 'Fill the Dockerfile' challenge of the #Dockerfile tutorial Level 1" data-via="docker" >Tweet</a>
|
||||
</div>
|
||||
<div class="alert alert-error" id="dockerfile_ko" style="display:none;">Wooops, there are one or more errors in the Dockerfile. Try again.</div>
|
||||
<br>
|
||||
<button class="btn btn-primary" id="check_level1_fill">Check the Dockerfile</button></p>
|
||||
|
||||
## What's next?
|
||||
|
||||
<p>In the next level, we will go into more detail about how to specify which command should be executed when the container starts,
|
||||
which user to use, and how expose a particular port.</p>
|
||||
|
||||
<a title="back" class="btn btn-primary back" href="/userguide/dockerimages/#creating-our-own-images">Back</a>
|
||||
<a title="next level" class="btn btn-primary" href="/userguide/level2">Go to the next level</a>
|
||||
@@ -0,0 +1,103 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
draft = true
|
||||
title = "Docker images test"
|
||||
description = "How to work with Docker images."
|
||||
keywords = ["documentation, docs, the docker guide, docker guide, docker, docker platform, virtualization framework, docker.io, Docker images, Docker image, image management, Docker repos, Docker repositories, docker, docker tag, docker tags, Docker Hub, collaboration"]
|
||||
[menu.main]
|
||||
parent = "identifier"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
<a title="back" class="dockerfile back" href="/userguide/dockerimages/#creating-our-own-images">Back</a>
|
||||
|
||||
#Dockerfile tutorial
|
||||
|
||||
## Test your Dockerfile knowledge - Level 2
|
||||
|
||||
### Questions:
|
||||
|
||||
<div class="level_questions">
|
||||
What is the Dockerfile instruction to specify the base image?<br>
|
||||
<input type="text" class="level">
|
||||
<div style="display:none;" id="level2_error0" class="alert alert-error level_error">The right answer was <code>FROM</code></div><br>
|
||||
Which Dockerfile instruction sets the default command for your image?<br>
|
||||
<input type="text" class="level">
|
||||
<div style="display:none;" id="level2_error4" class="alert alert-error level_error">The right answer was <code>ENTRYPOINT</code> or <code>CMD</code></div><br>
|
||||
What is the character used to add comments in Dockerfiles?<br>
|
||||
<input type="text" class="level">
|
||||
<div style="display:none;" id="level2_error3" class="alert alert-error level_error">The right answer was <code>#</code></div><br>
|
||||
Which Dockerfile instruction sets the username to use when running the image?<br>
|
||||
<input type="text" class="level">
|
||||
<div style="display:none;" id="level2_error5" class="alert alert-error level_error">The right answer was <code>USER</code></div><br>
|
||||
What is the Dockerfile instruction to execute any command on the current image and commit the results?<br>
|
||||
<input type="text" class="level">
|
||||
<div style="display:none;" id="level2_error1" class="alert alert-error level_error">The right answer was <code>RUN</code></div><br>
|
||||
Which Dockerfile instruction sets ports to be exposed when running the image?<br>
|
||||
<input type="text" class="level">
|
||||
<div style="display:none;" id="level2_error6" class="alert alert-error level_error">The right answer was <code>EXPOSE</code></div><br>
|
||||
What is the Dockerfile instruction to specify the maintainer of the Dockerfile?<br>
|
||||
<input type="text" class="level">
|
||||
<div style="display:none;" id="level2_error2" class="alert alert-error level_error">The right answer was <code>MAINTAINER</code></div><br>
|
||||
Which Dockerfile instruction lets you trigger a command as soon as the container starts?<br>
|
||||
<input type="text" class="level">
|
||||
<div style="display:none;" id="level2_error7" class="alert alert-error level_error">The right answer was <code>ENTRYPOINT</code> or <code>CMD</code></div><br>
|
||||
<p>
|
||||
|
||||
<div class="alert alert-success" id="all_good" style="display:none;">Congratulations, you made no mistake!<br />
|
||||
Tell the world <a href="https://twitter.com/share" class="twitter-share-button" data-url="http://www.docker.io/learn/dockerfile/level1/" data-text="I just successfully answered questions of the #Dockerfile tutorial Level 1. What's your score?" data-via="docker" >Tweet</a><br />
|
||||
And try the next challenge: <a href="#fill-the-dockerfile">Fill the Dockerfile</a>
|
||||
</div>
|
||||
<div class="alert alert-error" id="no_good" style="display:none;">Your Dockerfile skills are not yet perfect, try to take the time to read this tutorial again.</div>
|
||||
<div class="alert alert-block" id="some_good" style="display:none;">You're almost there! Read carefully the sections corresponding to your errors, and take the test again!</div>
|
||||
</p>
|
||||
<button class="btn btn-primary" id="check_level2_questions">Check your answers</button>
|
||||
</div>
|
||||
|
||||
### Fill the Dockerfile
|
||||
<br>
|
||||
Your best friend Roberto Hashioka sent you a Dockerfile, but some parts were lost in the ocean. Can you find the missing parts?
|
||||
<div class="form-inline">
|
||||
<pre>
|
||||
# Redis
|
||||
#
|
||||
# VERSION 0.42
|
||||
#
|
||||
# use the ubuntu base image provided by dotCloud
|
||||
<input id="from" class="l_fill" type="text"> ub<input id="ubuntu" class="l_fill" type="text"><br>
|
||||
MAINT<input id="maintainer" class="l_fill" type="text"> Ro<input id="roberto" class="l_fill" type="text"> Ha<input id="hashioka" class="l_fill" type="text"> roberto.hashioka@dotcloud.com<br>
|
||||
# make sure the package repository is up to date
|
||||
<input id="run0" class="l_fill" type="text"> echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
|
||||
<input id="run1" class="l_fill" type="text"> apt-get update<br>
|
||||
# install wget (required for redis installation)
|
||||
<input id="run2" class="l_fill" type="text"> apt-get install -y wget<br>
|
||||
# install make (required for redis installation)
|
||||
<input id="run3" class="l_fill" type="text"> apt-get install -y make<br>
|
||||
# install gcc (required for redis installation)
|
||||
RUN apt-get install -y <input id="gcc" class="l_fill" type="text"><br>
|
||||
# install apache2
|
||||
<input id="run4" class="l_fill" type="text"> wget http://download.redis.io/redis-stable.tar.gz
|
||||
<input id="run5" class="l_fill" type="text">tar xvzf redis-stable.tar.gz
|
||||
<input id="run6" class="l_fill" type="text">cd redis-stable && make && make install<br>
|
||||
# launch redis when starting the image
|
||||
<input id="entrypoint" class="l_fill" type="text"> ["redis-server"]<br>
|
||||
# run as user daemon
|
||||
<input id="user" class="l_fill" type="text"> daemon<br>
|
||||
# expose port 6379
|
||||
<input id="expose" class="l_fill" type="text"> 6379
|
||||
</pre>
|
||||
<div class="alert alert-success" id="dockerfile_ok" style="display:none;">Congratulations, you successfully restored Roberto's Dockerfile! You are ready to containerize the world!.<br />
|
||||
Tell the world! <a href="https://twitter.com/share" class="twitter-share-button" data-url="http://www.docker.io/learn/dockerfile/level2/" data-text="I just successfully completed the 'Dockerfill' challenge of the #Dockerfile tutorial Level 2" data-via="docker" >Tweet</a>
|
||||
</div>
|
||||
<div class="alert alert-error" id="dockerfile_ko" style="display:none;">Wooops, there are one or more errors in the Dockerfile. Try again.</div>
|
||||
<br>
|
||||
<button class="btn btn-primary" id="check_level2_fill">Check the Dockerfile</button></p>
|
||||
</div>
|
||||
|
||||
## What's next?
|
||||
<p>
|
||||
Thanks for going through our tutorial! We will be posting Level 3 in the future.
|
||||
|
||||
To improve your Dockerfile writing skills even further, visit the <a href="https://docs.docker.com/articles/dockerfile_best-practices/">Dockerfile best practices page</a>.
|
||||
|
||||
<a title="creating our own images" class="btn btn-primary" href="/userguide/dockerimages/#creating-our-own-images">Back to the Docs!</a>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,310 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Working with containers"
|
||||
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"]
|
||||
[menu.main]
|
||||
parent="smn_containers"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Working with containers
|
||||
|
||||
In the [last section of the Docker User Guide](/userguide/dockerizing)
|
||||
we launched our first containers. We launched two containers using the
|
||||
`docker run` command.
|
||||
|
||||
* Containers we ran interactively in the foreground.
|
||||
* One container we ran daemonized in the background.
|
||||
|
||||
In the process we learned about several Docker commands:
|
||||
|
||||
* `docker ps` - Lists containers.
|
||||
* `docker logs` - Shows us the standard output of a container.
|
||||
* `docker stop` - Stops running containers.
|
||||
|
||||
> **Tip:**
|
||||
> Another way to learn about `docker` commands is our
|
||||
> [interactive tutorial](https://www.docker.com/tryit/).
|
||||
|
||||
The `docker` client is pretty simple. Each action you can take
|
||||
with Docker is a command and each command can take a series of
|
||||
flags and arguments.
|
||||
|
||||
# Usage: [sudo] docker [command] [flags] [arguments] ..
|
||||
# Example:
|
||||
$ docker run -i -t ubuntu /bin/bash
|
||||
|
||||
Let's see this in action by using the `docker version` command to return
|
||||
version information on the currently installed Docker client and daemon.
|
||||
|
||||
$ docker version
|
||||
|
||||
This command will not only provide you the version of Docker client and
|
||||
daemon you are using, but also the version of Go (the programming
|
||||
language powering Docker).
|
||||
|
||||
Client version: 0.8.0
|
||||
Go version (client): go1.2
|
||||
|
||||
Git commit (client): cc3a8c8
|
||||
Server version: 0.8.0
|
||||
|
||||
Git commit (server): cc3a8c8
|
||||
Go version (server): go1.2
|
||||
|
||||
Last stable version: 0.8.0
|
||||
|
||||
## Get Docker command help
|
||||
|
||||
You can display the help for specific Docker commands. The help details the
|
||||
options and their usage. To see a list of all the possible commands, use the
|
||||
following:
|
||||
|
||||
$ docker --help
|
||||
|
||||
To see usage for a specific command, specify the command with the `--help` flag:
|
||||
|
||||
$ docker attach --help
|
||||
|
||||
Usage: docker attach [OPTIONS] CONTAINER
|
||||
|
||||
Attach to a running container
|
||||
|
||||
--help=false Print usage
|
||||
--no-stdin=false Do not attach stdin
|
||||
--sig-proxy=true Proxy all received signals to the process
|
||||
|
||||
> **Note:**
|
||||
> For further details and examples of each command, see the
|
||||
> [command reference](/reference/commandline/cli/) in this guide.
|
||||
|
||||
## Running a web application in Docker
|
||||
|
||||
So now we've learnt a bit more about the `docker` client let's move onto
|
||||
the important stuff: running more containers. So far none of the
|
||||
containers we've run did anything particularly useful though. So let's
|
||||
build on that experience by running an example web application in
|
||||
Docker.
|
||||
|
||||
For our web application we're going to run a Python Flask application.
|
||||
Let's start with a `docker run` command.
|
||||
|
||||
$ docker run -d -P training/webapp python app.py
|
||||
|
||||
Let's review what our command did. We've specified two flags: `-d` and
|
||||
`-P`. We've already seen the `-d` flag which tells Docker to run the
|
||||
container in the background. The `-P` flag is new and tells Docker to
|
||||
map any required network ports inside our container to our host. This
|
||||
lets us view our web application.
|
||||
|
||||
We've specified an image: `training/webapp`. This image is a
|
||||
pre-built image we've created that contains a simple Python Flask web
|
||||
application.
|
||||
|
||||
Lastly, we've specified a command for our container to run: `python app.py`. This launches our web application.
|
||||
|
||||
> **Note:**
|
||||
> You can see more detail on the `docker run` command in the [command
|
||||
> reference](/reference/commandline/cli/#run) and the [Docker Run
|
||||
> Reference](/reference/run/).
|
||||
|
||||
## Viewing our web application container
|
||||
|
||||
Now let's see our running container using the `docker ps` command.
|
||||
|
||||
$ 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 nostalgic_morse
|
||||
|
||||
You can see we've specified a new flag, `-l`, for the `docker ps`
|
||||
command. This tells the `docker ps` command to return 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.
|
||||
|
||||
We can see the same details we saw [when we first Dockerized a
|
||||
container](/userguide/dockerizing) with one important addition in the `PORTS`
|
||||
column.
|
||||
|
||||
PORTS
|
||||
0.0.0.0:49155->5000/tcp
|
||||
|
||||
When we passed the `-P` flag to the `docker run` command Docker mapped any
|
||||
ports exposed in our image to our host.
|
||||
|
||||
> **Note:**
|
||||
> We'll learn more about how to expose ports in Docker images when
|
||||
> [we learn how to build images](/userguide/dockerimages).
|
||||
|
||||
In this case Docker has exposed port 5000 (the default Python Flask
|
||||
port) on port 49155.
|
||||
|
||||
Network port bindings are very configurable in Docker. In our 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. We can also bind Docker containers to
|
||||
specific ports using the `-p` flag, for example:
|
||||
|
||||
$ docker run -d -p 80:5000 training/webapp python app.py
|
||||
|
||||
This would map port 5000 inside our container to port 80 on our 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. Let's say 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 let's now browse to port 49155 in a web browser to
|
||||
see the application.
|
||||
|
||||
.
|
||||
|
||||
Our Python application is live!
|
||||
|
||||
> **Note:**
|
||||
> If you have used the `boot2docker` virtual machine on OS X, Windows or Linux,
|
||||
> you'll need to get the IP of the virtual host instead of using localhost.
|
||||
> You can do this by running the following outside of the `boot2docker` shell
|
||||
> (i.e., from your comment line or terminal application).
|
||||
>
|
||||
> $ boot2docker ip
|
||||
> The VM's Host only interface IP address is: 192.168.59.103
|
||||
>
|
||||
> In this case you'd browse to http://192.168.59.103: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 we can use: `docker port`. To use `docker port` we
|
||||
specify the ID or name of our container and then the port for which we need the
|
||||
corresponding public-facing port.
|
||||
|
||||
$ docker port nostalgic_morse 5000
|
||||
0.0.0.0:49155
|
||||
|
||||
In this case we've looked up what port is mapped externally to port 5000 inside
|
||||
the container.
|
||||
|
||||
## Viewing the web application's logs
|
||||
|
||||
Let's also find out a bit more about what's happening with our application and
|
||||
use another of the commands we've learnt, `docker logs`.
|
||||
|
||||
$ docker logs -f nostalgic_morse
|
||||
* Running on http://0.0.0.0:5000/
|
||||
10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 -
|
||||
10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 -
|
||||
|
||||
This time though we've added a new flag, `-f`. This causes the `docker
|
||||
logs` command to act like the `tail -f` command and watch the
|
||||
container's standard out. We can see here the logs from Flask showing
|
||||
the application running on port 5000 and the access log entries for it.
|
||||
|
||||
## Looking at our web application container's processes
|
||||
|
||||
In addition to the container's logs we can also examine the processes
|
||||
running inside it using the `docker top` command.
|
||||
|
||||
$ docker top nostalgic_morse
|
||||
PID USER COMMAND
|
||||
854 root python app.py
|
||||
|
||||
Here we can see our `python app.py` command is the only process running inside
|
||||
the container.
|
||||
|
||||
## Inspecting our web application container
|
||||
|
||||
Lastly, we can take a low-level dive into our Docker container using the
|
||||
`docker inspect` command. It returns a JSON hash of useful configuration
|
||||
and status information about Docker containers.
|
||||
|
||||
$ docker inspect nostalgic_morse
|
||||
|
||||
Let's see a sample of that JSON output.
|
||||
|
||||
[{
|
||||
"ID": "bc533791f3f500b280a9626688bc79e342e3ea0d528efe3a86a51ecb28ea20",
|
||||
"Created": "2014-05-26T05:52:40.808952951Z",
|
||||
"Path": "python",
|
||||
"Args": [
|
||||
"app.py"
|
||||
],
|
||||
"Config": {
|
||||
"Hostname": "bc533791f3f5",
|
||||
"Domainname": "",
|
||||
"User": "",
|
||||
. . .
|
||||
|
||||
We can also narrow down the information we want to return by requesting a
|
||||
specific element, for example to return the container's IP address we would:
|
||||
|
||||
$ docker inspect -f '{{ .NetworkSettings.IPAddress }}' nostalgic_morse
|
||||
172.17.0.5
|
||||
|
||||
## Stopping our web application container
|
||||
|
||||
Okay we've seen web application working. Now let's stop it using the
|
||||
`docker stop` command and the name of our container: `nostalgic_morse`.
|
||||
|
||||
$ docker stop nostalgic_morse
|
||||
nostalgic_morse
|
||||
|
||||
We can now use the `docker ps` command to check if the container has
|
||||
been stopped.
|
||||
|
||||
$ docker ps -l
|
||||
|
||||
## Restarting our 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. Let's look at
|
||||
starting our previous container back up.
|
||||
|
||||
$ docker start nostalgic_morse
|
||||
nostalgic_morse
|
||||
|
||||
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:**
|
||||
> Also available is the `docker restart` command that runs a stop and
|
||||
> then start on the container.
|
||||
|
||||
## Removing our web application container
|
||||
|
||||
Your colleague has let you know that they've now finished with the container
|
||||
and won't need it again. So let's remove it using the `docker rm` command.
|
||||
|
||||
$ docker rm nostalgic_morse
|
||||
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? We can't actually remove a running container. This protects
|
||||
you from accidentally removing a running container you might need. Let's try
|
||||
this again by stopping the container first.
|
||||
|
||||
$ docker stop nostalgic_morse
|
||||
nostalgic_morse
|
||||
$ docker rm nostalgic_morse
|
||||
nostalgic_morse
|
||||
|
||||
And now our container is stopped and deleted.
|
||||
|
||||
> **Note:**
|
||||
> Always remember that deleting a container is final!
|
||||
|
||||
# Next steps
|
||||
|
||||
Until now we've only used images that we've downloaded from
|
||||
[Docker Hub](https://hub.docker.com) now let's get introduced to
|
||||
building and sharing our own images.
|
||||
|
||||
Go to [Working with Docker Images](/userguide/dockerimages).
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Reference in New Issue
Block a user