Skip to content

Commit

Permalink
Getstarted tweaks (docker#3294)
Browse files Browse the repository at this point in the history
* getting started edits, improvements to flow

Signed-off-by: Victoria Bialas <[email protected]>

* added image of app in browser, more subtopics

Signed-off-by: Victoria Bialas <[email protected]>

* copyedit of Orientation

Signed-off-by: Victoria Bialas <[email protected]>

* copyedits, rewording, examples, additions for swarms and services

Signed-off-by: Victoria Bialas <[email protected]>

* review comments, troubleshooting hints and clarifications

Signed-off-by: Victoria Bialas <[email protected]>

* corrected cloud link to AWS beta swarm topic, added Azure

Signed-off-by: Victoria Bialas <[email protected]>
  • Loading branch information
londoncalling authored Jun 10, 2017
1 parent b58c861 commit 4c05490
Show file tree
Hide file tree
Showing 10 changed files with 471 additions and 299 deletions.
Binary file added get-started/images/app-in-browser-redis.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added get-started/images/app-in-browser.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file added get-started/images/visualizer-with-redis.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 23 additions & 22 deletions get-started/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ An **image** is a lightweight, stand-alone, executable package that includes
everything needed to run a piece of software, including the code, a runtime,
libraries, environment variables, and config files.

A **container** is a runtime instance of an image -- what the image becomes in
memory when actually executed. It runs completely isolated from the host
environment by default, only accessing host files and ports if configured to
do so.
A **container** is a runtime instance of an image&#8212;what the image becomes
in memory when actually executed. It runs completely isolated from the host
environment by default, only accessing host files and ports if configured to do
so.

Containers run apps natively on the host machine's kernel. They have better
performance characteristics than virtual machines that only get virtual access
Expand All @@ -111,21 +111,21 @@ Consider this diagram comparing virtual machines to containers:

![Virtual machine stack example](https://www.docker.com/sites/default/files/VM%402x.png)

Virtual machines run guest operating systems -- note the OS layer in each box.
This is resource intensive, and the resulting disk image and application state is
an entanglement of OS settings, system-installed dependencies, OS security
patches, and other easy-to-lose, hard-to-replicate ephemera.
Virtual machines run guest operating systems&#8212;note the OS layer in each
box. This is resource intensive, and the resulting disk image and application
state is an entanglement of OS settings, system-installed dependencies, OS
security patches, and other easy-to-lose, hard-to-replicate ephemera.

### Container diagram

![Container stack example](https://www.docker.com/sites/default/files/Container%402x.png)

Containers can share a single kernel, and the only information that needs to be
in a container image is the executable and its package dependencies, which
never need to be installed on the host system. These processes run like native
in a container image is the executable and its package dependencies, which never
need to be installed on the host system. These processes run like native
processes, and you can manage them individually by running commands like `docker
ps` -- just like you would run `ps` on Linux to see active processes. Finally,
because they contain all their dependencies, there is no configuration
ps`&#8212;just like you would run `ps` on Linux to see active processes.
Finally, because they contain all their dependencies, there is no configuration
entanglement; a containerized app "runs anywhere."

## Setup
Expand All @@ -135,11 +135,11 @@ installed.

[Install Docker](/engine/installation/index.md){: class="button outline-btn" style="margin-bottom: 30px; margin-right:100%; clear: left;"}
<div style="clear:left"></div>
> **Note** version 1.13 or higher is required
> **Note**: version 1.13 or higher is required
You should be able to run `docker run hello-world` and see a response like this:

```
```shell
$ docker run hello-world

Hello from Docker!
Expand All @@ -149,22 +149,23 @@ To generate this message, Docker took the following steps:
...(snipped)...
```

Now would also be a good time to make sure you are using version 1.13 or higher
Now would also be a good time to make sure you are using version 1.13 or higher. Run `docker --version` to check it out.

```
```shell
$ docker --version
Docker version 17.05.0-ce-rc1, build 2878a85
```

If you see messages like the ones above, you're ready to begin the journey.
If you see messages like the ones above, you are ready to begin your journey.

## Conclusion

The unit of scale being an individual, portable executable has vast
implications. It means that CI/CD can push updates to one part of a distributed
application, system dependencies aren't a thing you worry about, resource
density is increased, and orchestrating scaling behavior is a matter of spinning
up new executables, not new VM hosts. We'll be learning about all of those
things, but first let's learn to walk.
implications. It means CI/CD can push updates to any part of a distributed
application, system dependencies are not an issue, and resource density is
increased. Orchestration of scaling behavior is a matter of spinning up new
executables, not new VM hosts.

We'll be learning about all of these things, but first let's learn to walk.

[On to Part 2 >>](part2.md){: class="button outline-btn" style="margin-bottom: 30px; margin-right: 100%"}
121 changes: 92 additions & 29 deletions get-started/part2.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ description: Learn how to write, build, and run a simple app -- the Docker way.
- Read the orientation in [Part 1](index.md).
- Give your environment a quick test run to make sure you're all set up:

```
```shell
docker run hello-world
```

Expand Down Expand Up @@ -136,10 +136,10 @@ isn't running (as we've only installed the Python library, and not Redis
itself), we should expect that the attempt to use it here will fail and produce
the error message.

> *Note*: Accessing the name of the host when inside a container retrieves the
> **Note**: Accessing the name of the host when inside a container retrieves the
container ID, which is like the process ID for a running executable.

## Build the App
## Build the app

That's it! You don't need Python or anything in `requirements.txt` on your
system, nor will building or running this image install them on your system. It
Expand Down Expand Up @@ -179,10 +179,23 @@ docker run -p 4000:80 friendlyhello
```

You should see a notice that Python is serving your app at `http://0.0.0.0:80`.
But that message coming from inside the container, which doesn't know you mapped
port 80 of that container to 4000, making the correct URL
`http://localhost:4000`. Go there, and you'll see the "Hello World" text, the
container ID, and the Redis error message.
But that message is coming from inside the container, which doesn't know you
mapped port 80 of that container to 4000, making the correct URL
`http://localhost:4000`.

Go to that URL in a web browser to see the display content served up on a
web page, including "Hello World" text, the container ID, and the Redis error
message.

![Hello World in browser](images/app-in-browser.png)

You can also use the `curl` command in a shell to view the same content.

```shell
$ curl http://localhost:4000

<h3>Hello World!</h3><b>Hostname:</b> 8fc990912a14<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>
```

> **Note**: This port remapping of `4000:80` is to demonstrate the difference
between what you `EXPOSE` within the `Dockerfile`, and what you `publish` using
Expand Down Expand Up @@ -218,55 +231,105 @@ docker stop 1fa4ab2cf395

## Share your image

To demonstrate the portability of what we just created, let's upload our build
and run it somewhere else. After all, you'll need to learn how to push to
registries to make deployment of containers actually happen.
To demonstrate the portability of what we just created, let's upload our built
image and run it somewhere else. After all, you'll need to learn how to push to
registries when you want to deploy containers to production.

A registry is a collection of repositories, and a repository is a collection of
images -- sort of like a GitHub repository, except the code is already built. An
account on a registry can create many repositories. The `docker` CLI is
preconfigured to use Docker's public registry by default.
images&#8212;sort of like a GitHub repository, except the code is already
built. An account on a registry can create many repositories. The `docker` CLI uses Docker's public registry by default.

> **Note**: We'll be using Docker's public registry here just because it's free
and pre-configured, but there are many public ones to choose from, and you can
even set up your own private registry using [Docker Trusted
Registry](/datacenter/dtr/2.2/guides/).

If you don't have a Docker account, sign up for one at
[cloud.docker.com](https://cloud.docker.com/). Make note of your username.
### Log in with your Docker ID

If you don't have a Docker account, sign up for one at [cloud.docker.com](https://cloud.docker.com/){: target="_blank" class="_" }. Make note of your username.

Log in your local machine.
Log in to the Docker public registry on your local machine.

```shell
docker login
```

Now, publish your image. The notation for associating a local image with a
repository on a registry, is `username/repository:tag`. The `:tag` is optional,
but recommended; it's the mechanism that registries use to give Docker images a
version. So, putting all that together, enter your username, and repo
and tag names, so your existing image will upload to your desired destination:
### Tag the image

The notation for associating a local image with a repository on a registry is
`username/repository:tag`. The tag is optional, but recommended, since it is
the mechanism that registries use to give Docker images a version. Give the
repository and tag meaningful names for the context, such as
`get-started:part1`. This will put the image in the `get-started` repository and
tag it as `part1`.

Now, put it all together to tag the image. Run `docker tag image` with your
username, repository, and tag names so that the image will upload to your
desired destination. The syntax of the command is:

```shell
docker tag friendlyhello username/repository:tag
docker tag image username/repository:tag
```

Upload your tagged image:
For example:

```shell
docker tag friendlyhello john/get-started:part1
```

Run [docker images](/engine/reference/commandline/images/) to see your newly tagged image. (You can also use `docker image ls`.)

```shell
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
friendlyhello latest d9e555c53008 3 minutes ago 195MB
john/get-started part1 d9e555c53008 3 minutes ago 195MB
python 2.7-slim 1c7128a655f6 5 days ago 183MB
...
```

### Publish the image

Upload your tagged image to the repository:

```shell
docker push username/repository:tag
```

Once complete, the results of this upload are publicly available. From now on,
you can use `docker run` and run your app on any machine with this command:
Once complete, the results of this upload are publicly available. If you log in
to [Docker Hub](https://hub.docker.com/), you will see the new image there, with
its pull command.

### Pull and run the image from the remote repository

From now on, you can use `docker run` and run your app on any machine with this
command:

```shell
docker run -p 4000:80 username/repository:tag
```

> Note: If you don't specify the `:tag` portion of these commands,
If the image isn't available locally on the machine, Docker will pull it from the repository.

```shell
$ docker run -p 4000:80 john/get-started:part1
Unable to find image 'john/get-started:part1' locally
part1: Pulling from orangesnap/get-started
10a267c67f42: Already exists
f68a39a6a5e4: Already exists
9beaffc0cf19: Already exists
3c1fe835fb6b: Already exists
4c9f1fa8fcb8: Already exists
ee7d8f576a14: Already exists
fbccdcced46e: Already exists
Digest: sha256:0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068
Status: Downloaded newer image for john/get-started:part1
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
```

> **Note**: If you don't specify the `:tag` portion of these commands,
the tag of `:latest` will be assumed, both when you build and when you run
images.
images. Docker will use the last version of the image that ran without a tag specified (not necessarily the most recent image).

No matter where `docker run` executes, it pulls your image, along with Python
and all the dependencies from `requirements.txt`, and runs your code. It all
Expand All @@ -287,8 +350,8 @@ Here's [a terminal recording of what was covered on this page](https://asciinema

<script type="text/javascript" src="https://asciinema.org/a/blkah0l4ds33tbe06y4vkme6g.js" id="asciicast-blkah0l4ds33tbe06y4vkme6g" speed="2" async></script>

Here is a list of the basic commands from this page, and some related ones if
you'd like to explore a bit before moving on.
Here is a list of the basic Docker commands from this page, and some related
ones if you'd like to explore a bit before moving on.

```shell
docker build -t friendlyname . # Create image using this directory's Dockerfile
Expand Down
Loading

0 comments on commit 4c05490

Please sign in to comment.