mirror of https://github.com/docker/docs.git
Getstarted tweaks (#3294)
* getting started edits, improvements to flow Signed-off-by: Victoria Bialas <victoria.bialas@docker.com> * added image of app in browser, more subtopics Signed-off-by: Victoria Bialas <victoria.bialas@docker.com> * copyedit of Orientation Signed-off-by: Victoria Bialas <victoria.bialas@docker.com> * copyedits, rewording, examples, additions for swarms and services Signed-off-by: Victoria Bialas <victoria.bialas@docker.com> * review comments, troubleshooting hints and clarifications Signed-off-by: Victoria Bialas <victoria.bialas@docker.com> * corrected cloud link to AWS beta swarm topic, added Azure Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
This commit is contained in:
parent
b58c86179e
commit
4c05490bab
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 196 KiB |
Binary file not shown.
After Width: | Height: | Size: 212 KiB |
|
@ -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—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
|
||||
|
@ -111,21 +111,21 @@ Consider this diagram comparing virtual machines to containers:
|
|||
|
||||

|
||||
|
||||
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—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
|
||||
|
||||

|
||||
|
||||
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`—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
|
||||
|
@ -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!
|
||||
|
@ -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%"}
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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
|
||||
|
@ -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—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
|
||||
|
||||
Log in your local machine.
|
||||
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 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
|
||||
|
@ -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
|
||||
|
|
|
@ -1,22 +1,29 @@
|
|||
---
|
||||
title: "Get Started, Part 3: Services"
|
||||
keywords: services, replicas, scale, ports, compose, compose file, stack, networking
|
||||
description: Learn how to define load-balanced and scalable service that runs containers.
|
||||
description: Learn how to define load-balanced and scalable service that runs containers.
|
||||
---
|
||||
{% include_relative nav.html selected="3" %}
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Install Docker version 1.13 or higher](/engine/installation/).
|
||||
- [Install Docker version 1.13 or higher](/engine/installation/index.md).
|
||||
|
||||
- Get [Docker Compose](/compose/overview.md). On [Docker for Mac](/docker-for-mac/index.md) and [Docker for
|
||||
Windows](/docker-for-windows/index.md) it's pre-installed so you are good-to-go,
|
||||
but on Linux systems you will need to [install it
|
||||
directly](https://github.com/docker/compose/releases). On pre Windows 10 systems
|
||||
_without Hyper-V_, use [Docker
|
||||
Toolbox](https://docs.docker.com/toolbox/overview.md).
|
||||
|
||||
- Read the orientation in [Part 1](index.md).
|
||||
- Learn how to create containers in [Part 2](part2.md).
|
||||
- Make sure you have pushed the container you created to a registry, as
|
||||
instructed; we'll be using it here.
|
||||
- Ensure your image is working by
|
||||
running this and visiting `http://localhost/` (slotting in your info for
|
||||
`username`, `repo`, and `tag`):
|
||||
- Make sure you have published the `friendlyhello` image you created by
|
||||
[pushing it to a registry](/get-started/part2.md#share-your-image). We will be using that shared image here.
|
||||
- Be sure your image works as a deployed container by running this command, and visting `http://localhost/` (slotting in your info for `username`,
|
||||
`repo`, and `tag`):
|
||||
|
||||
```
|
||||
```shell
|
||||
docker run -p 80:80 username/repo:tag
|
||||
```
|
||||
|
||||
|
@ -32,15 +39,15 @@ must go one level up in the hierarchy of a distributed application: the
|
|||
|
||||
## Understanding services
|
||||
|
||||
In a distributed application, different pieces of the app are called
|
||||
"services." For example, if you imagine a video sharing site, there will
|
||||
probably be a service for storing application data in a database, a service
|
||||
for video transcoding in the background after a user uploads something, a
|
||||
service for the front-end, and so on.
|
||||
In a distributed application, different pieces of the app are called "services."
|
||||
For example, if you imagine a video sharing site, it probably includes a service
|
||||
for storing application data in a database, a service for video transcoding in
|
||||
the background after a user uploads something, a service for the front-end, and
|
||||
so on.
|
||||
|
||||
A service really just means, "containers in production." A service only runs one
|
||||
image, but it codifies the way that image runs -- what ports it should use, how
|
||||
many replicas of the container should run so the service has the capacity it
|
||||
Services are really just "containers in production." A service only runs one
|
||||
image, but it codifies the way that image runs&8212;what ports it should use,
|
||||
how many replicas of the container should run so the service has the capacity it
|
||||
needs, and so on. Scaling a service changes the number of container instances
|
||||
running that piece of software, assigning more computing resources to the
|
||||
service in the process.
|
||||
|
@ -56,13 +63,15 @@ should behave in production.
|
|||
### `docker-compose.yml`
|
||||
|
||||
Save this file as `docker-compose.yml` wherever you want. Be sure you have
|
||||
pushed the image you created in [Part 2](part2.md) to a registry, and use
|
||||
that info to replace `username/repo:tag`:
|
||||
[pushed the image](/get-started/part2.md#share-your-image) you created in [Part
|
||||
2](part2.md) to a registry, and update this `.yml` by replacing
|
||||
`username/repo:tag` with your image details.
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
web:
|
||||
# replace username/repo:tag with your name and image details
|
||||
image: username/repository:tag
|
||||
deploy:
|
||||
replicas: 5
|
||||
|
@ -82,7 +91,8 @@ networks:
|
|||
|
||||
This `docker-compose.yml` file tells Docker to do the following:
|
||||
|
||||
- Run five instances of [the image we uploaded in step 2](part2.md) as a service
|
||||
- Pull [the image we uploaded in step 2](part2.md) from the registry.
|
||||
- Run five instances of that image as a service
|
||||
called `web`, limiting each one to use, at most, 10% of the CPU (across all
|
||||
cores), and 50MB of RAM.
|
||||
- Immediately restart containers if one fails.
|
||||
|
@ -95,9 +105,9 @@ This `docker-compose.yml` file tells Docker to do the following:
|
|||
|
||||
## Run your new load-balanced app
|
||||
|
||||
Before we can use the `docker stack deploy` command we'll first run
|
||||
Before we can use the `docker stack deploy` command we'll first run
|
||||
|
||||
```
|
||||
```shell
|
||||
docker swarm init
|
||||
```
|
||||
|
||||
|
@ -107,13 +117,13 @@ docker swarm init
|
|||
Now let's run it. You have to give your app a name -- here it is set to
|
||||
`getstartedlab` :
|
||||
|
||||
```
|
||||
```shell
|
||||
docker stack deploy -c docker-compose.yml getstartedlab
|
||||
```
|
||||
|
||||
See a list of the five containers you just launched:
|
||||
|
||||
```
|
||||
```shell
|
||||
docker stack ps getstartedlab
|
||||
```
|
||||
|
||||
|
@ -132,29 +142,35 @@ the five replicas is chosen, in a round-robin fashion, to respond.
|
|||
You can scale the app by changing the `replicas` value in `docker-compose.yml`,
|
||||
saving the change, and re-running the `docker stack deploy` command:
|
||||
|
||||
```
|
||||
```shell
|
||||
docker stack deploy -c docker-compose.yml getstartedlab
|
||||
```
|
||||
|
||||
Docker will do an in-place update, no need to tear the stack down first or kill
|
||||
any containers.
|
||||
|
||||
### Take down the app
|
||||
Now, re-run the `docker stack ps` command to see the deployed instances reconfigured. For example, if you scaled up the replicas, there will be more
|
||||
running containers.
|
||||
|
||||
### Take down the app and the swarm
|
||||
|
||||
Take the app down with `docker stack rm`:
|
||||
|
||||
```
|
||||
```shell
|
||||
docker stack rm getstartedlab
|
||||
```
|
||||
|
||||
It's as easy as that to stand up and scale your app with Docker. You've taken
|
||||
a huge step towards learning how to run containers in production. Up next,
|
||||
you will learn how to run this app on a cluster of machines.
|
||||
This removes the app, but our one-node swarm is still up and running (as shown
|
||||
by `docker node ls`). Take down the swarm with `docker swarm leave --force`.
|
||||
|
||||
> Note: Compose files like this are used to define applications with Docker, and
|
||||
can be uploaded to cloud providers using [Docker Cloud](/docker-cloud/), or on
|
||||
any hardware or cloud provider you choose with [Docker Enterprise
|
||||
Edition](https://www.docker.com/enterprise-edition).
|
||||
It's as easy as that to stand up and scale your app with Docker. You've taken a
|
||||
huge step towards learning how to run containers in production. Up next, you
|
||||
will learn how to run this app as a bonafide swarm on a cluster of Docker
|
||||
machines.
|
||||
|
||||
> **Note**: Compose files like this are used to define applications with Docker, and can be uploaded to cloud providers using [Docker
|
||||
Cloud](/docker-cloud/), or on any hardware or cloud provider you choose with
|
||||
[Docker Enterprise Edition](https://www.docker.com/enterprise-edition).
|
||||
|
||||
[On to "Part 4" >>](part4.md){: class="button outline-btn" style="margin-bottom: 30px"}
|
||||
|
||||
|
|
|
@ -7,17 +7,24 @@ description: Learn how to create clusters of Dockerized machines.
|
|||
|
||||
## Prerequisites
|
||||
|
||||
- [Install Docker version 1.13 or higher](/engine/installation/).
|
||||
- Unless you're on a Windows system that has Hyper-V, such as Windows 10, [install VirtualBox](https://www.virtualbox.org/wiki/Downloads) for your host
|
||||
- [Install Docker version 1.13 or higher](/engine/installation/index.md).
|
||||
|
||||
- Get [Docker Compose](/compose/overview.md) as described in [Part 3 prerequisites](/get-started/part3.md#prerequisites).
|
||||
|
||||
- Get [Docker Machine](/machine/overview.md), which is pre-installed with
|
||||
[Docker for Mac](/docker-for-mac/index.md) and [Docker for
|
||||
Windows](/docker-for-windows/index.md), but on Linux systems you need to
|
||||
[install it directly](/machine/install-machine/#installing-machine-directly). On pre Windows 10 systems _without Hyper-V_, use [Docker
|
||||
Toolbox](https://docs.docker.com/toolbox/overview.md).
|
||||
|
||||
- Read the orientation in [Part 1](index.md).
|
||||
- Learn how to create containers in [Part 2](part2.md).
|
||||
- Make sure you have pushed the container you created to a registry, as
|
||||
instructed; we'll be using it here.
|
||||
- Ensure your image is working by
|
||||
running this and visiting `http://localhost/` (slotting in your info for
|
||||
`username`, `repo`, and `tag`):
|
||||
- Make sure you have published the `friendlyhello` image you created by
|
||||
[pushing it to a registry](/get-started/part2.md#share-your-image). We will be using that shared image here.
|
||||
- Be sure your image works as a deployed container by running this command, and visting `http://localhost/` (slotting in your info for `username`,
|
||||
`repo`, and `tag`):
|
||||
|
||||
```
|
||||
```shell
|
||||
docker run -p 80:80 username/repo:tag
|
||||
```
|
||||
- Have a copy of your `docker-compose.yml` from [Part 3](part3.md) handy.
|
||||
|
@ -34,7 +41,7 @@ by joining multiple machines into a "Dockerized" cluster called a **swarm**.
|
|||
|
||||
## Understanding Swarm clusters
|
||||
|
||||
A swarm is a group of machines that are running Docker and have been joined into
|
||||
A swarm is a group of machines that are running Docker and joined into
|
||||
a cluster. After that has happened, you continue to run the Docker commands
|
||||
you're used to, but now they are executed on a cluster by a **swarm manager**.
|
||||
The machines in a swarm can be physical or virtual. After joining a swarm, they
|
||||
|
@ -49,24 +56,24 @@ file, just like the one you have already been using.
|
|||
Swarm managers are the only machines in a swarm that can execute your commands,
|
||||
or authorize other machines to join the swarm as **workers**. Workers are just
|
||||
there to provide capacity and do not have the authority to tell any other
|
||||
machine what it can and can't do.
|
||||
machine what it can and cannot do.
|
||||
|
||||
Up until now you have been using Docker in a single-host mode on your local
|
||||
Up until now, you have been using Docker in a single-host mode on your local
|
||||
machine. But Docker also can be switched into **swarm mode**, and that's what
|
||||
enables the use of swarms. Enabling swarm mode instantly makes the current
|
||||
machine a swarm manager. From then on, Docker will run the commands you execute
|
||||
on the swarm you're managing, rather than just on the current machine.
|
||||
|
||||
{% capture local-instructions %}
|
||||
You now have two VMs created, named `myvm1` and `myvm2`. The first one will act
|
||||
as the manager, which executes `docker` commands and authenticates workers to
|
||||
join the swarm, and the second will be a worker.
|
||||
You now have two VMs created, named `myvm1` and `myvm2` (as `docker machine ls`
|
||||
shows). The first one will act as the manager, which executes `docker` commands
|
||||
and authenticates workers to join the swarm, and the second will be a worker.
|
||||
|
||||
You can send commands to your VMs using `docker-machine ssh`. Instruct `myvm1`
|
||||
to become a swarm manager with `docker swarm init` and you'll see output like
|
||||
this:
|
||||
|
||||
```
|
||||
```shell
|
||||
$ docker-machine ssh myvm1 "docker swarm init"
|
||||
Swarm initialized: current node <node ID> is now a manager.
|
||||
|
||||
|
@ -77,7 +84,7 @@ To add a worker to this swarm, run the following command:
|
|||
<ip>:<port>
|
||||
```
|
||||
|
||||
> Getting an error about needing to use `--advertise-addr`?
|
||||
> Got an error about needing to use `--advertise-addr`?
|
||||
>
|
||||
> Copy the
|
||||
> IP address for `myvm1` by running `docker-machine ls`, then run the
|
||||
|
@ -87,13 +94,14 @@ To add a worker to this swarm, run the following command:
|
|||
> ```
|
||||
> docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100:2377"
|
||||
> ```
|
||||
{: .note-vanilla}
|
||||
|
||||
As you can see, the response to `docker swarm init` contains a pre-configured
|
||||
`docker swarm join` command for you to run on any nodes you want to add. Copy
|
||||
this command, and send it to `myvm2` via `docker-machine ssh` to have `myvm2`
|
||||
join your new swarm as a worker:
|
||||
|
||||
```
|
||||
```shell
|
||||
$ docker-machine ssh myvm2 "docker swarm join \
|
||||
--token <token> \
|
||||
<ip>:<port>"
|
||||
|
@ -108,6 +116,24 @@ to open a terminal session on that VM. Type `exit` when you're ready to return
|
|||
to the host shell prompt. It may be easier to paste the join command in that
|
||||
way.
|
||||
|
||||
Use `ssh` to connect to the (`docker-machine ssh myvm1`), and run `docker node ls` to view the nodes in this swarm:
|
||||
|
||||
```shell
|
||||
docker@myvm1:~$ docker node ls
|
||||
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
|
||||
brtu9urxwfd5j0zrmkubhpkbd myvm2 Ready Active
|
||||
rihwohkh3ph38fhillhhb84sk * myvm1 Ready Active Leader
|
||||
```
|
||||
|
||||
Type `exit` to get back out of that machine.
|
||||
|
||||
Alternatively, wrap commands in `docker-machine ssh` to keep from having to directly log in and out. For example:
|
||||
|
||||
```shell
|
||||
docker-machine ssh myvm1 "docker node ls"
|
||||
```
|
||||
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
{% capture local %}
|
||||
|
@ -146,7 +172,7 @@ able to connect to each other.
|
|||
Now, create a couple of virtual machines using our node management tool,
|
||||
`docker-machine`:
|
||||
|
||||
```none
|
||||
```shell
|
||||
$ docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1
|
||||
$ docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm2
|
||||
```
|
||||
|
@ -159,7 +185,7 @@ $ docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm2
|
|||
A swarm is made up of multiple nodes, which can be either physical or virtual
|
||||
machines. The basic concept is simple enough: run `docker swarm init` to enable
|
||||
swarm mode and make your current machine a swarm manager, then run
|
||||
`docker swarm join` on other machines to have them join the swarm as a worker.
|
||||
`docker swarm join` on other machines to have them join the swarm as workers.
|
||||
Choose a tab below to see how this plays out in various contexts. We'll use VMs
|
||||
to quickly create a two-machine cluster and turn it into a swarm.
|
||||
|
||||
|
@ -229,27 +255,51 @@ look:
|
|||
|
||||

|
||||
|
||||
> **Note**: If you're having any connectivity trouble, keep in mind that in
|
||||
> order to use the ingress network in the swarm, you need to have
|
||||
> the following ports open between the swarm nodes before you enable swarm mode:
|
||||
> Having connectivity trouble?
|
||||
>
|
||||
> Keep in mind that in order to use the ingress network in the swarm,
|
||||
> you need to have the following ports open between the swarm nodes
|
||||
> before you enable swarm mode:
|
||||
>
|
||||
> - Port 7946 TCP/UDP for container network discovery.
|
||||
> - Port 4789 UDP for the container ingress network.
|
||||
{: .note-vanilla}
|
||||
|
||||
## Iterating and scaling your app
|
||||
|
||||
From here you can do everything you learned about in part 3: scale the app by
|
||||
changing the `docker-compose.yml` file, or change the app behavior by editing
|
||||
code. In either case, simply running `docker stack deploy` again deploys these
|
||||
changes. You can tear down the stack with `docker stack rm`. You can also join
|
||||
any machine, physical or virtual, to this swarm, using the same
|
||||
`docker swarm join` command you used on `myvm2`, and capacity will be added to
|
||||
your cluster; just run `docker stack deploy` afterwards and your app will take
|
||||
advantage of the new resources.
|
||||
From here you can do everything you learned about in part 3.
|
||||
|
||||
Scale the app by changing the `docker-compose.yml` file.
|
||||
|
||||
Change the app behavior by editing code.
|
||||
|
||||
In either case, simply run `docker stack deploy` again to deploy these
|
||||
changes.
|
||||
|
||||
You can join any machine, physical or virtual, to this swarm, using the
|
||||
same `docker swarm join` command you used on `myvm2`, and capacity will be added
|
||||
to your cluster. Just run `docker stack deploy` afterwards, and your app will
|
||||
take advantage of the new resources.
|
||||
|
||||
## Cleanup
|
||||
|
||||
You can tear down the stack with `docker stack rm`. For example:
|
||||
|
||||
```
|
||||
docker-machine ssh myvm1 "docker stack rm getstartedlab"
|
||||
```
|
||||
|
||||
> Keep the swarm or remove it?
|
||||
>
|
||||
> At some point later, you can remove this swarm if you want to with
|
||||
> `docker-machine ssh myvm2 "docker swarm leave"` on the worker
|
||||
> and `docker-machine ssh myvm1 "docker swarm leave --force"` on the
|
||||
> manager, but _you'll need this swarm for part 5, so please keep it
|
||||
> around for now_.
|
||||
{: .note-vanilla}
|
||||
|
||||
[On to Part 5 >>](part5.md){: class="button outline-btn" style="margin-bottom: 30px"}
|
||||
|
||||
|
||||
## Recap and cheat sheet (optional)
|
||||
|
||||
Here's [a terminal recording of what was covered on this page](https://asciinema.org/a/113837):
|
||||
|
|
|
@ -9,19 +9,31 @@ description: Learn how to create a multi-container application that uses all the
|
|||
## Prerequisites
|
||||
|
||||
- [Install Docker version 1.13 or higher](/engine/installation/).
|
||||
- Get [Docker Compose](/compose/overview.md) as described in [Part 3 prerequisites](/get-started/part3.md#prerequisites).
|
||||
- Get [Docker Machine](/machine/overview.md) as described in [Part 4 prerequisites](/get-started/part4.md#prerequisites).
|
||||
- Read the orientation in [Part 1](index.md).
|
||||
- Learn how to create containers in [Part 2](part2.md).
|
||||
- Make sure you have pushed the container you created to a registry, as
|
||||
instructed; we'll be using it here.
|
||||
- Ensure your image is working by
|
||||
running this and visiting `http://localhost/` (slotting in your info for
|
||||
`username`, `repo`, and `tag`):
|
||||
|
||||
```
|
||||
- Be sure your image works as a deployed container by running this command, and visting `http://localhost/` (slotting in your info for `username`,
|
||||
`repo`, and `tag`):
|
||||
|
||||
```shell
|
||||
docker run -p 80:80 username/repo:tag
|
||||
```
|
||||
- Have a copy of your `docker-compose.yml` from [Part 3](part3.md) handy.
|
||||
- Have the swarm you created in [part 4](part4.md) running and ready.
|
||||
|
||||
- Make sure that the machines you set up in [part 4](part4.md) are running
|
||||
and ready. Run `docker-machine ls` to verify this. If the machines are
|
||||
stopped, run `docker-machine start myvm1` to boot the manager, followed
|
||||
by `docker-machine start myvm2` to boot the worker.
|
||||
|
||||
- Have the swarm you created in [part 4](part4.md) running and ready. Run
|
||||
`docker-machine ssh myvm1 "docker node ls"` to verify this. If the swarm is up,
|
||||
both nodes will report a `ready` status. If not, reinitialze the swarm and join
|
||||
the worker as described in [Set up your
|
||||
swarm](/get-started/part4.md#set-up-your-swarm).
|
||||
|
||||
## Introduction
|
||||
|
||||
|
@ -38,182 +50,208 @@ application (though very complex applications may want to use multiple stacks).
|
|||
Some good news is, you have technically been working with stacks since part 3,
|
||||
when you created a Compose file and used `docker stack deploy`. But that was a
|
||||
single service stack running on a single host, which is not usually what takes
|
||||
place in production. Here, you're going to take what you've learned and make
|
||||
place in production. Here, you will take what you've learned, make
|
||||
multiple services relate to each other, and run them on multiple machines.
|
||||
|
||||
This is the home stretch, so congratulate yourself!
|
||||
You're doing great, this is the home stretch!
|
||||
|
||||
## Adding a new service and redeploying.
|
||||
## Add a new service and redeploy
|
||||
|
||||
It's easy to add services to our `docker-compose.yml` file. First, let's add
|
||||
a free visualizer service that lets us look at how our swarm is scheduling
|
||||
containers. Open up `docker-compose.yml` in an editor and replace its contents
|
||||
with the following:
|
||||
containers.
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
web:
|
||||
image: username/repo:tag
|
||||
deploy:
|
||||
replicas: 5
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
resources:
|
||||
limits:
|
||||
cpus: "0.1"
|
||||
memory: 50M
|
||||
ports:
|
||||
- "80:80"
|
||||
1. Open up `docker-compose.yml` in an editor and replace its contents
|
||||
with the following. Be sure to replace `username/repo:tag` with your image details.
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
web:
|
||||
# replace username/repo:tag with your name and image details
|
||||
image: username/repo:tag
|
||||
deploy:
|
||||
replicas: 5
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
resources:
|
||||
limits:
|
||||
cpus: "0.1"
|
||||
memory: 50M
|
||||
ports:
|
||||
- "80:80"
|
||||
networks:
|
||||
- webnet
|
||||
visualizer:
|
||||
image: dockersamples/visualizer:stable
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
deploy:
|
||||
placement:
|
||||
constraints: [node.role == manager]
|
||||
networks:
|
||||
- webnet
|
||||
networks:
|
||||
- webnet
|
||||
visualizer:
|
||||
image: dockersamples/visualizer:stable
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
deploy:
|
||||
placement:
|
||||
constraints: [node.role == manager]
|
||||
webnet:
|
||||
```
|
||||
|
||||
The only thing new here is the peer service to `web`, named `visualizer`.
|
||||
You'll see two new things here: a `volumes` key, giving the visualizer
|
||||
access to the host's socket file for Docker, and a `placement` key, ensuring
|
||||
that this service only ever runs on a swarm manager -- never a worker.
|
||||
That's because this container, built from [an open source project created by
|
||||
Docker](https://github.com/ManoMarks/docker-swarm-visualizer), displays
|
||||
Docker services running on a swarm in a diagram.
|
||||
|
||||
We'll talk more about placement constraints and volumes in a moment.
|
||||
|
||||
2. Copy this new `docker-compose.yml` file to the swarm manager, `myvm1`:
|
||||
|
||||
```shell
|
||||
docker-machine scp docker-compose.yml myvm1:~
|
||||
```
|
||||
|
||||
3. Re-run the `docker stack deploy` command on the manager, and
|
||||
whatever services need updating will be updated:
|
||||
|
||||
```shell
|
||||
$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"
|
||||
Updating service getstartedlab_web (id: angi1bf5e4to03qu9f93trnxm)
|
||||
Updating service getstartedlab_visualizer (id: l9mnwkeq2jiononb5ihz9u7a4)
|
||||
```
|
||||
|
||||
4. Take a look at the visualizer.
|
||||
|
||||
You saw in the Compose file that `visualizer` runs on port 8080. Get the
|
||||
IP address of one of your nodes by running `docker-machine ls`. Go
|
||||
to either IP address at port 8080 and you will see the visualizer running:
|
||||
|
||||

|
||||
|
||||
The single copy of `visualizer` is running on the manager as you expect, and
|
||||
the five instances of `web` are spread out across the swarm. You can
|
||||
corroborate this visualization by running `docker stack ps <stack>`:
|
||||
|
||||
```shell
|
||||
docker-machine ssh myvm1 "docker stack ps getstartedlab"
|
||||
```
|
||||
|
||||
The visualizer is a standalone service that can run in any app
|
||||
that includes it in the stack. It doesn't depend on anything else.
|
||||
Now let's create a service that *does* have a dependency: the Redis
|
||||
service that will provide a visitor counter.
|
||||
|
||||
## Persist the data
|
||||
|
||||
Let's go through the same workflow once more to add a Redis database for storing
|
||||
app data.
|
||||
|
||||
1. Save this new `docker-compose.yml` file, which finally adds a
|
||||
Redis service. Be sure to replace `username/repo:tag` with your image details.
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
web:
|
||||
# replace username/repo:tag with your name and image details
|
||||
image: username/repo:tag
|
||||
deploy:
|
||||
replicas: 5
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
resources:
|
||||
limits:
|
||||
cpus: "0.1"
|
||||
memory: 50M
|
||||
ports:
|
||||
- "80:80"
|
||||
networks:
|
||||
- webnet
|
||||
visualizer:
|
||||
image: dockersamples/visualizer:stable
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
deploy:
|
||||
placement:
|
||||
constraints: [node.role == manager]
|
||||
networks:
|
||||
- webnet
|
||||
redis:
|
||||
image: redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- ./data:/data
|
||||
deploy:
|
||||
placement:
|
||||
constraints: [node.role == manager]
|
||||
networks:
|
||||
- webnet
|
||||
networks:
|
||||
- webnet
|
||||
networks:
|
||||
webnet:
|
||||
```
|
||||
webnet:
|
||||
```
|
||||
|
||||
The only thing new here is the peer service to `web`, named `visualizer`. You'll
|
||||
see two new things here: a `volumes` key, giving the visualizer access to the
|
||||
host's socket file for Docker, and a `placement` key, ensuring that this service
|
||||
only ever runs on a swarm manager -- never a worker. That's because this
|
||||
container, built from [an open source project created by
|
||||
Docker](https://github.com/ManoMarks/docker-swarm-visualizer), displays Docker
|
||||
services running on a swarm in a diagram.
|
||||
Redis has an official image in the Docker library and has been granted the
|
||||
short `image` name of just `redis`, so no `username/repo` notation here. The
|
||||
Redis port, 6379, has been pre-configured by Redis to be exposed from the
|
||||
container to the host, and here in our Compose file we expose it from the
|
||||
host to the world, so you can actually enter the IP for any of your nodes
|
||||
into Redis Desktop Manager and manage this Redis instance, if you so choose.
|
||||
|
||||
We'll talk more about placement constraints and volumes in a moment. But for
|
||||
now, copy this new `docker-compose.yml` file to the swarm manager, `myvm1`:
|
||||
Most importantly, there are a couple of things in the `redis` specification
|
||||
that make data persist between deployments of this stack:
|
||||
|
||||
```
|
||||
docker-machine scp docker-compose.yml myvm1:~
|
||||
```
|
||||
- `redis` always runs on the manager, so it's always using the
|
||||
same filesystem.
|
||||
- `redis` accesses an arbitrary directory in the host's file system
|
||||
as `/data` inside the container, which is where Redis stores data.
|
||||
|
||||
Now just re-run the `docker stack deploy` command on the manager, and whatever
|
||||
services need updating will be updated:
|
||||
Together, this is creating a "source of truth" in your host's physical
|
||||
filesystem for the Redis data. Without this, Redis would store its data in
|
||||
`/data` inside the container's filesystem, which would get wiped out if that
|
||||
container were ever redeployed.
|
||||
|
||||
```
|
||||
$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"
|
||||
Updating service getstartedlab_web (id: angi1bf5e4to03qu9f93trnxm)
|
||||
Updating service getstartedlab_visualizer (id: l9mnwkeq2jiononb5ihz9u7a4)
|
||||
```
|
||||
This source of truth has two components:
|
||||
|
||||
You saw in the Compose file that `visualizer` runs on port 8080. Get the IP
|
||||
address of the one of your nodes by running `docker-machine ls`. Go to either IP
|
||||
address @ port 8080 and you will see the visualizer running:
|
||||
- The placement constraint you put on the Redis service, ensuring that it
|
||||
always uses the same host.
|
||||
- The volume you created that lets the container access `./data` (on the host)
|
||||
as `/data` (inside the Redis container). While containers come and go, the
|
||||
files stored on `./data` on the specified host will persist, enabling
|
||||
continuity.
|
||||
|
||||

|
||||
You are ready to deploy your new Redis-using stack.
|
||||
|
||||
The single copy of `visualizer` is running on the manager as you expect, and the
|
||||
five instances of `web` are spread out across the swarm. You can corroborate
|
||||
this visualization by running `docker stack ps <stack>`:
|
||||
2. Create a `./data` directory on the manager:
|
||||
|
||||
```
|
||||
docker-machine ssh myvm1 "docker stack ps getstartedlab"
|
||||
```
|
||||
```shell
|
||||
$ docker-machine ssh myvm1 "mkdir ./data"
|
||||
```
|
||||
|
||||
The visualizer is a standalone service that can run in any app that includes it
|
||||
in the stack. It doesn't depend on anything else. Now let's create a service
|
||||
that *does* have a dependency: the Redis service that will provide a visitor
|
||||
counter.
|
||||
3. Copy over the new `docker-compose.yml` file with `docker-machine scp`:
|
||||
|
||||
```shell
|
||||
$ docker-machine scp docker-compose.yml myvm1:~
|
||||
```
|
||||
|
||||
## Persisting data
|
||||
4. Run `docker stack deploy` one more time.
|
||||
|
||||
Go through the same workflow once more. Save this new `docker-compose.yml` file,
|
||||
which finally adds a Redis service.
|
||||
```shell
|
||||
$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"
|
||||
```
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
web:
|
||||
image: username/repo:tag
|
||||
deploy:
|
||||
replicas: 5
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
resources:
|
||||
limits:
|
||||
cpus: "0.1"
|
||||
memory: 50M
|
||||
ports:
|
||||
- "80:80"
|
||||
networks:
|
||||
- webnet
|
||||
visualizer:
|
||||
image: dockersamples/visualizer:stable
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
deploy:
|
||||
placement:
|
||||
constraints: [node.role == manager]
|
||||
networks:
|
||||
- webnet
|
||||
redis:
|
||||
image: redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- ./data:/data
|
||||
deploy:
|
||||
placement:
|
||||
constraints: [node.role == manager]
|
||||
networks:
|
||||
- webnet
|
||||
networks:
|
||||
webnet:
|
||||
```
|
||||
5. Check the web page at `http://localhost` and you'll see the results of the visitor counter, which is now live and storing information on Redis.
|
||||
|
||||
Redis has an official image in the Docker library and has been granted the short
|
||||
`image` name of just `redis`, so no `username/repo` notation here. The Redis
|
||||
port, 6379, has been pre-configured by Redis to be exposed from the container to
|
||||
the host, and here in our Compose file we expose it from the host to the world,
|
||||
so you can actually enter the IP for any of your nodes into Redis Desktop
|
||||
Manager and manage this Redis instance, if you so choose.
|
||||

|
||||
|
||||
Most importantly, there are a couple of things in the `redis` specification that
|
||||
make data persist between deployments of this stack:
|
||||
Also, check the visualizer at port 8080 on either node's IP address, and you'll see the `redis` service running along with the `web` and `visualizer` services.
|
||||
|
||||
- `redis` always runs on the manager, so it's always using the same filesystem.
|
||||
- `redis` accesses an arbitrary directory in the host's file system as `/data`
|
||||
inside the container, which is where Redis stores data.
|
||||

|
||||
|
||||
Together, this is creating a "source of truth" in your host's physical
|
||||
filesystem for the Redis data. Without this, Redis would store its data in
|
||||
`/data` inside the container's filesystem, which would get wiped out if that
|
||||
container were ever redeployed.
|
||||
|
||||
This source of truth has two components:
|
||||
|
||||
- The placement constraint you put on the Redis service, ensuring that it
|
||||
always uses the same host.
|
||||
- The volume you created that lets the container access `./data` (on the host)
|
||||
as `/data` (inside the Redis container). While containers come and go, the
|
||||
files stored on `./data` on the specified host will persist, enabling
|
||||
continuity.
|
||||
|
||||
To deploy your new Redis-using stack, create `./data` on the manager, copy over
|
||||
the new `docker-compose.yml` file with `docker-machine scp`, and run
|
||||
`docker stack deploy` one more time.
|
||||
|
||||
```
|
||||
$ docker-machine ssh myvm1 "mkdir ./data"
|
||||
$ docker-machine scp docker-compose.yml myvm1:~
|
||||
$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"
|
||||
```
|
||||
|
||||
Check the results on either nodes IP address and you'll see that a visitor counter is
|
||||
now live and storing information on Redis.
|
||||
|
||||
[On to Part 6 >>](part6.md){: class="button outline-btn" style="margin-bottom: 30px"}
|
||||
|
||||
|
|
|
@ -8,32 +8,32 @@ description: Deploy your app to production using Docker CE or EE.
|
|||
## Prerequisites
|
||||
|
||||
- [Install Docker version 1.13 or higher](/engine/installation/).
|
||||
- Get [Docker Compose](/compose/overview.md) as described in [Part 3 prerequisites](/get-started/part3.md#prerequisites).
|
||||
- Get [Docker Machine](/machine/overview.md) as described in [Part 4 prerequisites](/get-started/part4.md#prerequisites).
|
||||
- Read the orientation in [Part 1](index.md).
|
||||
- Learn how to create containers in [Part 2](part2.md).
|
||||
- Make sure you have pushed the container you created to a registry, as
|
||||
instructed; we'll be using it here.
|
||||
- Ensure your image is working by
|
||||
running this and visiting `http://localhost/` (slotting in your info for
|
||||
`username`, `repo`, and `tag`):
|
||||
- Be sure your image works as a deployed container by running this command, and visting `http://localhost/` (slotting in your info for `username`,
|
||||
`repo`, and `tag`):
|
||||
|
||||
```
|
||||
```shell
|
||||
docker run -p 80:80 username/repo:tag
|
||||
```
|
||||
- Have [the final version of `docker-compose.yml` from Part 5](/get-started/part5/#persisting-data) handy.
|
||||
- Have [the final version of `docker-compose.yml` from Part 5](/get-started/part5.md#persisting-data) handy.
|
||||
|
||||
## Introduction
|
||||
|
||||
You've been editing the same Compose file for this entire tutorial. Well, we
|
||||
have good news: that Compose file works just as well in production as it does
|
||||
on your machine. Here, we go through some options for running your
|
||||
have good news. That Compose file works just as well in production as it does
|
||||
on your machine. Here, we'll go through some options for running your
|
||||
Dockerized application.
|
||||
|
||||
## Choose an option
|
||||
|
||||
{% capture cloud %}
|
||||
If you're okay with using Docker Community Edition in
|
||||
production, you can use Docker Cloud to help manage your app on popular
|
||||
cloud providers such as Amazon Web Services, DigitalOcean, and Microsoft Azure.
|
||||
production, you can use Docker Cloud to help manage your app on popular service providers such as Amazon Web Services, DigitalOcean, and Microsoft Azure.
|
||||
|
||||
To set up and deploy:
|
||||
|
||||
|
@ -60,9 +60,13 @@ First, link Docker Cloud with your cloud provider:
|
|||
|
||||
After your cloud provider is all set up, create a Swarm:
|
||||
|
||||
* If you're on AWS you
|
||||
* If you're on Amazon Web Services (AWS) you
|
||||
can [automatically create a
|
||||
swarm](/docker-cloud/cloud-swarm/create-cloud-swarm/){: onclick="ga('send', 'event', 'Get Started Referral', 'Cloud', 'Create AWS Swarm');"}.
|
||||
swarm](/docker-cloud/cloud-swarm/create-cloud-swarm-aws/){: onclick="ga('send', 'event', 'Get Started Referral AWS', 'Cloud', 'Create AWS Swarm');"}.
|
||||
|
||||
* If you are on Microsoft Azure, you can [automatically create a
|
||||
swarm](/docker-cloud/cloud-swarm/create-cloud-swarm-azure/){: onclick="ga('send', 'event', 'Get Started Referral Azure', 'Cloud', 'Create Azure Swarm');"}.
|
||||
|
||||
* Otherwise, [create your nodes](/docker-cloud/getting-started/your_first_node/){: onclick="ga('send', 'event', 'Get Started Referral', 'Cloud', 'Create Nodes');"}
|
||||
in the Docker Cloud UI, and run the `docker swarm init` and `docker swarm join`
|
||||
commands you learned in [part 4](part4.md) over [SSH via Docker
|
||||
|
|
Loading…
Reference in New Issue