From 7014cabb04fed3e31fe65c034604f1224195a2fa Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Fri, 9 Oct 2015 12:34:55 -0400 Subject: [PATCH 1/6] Remove duplication from extends docs. Start restructuring extends docs in preparation for adding documentation about using multiple compose files. Signed-off-by: Daniel Nephin --- docs/compose-file.md | 51 ++++----- docs/extends.md | 240 +++++++++++-------------------------------- 2 files changed, 80 insertions(+), 211 deletions(-) diff --git a/docs/compose-file.md b/docs/compose-file.md index 7723a784..00b04d58 100644 --- a/docs/compose-file.md +++ b/docs/compose-file.md @@ -168,44 +168,29 @@ accessible to linked services. Only the internal port can be specified. Extend another service, in the current file or another, optionally overriding configuration. -Here's a simple example. Suppose we have 2 files - **common.yml** and -**development.yml**. We can use `extends` to define a service in -**development.yml** which uses configuration defined in **common.yml**: +You can use `extends` on any service together with other configuration keys. +The value must be a dictionary with the key: `service` and may optionally have +the `file` key. -**common.yml** + extends: + file: common.yml + service: webapp - webapp: - build: ./webapp - environment: - - DEBUG=false - - SEND_EMAILS=false +The `file` key specifies the location of a Compose configuration file defining +the service which is being extended. The `file` value can be an absolute or +relative path. If you specify a relative path, Docker Compose treats it as +relative to the location of the current file. If you don't specify a `file`, +Compose looks in the current configuration file. -**development.yml** +The `service` key specifies the name of the service to extend, for example `web` +or `database`. - web: - extends: - file: common.yml - service: webapp - ports: - - "8000:8000" - links: - - db - environment: - - DEBUG=true - db: - image: postgres +You can extend a service that itself extends another. You can extend +indefinitely. Compose does not support circular references and `docker-compose` +returns an error if it encounters one. -Here, the `web` service in **development.yml** inherits the configuration of -the `webapp` service in **common.yml** - the `build` and `environment` keys - -and adds `ports` and `links` configuration. It overrides one of the defined -environment variables (DEBUG) with a new value, and the other one -(SEND_EMAILS) is left untouched. - -The `file` key is optional, if it is not set then Compose will look for the -service within the current file. - -For more on `extends`, see the [tutorial](extends.md#example) and -[reference](extends.md#reference). +For more on `extends`, see the +[the extends documentation](extends.md#extending-services). ### external_links diff --git a/docs/extends.md b/docs/extends.md index e63cf466..c97b2b4f 100644 --- a/docs/extends.md +++ b/docs/extends.md @@ -10,20 +10,29 @@ weight=2 -## Extending services in Compose +## Extending services and Compose files + +Compose supports two ways to sharing common configuration and +extend a service with that shared configuration. + +1. Extending individual services with [the `extends` field](#extending-services) +2. Extending entire compositions by + [exnteding compose files](#extending-compose-files) + +### Extending services Docker Compose's `extends` keyword enables sharing of common configurations among different files, or even different projects entirely. Extending services -is useful if you have several applications that reuse commonly-defined services. -Using `extends` you can define a service in one place and refer to it from -anywhere. +is useful if you have several services that reuse a common set of configuration +options. Using `extends` you can define a common set of service options in one +place and refer to it from anywhere. -Alternatively, you can deploy the same application to multiple environments with -a slightly different set of services in each case (or with changes to the -configuration of some services). Moreover, you can do so without copy-pasting -the configuration around. +> **Note:** `links` and `volumes_from` are never shared between services using +> `extends`. See +> [Adding and overriding configuration](#adding-and-overriding-configuration) +> for more information. -### Understand the extends configuration +#### Understand the extends configuration When defining any service in `docker-compose.yml`, you can declare that you are extending another service like this: @@ -77,183 +86,46 @@ You can also write other services and link your `web` service to them: db: image: postgres -For full details on how to use `extends`, refer to the [reference](#reference). +#### Example use case -### Example use case +Extending an individual service is useful when you have multiple services that +have a common configuration. In this example we have a composition that with +a web application and a queue worker. Both services use the same codebase and +share many configuration options. -In this example, you’ll repurpose the example app from the [quick start -guide](/). (If you're not familiar with Compose, it's recommended that -you go through the quick start first.) This example assumes you want to use -Compose both to develop an application locally and then deploy it to a -production environment. +In a **common.yml** we'll define the common configuration: -The local and production environments are similar, but there are some -differences. In development, you mount the application code as a volume so that -it can pick up changes; in production, the code should be immutable from the -outside. This ensures it’s not accidentally changed. The development environment -uses a local Redis container, but in production another team manages the Redis -service, which is listening at `redis-production.example.com`. + app: + build: . + environment: + CONFIG_FILE_PATH: /code/config + API_KEY: xxxyyy + cpu_shares: 5 -To configure with `extends` for this sample, you must: - -1. Define the web application as a Docker image in `Dockerfile` and a Compose - service in `common.yml`. - -2. Define the development environment in the standard Compose file, - `docker-compose.yml`. - - - Use `extends` to pull in the web service. - - Configure a volume to enable code reloading. - - Create an additional Redis service for the application to use locally. - -3. Define the production environment in a third Compose file, `production.yml`. - - - Use `extends` to pull in the web service. - - Configure the web service to talk to the external, production Redis service. - -#### Define the web app - -Defining the web application requires the following: - -1. Create an `app.py` file. - - This file contains a simple Python application that uses Flask to serve HTTP - and increments a counter in Redis: - - from flask import Flask - from redis import Redis - import os - - app = Flask(__name__) - redis = Redis(host=os.environ['REDIS_HOST'], port=6379) - - @app.route('/') - def hello(): - redis.incr('hits') - return 'Hello World! I have been seen %s times.\n' % redis.get('hits') - - if __name__ == "__main__": - app.run(host="0.0.0.0", debug=True) - - This code uses a `REDIS_HOST` environment variable to determine where to - find Redis. - -2. Define the Python dependencies in a `requirements.txt` file: - - flask - redis - -3. Create a `Dockerfile` to build an image containing the app: - - FROM python:2.7 - ADD . /code - WORKDIR /code - RUN pip install -r requirements.txt - CMD python app.py - -4. Create a Compose configuration file called `common.yml`: - - This configuration defines how to run the app. - - web: - build: . - ports: - - "5000:5000" - - Typically, you would have dropped this configuration into - `docker-compose.yml` file, but in order to pull it into multiple files with - `extends`, it needs to be in a separate file. - -#### Define the development environment - -1. Create a `docker-compose.yml` file. - - The `extends` option pulls in the `web` service from the `common.yml` file - you created in the previous section. - - web: - extends: - file: common.yml - service: web - volumes: - - .:/code - links: - - redis - environment: - - REDIS_HOST=redis - redis: - image: redis - - The new addition defines a `web` service that: - - - Fetches the base configuration for `web` out of `common.yml`. - - Adds `volumes` and `links` configuration to the base (`common.yml`) - configuration. - - Sets the `REDIS_HOST` environment variable to point to the linked redis - container. This environment uses a stock `redis` image from the Docker Hub. - -2. Run `docker-compose up`. - - Compose creates, links, and starts a web and redis container linked together. - It mounts your application code inside the web container. - -3. Verify that the code is mounted by changing the message in - `app.py`—say, from `Hello world!` to `Hello from Compose!`. - - Don't forget to refresh your browser to see the change! - -#### Define the production environment - -You are almost done. Now, define your production environment: - -1. Create a `production.yml` file. - - As with `docker-compose.yml`, the `extends` option pulls in the `web` service - from `common.yml`. - - web: - extends: - file: common.yml - service: web - environment: - - REDIS_HOST=redis-production.example.com - -2. Run `docker-compose -f production.yml up`. - - Compose creates *just* a web container and configures the Redis connection via - the `REDIS_HOST` environment variable. This variable points to the production - Redis instance. - - > **Note**: If you try to load up the webapp in your browser you'll get an - > error—`redis-production.example.com` isn't actually a Redis server. - -You've now done a basic `extends` configuration. As your application develops, -you can make any necessary changes to the web service in `common.yml`. Compose -picks up both the development and production environments when you next run -`docker-compose`. You don't have to do any copy-and-paste, and you don't have to -manually keep both environments in sync. +In a **docker-compose.yml** we'll define the concrete services which use the +common configuration: -### Reference + webapp: + extends: + file: common.yml + service: app + command: /code/run_web_app + ports: + - 8080:8080 + links: + - queue + - db -You can use `extends` on any service together with other configuration keys. It -expects a dictionary that contains a `service` key and optionally a `file` key. -The `extends` key can also take a string, whose value is the name of a `service` defined in the same file. + queue_worker: + extends: + file: common.yml + service: app + command: /code/run_worker + links: + - queue -The `file` key specifies the location of a Compose configuration file defining -the extension. The `file` value can be an absolute or relative path. If you -specify a relative path, Docker Compose treats it as relative to the location -of the current file. If you don't specify a `file`, Compose looks in the -current configuration file. - -The `service` key specifies the name of the service to extend, for example `web` -or `database`. - -You can extend a service that itself extends another. You can extend -indefinitely. Compose does not support circular references and `docker-compose` -returns an error if it encounters them. - -#### Adding and overriding configuration +#### Adding and overriding configuration Compose copies configurations from the original service over to the local one, **except** for `links` and `volumes_from`. These exceptions exist to avoid @@ -282,6 +154,8 @@ listed below.** In the case of `build` and `image`, using one in the local service causes Compose to discard the other, if it was defined in the original service. +Example of image replacing build: + # original service build: . @@ -291,6 +165,9 @@ Compose to discard the other, if it was defined in the original service. # result image: redis + +Example of build replacing image: + # original service image: redis @@ -356,6 +233,13 @@ locally-defined bindings taking precedence: - /local-dir/bar:/bar - /local-dir/baz/:baz + +### Extending Compose files + +> **Note:** This feature is new in `docker-compose` 1.5 + + + ## Compose documentation - [User guide](/) From 1c4c7ccface1e71e462b1ff3d840c0d0804d230d Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 29 Oct 2015 15:21:06 -0400 Subject: [PATCH 2/6] Support a volume to the docs directory and add --watch, so docs can be refreshed. Signed-off-by: Daniel Nephin --- docs/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index 021e8f6e..b9ef0548 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -13,8 +13,8 @@ DOCKER_ENVS := \ -e TIMEOUT # note: we _cannot_ add "-e DOCKER_BUILDTAGS" here because even if it's unset in the shell, that would shadow the "ENV DOCKER_BUILDTAGS" set in our Dockerfile, which is very important for our official builds -# to allow `make DOCSDIR=docs docs-shell` (to create a bind mount in docs) -DOCS_MOUNT := $(if $(DOCSDIR),-v $(CURDIR)/$(DOCSDIR):/$(DOCSDIR)) +# to allow `make DOCSDIR=1 docs-shell` (to create a bind mount in docs) +DOCS_MOUNT := $(if $(DOCSDIR),-v $(CURDIR):/docs/content/compose) # to allow `make DOCSPORT=9000 docs` DOCSPORT := 8000 @@ -37,7 +37,7 @@ GITCOMMIT := $(shell git rev-parse --short HEAD 2>/dev/null) default: docs docs: docs-build - $(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 -e DOCKERHOST "$(DOCKER_DOCS_IMAGE)" hugo server --port=$(DOCSPORT) --baseUrl=$(HUGO_BASE_URL) --bind=$(HUGO_BIND_IP) + $(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 -e DOCKERHOST "$(DOCKER_DOCS_IMAGE)" hugo server --port=$(DOCSPORT) --baseUrl=$(HUGO_BASE_URL) --bind=$(HUGO_BIND_IP) --watch docs-draft: docs-build $(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 -e DOCKERHOST "$(DOCKER_DOCS_IMAGE)" hugo server --buildDrafts="true" --port=$(DOCSPORT) --baseUrl=$(HUGO_BASE_URL) --bind=$(HUGO_BIND_IP) From c5cf5cfad45afb66f6b47fd6b7a0937e1e82f7f3 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Wed, 21 Oct 2015 17:17:38 -0400 Subject: [PATCH 3/6] Changes to production.md for working with multiple Compose files. Signed-off-by: Daniel Nephin --- docs/production.md | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/docs/production.md b/docs/production.md index 0b0e46c3..39f0e1fe 100644 --- a/docs/production.md +++ b/docs/production.md @@ -12,11 +12,9 @@ weight=1 ## Using Compose in production -While **Compose is not yet considered production-ready**, if you'd like to experiment and learn more about using it in production deployments, this guide -can help. -The project is actively working towards becoming -production-ready; to learn more about the progress being made, check out the roadmap for details -on how it's coming along and what still needs to be done. +> Compose is still primarily aimed at development and testing environments. +> Compose may be used for smaller production deployments, but is probably +> not yet suitable for larger deployments. When deploying to production, you'll almost certainly want to make changes to your app configuration that are more appropriate to a live environment. These @@ -30,22 +28,16 @@ changes may include: - Specifying a restart policy (e.g., `restart: always`) to avoid downtime - Adding extra services (e.g., a log aggregator) -For this reason, you'll probably want to define a separate Compose file, say -`production.yml`, which specifies production-appropriate configuration. +For this reason, you'll probably want to define an additional Compose file, say +`production.yml`, which specifies production-appropriate +configuration. This configuration file only needs to include the changes you'd +like to make from the original Compose file. The additional Compose file +can be applied over the original `docker-compose.yml` to create a new configuration. -> **Note:** The [extends](extends.md) keyword is useful for maintaining multiple -> Compose files which re-use common services without having to manually copy and -> paste. +Once you've got a second configuration file, tell Compose to use it with the +`-f` option: -Once you've got an alternate configuration file, make Compose use it -by setting the `COMPOSE_FILE` environment variable: - - $ export COMPOSE_FILE=production.yml - $ docker-compose up -d - -> **Note:** You can also use the file for a one-off command without setting -> an environment variable. You do this by passing the `-f` flag, e.g., -> `docker-compose -f production.yml up -d`. + $ docker-compose -f docker-compose.yml -f production.yml up -d ### Deploying changes From eab265befaa6c48d44ad2b9314ccc97ad6630f7b Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Fri, 9 Oct 2015 12:56:59 -0400 Subject: [PATCH 4/6] Document using multiple Compose files use cases. Signed-off-by: Daniel Nephin --- docs/compose-file.md | 18 ++-- docs/extends.md | 208 ++++++++++++++++++++++++++++++++++--------- docs/production.md | 3 + 3 files changed, 176 insertions(+), 53 deletions(-) diff --git a/docs/compose-file.md b/docs/compose-file.md index 00b04d58..4f8fc9e0 100644 --- a/docs/compose-file.md +++ b/docs/compose-file.md @@ -169,21 +169,21 @@ Extend another service, in the current file or another, optionally overriding configuration. You can use `extends` on any service together with other configuration keys. -The value must be a dictionary with the key: `service` and may optionally have -the `file` key. +The `extends` value must be a dictionary defined with a required `service` +and an optional `file` key. extends: file: common.yml service: webapp -The `file` key specifies the location of a Compose configuration file defining -the service which is being extended. The `file` value can be an absolute or -relative path. If you specify a relative path, Docker Compose treats it as -relative to the location of the current file. If you don't specify a `file`, -Compose looks in the current configuration file. +The `service` the name of the service being extended, for example +`web` or `database`. The `file` is the location of a Compose configuration +file defining that service. -The `service` key specifies the name of the service to extend, for example `web` -or `database`. +If you omit the `file` Compose looks for the service configuration in the +current file. The `file` value can be an absolute or relative path. If you +specify a relative path, Compose treats it as relative to the location of the +current file. You can extend a service that itself extends another. You can extend indefinitely. Compose does not support circular references and `docker-compose` diff --git a/docs/extends.md b/docs/extends.md index c97b2b4f..58def22d 100644 --- a/docs/extends.md +++ b/docs/extends.md @@ -10,16 +10,15 @@ weight=2 -## Extending services and Compose files +# Extending services and Compose files -Compose supports two ways to sharing common configuration and -extend a service with that shared configuration. +Compose supports two methods of sharing common configuration: 1. Extending individual services with [the `extends` field](#extending-services) 2. Extending entire compositions by - [exnteding compose files](#extending-compose-files) + [using multiple compose files](#multiple-compose-files) -### Extending services +## Extending services Docker Compose's `extends` keyword enables sharing of common configurations among different files, or even different projects entirely. Extending services @@ -30,9 +29,9 @@ place and refer to it from anywhere. > **Note:** `links` and `volumes_from` are never shared between services using > `extends`. See > [Adding and overriding configuration](#adding-and-overriding-configuration) -> for more information. + > for more information. -#### Understand the extends configuration +### Understand the extends configuration When defining any service in `docker-compose.yml`, you can declare that you are extending another service like this: @@ -54,8 +53,8 @@ looks like this: - "/data" In this case, you'll get exactly the same result as if you wrote -`docker-compose.yml` with that `build`, `ports` and `volumes` configuration -defined directly under `web`. +`docker-compose.yml` with the same `build`, `ports` and `volumes` configuration +values defined directly under `web`. You can go further and define (or re-define) configuration locally in `docker-compose.yml`: @@ -86,14 +85,14 @@ You can also write other services and link your `web` service to them: db: image: postgres -#### Example use case +### Example use case Extending an individual service is useful when you have multiple services that -have a common configuration. In this example we have a composition that with -a web application and a queue worker. Both services use the same codebase and -share many configuration options. +have a common configuration. The example below is a composition with +two services: a web application and a queue worker. Both services use the same +codebase and share many configuration options. -In a **common.yml** we'll define the common configuration: +In a **common.yml** we define the common configuration: app: build: . @@ -102,10 +101,9 @@ In a **common.yml** we'll define the common configuration: API_KEY: xxxyyy cpu_shares: 5 -In a **docker-compose.yml** we'll define the concrete services which use the +In a **docker-compose.yml** we define the concrete services which use the common configuration: - webapp: extends: file: common.yml @@ -121,11 +119,11 @@ common configuration: extends: file: common.yml service: app - command: /code/run_worker - links: - - queue + command: /code/run_worker + links: + - queue -#### Adding and overriding configuration +### Adding and overriding configuration Compose copies configurations from the original service over to the local one, **except** for `links` and `volumes_from`. These exceptions exist to avoid @@ -134,13 +132,11 @@ locally. This ensures dependencies between services are clearly visible when reading the current file. Defining these locally also ensures changes to the referenced file don't result in breakage. -If a configuration option is defined in both the original service and the local -service, the local value either *override*s or *extend*s the definition of the -original service. This works differently for other configuration options. +If a configuration option is defined in both the original service the local +service, the local value *replaces* or *extends* the original value. For single-value options like `image`, `command` or `mem_limit`, the new value -replaces the old value. **This is the default behaviour - all exceptions are -listed below.** +replaces the old value. # original service command: python app.py @@ -195,8 +191,8 @@ For the **multi-value options** `ports`, `expose`, `external_links`, `dns` and - "4000" - "5000" -In the case of `environment` and `labels`, Compose "merges" entries together -with locally-defined values taking precedence: +In the case of `environment`, `labels`, `volumes` and `devices`, Compose +"merges" entries together with locally-defined values taking precedence: # original service environment: @@ -214,30 +210,154 @@ with locally-defined values taking precedence: - BAR=local - BAZ=local -Finally, for `volumes` and `devices`, Compose "merges" entries together with -locally-defined bindings taking precedence: - # original service - volumes: - - /original-dir/foo:/foo - - /original-dir/bar:/bar +## Multiple Compose files - # local service - volumes: - - /local-dir/bar:/bar - - /local-dir/baz/:baz +Using multiple Compose files enables you to customize a composition for +different environments or different workflows. - # result - volumes: - - /original-dir/foo:/foo - - /local-dir/bar:/bar - - /local-dir/baz/:baz +### Understanding multiple Compose files + +By default, Compose reads two files, a `docker-compose.yml` and an optional +`docker-compose.override.yml` file. By convention, the `docker-compose.yml` +contains your base configuration. The override file, as its name implies, can +contain configuration overrides for existing services or entirely new +services. + +If a service is defined in both files, Compose merges the configurations using +the same rules as the `extends` field (see [Adding and overriding +configuration](#adding-and-overriding-configuration)), with one exception. If a +service contains `links` or `volumes_from` those fields are copied over and +replace any values in the original service, in the same way single-valued fields +are copied. + +To use multiple override files, or an override file with a different name, you +can use the `-f` option to specify the list of files. Compose merges files in +the order they're specified on the command line. See the [`docker-compose` +command reference](./reference/docker-compose.md) for more information about +using `-f`. + +When you use multiple configuration files, you must make sure all paths in the +files are relative to the base Compose file (the first Compose file specified +with `-f`). This is required because override files need not be valid +Compose files. Override files can contain small fragments of configuration. +Tracking which fragment of a service is relative to which path is difficult and +confusing, so to keep paths easier to understand, all paths must be defined +relative to the base file. + +### Example use case + +In this section are two common use cases for multiple compose files: changing a +composition for different environments, and running administrative tasks +against a composition. + +#### Different environments + +A common use case for multiple files is changing a development composition +for a production-like environment (which may be production, staging or CI). +To support these differences, you can split your Compose configuration into +a few different files: + +Start with a base file that defines the canonical configuration for the +services. + +**docker-compose.yml** + + web: + image: example/my_web_app:latest + links: + - db + - cache + + db: + image: postgres:latest + + cache: + image: redis:latest + +In this example the development configuration exposes some ports to the +host, mounts our code as a volume, and builds the web image. + +**docker-compose.override.yml** -### Extending Compose files + web: + build: . + volumes: + - '.:/code' + ports: + - 8883:80 + environment: + DEBUG: 'true' -> **Note:** This feature is new in `docker-compose` 1.5 + db: + command: '-d' + ports: + - 5432:5432 + cache: + ports: + - 6379:6379 + +When you run `docker-compose up` it reads the overrides automatically. + +Now, it would be nice to use this composition in a production environment. So, +create another override file (which might be stored in a different git +repo or managed by a different team). + +**docker-compose.prod.yml** + + web: + ports: + - 80:80 + environment: + PRODUCTION: 'true' + + cache: + environment: + TTL: '500' + +To deploy with this production Compose file you can run + + docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d + +This deploys all three services using the configuration in +`docker-compose.yml` and `docker-compose.prod.yml` (but not the +dev configuration in `docker-compose.override.yml`). + + +See [production](production.md) for more information about Compose in +production. + +#### Administrative tasks + +Another common use case is running adhoc or administrative tasks against one +or more services in a composition. This example demonstrates running a +database backup. + +Start with a **docker-compose.yml**. + + web: + image: example/my_web_app:latest + links: + - db + + db: + image: postgres:latest + +In a **docker-compose.admin.yml** add a new service to run the database +export or backup. + + dbadmin: + build: database_admin/ + links: + - db + +To start a normal environment run `docker-compose up -d`. To run a database +backup, include the `docker-compose.admin.yml` as well. + + docker-compose -f docker-compose.yml -f docker-compose.admin.yml \ + run dbadmin db-backup ## Compose documentation diff --git a/docs/production.md b/docs/production.md index 39f0e1fe..0a5e77b5 100644 --- a/docs/production.md +++ b/docs/production.md @@ -39,6 +39,9 @@ Once you've got a second configuration file, tell Compose to use it with the $ docker-compose -f docker-compose.yml -f production.yml up -d +See [Using multiple compose files](extends.md#different-environments) for a more +complete example. + ### Deploying changes When you make changes to your app code, you'll need to rebuild your image and From 8bdde9a7313fbaf5221dff20b314aa0fed0dd66a Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Mon, 2 Nov 2015 15:14:42 -0500 Subject: [PATCH 5/6] Replace composition with Compose app. Signed-off-by: Daniel Nephin --- docs/extends.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/extends.md b/docs/extends.md index 58def22d..e4d09af9 100644 --- a/docs/extends.md +++ b/docs/extends.md @@ -15,8 +15,8 @@ weight=2 Compose supports two methods of sharing common configuration: 1. Extending individual services with [the `extends` field](#extending-services) -2. Extending entire compositions by - [using multiple compose files](#multiple-compose-files) +2. Extending entire Compose file by + [using multiple Compose files](#multiple-compose-files) ## Extending services @@ -88,7 +88,7 @@ You can also write other services and link your `web` service to them: ### Example use case Extending an individual service is useful when you have multiple services that -have a common configuration. The example below is a composition with +have a common configuration. The example below is a Compose app with two services: a web application and a queue worker. Both services use the same codebase and share many configuration options. @@ -213,8 +213,8 @@ In the case of `environment`, `labels`, `volumes` and `devices`, Compose ## Multiple Compose files -Using multiple Compose files enables you to customize a composition for -different environments or different workflows. +Using multiple Compose files enables you to customize a Compose application +for different environments or different workflows. ### Understanding multiple Compose files @@ -248,12 +248,12 @@ relative to the base file. ### Example use case In this section are two common use cases for multiple compose files: changing a -composition for different environments, and running administrative tasks -against a composition. +Compose app for different environments, and running administrative tasks +against a Compose app. #### Different environments -A common use case for multiple files is changing a development composition +A common use case for multiple files is changing a development Compose app for a production-like environment (which may be production, staging or CI). To support these differences, you can split your Compose configuration into a few different files: @@ -301,7 +301,7 @@ host, mounts our code as a volume, and builds the web image. When you run `docker-compose up` it reads the overrides automatically. -Now, it would be nice to use this composition in a production environment. So, +Now, it would be nice to use this Compose app in a production environment. So, create another override file (which might be stored in a different git repo or managed by a different team). @@ -332,7 +332,7 @@ production. #### Administrative tasks Another common use case is running adhoc or administrative tasks against one -or more services in a composition. This example demonstrates running a +or more services in a Compose app. This example demonstrates running a database backup. Start with a **docker-compose.yml**. From e503e085ac98e6e744020f5068be40412f443f67 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Tue, 3 Nov 2015 11:52:44 -0500 Subject: [PATCH 6/6] Re-order extends docs. Signed-off-by: Daniel Nephin --- docs/extends.md | 391 ++++++++++++++++++++++++------------------------ 1 file changed, 197 insertions(+), 194 deletions(-) diff --git a/docs/extends.md b/docs/extends.md index e4d09af9..b21b6d76 100644 --- a/docs/extends.md +++ b/docs/extends.md @@ -14,201 +14,9 @@ weight=2 Compose supports two methods of sharing common configuration: -1. Extending individual services with [the `extends` field](#extending-services) -2. Extending entire Compose file by +1. Extending an entire Compose file by [using multiple Compose files](#multiple-compose-files) - -## Extending services - -Docker Compose's `extends` keyword enables sharing of common configurations -among different files, or even different projects entirely. Extending services -is useful if you have several services that reuse a common set of configuration -options. Using `extends` you can define a common set of service options in one -place and refer to it from anywhere. - -> **Note:** `links` and `volumes_from` are never shared between services using -> `extends`. See -> [Adding and overriding configuration](#adding-and-overriding-configuration) - > for more information. - -### Understand the extends configuration - -When defining any service in `docker-compose.yml`, you can declare that you are -extending another service like this: - - web: - extends: - file: common-services.yml - service: webapp - -This instructs Compose to re-use the configuration for the `webapp` service -defined in the `common-services.yml` file. Suppose that `common-services.yml` -looks like this: - - webapp: - build: . - ports: - - "8000:8000" - volumes: - - "/data" - -In this case, you'll get exactly the same result as if you wrote -`docker-compose.yml` with the same `build`, `ports` and `volumes` configuration -values defined directly under `web`. - -You can go further and define (or re-define) configuration locally in -`docker-compose.yml`: - - web: - extends: - file: common-services.yml - service: webapp - environment: - - DEBUG=1 - cpu_shares: 5 - - important_web: - extends: web - cpu_shares: 10 - -You can also write other services and link your `web` service to them: - - web: - extends: - file: common-services.yml - service: webapp - environment: - - DEBUG=1 - cpu_shares: 5 - links: - - db - db: - image: postgres - -### Example use case - -Extending an individual service is useful when you have multiple services that -have a common configuration. The example below is a Compose app with -two services: a web application and a queue worker. Both services use the same -codebase and share many configuration options. - -In a **common.yml** we define the common configuration: - - app: - build: . - environment: - CONFIG_FILE_PATH: /code/config - API_KEY: xxxyyy - cpu_shares: 5 - -In a **docker-compose.yml** we define the concrete services which use the -common configuration: - - webapp: - extends: - file: common.yml - service: app - command: /code/run_web_app - ports: - - 8080:8080 - links: - - queue - - db - - queue_worker: - extends: - file: common.yml - service: app - command: /code/run_worker - links: - - queue - -### Adding and overriding configuration - -Compose copies configurations from the original service over to the local one, -**except** for `links` and `volumes_from`. These exceptions exist to avoid -implicit dependencies—you always define `links` and `volumes_from` -locally. This ensures dependencies between services are clearly visible when -reading the current file. Defining these locally also ensures changes to the -referenced file don't result in breakage. - -If a configuration option is defined in both the original service the local -service, the local value *replaces* or *extends* the original value. - -For single-value options like `image`, `command` or `mem_limit`, the new value -replaces the old value. - - # original service - command: python app.py - - # local service - command: python otherapp.py - - # result - command: python otherapp.py - -In the case of `build` and `image`, using one in the local service causes -Compose to discard the other, if it was defined in the original service. - -Example of image replacing build: - - # original service - build: . - - # local service - image: redis - - # result - image: redis - - -Example of build replacing image: - - # original service - image: redis - - # local service - build: . - - # result - build: . - -For the **multi-value options** `ports`, `expose`, `external_links`, `dns` and -`dns_search`, Compose concatenates both sets of values: - - # original service - expose: - - "3000" - - # local service - expose: - - "4000" - - "5000" - - # result - expose: - - "3000" - - "4000" - - "5000" - -In the case of `environment`, `labels`, `volumes` and `devices`, Compose -"merges" entries together with locally-defined values taking precedence: - - # original service - environment: - - FOO=original - - BAR=original - - # local service - environment: - - BAR=local - - BAZ=local - - # result - environment: - - FOO=original - - BAR=local - - BAZ=local +2. Extending individual services with [the `extends` field](#extending-services) ## Multiple Compose files @@ -360,6 +168,201 @@ backup, include the `docker-compose.admin.yml` as well. run dbadmin db-backup +## Extending services + +Docker Compose's `extends` keyword enables sharing of common configurations +among different files, or even different projects entirely. Extending services +is useful if you have several services that reuse a common set of configuration +options. Using `extends` you can define a common set of service options in one +place and refer to it from anywhere. + +> **Note:** `links` and `volumes_from` are never shared between services using +> `extends`. See +> [Adding and overriding configuration](#adding-and-overriding-configuration) + > for more information. + +### Understand the extends configuration + +When defining any service in `docker-compose.yml`, you can declare that you are +extending another service like this: + + web: + extends: + file: common-services.yml + service: webapp + +This instructs Compose to re-use the configuration for the `webapp` service +defined in the `common-services.yml` file. Suppose that `common-services.yml` +looks like this: + + webapp: + build: . + ports: + - "8000:8000" + volumes: + - "/data" + +In this case, you'll get exactly the same result as if you wrote +`docker-compose.yml` with the same `build`, `ports` and `volumes` configuration +values defined directly under `web`. + +You can go further and define (or re-define) configuration locally in +`docker-compose.yml`: + + web: + extends: + file: common-services.yml + service: webapp + environment: + - DEBUG=1 + cpu_shares: 5 + + important_web: + extends: web + cpu_shares: 10 + +You can also write other services and link your `web` service to them: + + web: + extends: + file: common-services.yml + service: webapp + environment: + - DEBUG=1 + cpu_shares: 5 + links: + - db + db: + image: postgres + +### Example use case + +Extending an individual service is useful when you have multiple services that +have a common configuration. The example below is a Compose app with +two services: a web application and a queue worker. Both services use the same +codebase and share many configuration options. + +In a **common.yml** we define the common configuration: + + app: + build: . + environment: + CONFIG_FILE_PATH: /code/config + API_KEY: xxxyyy + cpu_shares: 5 + +In a **docker-compose.yml** we define the concrete services which use the +common configuration: + + webapp: + extends: + file: common.yml + service: app + command: /code/run_web_app + ports: + - 8080:8080 + links: + - queue + - db + + queue_worker: + extends: + file: common.yml + service: app + command: /code/run_worker + links: + - queue + +## Adding and overriding configuration + +Compose copies configurations from the original service over to the local one, +**except** for `links` and `volumes_from`. These exceptions exist to avoid +implicit dependencies—you always define `links` and `volumes_from` +locally. This ensures dependencies between services are clearly visible when +reading the current file. Defining these locally also ensures changes to the +referenced file don't result in breakage. + +If a configuration option is defined in both the original service the local +service, the local value *replaces* or *extends* the original value. + +For single-value options like `image`, `command` or `mem_limit`, the new value +replaces the old value. + + # original service + command: python app.py + + # local service + command: python otherapp.py + + # result + command: python otherapp.py + +In the case of `build` and `image`, using one in the local service causes +Compose to discard the other, if it was defined in the original service. + +Example of image replacing build: + + # original service + build: . + + # local service + image: redis + + # result + image: redis + + +Example of build replacing image: + + # original service + image: redis + + # local service + build: . + + # result + build: . + +For the **multi-value options** `ports`, `expose`, `external_links`, `dns` and +`dns_search`, Compose concatenates both sets of values: + + # original service + expose: + - "3000" + + # local service + expose: + - "4000" + - "5000" + + # result + expose: + - "3000" + - "4000" + - "5000" + +In the case of `environment`, `labels`, `volumes` and `devices`, Compose +"merges" entries together with locally-defined values taking precedence: + + # original service + environment: + - FOO=original + - BAR=original + + # local service + environment: + - BAR=local + - BAZ=local + + # result + environment: + - FOO=original + - BAR=local + - BAZ=local + + + + ## Compose documentation - [User guide](/)