2015-01-19 06:46:23 +01:00
|
|
|
page_title: Compose: Multi-container orchestration for Docker
|
2015-01-30 03:21:49 +01:00
|
|
|
page_description: Introduction and Overview of Compose
|
2015-01-30 12:27:57 +01:00
|
|
|
page_keywords: documentation, docs, docker, compose, orchestration, containers
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-19 06:46:23 +01:00
|
|
|
|
2015-02-19 15:34:08 +01:00
|
|
|
# Docker Compose
|
2015-01-30 03:21:49 +01:00
|
|
|
|
2015-02-16 20:21:17 +01:00
|
|
|
Compose is a tool for defining and running complex applications with Docker.
|
|
|
|
With Compose, you define a multi-container application in a single file, then
|
|
|
|
spin your application up in a single command which does everything that needs to
|
|
|
|
be done to get it running.
|
2015-01-30 03:21:49 +01:00
|
|
|
|
2015-02-16 20:21:17 +01:00
|
|
|
Compose is great for development environments, staging servers, and CI. We don't
|
|
|
|
recommend that you use it in production yet.
|
2015-01-30 03:21:49 +01:00
|
|
|
|
|
|
|
Using Compose is basically a three-step process.
|
2015-01-30 12:27:57 +01:00
|
|
|
|
|
|
|
First, you define your app's environment with a `Dockerfile` so it can be
|
|
|
|
reproduced anywhere:
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-02-16 20:21:17 +01:00
|
|
|
```Dockerfile
|
|
|
|
FROM python:2.7
|
|
|
|
WORKDIR /code
|
|
|
|
ADD requirements.txt /code/
|
|
|
|
RUN pip install -r requirements.txt
|
|
|
|
ADD . /code
|
|
|
|
CMD python app.py
|
|
|
|
```
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-30 12:27:57 +01:00
|
|
|
Next, you define the services that make up your app in `docker-compose.yml` so
|
|
|
|
they can be run together in an isolated environment:
|
2014-01-27 12:42:38 +01:00
|
|
|
|
|
|
|
```yaml
|
|
|
|
web:
|
|
|
|
build: .
|
|
|
|
links:
|
|
|
|
- db
|
|
|
|
ports:
|
2014-02-20 13:53:43 +01:00
|
|
|
- "8000:8000"
|
2014-01-27 12:42:38 +01:00
|
|
|
db:
|
2014-08-07 01:33:31 +02:00
|
|
|
image: postgres
|
2014-01-27 12:42:38 +01:00
|
|
|
```
|
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
Lastly, run `docker-compose up` and Compose will start and run your entire app.
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-02-16 20:21:17 +01:00
|
|
|
Compose has commands for managing the whole lifecycle of your application:
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
* Start, stop and rebuild services
|
|
|
|
* View the status of running services
|
2015-02-16 20:21:17 +01:00
|
|
|
* Stream the log output of running services
|
|
|
|
* Run a one-off command on a service
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-02-25 15:09:30 +01:00
|
|
|
## Compose documentation
|
|
|
|
|
|
|
|
- [Installing Compose](install.md)
|
|
|
|
- [Command line reference](cli.md)
|
|
|
|
- [Yaml file reference](yml.md)
|
|
|
|
- [Compose environment variables](env.md)
|
|
|
|
- [Compose command line completion](completion.md)
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-19 06:46:23 +01:00
|
|
|
## Quick start
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-30 12:27:57 +01:00
|
|
|
Let's get started with a walkthrough of getting a simple Python web app running
|
|
|
|
on Compose. It assumes a little knowledge of Python, but the concepts
|
|
|
|
demonstrated here should be understandable even if you're not familiar with
|
|
|
|
Python.
|
2015-01-30 03:21:49 +01:00
|
|
|
|
|
|
|
### Installation and set-up
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-02-23 04:56:13 +01:00
|
|
|
First, [install Docker and Compose](install.md).
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
Next, you'll want to make a directory for the project:
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-20 18:44:48 +01:00
|
|
|
$ mkdir composetest
|
|
|
|
$ cd composetest
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-19 06:46:23 +01:00
|
|
|
Inside this directory, create `app.py`, a simple web app that uses the Flask
|
|
|
|
framework and increments a value in Redis:
|
2014-01-27 12:42:38 +01:00
|
|
|
|
|
|
|
```python
|
|
|
|
from flask import Flask
|
|
|
|
from redis import Redis
|
|
|
|
import os
|
|
|
|
app = Flask(__name__)
|
2014-08-08 20:00:10 +02:00
|
|
|
redis = Redis(host='redis', port=6379)
|
2014-01-27 12:42:38 +01:00
|
|
|
|
|
|
|
@app.route('/')
|
|
|
|
def hello():
|
|
|
|
redis.incr('hits')
|
|
|
|
return 'Hello World! I have been seen %s times.' % redis.get('hits')
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
app.run(host="0.0.0.0", debug=True)
|
|
|
|
```
|
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
Next, define the Python dependencies in a file called `requirements.txt`:
|
2014-01-27 12:42:38 +01:00
|
|
|
|
|
|
|
flask
|
|
|
|
redis
|
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
### Create a Docker image
|
|
|
|
|
|
|
|
Now, create a Docker image containing all of your app's dependencies. You
|
2015-01-30 12:27:57 +01:00
|
|
|
specify how to build the image using a file called
|
|
|
|
[`Dockerfile`](http://docs.docker.com/reference/builder/):
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2014-08-07 23:50:55 +02:00
|
|
|
FROM python:2.7
|
2014-01-27 12:42:38 +01:00
|
|
|
ADD . /code
|
|
|
|
WORKDIR /code
|
|
|
|
RUN pip install -r requirements.txt
|
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
This tells Docker to include Python, your code, and your Python dependencies in
|
2015-01-19 06:46:23 +01:00
|
|
|
a Docker image. For more information on how to write Dockerfiles, see the
|
2015-01-30 12:27:57 +01:00
|
|
|
[Docker user
|
|
|
|
guide](https://docs.docker.com/userguide/dockerimages/#building-an-image-from-a-dockerfile)
|
|
|
|
and the
|
2015-01-30 03:21:49 +01:00
|
|
|
[Dockerfile reference](http://docs.docker.com/reference/builder/).
|
|
|
|
|
|
|
|
### Define services
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
Next, define a set of services using `docker-compose.yml`:
|
2014-01-27 12:42:38 +01:00
|
|
|
|
|
|
|
web:
|
|
|
|
build: .
|
2014-01-28 11:32:55 +01:00
|
|
|
command: python app.py
|
2014-01-27 12:42:38 +01:00
|
|
|
ports:
|
2014-02-20 13:53:43 +01:00
|
|
|
- "5000:5000"
|
2014-01-27 12:42:38 +01:00
|
|
|
volumes:
|
|
|
|
- .:/code
|
|
|
|
links:
|
|
|
|
- redis
|
|
|
|
redis:
|
2014-08-07 23:50:55 +02:00
|
|
|
image: redis
|
2014-01-27 12:42:38 +01:00
|
|
|
|
|
|
|
This defines two services:
|
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
- `web`, which is built from the `Dockerfile` in the current directory. It also
|
2015-01-30 12:27:57 +01:00
|
|
|
says to run the command `python app.py` inside the image, forward the exposed
|
|
|
|
port 5000 on the container to port 5000 on the host machine, connect up the
|
|
|
|
Redis service, and mount the current directory inside the container so we can
|
|
|
|
work on code without having to rebuild the image.
|
|
|
|
- `redis`, which uses the public image
|
|
|
|
[redis](https://registry.hub.docker.com/_/redis/), which gets pulled from the
|
|
|
|
Docker Hub registry.
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
### Build and run your app with Compose
|
|
|
|
|
|
|
|
Now, when you run `docker-compose up`, Compose will pull a Redis image, build an
|
|
|
|
image for your code, and start everything up:
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-20 18:29:28 +01:00
|
|
|
$ docker-compose up
|
2014-08-07 23:50:55 +02:00
|
|
|
Pulling image redis...
|
2014-01-27 12:42:38 +01:00
|
|
|
Building web...
|
2015-01-20 18:44:48 +01:00
|
|
|
Starting composetest_redis_1...
|
|
|
|
Starting composetest_web_1...
|
2014-07-10 02:34:17 +02:00
|
|
|
redis_1 | [8] 02 Jan 18:43:35.576 # Server started, Redis version 2.8.3
|
|
|
|
web_1 | * Running on http://0.0.0.0:5000/
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-30 12:27:57 +01:00
|
|
|
The web app should now be listening on port 5000 on your Docker daemon host (if
|
|
|
|
you're using Boot2docker, `boot2docker ip` will tell you its address).
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
If you want to run your services in the background, you can pass the `-d` flag
|
|
|
|
(for daemon mode) to `docker-compose up` and use `docker-compose ps` to see what
|
|
|
|
is currently running:
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-20 18:29:28 +01:00
|
|
|
$ docker-compose up -d
|
2015-01-20 18:44:48 +01:00
|
|
|
Starting composetest_redis_1...
|
|
|
|
Starting composetest_web_1...
|
2015-01-20 18:29:28 +01:00
|
|
|
$ docker-compose ps
|
2015-01-30 12:27:57 +01:00
|
|
|
Name Command State Ports
|
2014-01-27 12:42:38 +01:00
|
|
|
-------------------------------------------------------------------
|
2015-01-20 18:44:48 +01:00
|
|
|
composetest_redis_1 /usr/local/bin/run Up
|
|
|
|
composetest_web_1 /bin/sh -c python app.py Up 5000->5000/tcp
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
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
|
|
|
|
`web` service:
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-20 18:29:28 +01:00
|
|
|
$ docker-compose run web env
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-30 03:21:49 +01:00
|
|
|
See `docker-compose --help` to see other available commands.
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-19 06:46:23 +01:00
|
|
|
If you started Compose with `docker-compose up -d`, you'll probably want to stop
|
|
|
|
your services once you've finished with them:
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-01-20 18:29:28 +01:00
|
|
|
$ docker-compose stop
|
2014-01-27 12:42:38 +01:00
|
|
|
|
2015-02-25 15:04:30 +01:00
|
|
|
At this point, you have seen the basics of how Compose works.
|
2015-02-25 09:43:33 +01:00
|
|
|
|
2015-02-25 15:04:30 +01:00
|
|
|
- Next, try the quick start guide for [Django](django.md),
|
|
|
|
[Rails](rails.md), or [Wordpress](wordpress.md).
|
|
|
|
- See the reference guides for complete details on the [commands](cli.md), the
|
|
|
|
[configuration file](yml.md) and [environment variables](env.md).
|