1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
<h1>Share Compose configurations between files and projects</h1>
<p>Compose supports two methods of sharing common configuration:</p> <ol> <li>Extending an entire Compose file by <a href="index#multiple-compose-files">using multiple Compose files</a>
</li> <li>Extending individual services with <a href="index#extending-services">the <code class="language-plaintext highlighter-rouge">extends</code> field</a> (for Compose file versions up to 2.1)</li> </ol> <h2 id="multiple-compose-files">Multiple Compose files</h2> <p>Using multiple Compose files enables you to customize a Compose application for different environments or different workflows.</p> <h3 id="understanding-multiple-compose-files">Understanding multiple Compose files</h3> <p>By default, Compose reads two files, a <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> and an optional <code class="language-plaintext highlighter-rouge">docker-compose.override.yml</code> file. By convention, the <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> contains your base configuration. The override file, as its name implies, can contain configuration overrides for existing services or entirely new services.</p> <p>If a service is defined in both files, Compose merges the configurations using the rules described in <a href="index#adding-and-overriding-configuration">Adding and overriding configuration</a>.</p> <p>To use multiple override files, or an override file with a different name, you can use the <code class="language-plaintext highlighter-rouge">-f</code> option to specify the list of files. Compose merges files in the order they’re specified on the command line. See the <a href="../reference/index"><code class="language-plaintext highlighter-rouge">docker-compose</code> command reference</a> for more information about using <code class="language-plaintext highlighter-rouge">-f</code>.</p> <p>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 <code class="language-plaintext highlighter-rouge">-f</code>). 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.</p> <h3 id="example-use-case">Example use case</h3> <p>In this section, there are two common use cases for multiple Compose files: changing a Compose app for different environments, and running administrative tasks against a Compose app.</p> <h4 id="different-environments">Different environments</h4> <p>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:</p> <p>Start with a base file that defines the canonical configuration for the services.</p> <p><strong>docker-compose.yml</strong></p> <div class="highlight"><pre class="highlight" data-language="">web:
image: example/my_web_app:latest
depends_on:
- db
- cache
db:
image: postgres:latest
cache:
image: redis:latest
</pre></div> <p>In this example the development configuration exposes some ports to the host, mounts our code as a volume, and builds the web image.</p> <p><strong>docker-compose.override.yml</strong></p> <div class="highlight"><pre class="highlight" data-language="">web:
build: .
volumes:
- '.:/code'
ports:
- 8883:80
environment:
DEBUG: 'true'
db:
command: '-d'
ports:
- 5432:5432
cache:
ports:
- 6379:6379
</pre></div> <p>When you run <code class="language-plaintext highlighter-rouge">docker-compose up</code> it reads the overrides automatically.</p> <p>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).</p> <p><strong>docker-compose.prod.yml</strong></p> <div class="highlight"><pre class="highlight" data-language="">web:
ports:
- 80:80
environment:
PRODUCTION: 'true'
cache:
environment:
TTL: '500'
</pre></div> <p>To deploy with this production Compose file you can run</p> <div class="highlight"><pre class="highlight" data-language="">$ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
</pre></div> <p>This deploys all three services using the configuration in <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> and <code class="language-plaintext highlighter-rouge">docker-compose.prod.yml</code> (but not the dev configuration in <code class="language-plaintext highlighter-rouge">docker-compose.override.yml</code>).</p> <p>See <a href="../production/index">production</a> for more information about Compose in production.</p> <h4 id="administrative-tasks">Administrative tasks</h4> <p>Another common use case is running adhoc or administrative tasks against one or more services in a Compose app. This example demonstrates running a database backup.</p> <p>Start with a <strong>docker-compose.yml</strong>.</p> <div class="highlight"><pre class="highlight" data-language="">web:
image: example/my_web_app:latest
depends_on:
- db
db:
image: postgres:latest
</pre></div> <p>In a <strong>docker-compose.admin.yml</strong> add a new service to run the database export or backup.</p> <div class="highlight"><pre class="highlight" data-language=""> dbadmin:
build: database_admin/
depends_on:
- db
</pre></div> <p>To start a normal environment run <code class="language-plaintext highlighter-rouge">docker-compose up -d</code>. To run a database backup, include the <code class="language-plaintext highlighter-rouge">docker-compose.admin.yml</code> as well.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker-compose -f docker-compose.yml -f docker-compose.admin.yml \
run dbadmin db-backup
</pre></div> <h2 id="extending-services">Extending services</h2> <blockquote> <p><strong>Note</strong></p> <p>The <code class="language-plaintext highlighter-rouge">extends</code> keyword is supported in earlier Compose file formats up to Compose file version 2.1 (see <a href="../compose-file/compose-file-v2/index#extends">extends in v2</a>), but is not supported in Compose version 3.x. See the <a href="../compose-file/compose-versioning/index#version-3">Version 3 summary</a> of keys added and removed, along with information on <a href="../compose-file/compose-versioning/index#upgrading">how to upgrade</a>. See <a href="https://github.com/moby/moby/issues/31101">moby/moby#31101</a> to follow the discussion thread on the possibility of adding support for <code class="language-plaintext highlighter-rouge">extends</code> in some form in future versions. The <code class="language-plaintext highlighter-rouge">extends</code> keyword has been included in docker-compose versions 1.27 and higher.</p> </blockquote> <p>Docker Compose’s <code class="language-plaintext highlighter-rouge">extends</code> keyword enables the 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 <code class="language-plaintext highlighter-rouge">extends</code> you can define a common set of service options in one place and refer to it from anywhere.</p> <p>Keep in mind that <code class="language-plaintext highlighter-rouge">volumes_from</code> and <code class="language-plaintext highlighter-rouge">depends_on</code> are never shared between services using <code class="language-plaintext highlighter-rouge">extends</code>. These exceptions exist to avoid implicit dependencies; you always define <code class="language-plaintext highlighter-rouge">volumes_from</code> locally. This ensures dependencies between services are clearly visible when reading the current file. Defining these locally also ensures that changes to the referenced file don’t break anything.</p> <h3 id="understand-the-extends-configuration">Understand the extends configuration</h3> <p>When defining any service in <code class="language-plaintext highlighter-rouge">docker-compose.yml</code>, you can declare that you are extending another service like this:</p> <div class="highlight"><pre class="highlight" data-language="">services:
web:
extends:
file: common-services.yml
service: webapp
</pre></div> <p>This instructs Compose to re-use the configuration for the <code class="language-plaintext highlighter-rouge">webapp</code> service defined in the <code class="language-plaintext highlighter-rouge">common-services.yml</code> file. Suppose that <code class="language-plaintext highlighter-rouge">common-services.yml</code> looks like this:</p> <div class="highlight"><pre class="highlight" data-language="">services:
webapp:
build: .
ports:
- "8000:8000"
volumes:
- "/data"
</pre></div> <p>In this case, you get exactly the same result as if you wrote <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> with the same <code class="language-plaintext highlighter-rouge">build</code>, <code class="language-plaintext highlighter-rouge">ports</code> and <code class="language-plaintext highlighter-rouge">volumes</code> configuration values defined directly under <code class="language-plaintext highlighter-rouge">web</code>.</p> <p>You can go further and define (or re-define) configuration locally in <code class="language-plaintext highlighter-rouge">docker-compose.yml</code>:</p> <div class="highlight"><pre class="highlight" data-language="">services:
web:
extends:
file: common-services.yml
service: webapp
environment:
- DEBUG=1
cpu_shares: 5
important_web:
extends: web
cpu_shares: 10
</pre></div> <p>You can also write other services and link your <code class="language-plaintext highlighter-rouge">web</code> service to them:</p> <div class="highlight"><pre class="highlight" data-language="">services:
web:
extends:
file: common-services.yml
service: webapp
environment:
- DEBUG=1
cpu_shares: 5
depends_on:
- db
db:
image: postgres
</pre></div> <h3 id="example-use-case-1">Example use case</h3> <p>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.</p> <p>In a <strong>common.yml</strong> we define the common configuration:</p> <div class="highlight"><pre class="highlight" data-language="">services:
app:
build: .
environment:
CONFIG_FILE_PATH: /code/config
API_KEY: xxxyyy
cpu_shares: 5
</pre></div> <p>In a <strong>docker-compose.yml</strong> we define the concrete services which use the common configuration:</p> <div class="highlight"><pre class="highlight" data-language="">services:
webapp:
extends:
file: common.yml
service: app
command: /code/run_web_app
ports:
- 8080:8080
depends_on:
- queue
- db
queue_worker:
extends:
file: common.yml
service: app
command: /code/run_worker
depends_on:
- queue
</pre></div> <h2 id="adding-and-overriding-configuration">Adding and overriding configuration</h2> <p>Compose copies configurations from the original service over to the local one. If a configuration option is defined in both the original service and the local service, the local value <em>replaces</em> or <em>extends</em> the original value.</p> <p>For single-value options like <code class="language-plaintext highlighter-rouge">image</code>, <code class="language-plaintext highlighter-rouge">command</code> or <code class="language-plaintext highlighter-rouge">mem_limit</code>, the new value replaces the old value.</p> <p>original service:</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
command: python app.py
</pre></div> <p>local service:</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
command: python otherapp.py
</pre></div> <p>result:</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
command: python otherapp.py
</pre></div> <p>For the <strong>multi-value options</strong> <code class="language-plaintext highlighter-rouge">ports</code>, <code class="language-plaintext highlighter-rouge">expose</code>, <code class="language-plaintext highlighter-rouge">external_links</code>, <code class="language-plaintext highlighter-rouge">dns</code>, <code class="language-plaintext highlighter-rouge">dns_search</code>, and <code class="language-plaintext highlighter-rouge">tmpfs</code>, Compose concatenates both sets of values:</p> <p>original service:</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
expose:
- "3000"
</pre></div> <p>local service:</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
expose:
- "4000"
- "5000"
</pre></div> <p>result:</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
expose:
- "3000"
- "4000"
- "5000"
</pre></div> <p>In the case of <code class="language-plaintext highlighter-rouge">environment</code>, <code class="language-plaintext highlighter-rouge">labels</code>, <code class="language-plaintext highlighter-rouge">volumes</code>, and <code class="language-plaintext highlighter-rouge">devices</code>, Compose “merges” entries together with locally-defined values taking precedence. For <code class="language-plaintext highlighter-rouge">environment</code> and <code class="language-plaintext highlighter-rouge">labels</code>, the environment variable or label name determines which value is used:</p> <p>original service:</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
environment:
- FOO=original
- BAR=original
</pre></div> <p>local service:</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
environment:
- BAR=local
- BAZ=local
</pre></div> <p>result</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
environment:
- FOO=original
- BAR=local
- BAZ=local
</pre></div> <p>Entries for <code class="language-plaintext highlighter-rouge">volumes</code> and <code class="language-plaintext highlighter-rouge">devices</code> are merged using the mount path in the container:</p> <p>original service:</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
volumes:
- ./original:/foo
- ./original:/bar
</pre></div> <p>local service:</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
volumes:
- ./local:/bar
- ./local:/baz
</pre></div> <p>result:</p> <div class="highlight"><pre class="highlight" data-language="">services:
myservice:
# ...
volumes:
- ./original:/foo
- ./local:/bar
- ./local:/baz
</pre></div> <h2 id="compose-documentation">Compose documentation</h2> <ul> <li><a href="../index">User guide</a></li> <li><a href="../install/index">Installing Compose</a></li> <li><a href="../gettingstarted/index">Getting Started</a></li> <li><a href="../reference/index">Command line reference</a></li> <li><a href="../compose-file/index">Compose file reference</a></li> <li><a href="../samples-for-compose/index">Sample apps with Compose</a></li> </ul>
<p><a href="https://docs.docker.com/search/?q=fig">fig</a>, <a href="https://docs.docker.com/search/?q=composition">composition</a>, <a href="https://docs.docker.com/search/?q=compose">compose</a>, <a href="https://docs.docker.com/search/?q=docker">docker</a>, <a href="https://docs.docker.com/search/?q=orchestration">orchestration</a>, <a href="https://docs.docker.com/search/?q=documentation">documentation</a>, <a href="https://docs.docker.com/search/?q=docs">docs</a></p>
<div class="_attribution">
<p class="_attribution-p">
© 2019 Docker, Inc.<br>Licensed under the Apache License, Version 2.0.<br>Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.<br>Docker, Inc. and other parties may also have trademark rights in other terms used herein.<br>
<a href="https://docs.docker.com/compose/extends/" class="_attribution-link">https://docs.docker.com/compose/extends/</a>
</p>
</div>
|