Updates to Compose getting started guide

- Some wording and formatting tweaks
- Use Python 3.4, because it's 2016
- Use Alpine-based images for faster downloads and less disk space usage
- Use the list form of `CMD` in the Dockerfile, so it's not wrapped in
  sh
- Remove the `depends_on` from `docker-compose.yml`, as it's not really
  needed - the web app connects to Redis when it's visited, not on
  startup
- Add a section on updating the app and seeing the changes, because
  that's the point of mounting the code in!
- Add a note about `docker-compose down`

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
This commit is contained in:
Aanand Prasad 2016-11-22 16:30:15 +00:00
parent 0e65544a3f
commit b08c014fd8
1 changed files with 84 additions and 71 deletions

View File

@ -4,26 +4,25 @@ keywords: documentation, docs, docker, compose, orchestration, containers
title: Get started with Docker Compose title: Get started with Docker Compose
--- ---
On this page you build a simple Python web application running on Docker Compose. The On this page you build a simple Python web application running on Docker
application uses the Flask framework and increments a value in Redis. While the Compose. The application uses the Flask framework and maintains a hit counter in
sample uses Python, the concepts demonstrated here should be understandable even Redis. While the sample uses Python, the concepts demonstrated here should be
if you're not familiar with it. understandable even if you're not familiar with it.
## Prerequisites ## Prerequisites
Make sure you have already Make sure you have already [installed both Docker Engine and Docker
[installed both Docker Engine and Docker Compose](install.md). You Compose](install.md). You don't need to install Python or Redis, as both are
don't need to install Python, it is provided by a Docker image. provided by Docker images.
## Step 1: Setup ## Step 1: Setup
1. Create a directory for the project: 1. Create a directory for the project:
$ mkdir composetest $ mkdir composetest
$ cd composetest $ cd composetest
2. With your favorite text editor create a file called `app.py` in your project 2. Create a file called `app.py` in your project directory and paste this in:
directory.
from flask import Flask from flask import Flask
from redis import Redis from redis import Redis
@ -33,82 +32,74 @@ don't need to install Python, it is provided by a Docker image.
@app.route('/') @app.route('/')
def hello(): def hello():
redis.incr('hits') count = redis.incr('hits')
return 'Hello World! I have been seen %s times.' % redis.get('hits') return 'Hello World! I have been seen {} times.\n'.format(count)
if __name__ == "__main__": if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True) app.run(host="0.0.0.0", debug=True)
3. Create another file called `requirements.txt` in your project directory and 3. Create another file called `requirements.txt` in your project directory and
add the following: paste this in:
flask flask
redis redis
These define the applications dependencies. These define the application's dependencies.
## Step 2: Create a Docker image
In this step, you build a new Docker image. The image contains all the
dependencies the Python application requires, including Python itself.
1. In your project directory create a file named `Dockerfile` and add the
following:
FROM python:2.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD python app.py
This tells Docker to:
* Build an image starting with the Python 2.7 image.
* Add the current directory `.` into the path `/code` in the image.
* Set the working directory to `/code`.
* Install the Python dependencies.
* Set the default command for the container to `python app.py`
<br>
For more information on how to write Dockerfiles, see the [Docker user guide](/engine/tutorials/dockerimages.md#building-an-image-from-a-dockerfile) and the [Dockerfile reference](/engine/reference/builder.md).
<br>
2. Build the image.
$ docker build -t web .
This command builds an image named `web` from the contents of the current
directory. The command automatically locates the `Dockerfile`, `app.py`, and
`requirements.txt` files.
## Step 3: Define services ## Step 2: Create a Dockerfile
Define a set of services using `docker-compose.yml`: In this step, you write a Dockerfile that builds a Docker image. The image
contains all the dependencies the Python application requires, including Python
itself.
Create a file called docker-compose.yml in your project directory and add In your project directory, create a file named `Dockerfile` and paste the
the following: following:
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
This tells Docker to:
* Build an image starting with the Python 3.4 image.
* Add the current directory `.` into the path `/code` in the image.
* Set the working directory to `/code`.
* Install the Python dependencies.
* Set the default command for the container to `python app.py`
For more information on how to write Dockerfiles, see the [Docker user
guide](/engine/tutorials/dockerimages.md#building-an-image-from-a-dockerfile)
and the [Dockerfile reference](/engine/reference/builder.md).
version: '2' ## Step 3: Define services in a Compose file
services:
web: Create a file called `docker-compose.yml` in your project directory and paste
build: . the following:
ports:
- "5000:5000" version: '2'
volumes: services:
- .:/code web:
depends_on: build: .
- redis ports:
redis: - "5000:5000"
image: redis volumes:
- .:/code
redis:
image: "redis:alpine"
This Compose file defines two services, `web` and `redis`. The web service: This Compose file defines two services, `web` and `redis`. The web service:
* Builds from the `Dockerfile` in the current directory. * Uses an image that's built from the `Dockerfile` in the current directory.
* Forwards the exposed port 5000 on the container to port 5000 on the host machine. * Forwards the exposed port 5000 on the container to port 5000 on the host
* Mounts the project directory on the host to `/code` inside the container allowing you to modify the code without having to rebuild the image. machine.
* Links the web service to the Redis service. * Mounts the project directory on the host to `/code` inside the container,
allowing you to modify the code without having to rebuild the image.
The `redis` service uses the latest public The `redis` service uses a public
[Redis](https://registry.hub.docker.com/_/redis/) image pulled from the Docker [Redis](https://registry.hub.docker.com/_/redis/) image pulled from the Docker
Hub registry. Hub registry.
@ -160,7 +151,22 @@ containers](../engine/tutorials/dockervolumes.md).
The number should increment. The number should increment.
## Step 5: Experiment with some other commands
## Step 5: Update the application
Because the application code is mounted into the container using a volume, you
can make changes to its code and see the changes instantly, without having to
rebuild the image.
1. Change the greeting in `app.py` and save it. For example:
return 'Hello from Docker! I have been seen {} times.\n'.format(count)
2. Refresh the app in your browser. The greeting should be updated, and the
counter should still be incrementing.
## Step 6: Experiment with some other commands
If you want to run your services in the background, you can pass the `-d` flag If you want to run your services in the background, you can pass the `-d` flag
(for "detached" mode) to `docker-compose up` and use `docker-compose ps` to (for "detached" mode) to `docker-compose up` and use `docker-compose ps` to
@ -169,6 +175,7 @@ see what is currently running:
$ docker-compose up -d $ docker-compose up -d
Starting composetest_redis_1... Starting composetest_redis_1...
Starting composetest_web_1... Starting composetest_web_1...
$ docker-compose ps $ docker-compose ps
Name Command State Ports Name Command State Ports
------------------------------------------------------------------- -------------------------------------------------------------------
@ -179,14 +186,20 @@ The `docker-compose run` command allows you to run one-off commands for your
services. For example, to see what environment variables are available to the services. For example, to see what environment variables are available to the
`web` service: `web` service:
docker-compose run web env $ docker-compose run web env
See `docker-compose --help` to see other available commands. You can also install [command completion](completion.md) for the bash and zsh shell, which will also show you available commands. See `docker-compose --help` to see other available commands. You can also install [command completion](completion.md) for the bash and zsh shell, which will also show you available commands.
If you started Compose with `docker-compose up -d`, you'll probably want to stop If you started Compose with `docker-compose up -d`, you'll probably want to stop
your services once you've finished with them: your services once you've finished with them:
docker-compose stop $ docker-compose stop
You can bring everything down, removing the containers entirely, with the `down`
command. Pass `--volumes` to also remove the data volume used by the Redis
container:
$ docker-compose down --volumes
At this point, you have seen the basics of how Compose works. At this point, you have seen the basics of how Compose works.