mirror of https://github.com/docker/docs.git
Fix for 404 bg object, right-nav
This commit is contained in:
parent
6b2de29fa7
commit
d9701c4b51
|
@ -336,7 +336,6 @@ color: #F04124;
|
||||||
border: 0;
|
border: 0;
|
||||||
text-indent: -9999px;
|
text-indent: -9999px;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
background-image: url("https://blog.docker.com/wp-content/themes/whale_roots/assets/img/search-icon.png");
|
|
||||||
/* background-size: 38px 38px; */
|
/* background-size: 38px 38px; */
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
|
|
|
@ -10,24 +10,19 @@ title: "Getting Started, Part 1: Orientation and Setup"
|
||||||
|
|
||||||
This tutorial will create a simple application that runs in a cluster, so you
|
This tutorial will create a simple application that runs in a cluster, so you
|
||||||
get a sense of how to build distributed applications with the Docker platform.
|
get a sense of how to build distributed applications with the Docker platform.
|
||||||
|
We will achieve this in the following steps:
|
||||||
|
|
||||||
1. In part one, which you're reading now, we get set up and oriented.
|
1. Get set up and oriented, on this page.
|
||||||
2. In part two, we create a "Hello World" application that identifies itself.
|
2. [Create a "Hello World" application that identifies its environment](part2.md)
|
||||||
3. In part three, we hook up a visitor counter.
|
3. [Hook up a visitor counter](part3.md)
|
||||||
4. In part four, we show how to scale this "Hello World" app as if it were very
|
4. [Scale our app as if it were very high traffic, by setting up a cluster in
|
||||||
high traffic, by setting up a cluster.
|
production](part4.md)
|
||||||
5. In part five, we show how to manage our cluster with a graphical user
|
|
||||||
interface tool, and roll out code updates.
|
|
||||||
|
|
||||||
The application itself is very simple so that you are not too distracted by
|
The application itself is very simple so that you are not too distracted by
|
||||||
what the code is doing. After all, the value of Docker is in how it can build,
|
what the code is doing. After all, the value of Docker is in how it can build,
|
||||||
ship, and run applications; it's totally agnostic as to what your application
|
ship, and run applications; it's totally agnostic as to what your application
|
||||||
actually does.
|
actually does.
|
||||||
|
|
||||||
By the end of this tutorial, you should have a good sense of how the entire
|
|
||||||
platform works, from setting up your dev environment, running and testing your
|
|
||||||
code, and finally, building, deploying, and managing your application.
|
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
Before we get started, make sure your system has the latest version of Docker
|
Before we get started, make sure your system has the latest version of Docker
|
||||||
|
@ -35,6 +30,11 @@ installed.
|
||||||
|
|
||||||
[Install Docker](/engine/installation/index.md){: class="button darkblue-btn"}
|
[Install Docker](/engine/installation/index.md){: class="button darkblue-btn"}
|
||||||
|
|
||||||
|
> Note: If you're in Linux, you'll want to install
|
||||||
|
[Docker Toolbox](../toolbox/index.md) so you get Docker Compose.
|
||||||
|
|
||||||
|
## Let's go!
|
||||||
|
|
||||||
If you understand that container images package application code and their
|
If you understand that container images package application code and their
|
||||||
dependencies all together in a portable deliverable, and your environment has
|
dependencies all together in a portable deliverable, and your environment has
|
||||||
Docker installed, let's move on!
|
Docker installed, let's move on!
|
||||||
|
|
|
@ -13,26 +13,28 @@ In this section, you will write, build, run, and share an app, the Docker way.
|
||||||
|
|
||||||
## Your development environment
|
## Your development environment
|
||||||
|
|
||||||
Normally if you were to start writing a Python app on your laptop, your first
|
In the past, if you were to start writing a Python app, your first
|
||||||
order of business would be to install a Python runtime onto your machine. But,
|
order of business was to install a Python runtime onto your machine. But,
|
||||||
that creates a situation where the environment on your machine has to be just so
|
that creates a situation where the environment on your machine has to be just
|
||||||
in order for your app to run as expected.
|
so in order for your app to run as expected; ditto for the server that runs
|
||||||
|
your app.
|
||||||
|
|
||||||
In Docker, you can just grab an image of Python runtime that is already set up,
|
With Docker, you can just grab a portable Python runtime as an image, no
|
||||||
and use that as a base for creating your app. Then, your build can include the
|
installation necessary. Then, your build can include the base Python image
|
||||||
base Python image right alongside your app code, ensuring that your app and the
|
right alongside your app code, ensuring that your app, its dependencies, and the
|
||||||
runtime it needs to run all travel together.
|
runtime, all travel together.
|
||||||
|
|
||||||
It's done with something called a Dockerfile.
|
These builds are configured with something called a `Dockerfile`.
|
||||||
|
|
||||||
## Your first Dockerfile
|
## Your first Dockerfile
|
||||||
|
|
||||||
Create a folder and put this file in it, with the name `Dockerfile` (no
|
Create an empty directory and put this file in it, with the name `Dockerfile`.
|
||||||
extension). This Dockerfile defines what goes on in the environment inside your
|
`Dockerfile` will define what goes on in the environment inside your
|
||||||
container. Things are virtualized inside this environment, which is isolated
|
container. Access to resources like networking interfaces and disk drives is
|
||||||
from the rest of your system, so you have to map ports to the outside world, and
|
virtualized inside this environment, which is isolated from the rest of your
|
||||||
|
system, so you have to map ports to the outside world, and
|
||||||
be specific about what files you want to "copy in" to that environment. However,
|
be specific about what files you want to "copy in" to that environment. However,
|
||||||
after doing that, you can expect that the build of your app with this
|
after doing that, you can expect that the build of your app defined in this
|
||||||
`Dockerfile` will behave exactly the same wherever it runs.
|
`Dockerfile` will behave exactly the same wherever it runs.
|
||||||
|
|
||||||
{% gist johndmulhausen/c31813e076827178216b74e6a6f4a087 %}
|
{% gist johndmulhausen/c31813e076827178216b74e6a6f4a087 %}
|
||||||
|
@ -41,34 +43,30 @@ This `Dockerfile` refers to a couple of things we haven't created yet, namely
|
||||||
`app.py` and `requirements.txt`. We'll get there. But here's what this
|
`app.py` and `requirements.txt`. We'll get there. But here's what this
|
||||||
`Dockerfile` is saying:
|
`Dockerfile` is saying:
|
||||||
|
|
||||||
- Go get the base Python 2.7 runtime
|
- Download the official image of the Python 2.7 runtime and include it here.
|
||||||
- Create `/app` and set it as the current working directory inside the container
|
- Create `/app` and set it as the current working directory inside the container
|
||||||
- Copy the contents of my current directory (on my machine) into `/app` (in this container image)
|
- Copy the contents of the current directory on my machine into `/app` inside the container
|
||||||
- Install any Python packages that I list inside what is now `/app/requirements.txt` inside the container
|
- Install any Python packages that I list inside `requirements.txt`
|
||||||
- Ensure that this container has port 80 open when it runs
|
- Ensure that port 80 is exposed to the world outside this container
|
||||||
- Set an environment variable within this container named `NAME` to be the string `World`
|
- Set an environment variable within this container named `NAME` to be the string `World`
|
||||||
- Finally, when the container runs, execute `python` and pass in what is now `/app/app.py`
|
- Finally, execute `python` and pass in `app.py` as the "entry point" command,
|
||||||
|
the default command that is executed at runtime.
|
||||||
This paradigm is how developing with Docker essentially works. Make a
|
|
||||||
`Dockerfile` that includes the base image, grabs your code, installs
|
|
||||||
dependencies, initializes variables, and runs the command.
|
|
||||||
|
|
||||||
### The app itself
|
### The app itself
|
||||||
|
|
||||||
Grab these two files that were referred to in the above `Dockerfile` and place
|
Grab these two files and place them in the same folder as `Dockerfile`.
|
||||||
them together with `Dockerfile`, all in the same folder.
|
|
||||||
|
|
||||||
{% gist johndmulhausen/074cc7f4c26a9a8f9164b20b22602ad7 %}
|
{% gist johndmulhausen/074cc7f4c26a9a8f9164b20b22602ad7 %}
|
||||||
{% gist johndmulhausen/8728902faede400c057f3205392bb9a8 %}
|
{% gist johndmulhausen/8728902faede400c057f3205392bb9a8 %}
|
||||||
|
|
||||||
You're probably getting the picture by now. In `Dockerfile` we told the `pip`
|
Now we see that the `Dockerfile` command `pip install requirements.txt` installs
|
||||||
package installer to install whatever was in `requirements.txt`, which we
|
the Flask and Redis libraries for Python. We can also see that app itself
|
||||||
now see is the Flask and Redis libraries for Python. The app itself is going to
|
prints the environment variable of `NAME`, which we set as `World`, as well as
|
||||||
print the environment variable of `NAME`, which we set as `World`, as well as
|
|
||||||
the output of a call to `socket.gethostname()`, which the Docker runtime is
|
the output of a call to `socket.gethostname()`, which the Docker runtime is
|
||||||
going to answer with the container ID. Finally, because Redis isn't running
|
going to answer with the container ID, which is sort of like the process ID for
|
||||||
(we've only installed the Python library), we should expect that the attempt to
|
an executable. Finally, because Redis isn't running
|
||||||
use it here will fail and show the error message.
|
(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.
|
||||||
|
|
||||||
## Build the App
|
## Build the App
|
||||||
|
|
||||||
|
@ -77,8 +75,7 @@ That's it! You don't need to have installed Python or anything in
|
||||||
your system. It doesn't seem like you've really set up an environment with
|
your system. It doesn't seem like you've really set up an environment with
|
||||||
Python and Flask, but you have. Let's build and run your app and prove it.
|
Python and Flask, but you have. Let's build and run your app and prove it.
|
||||||
|
|
||||||
Make sure you're in the directory where you saved the three files we've shown,
|
7Here's what `ls` should show:
|
||||||
and you've got everything.
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ ls
|
$ ls
|
||||||
|
@ -86,15 +83,13 @@ Dockerfile app.py requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
Now run the build command. This creates a Docker image, which we're going to
|
Now run the build command. This creates a Docker image, which we're going to
|
||||||
tag using `-t` so it has a friendly name, which you can use interchangeable
|
tag using `-t` so it has a friendly name.
|
||||||
with the image ID in commands.
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker build -t "friendlyhello" .
|
docker build -t friendlyhello .
|
||||||
```
|
```
|
||||||
|
|
||||||
In the output spew you can see everything defined in the `Dockerfile` happening,
|
In the output spew you can see everything defined in the `Dockerfile` happening.
|
||||||
including the installation of the packages we specified in `requirements.txt`.
|
|
||||||
Where is your built image? It's in your machine's local Docker image registry.
|
Where is your built image? It's in your machine's local Docker image registry.
|
||||||
Check it out:
|
Check it out:
|
||||||
|
|
||||||
|
@ -106,22 +101,25 @@ friendlyhello latest 326387cea398 47 seconds ago
|
||||||
|
|
||||||
## Run the app
|
## Run the app
|
||||||
|
|
||||||
We're going to run the app and route traffic from our machine's port 80 to the
|
Run the app, mapping our machine's port 4000 to the container's exposed port 80
|
||||||
port 80 we exposed
|
using `-p`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker run -p 80:80 friendlyhello
|
docker run -p 4000:80 friendlyhello
|
||||||
```
|
```
|
||||||
|
|
||||||
You should see a notice that Python is serving your app at `http://0.0.0.0:80`.
|
You should see a notice that Python is serving your app at `http://0.0.0.0:80`.
|
||||||
You can go there, or just to `http://localhost`, and see your app, "Hello World"
|
But that message coming from inside the container, which doesn't know you
|
||||||
text, the container ID, and the Redis error message, all printed out in
|
actually want to access your app at: `http://localhost:4000`. Go there, and
|
||||||
beautiful Times New Roman.
|
you'll see the "Hello World" text, the container ID, and the Redis error
|
||||||
|
message, all printed out in beautiful Times New Roman.
|
||||||
|
|
||||||
Hit `CTRL+C` and let's run the app in the background, in detached mode.
|
Hit `CTRL+C` in your terminal to quit.
|
||||||
|
|
||||||
|
Now let's run the app in the background, in detached mode:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker run -d -p 80:80 friendlyhello
|
docker run -d -p 4000:80 friendlyhello
|
||||||
```
|
```
|
||||||
|
|
||||||
You get a hash ID of the container instance and then are kicked back to your
|
You get a hash ID of the container instance and then are kicked back to your
|
||||||
|
@ -133,25 +131,22 @@ CONTAINER ID IMAGE COMMAND CREATED
|
||||||
1fa4ab2cf395 friendlyhello "python app.py" 28 seconds ago Up 25 seconds
|
1fa4ab2cf395 friendlyhello "python app.py" 28 seconds ago Up 25 seconds
|
||||||
```
|
```
|
||||||
|
|
||||||
You'll see that `CONTAINER ID` matches what's on `http://localhost`, if you
|
You'll see that `CONTAINER ID` matches what's on `http://localhost:4000`, if you
|
||||||
refresh the browser page. You can't `CTRL+C` now, so let's kill the process this
|
refresh the browser page. Now use `docker stop` to end the process, using
|
||||||
way. Use the value you see under `CONTAINER ID`:
|
`CONTAINER ID`, like so:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker kill (containerID)
|
docker stop 1fa4ab2cf395
|
||||||
```
|
```
|
||||||
|
|
||||||
## Share the App
|
## Share your image
|
||||||
|
|
||||||
Now let's test how portable this app really is.
|
Sign up a Docker account at [hub.docker.com](https://hub.docker.com/).
|
||||||
|
|
||||||
Sign up for Docker Hub at [https://hub.docker.com/](https://hub.docker.com/).
|
|
||||||
Make note of your username. We're going to use it in a couple commands.
|
Make note of your username. We're going to use it in a couple commands.
|
||||||
|
|
||||||
Docker Hub is a public registry. A registry is a collection of accounts and
|
Docker Hub is a public registry. A registry is a collection of accounts and
|
||||||
their various repositories. A repository is a collection of assets associated
|
their various repositories. A repository is a collection of tagged images like a
|
||||||
with your account - like a GitHub repository, except the code is already built.
|
GitHub repository, except the code is already built.
|
||||||
|
|
||||||
|
|
||||||
Log in your local machine to Docker Hub.
|
Log in your local machine to Docker Hub.
|
||||||
|
|
||||||
|
@ -187,9 +182,40 @@ and run this command:
|
||||||
docker run YOURUSERNAME/YOURREPO:ARBITRARYTAG
|
docker run YOURUSERNAME/YOURREPO:ARBITRARYTAG
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note: If you don't specify the `:ARBITRARYTAG` portion of these commands,
|
||||||
|
the tag of `:latest` will be assumed, both when you build and when you run
|
||||||
|
images.
|
||||||
|
|
||||||
You'll see this stranger of a machine pull your image, along with Python and all
|
You'll see this stranger of a machine pull your image, along with Python and all
|
||||||
the dependencies from `requirements.txt`, and run your code. It all travels
|
the dependencies from `requirements.txt`, and run your code. It all travels
|
||||||
together in a neat little package, and the new machine didn't have to install
|
together in a neat little package, and the new machine didn't have to install
|
||||||
anything but Docker to run it.
|
anything but Docker to run it.
|
||||||
|
|
||||||
|
## Recap and cheat sheet for images and containers
|
||||||
|
|
||||||
|
To recap: After calling `docker run`, you created and ran a container, based on
|
||||||
|
the image created when you called `docker build`. Images are defined in a
|
||||||
|
`Dockerfile`. A container is an instance of an image, and it has any package
|
||||||
|
installations, file writes, etc that happen after you call `docker run` and run
|
||||||
|
the app. And lastly, images are shared via a registry.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker build -t friendlyname . #Create image using this directory's Dockerfile
|
||||||
|
docker run -p 4000:80 friendlyname #Run image "friendlyname" mapping port 4000 to 80
|
||||||
|
docker run -d -p 4000:80 friendlyname #Same thing, but in detached mode
|
||||||
|
docker ps #See a list of all running containers
|
||||||
|
docker stop <hash> #Gracefully stop the specified container
|
||||||
|
docker ps -a #See a list of all containers on this machine, even the ones not running
|
||||||
|
docker kill <hash> #Force shutdown of the specified container
|
||||||
|
docker rm <hash> #Remove the specified container from this machine
|
||||||
|
docker rm $(docker ps -a -q) #Remove all containers from this machine
|
||||||
|
docker images -a #Show all images that have been built or downloaded onto this machine
|
||||||
|
docker rmi <imagename> #Remove the specified image from this machine
|
||||||
|
docker rmi $(docker images -q) #Remove all images from this machine
|
||||||
|
docker login #Log in this CLI session using your Docker credentials (to Docker Hub by default)
|
||||||
|
docker tag <image> username/repository:tag #Tag <image> on your local machine for upload
|
||||||
|
docker push username/repository:tag #Upload tagged image to registry (Docker Hub by default)
|
||||||
|
docker run username/repository:tag #Run image from a registry (Docker Hub by default)
|
||||||
|
```
|
||||||
|
|
||||||
[On to "Getting Started, Part 3: Stateful, Multi-container Applications" >>](part3.md){: class="button darkblue-btn"}
|
[On to "Getting Started, Part 3: Stateful, Multi-container Applications" >>](part3.md){: class="button darkblue-btn"}
|
||||||
|
|
|
@ -9,8 +9,8 @@ wrote, built, ran, and shared our first Dockerized app, which all fit in a
|
||||||
single container.
|
single container.
|
||||||
|
|
||||||
In part 3, we will expand this application so that it is comprised of two
|
In part 3, we will expand this application so that it is comprised of two
|
||||||
containers simultaneously: one running the web app we have already written, and
|
containers running simultaneously: one running the web app we have already
|
||||||
another that stores data on the web app's behalf.
|
written, and another that stores data on the web app's behalf.
|
||||||
|
|
||||||
## Understanding services
|
## Understanding services
|
||||||
|
|
||||||
|
@ -28,18 +28,17 @@ and that's going to happen via a different executable entirely.
|
||||||
|
|
||||||
In a distributed application, these different pieces of the app are called
|
In a distributed application, these different pieces of the app are called
|
||||||
"services." For example, if you imagine a video sharing site, there will
|
"services." For example, if you imagine a video sharing site, there will
|
||||||
probably be a service for storing application data in a database, another one
|
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
|
for video transcoding in the background after a user uploads something, a
|
||||||
service for streaming, and so on, and they all need to work in concert.
|
service for the front-end, and so on, and they all need to work in concert.
|
||||||
|
|
||||||
The easiest way to introduce the organization of your app into services using
|
The easiest way to organize your containerized app into services using
|
||||||
containers is by using Docker Compose. We're going to add a data storage service
|
is using Docker Compose. We're going to add a data storage service
|
||||||
to our simple Hello World app. Don't worry, it's shockingly easy.
|
to our simple Hello World app. Don't worry, it's shockingly easy.
|
||||||
|
|
||||||
## Your first `docker-compose.yml` File
|
## Your first `docker-compose.yml` File
|
||||||
|
|
||||||
As you saw, a `Dockerfile` is a text file that defines a single Docker image.
|
A `docker-compose.yml` file is a YAML markup file that is hierarchical in
|
||||||
But a `docker-compose.yml` file is a YAML markup file that is hierarchical in
|
|
||||||
structure, and defines how multiple Docker images should work together when
|
structure, and defines how multiple Docker images should work together when
|
||||||
they are running in containers.
|
they are running in containers.
|
||||||
|
|
||||||
|
@ -63,14 +62,14 @@ image](https://store.docker.com/images/1f6ef28b-3e48-4da1-b838-5bd8710a2053)).
|
||||||
|
|
||||||
This `docker-compose.yml` file tells Docker to do the following:
|
This `docker-compose.yml` file tells Docker to do the following:
|
||||||
|
|
||||||
- Pull and run [the image we uploaded in step 2](/getting-started/part2/#/share-the-app) as a service called `web`
|
- Pull and run [the image we uploaded to Docker Hub in step 2](/getting-started/part2/#/share-the-app) as a service called `web`
|
||||||
- Map port 80 on the host to the container's port 80 (so http://localhost:80 resolves properly)
|
- Map port 4000 on the host to `web`'s port 80
|
||||||
- Link this container to the service we named `redis`; this ensures that the
|
- Link the `web` service to the service we named `redis`; this ensures that the
|
||||||
dependency between `redis` and `web` is expressed, as well as the order of service
|
dependency between `redis` and `web` is expressed, and these containers will
|
||||||
startup.
|
run together in the same subnet.
|
||||||
- Pull and run the official Redis image as a service called `redis`
|
- Our service named `redis` just runs the official Redis image, so go get it from Docker Hub.
|
||||||
|
|
||||||
## Run your first multi-container app
|
## Run and scale up your first multi-container app
|
||||||
|
|
||||||
Run this command in the directory where you saved `docker-compose.yml`:
|
Run this command in the directory where you saved `docker-compose.yml`:
|
||||||
|
|
||||||
|
@ -79,52 +78,63 @@ docker-compose up
|
||||||
```
|
```
|
||||||
|
|
||||||
This will pull all the necessary images and run them in concert. Now when you
|
This will pull all the necessary images and run them in concert. Now when you
|
||||||
visit `http://localhost`, you'll see a number next to the visitor counter
|
visit `http://localhost:4000`, you'll see a number next to the visitor counter
|
||||||
instead of the error message. It really works -- just keep hitting refresh.
|
instead of the error message. It really works -- just keep hitting refresh.
|
||||||
|
|
||||||
## Connecting to this instance of Redis
|
## Connecting to containers with port mapping
|
||||||
|
|
||||||
With a containerized instance of Redis running, you're probably wondering --
|
With a containerized instance of Redis running, you're probably wondering --
|
||||||
how do I break through the wall of isolation and manage my data? The answer is,
|
how do I break through the wall of isolation and manage my data? The answer is,
|
||||||
port mapping. [The page for the official Redis
|
port mapping. [The page for the official Redis
|
||||||
image](https://store.docker.com/images/1f6ef28b-3e48-4da1-b838-5bd8710a2053)
|
image](https://store.docker.com/images/1f6ef28b-3e48-4da1-b838-5bd8710a2053)
|
||||||
states that the normal management ports are open in their image, so you should
|
states that the normal management ports are open in their image, so you would
|
||||||
be able to connect to it at `localhost:6379` if you add a `ports:` section to
|
be able to connect to it at `localhost:6379` if you add a `ports:` section to
|
||||||
`docker-compose.yml` under `redis` that maps `6379` to your host, just as port
|
`docker-compose.yml` under `redis` that maps `6379` to your host, just as port
|
||||||
`80` is mapped for `web`. Same with MySQL or any other data solution;
|
`80` is mapped for `web`. Same with MySQL or any other data solution; once you
|
||||||
containerized doesn't mean unreachable, it just means portable. Once you map
|
map your ports, you can use your fave UI tools like MySQL Workbench, Redis
|
||||||
your ports, you can use your fave UI tools like MySQL Workbench, Redis Desktop
|
Desktop Manager, etc, to connect to your Dockerized instance.
|
||||||
Manager, etc, to connect to your Dockerized instance.
|
|
||||||
|
|
||||||
Redis port mapping isn't necessary in `docker-compose.yml` because the two
|
Redis port mapping isn't necessary in `docker-compose.yml` because the two
|
||||||
services (`web` and `redis`) are linked, ensuring they run on the same host (VM
|
services (`web` and `redis`) are linked, ensuring they run on the same host (VM
|
||||||
or physical machine). Within that host, the containers can talk to each other
|
or physical machine), in a private subnet that is automatically created by the
|
||||||
in a private subnet that is automatically created by the Docker runtime, which
|
Docker runtime. Containers within
|
||||||
isn't accessible to the outside world, only to other containers. In our app,
|
that subnet can already talk to each other; it's connecting from the outside
|
||||||
we specify `EXPOSE 80` in our Dockerfile, and as you can see in the Redis
|
that necessitates port mapping.
|
||||||
documentation, they specify `EXPOSE 6379` in the Dockerfile that defines the
|
|
||||||
official Redis image. But those ports aren't accessible outside of the private
|
## Cheat sheet and recap: Hosts, subnets, and Docker Compose
|
||||||
subnet (or, in turn, reachable at `http://localhost`) until you map the host's
|
|
||||||
port 80 to the container's port 80, which is why we specified as much in
|
You learned that by creating a `docker-compose.yml` file, you can define the
|
||||||
`docker run` previously, and `docker-compose.yml` just now.
|
entire stack for your application. This ensures that your services run
|
||||||
|
together in a private subnet that lets them connect to each
|
||||||
|
other, but only to the world as specifically dircted. This means that if you
|
||||||
|
want to connect your favorite data management software to your data storage
|
||||||
|
service, you'll have to ensure the container has the proper port exposed and
|
||||||
|
your host has that port mapped to the container in `docker-compose.yml`.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker-compose up #Pull and run images specified in `docker-compose.yml` as services
|
||||||
|
docker-compose up -d #Same thing, but in background mode
|
||||||
|
docker-compose stop #Stop all running containers for this app
|
||||||
|
docker-compose rm -f #Remove all containers for this app
|
||||||
|
```
|
||||||
|
|
||||||
## Get ready to scale
|
## Get ready to scale
|
||||||
|
|
||||||
Until now, I've been able to shield you from worrying too much about host
|
Until now, I've been able to shield you from worrying too much about host
|
||||||
management. That's because installing Docker always sets up a default way
|
management. That's because installing Docker always sets up a default way
|
||||||
to run containers in a single-host environment. Docker for Windows and Mac
|
to run containers on that machine. Docker for Windows and Mac
|
||||||
comes with a virtual machine host running a lighweight operating system
|
comes with a virtual machine host running a lighweight operating system
|
||||||
we call Moby, which is just a very slimmed-down Linux. Docker for Linux
|
we call Moby, which is just a very slimmed-down Linux. Docker for Linux
|
||||||
just works without a VM at all. And Docker for Windows can run Microsoft
|
just works without a VM at all. And Docker for Windows can even run Microsoft
|
||||||
Windows containers using native Hyper-V support. When you've run `docker
|
Windows containers using native Hyper-V support. When you've run `docker
|
||||||
run` and `docker-compose up` so far, Docker has used these default hosts
|
run` and `docker-compose up` so far, Docker has used these solutions
|
||||||
to run your containers. That's because we want you to be able to install
|
to run your containers. That's because we want you to be able to install
|
||||||
Docker and get straight to the work of development and building images.
|
Docker and get straight to the work of development and building images.
|
||||||
|
|
||||||
But when it comes to getting your app into production, we all know that
|
But when it comes to getting your app into production, we all know that
|
||||||
you're not going to run just one host machine that has Redis, Python, and
|
you're not going to run just one host machine that has Redis, Python, and
|
||||||
all your other sevices. That won't scale. You need to learn how to run not
|
all your other sevices. That won't scale. You need to learn how to run not
|
||||||
just multiple containers on one host, but multiple containers on multiple
|
just multiple containers on your local host, but multiple containers on
|
||||||
hosts. And that's precisely what we're going to get into next.
|
multiple hosts. And that's precisely what we're going to get into next.
|
||||||
|
|
||||||
[On to "Part 4: Running our App in Production" >>](part4.md){: class="button darkblue-btn"}
|
[On to "Part 4: Running our App in Production" >>](part4.md){: class="button darkblue-btn"}
|
||||||
|
|
|
@ -98,15 +98,18 @@ into a swarm.
|
||||||
## Creating your first Swarm cluster
|
## Creating your first Swarm cluster
|
||||||
|
|
||||||
1. Go back to Docker Cloud by visiting [cloud.docker.com](https://cloud.docker.com).
|
1. Go back to Docker Cloud by visiting [cloud.docker.com](https://cloud.docker.com).
|
||||||
2. Click **Node Clusters** in the left-navigation, then click the **Create** button.
|
2. Click **Node Clusters** in the left navigation, then click the **Create** button.
|
||||||
This pulls up a form where you can create our cluster.
|
This pulls up a form where you can create our cluster.
|
||||||
3. Leave everything default, except:
|
3. Leave everything default, except:
|
||||||
- Name: Give your cluster a name.
|
- Name: Give your cluster a name
|
||||||
- Region: Select a region that's close to you.
|
- Region: Select a region that's close to you
|
||||||
- Provider: Set to "Amazon Web Services"
|
- Provider: Set to "Amazon Web Services"
|
||||||
- Type/Size:
|
- Type/Size: Select the `t2.nano` option as that is free-tier
|
||||||
4. Launch the cluster by clicking **Launch node cluster**, and
|
4. Launch the cluster by clicking **Launch node cluster**; this will spin
|
||||||
5.
|
up a free-tier Amazon instance.
|
||||||
|
5. Now, click **Services** in the left navigation, then the **Create** button,
|
||||||
|
then the **globe icon**.
|
||||||
|
6. Search Docker Hub for the image you uploaded
|
||||||
|
|
||||||
|
|
||||||
[On to next >>](part5.md){: class="button darkblue-btn"}
|
[On to next >>](part5.md){: class="button darkblue-btn"}
|
||||||
|
|
|
@ -54,8 +54,8 @@ jQuery(document).ready(function(){
|
||||||
|
|
||||||
var index = 0;
|
var index = 0;
|
||||||
var currentHeader = 0, lastHeader = 0;
|
var currentHeader = 0, lastHeader = 0;
|
||||||
var output = "";
|
var output = "<ul>";
|
||||||
$("h2, h3, h4").each(function() {
|
$("h1, h2, h3, h4").each(function() {
|
||||||
var li= "<li><a href='" + window.location + "#" + $(this).attr('id') + "'>" + $(this).text().replace("¶","") + "</a></li>";
|
var li= "<li><a href='" + window.location + "#" + $(this).attr('id') + "'>" + $(this).text().replace("¶","") + "</a></li>";
|
||||||
if( $(this).is("h2") ){
|
if( $(this).is("h2") ){
|
||||||
// h2
|
// h2
|
||||||
|
@ -67,12 +67,14 @@ jQuery(document).ready(function(){
|
||||||
// h4
|
// h4
|
||||||
currentHeader = 4;
|
currentHeader = 4;
|
||||||
}
|
}
|
||||||
|
console.log("currentHeader ",currentHeader, "lastHeader ",lastHeader, "text ", $(this).text());
|
||||||
if (currentHeader > lastHeader) {
|
if (currentHeader > lastHeader) {
|
||||||
// nest further
|
// nest further
|
||||||
output += "<ul>"
|
output += "<ul>"
|
||||||
}
|
}
|
||||||
if (currentHeader < lastHeader && lastHeader > 0) {
|
if (currentHeader < lastHeader && lastHeader > 0) {
|
||||||
// close nesting
|
// close nesting
|
||||||
|
console.log("Closing nesting because ", lastHeader, "is <", currentHeader);
|
||||||
for (i=0; i < (lastHeader - currentHeader); i++)
|
for (i=0; i < (lastHeader - currentHeader); i++)
|
||||||
{
|
{
|
||||||
output += "</ul>"
|
output += "</ul>"
|
||||||
|
|
Loading…
Reference in New Issue