Compare commits

..

1,381 commits

Author SHA1 Message Date
Joffrey F
aa8fb8f708 Merge pull request #4499 from xulike666/function-name-modification
function-name-modification for tests/*
2017-02-16 11:59:36 -08:00
Joffrey F
b49f42f9b7 Merge pull request #4496 from xulike666/quick-easy-typo-fix
fix a typo in script/release/utils.sh
2017-02-16 11:59:17 -08:00
Joffrey F
afd3bcfbf4 Merge pull request #4484 from shin-/4425-sys-path-fix
Reinitialize sys.path after it's been potentially modified by pip
2017-02-16 11:39:54 -08:00
Aaron.L.Xu
d20e3f3342 function-name-modification for tests/*
Signed-off-by: Aaron.L.Xu <likexu@harmonycloud.cn>
2017-02-16 15:25:20 +08:00
Aaron.L.Xu
27297fd1af fix a typo in script/release/utils.sh
Signed-off-by: Aaron.L.Xu <likexu@harmonycloud.cn>
2017-02-16 11:14:49 +08:00
Joffrey F
66f4a795a2 Don't import pip inside Compose
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-02-15 16:31:50 -08:00
Joffrey F
40c26ca676 Merge pull request #4480 from shin-/4479-merge-secrets
Fix `config` command output with service.secrets section
2017-02-14 17:08:18 -08:00
Joffrey F
abce83ef25 Fix config command output with service.secrets section
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-02-13 16:51:50 -08:00
Joffrey F
bb5d7b2433 Merge pull request #4473 from Vehsamrak/patch-1
Compose file reference link fix in README.md
2017-02-13 13:03:39 -08:00
Petr Karmashev
252699c1d1 Compose file reference link fix in README.md
Signed-off-by: Petr Karmashev <smonkl@bk.ru>
2017-02-12 02:10:34 +03:00
Joffrey F
ad0e6d219b Merge pull request #4469 from dnephin/fix_secrets_config
Fixes secrets config loading
2017-02-10 18:39:53 -08:00
Daniel Nephin
dc5b3f3b3e Fix secrets config.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2017-02-10 17:11:24 -05:00
Joffrey F
1fe2443735 Merge pull request #4438 from fate-grand-order/master
fix typo in CHANGELOG.md
2017-02-09 16:35:35 -08:00
Joffrey F
27e0f31275 Merge pull request #4443 from xulike666/fix-accessibility
Referencing the right segment of code in compose/bundle.py
2017-02-09 16:34:48 -08:00
Joffrey F
2f13201b9e Merge pull request #4453 from kevinetc123/patch-typo
fix typo in project.py
2017-02-09 16:33:07 -08:00
Joffrey F
276db7231a Merge pull request #4455 from dnephin/fix_3.1
Fix version 3.1
2017-02-09 12:38:29 -08:00
Daniel Nephin
c092fa37de Fix version 3.1
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2017-02-09 12:39:57 -05:00
kevinetc123
47e4442722 fix typo in project.py
Signed-off-by: kevinetc123 <kaiwentan@harmonycloud.cn>
2017-02-09 19:10:26 +08:00
Joffrey F
b306e843d3 Merge pull request #4448 from shin-/1.11-release
1.11 release-master realign
2017-02-08 13:54:12 -08:00
Joffrey F
fc7b74d7f9 Bump to next dev version
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-02-08 13:47:08 -08:00
Joffrey F
2cd6cb9a47 Bump 1.10.1
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-02-08 13:45:25 -08:00
Joffrey F
01d1895a35 Bump 1.11.0
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-02-08 13:44:40 -08:00
Joffrey F
979a0d53f7 Bump 1.11.0-rc1
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-02-08 13:44:31 -08:00
Aaron.L.Xu
f083526829 referencing right segment of code
Signed-off-by: Aaron.L.Xu <likexu@harmonycloud.cn>
2017-02-08 18:50:26 +08:00
fate-grand-order
b392b6e12e fix typo in CHANGELOG.md
Signed-off-by: fate-grand-order <chenjg@harmonycloud.cn>
2017-02-07 15:59:34 +08:00
Joffrey F
165eb9c91a Merge pull request #3558 from shin-/1135-pyinstaller-update
Use newer version of PyInstaller to fix prelinking issues
2017-02-06 15:00:39 -08:00
Joffrey F
1636985a7a Merge pull request #4426 from shin-/4392-context-mgr
Close the open file handle using context manager
2017-02-06 13:30:49 -08:00
Kevin Jing Qiu
a3a9d8944a Close the open file handle using context manager
Signed-off-by: Kevin Jing Qiu <kevin.qiu@points.com>
2017-02-03 14:50:40 -08:00
Joffrey F
951497c0f2 Merge pull request #4419 from shin-/4418-healthcheck-extends
Don't re-parse healthcheck values coming from extended services
2017-02-03 12:24:53 -08:00
Joffrey F
e22164ec9f Merge pull request #4035 from urda/urda/compose-top
Added `top` to `docker-compose` to display running processes
2017-02-02 15:41:14 -08:00
Joffrey F
f106d23776 Merge pull request #4414 from shin-/4184-merge-pids
Add missing comma in DOCKER_CONFIG_KEYS list
2017-02-02 14:51:42 -08:00
Joffrey F
cf43e6edf7 Don't re-parse healthcheck values coming from extended services
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-02-02 14:50:53 -08:00
Joffrey F
7e8958e6ca Add missing comma in DOCKER_CONFIG_KEYS list
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-02-01 16:40:43 -08:00
Joffrey F
11038c455b Merge pull request #4334 from muicoder/master
add IMAGE_EVENTS: load/save
2017-02-01 15:49:03 -08:00
Peter Urda
a67500ee57
Added top to docker-compose to display running processes.
This commit allows `docker-compose` to access `top` for containers
much like running `docker top` directly on a given container.

This commit includes:

* `docker-compose` CLI changes to expose `top`
* Completions for `bash` and `zsh`
* Required testing for the new `top` command

Signed-off-by: Peter Urda <peter.urda@gmail.com>
2017-02-01 15:42:30 -08:00
Joffrey F
1f39b33357 Merge pull request #3989 from mattjbray/patch-1
Zsh completion: permit multiple --file arguments
2017-02-01 15:08:39 -08:00
Joffrey F
67e1111806 Merge pull request #4410 from shin-/4408-colors-no-tty
Don't strip ANSI color codes when output is not a TTY
2017-02-01 14:20:10 -08:00
Joffrey F
84774cacd2 Upgrade python and pip versions in Dockerfile
Add libbz2 dependency

Signed-off-by: Joffrey F <joffrey@docker.com>
2017-02-01 14:12:41 -08:00
Joffrey F
c9eb9380ed Merge pull request #4368 from dnephin/secrets-using-bind-mounts
Secrets using bind mounts
2017-02-01 14:11:20 -08:00
Joffrey F
c16cd77737 Merge pull request #4406 from shin-/bump_docker_py
Bump docker SDK version
2017-01-31 15:36:30 -08:00
Joffrey F
8efb7e6e8b Don't strip ANSI color codes when output is not a TTY
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-31 12:51:46 -08:00
Daniel Nephin
59d1847d9b Fix some test failures.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2017-01-31 09:53:40 -05:00
Daniel Nephin
3a2735abb9 Rebase compose v3.1 on the latest v3
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2017-01-31 09:53:16 -05:00
Daniel Nephin
0d609b68ac Add a warning for unsupported secret fields.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2017-01-31 09:53:16 -05:00
Daniel Nephin
4053adc7d3 Add an integration test for secrets using bind mounts.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2017-01-31 09:53:16 -05:00
Daniel Nephin
e0c6397999 Implement secrets using bind mounts
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2017-01-31 09:53:16 -05:00
Daniel Nephin
add56ce818 Read service secrets as a type.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2017-01-31 09:53:16 -05:00
Daniel Nephin
a82de8863e Add v3.1 with secrets.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2017-01-31 09:53:16 -05:00
Joffrey F
2593366a3e Bump docker SDK version
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-30 16:49:05 -08:00
Joffrey F
22249add84 Use newer version of PyInstaller to fix prelinking issues
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-30 13:52:27 -08:00
Joffrey F
76d4f5bea6 Merge pull request #4383 from shin-/4344-detect-docker-py
Detect conflicting version of the docker python SDK
2017-01-30 12:14:27 -08:00
Joffrey F
5895d8bbc9 Detect conflicting version of the docker python SDK and prevent execution
until issue is fixed

Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-26 17:12:41 -08:00
Joffrey F
e05a9f4e62 Merge pull request #4389 from shin-/4372-normalize-time-values
Convert time data back to string values when serializing config
2017-01-26 13:47:34 -08:00
Joffrey F
e10d1140b9 Convert time data back to string values when serializing config
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-26 11:59:22 -08:00
Joffrey F
56e01f25ea Merge pull request #4367 from dnephin/add-missing-network-internal-to-v3
Add missing network.internal to v3 schema.
2017-01-25 13:41:41 -08:00
Joffrey F
c86faab4ec Merge pull request #4370 from shin-/4357-win32-unicode-paths
Don't encode build context path on Windows
2017-01-23 12:04:42 -08:00
Joffrey F
20d6f450b5 Don't encode build context path on Windows
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-20 15:05:53 -08:00
Daniel Nephin
644e1716c3 Add missing network.internal to v3 schema.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2017-01-20 12:55:59 -05:00
Joffrey F
9a0962dacb Merge pull request #4361 from shin-/4348-serialize-ext-volumes
Remove external_name from volume def in config output
2017-01-19 17:41:08 -08:00
Joffrey F
263b9e9317 Merge pull request #4360 from shin-/4359-volume-labels
Fix volume definition in v3 schema
2017-01-19 17:40:29 -08:00
Joffrey F
d83d31889e Remove external_name from volume def in config output
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-19 16:05:13 -08:00
Joffrey F
5c2165eaaf Fix volume definition in v3 schema
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-19 15:41:31 -08:00
Joffrey F
8a27a0f059 Merge pull request #4350 from shin-/fix-invalid-depends-on-merge
depends_on merge now retains condition information when present
2017-01-19 14:50:29 -08:00
Joffrey F
b47c97e94e Merge pull request #4358 from shin-/1.11-dev
1.11.0dev
2017-01-19 14:50:10 -08:00
Joffrey F
a482c138d8 Merge pull request #4353 from xulike666/fight-for-readability
Fix typo in script/test/versions.py
2017-01-19 14:49:05 -08:00
Joffrey F
1c46525c2b 1.11.0dev
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-19 14:47:31 -08:00
Aaron.L.Xu
169289c8b6 find a fishbone
Signed-off-by: Aaron.L.Xu <likexu@harmonycloud.cn>
2017-01-20 00:52:19 +08:00
Joffrey F
1a02121ab5 depends_on merge now retains condition information when present
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-18 17:52:03 -08:00
Joffrey F
708c4f9534 Merge pull request #4339 from shin-/4328-catch-healthcheck-exception
Catch healthcheck exceptions in parallel_execute
2017-01-17 14:16:37 -08:00
Joffrey F
56a1b02aac Catch healthcheck exceptions in parallel_execute
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-17 13:22:16 -08:00
muicoder
931027c598 add IMAGE_EVENTS: load/save
Signed-off-by: muicoder <muicoder@gmail.com>
2017-01-16 10:53:40 +08:00
Joffrey F
5ade097d74 Merge pull request #4324 from shin-/4321-v3-depends-on
Provide valid serialization of depends_on when format is not 2.1
2017-01-12 11:52:15 -08:00
Joffrey F
62cdd25b7d Merge pull request #4323 from shin-/fix-push-release-script
Use correct wheel file name in twine upload command
2017-01-12 11:52:05 -08:00
Joffrey F
2df31bb13c Provide valid serialization of depends_on when format is not 2.1
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-11 16:25:40 -08:00
Joffrey F
29b46d5b26 Use correct wheel file name in twine upload command
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-11 15:39:48 -08:00
Joffrey F
2091149fee Merge pull request #4317 from shin-/release-script-fixes
Fix docker image build script when using universal wheels
2017-01-10 17:21:27 -08:00
Joffrey F
19190ea0df Fix docker image build script when using universal wheels
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-10 16:43:26 -08:00
Joffrey F
1c1fe89e43 Merge pull request #4316 from shin-/update-setup-py
Update setup.py extra_requires
2017-01-10 15:50:11 -08:00
Joffrey F
52792b7a96 Update setup.py extra_requires
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-10 14:59:11 -08:00
Joffrey F
9f6778aa73 Merge pull request #4172 from graingert/enable-universal-wheels
enable universal wheels
2017-01-10 14:57:22 -08:00
Joffrey F
545153f117 Merge pull request #4288 from tntC4stl3/fix_404_issue
Fix 404 issue, change APIError to more accureate ImageNotFound
2017-01-09 16:43:57 -08:00
Joffrey F
3f7b3fbf0a Merge pull request #4304 from shin-/4302-dockerignore-windows
Use docker SDK patch
2017-01-09 16:14:57 -08:00
Joffrey F
88294b46dd Merge pull request #4294 from shin-/4240-compose-convert-false
Ensure falsy values in COMPOSE_CONVERT_WINDOWS_PATHS are properly recognized
2017-01-09 15:49:44 -08:00
Joffrey F
2c157e8fa9 Use docker SDK 2.0.1
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-09 15:27:20 -08:00
Joffrey F
b570cba965 Merge pull request #3961 from ankon/patch-1
Fix typo
2017-01-09 12:15:04 -08:00
Joffrey F
3bb8a7d178 Merge pull request #4297 from shin-/4271-fix-schemas
Fix config schemas (misplaced "additionalProperties")
2017-01-06 12:10:22 -08:00
Joffrey F
45c7ee4466 Merge pull request #4279 from dnephin/fix-schema-typo
Fix schema typo
2017-01-05 17:15:39 -08:00
Joffrey F
e063c5739f Fix config schemas (misplaced "additionalProperties")
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-05 11:18:21 -08:00
Joffrey F
534b4ed820 Falsy values in COMPOSE_CONVERT_WINDOWS_PATHS are properly recognized
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-04 15:45:11 -08:00
Joffrey F
27d91bba01 Merge pull request #4293 from shin-/stop_timeout_v2.1
Add support for stop_grace_period in v2
2017-01-04 15:14:18 -08:00
Joffrey F
1be41f59c9 Add support for stop_grace_period in v2
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-04 14:30:20 -08:00
Joffrey F
838bdd71f3 Merge pull request #4291 from shin-/unify-healthcheck-def-v2v3
Unify healthcheck spec definition in v2 and v3
2017-01-04 13:53:39 -08:00
Joffrey F
47b672e393 Merge pull request #4051 from shin-/update-release-process
Update release process document to account for recent changes.
2017-01-04 13:15:49 -08:00
Joffrey F
8145429399 Unify healthcheck spec definition in v2 and v3
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-04 13:14:23 -08:00
Joffrey F
be88bb0e6c Merge pull request #4267 from shin-/3754-depends-on-healthcheck
Allow service dependencies to wait on healthy containers
2017-01-04 13:00:19 -08:00
Joffrey F
bef2308530 Fix condition name in config tests
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-04 11:28:30 -08:00
Joffrey F
04394b1d0a Expand depends_on to allow different conditions (service_start, service_healthy)
Rework "up" and "start" to wait on conditional state of dependent services
Add integration tests

Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-04 11:28:30 -08:00
Joffrey F
f6edd610f3 Add 3.0 schema to docker-compose.spec
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-04 11:26:45 -08:00
Joffrey F
0edfe08bf0 Add healthchecks to 2.1 schema. Update depends_on
Signed-off-by: Joffrey F <joffrey@docker.com>
2017-01-04 11:26:45 -08:00
Thomas Grainger
2648af6807
enable universal wheels
Signed-off-by: Thomas Grainger <tom.grainger@procensus.com>
2017-01-04 18:33:58 +00:00
Jun Guo
c73fc26824 Fix 404 issue, change APIError to more accureate ImageNotFound
Signed-off-by: Jun Guo <blackhumour.gj@gmail.com>
2017-01-04 15:42:31 +08:00
Daniel Nephin
a74b2f2f70 Fix schema typo.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-12-28 15:16:53 -05:00
Joffrey F
09690e1758 Merge pull request #4220 from shin-/4211-default_network_labels
Add default labels to networks and volumes created by Compose
2016-12-20 02:34:57 -08:00
Joffrey F
3058e39407 Merge pull request #4268 from shin-/jtakkala-3765-sysctl-support
Add sysctl option support when creating service
2016-12-20 02:34:02 -08:00
Joffrey F
e1ebb0df22 Merge pull request #4070 from shin-/use-colorama
Use colorama to enable colored output on Windows
2016-12-20 02:32:51 -08:00
Joffrey F
ba47fb99ba Add default labels to networks and volumes created by Compose
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-12-19 20:43:35 -08:00
Joffrey F
346802715d Use colorama to enable colored output on Windows
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-12-19 20:40:47 -08:00
Joffrey F
eb6441c8e3 Add sysctls option to 3.0 schema
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-12-19 20:35:09 -08:00
Joffrey F
82230071d5 Merge branch '3765-sysctl-support' of https://github.com/jtakkala/compose into jtakkala-3765-sysctl-support
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-12-19 20:33:54 -08:00
Joffrey F
e6b2949edc Merge pull request #4216 from lawliet89/userns_mode
Implement `userns_mode` HostConfig for services
2016-12-19 18:12:15 -08:00
Joffrey F
ea7b565009 Merge pull request #4232 from shin-/attachable_networks
Make created networks attachable for file format >=2.1
2016-12-16 13:06:57 -08:00
Joffrey F
e736151ee4 Make created networks attachable for file format >=2.1
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-12-16 12:23:24 -08:00
Joffrey F
fb165d9c15 Add v3_only marker to healthcheck test
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-12-16 12:21:59 -08:00
Joffrey F
9cb6a70b6f Merge pull request #4219 from shin-/dockerpy_2.0
Use docker SDK 2.0
2016-12-14 16:19:34 -08:00
Joffrey F
04e5925a23 Use docker SDK 2.0
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-12-14 15:36:08 -08:00
Joffrey F
635a281777 Merge pull request #4163 from aanand/add-healthcheck
Implement 'healthcheck' option
2016-12-14 15:35:05 -08:00
Aanand Prasad
599b29e405 Merge pull request #4213 from shin-/4212-interactive-connect
Win32 interactive run - Connect container to networks before starting
2016-12-08 13:41:33 +00:00
Aanand Prasad
30eac9f1ae Merge pull request #4226 from dnephin/update-api-version-for-v3
Increase minimum version for compose format v3
2016-12-07 16:59:28 +00:00
Daniel Nephin
e04a12b5ca Increase minimum version for v3.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-12-07 11:16:40 -05:00
Joffrey F
b453ee46e8 Merge pull request #4228 from shin-/bump_version
Bump master version to 1.10.0dev
2016-12-06 17:50:44 -08:00
Joffrey F
4d0575355c Bump master version to 1.10.0dev
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-12-06 17:14:05 -08:00
Yong Wen Chua
62f8b1402e Implement userns_mode HostConfig for services
Fixes #3349

This allows the key `userns_mode` to be used in service definitions.
Since `userns_mode` requires API version > 1.23, this is only available
in 2.1 and 3.0 versions of compose file

Signed-off-by: Yong Wen Chua <me@yongwen.xyz>
2016-12-05 14:25:56 +08:00
Joffrey F
6aacf51427 Win32 interactive run - Connect container to networks before starting
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-12-02 16:10:15 -08:00
Joffrey F
9bfb855b89 Merge pull request #4187 from ijc25/pull-urxvt-corruption
progress_stream: Avoid undefined ANSI escape codes
2016-12-02 13:54:08 -08:00
Ian Campbell
dc9184a90f progress_stream: Avoid undefined ANSI escape codes
The ANSI escape codes \e[0A (cursor up 0 lines) and \e[0B (cursor down 0 lines)
are not well defined and are treated differently by different terminals. In
particular xterm treats 0 as a missing parameter and therefore defaults to 1,
whereas rxvt-unicode treats these escapes as a request to move 0 lines.

However the use of these codes is unnecessary and were really just hiding the
fact that we were not correctly computing diff when adding a new line. Having
added the new line to the ids map and output the corresponding \n the correct
diff would be 1 and not 0 (which xterm interprets as 1) as currently.

Rather than changing the hardcoded 0 to a 1 pull the diff calculation out and
always do it since it produces the correct answer in both cases.

This fixes similar corruption when compose is pulling an image to that seen
with `docker pull` and rxvt-unicode (and likely other terminals in that family)
seen in docker/docker#28111.

This is the same as the fix made to Docker's pkg/jsonmessage in
https://github.com/docker/docker/pull/28238 (and I have shamelessly ripped off
most of this commit message from there).

Signed-off-by: Ian Campbell <ian.campbell@docker.com>
2016-11-25 10:16:37 +00:00
Joffrey F
def150a129 Merge pull request #4173 from graingert/case-pypi-correctly
case PyPI correctly
2016-11-22 18:15:10 -08:00
Aanand Prasad
af894b4dff Merge pull request #4170 from dnephin/warn-on-deploy
Update messages about docker stack deploy
2016-11-22 17:07:13 +00:00
Thomas Grainger
024b5dd6da
case PyPI correctly
Signed-off-by: Thomas Grainger <tom.grainger@procensus.com>
2016-11-22 11:15:21 +00:00
Daniel Nephin
c26a2afaf3 Update messages about docker stack deploy.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-11-21 16:34:49 -05:00
Aanand Prasad
716a6baa59 Implement 'healthcheck' option
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-11-18 14:47:02 +00:00
Joffrey F
f5ad3e7577 Merge pull request #4165 from shin-/changelog_update
Changelog update
2016-11-17 13:29:32 -08:00
Joffrey F
b93211881b Changelog update
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-11-16 13:35:29 -08:00
Aanand Prasad
466ebb6cc1 Merge pull request #4146 from dnephin/add-stop-grace-period
Add stop grace period to v3
2016-11-16 17:56:20 +00:00
Daniel Nephin
079c95c340 Use stop grace period for container stop.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-11-16 12:12:28 -05:00
Daniel Nephin
6cac48c056 Add a vendored and modified pytimeparse
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-11-16 12:10:32 -05:00
Aanand Prasad
586443ba5d Merge pull request #4147 from aanand/version-3.0
Support version 3.0 of the Compose file format
2016-11-16 16:34:50 +00:00
Aanand Prasad
f75ef6862f Warn if any services use 'deploy'
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-11-16 16:07:02 +00:00
Aanand Prasad
d717c88b6e Support version 3.0 of the Compose file format
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-11-16 16:07:02 +00:00
Joffrey F
721bf89447 Merge pull request #4134 from shin-/fix_none_opts_network_check
Avoid breaking when remote driver options are null
2016-11-15 15:01:24 -08:00
Joffrey F
09540339e0 Merge pull request #4131 from aanand/test-environment-overrides-env-file
Test that values in 'environment' override env files
2016-11-15 14:18:54 -08:00
Joffrey F
7f60ff5ae6 Avoid breaking when remote driver options are null.
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-11-15 12:00:52 -08:00
Joffrey F
3d0747017a Merge pull request #4151 from shin-/fix_ignore_pull_failure_behavior_1.13
Handle new pull failures behavior in Engine 1.13
2016-11-15 12:00:19 -08:00
Joffrey F
efb4ed1b9e Handle new pull failures behavior in Engine 1.13
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-11-15 11:30:52 -08:00
Joffrey F
d7e9748501 Merge pull request #4150 from shin-/test_only_ubuntu_host
Limit testing pool to Ubuntu hosts to avoid errors with dind
2016-11-14 18:04:30 -08:00
Joffrey F
0291d9ade5 Limit testing pool to Ubuntu hosts to avoid errors with dind not
starting properly.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-11-14 17:23:25 -08:00
Jari Takkala
91620ae97b Add sysctl option support when creating service
Closes #3765

Signed-off-by: Jari Takkala <jtakkala@gmail.com>
2016-11-10 16:41:16 -05:00
Aanand Prasad
ba249e5179 Test that values in 'environment' override env files
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-11-09 15:10:27 +00:00
Joffrey F
0e28163ccb Merge pull request #4115 from shin-/fix_overlay_options_mismatch
Call check_remote_network_config from Network.ensure
2016-11-08 15:35:38 -08:00
Aanand Prasad
0902edef43 Merge pull request #4113 from shin-/4103-merge-empty-logging
Fix logging dict merging
2016-11-08 14:56:27 +00:00
Joffrey F
4aa7d15d97 Call check_remote_network_config from Network.ensure
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-11-04 10:51:14 -07:00
Joffrey F
10417eebd7 Fix logging dict merging
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-11-03 17:22:31 -07:00
Joffrey F
9046e33ab2 Merge pull request #4112 from mikedougherty/rm-docs-checker
Remove docs checker from Jenkinsfile and use cleanWorkspace option on wrappedNode
2016-11-03 17:22:05 -07:00
Mike Dougherty
da1508051d Remove docs checker from Jenkinsfile and use cleanWorkspace option on wrappedNode
Signed-off-by: Mike Dougherty <mike.dougherty@docker.com>
2016-11-03 14:00:17 -07:00
Joffrey F
969abca47f Merge pull request #4098 from shin-/fix_overlay_options_mismatch
Add whitelisted driver option added by the overlay driver
2016-11-03 11:43:11 -07:00
Joffrey F
d525dd1846 Merge pull request #4104 from shin-/bump_docker_py
Bump docker-py
2016-11-03 11:43:04 -07:00
Joffrey F
7a430dbe96 Updated docker-py dependency to latest version
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-11-02 16:56:45 -07:00
Joffrey F
3b46a62f36 Merge pull request #4073 from mikedougherty/jenkinsfile
Update Jenkinsfile to run "janky" tasks
2016-11-02 14:55:11 -07:00
Joffrey F
ba43d08fbd Add whitelisted driver option added by the overlay driver to avoid breakage
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-11-01 11:47:12 -07:00
Joffrey F
ed71391f66 Merge pull request #4062 from strayobject/patch-1
fix(docs): updated documentation links
2016-10-28 11:55:58 -07:00
Joffrey F
e563b58595 Merge pull request #4071 from NiR-/fix/run-as-container
Fix path of the parent dir of COMPOSE_FILE
2016-10-27 15:03:54 -07:00
Aanand Prasad
62c9ed93d0 Merge pull request #4084 from shin-/bump_docker_py
Bump docker-py version to include latest patch
2016-10-27 12:53:44 -07:00
Joffrey F
046144e8f4 Bump docker-py version to include latest patch
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-27 12:13:32 -07:00
Mike Dougherty
4871523d5e Update Jenkinsfile to perform existing jenkins tasks
Signed-off-by: Mike Dougherty <mike.dougherty@docker.com>
2016-10-25 11:51:02 -07:00
Aanand Prasad
505c785c5c Merge pull request #4066 from shin-/fix-schema-divergence
Fix schema divergence - add missing fields to compose 2.1 schema
2016-10-25 11:20:51 -07:00
Albin Kerouanton
99343fd76c Fix path of the parent dir of COMPOSE_FILE
Signed-off-by: Albin Kerouanton <albin.kerouanton@knplabs.com>
2016-10-25 11:09:45 +02:00
Aanand Prasad
8b5782ba9f Merge pull request #4067 from shin-/portable-find-exe
Replace "which" calls with the portable find_executable function
2016-10-24 16:15:21 -07:00
Aanand Prasad
d586328812 Merge pull request #4065 from shin-/refine-swarm-warning
Do not print Swarm mode warning when connecting to a UCP server
2016-10-24 16:15:14 -07:00
Aanand Prasad
021bb41fc6 Merge pull request #4069 from shin-/project_tests_robustness
Improve robustness of a couple integration tests with occasional failures
2016-10-24 15:35:52 -07:00
Joffrey F
60d005b055 Improve robustness of a couple integration tests with occasional failures
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-24 13:58:45 -07:00
Joffrey F
d2fb146913 Replace "which" calls with the portable find_executable function
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-24 13:22:52 -07:00
Joffrey F
43e29b41c0 Fix schema divergence - add missing fields to compose 2.1 schema
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-24 11:51:45 -07:00
Joffrey F
a652b6818c Merge pull request #4064 from shin-/missing-2.1-spec
Add missing config schema to docker-compose.spec
2016-10-24 11:43:17 -07:00
Joffrey F
ea68be3441 Do not print Swarm mode warning when connecting to a UCP server
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-24 11:36:44 -07:00
Joffrey F
2c24bc3a08 Add missing config schema to docker-compose.spec
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-24 10:55:04 -07:00
Michal Zdrojewski
3d8dc6f47a fix(docs): updated documentation links
Signed-off-by: Michal Zdrojewski <code@strayobject.co.uk>
2016-10-24 15:41:31 +01:00
Joffrey F
f039c8b43c Update release process document to account for recent changes.
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-20 17:47:07 -07:00
Joffrey F
3147090fb4 Merge pull request #4030 from shin-/npipe-fixes
Bump docker-py dependency (includes several npipe fixes)
2016-10-19 11:44:52 -07:00
Joffrey F
de15ec835a Merge pull request #3980 from aanand/shell-out-attach
Attach interactively on Windows by shelling out
2016-10-19 11:14:36 -07:00
Joffrey F
2d3c76950f Merge pull request #3972 from shin-/fix-contributors-script
Fix the contributors script
2016-10-18 15:25:55 -07:00
Joffrey F
932b3cc10a Merge pull request #4026 from shin-/3923-windows-volumes
Do not normalize volume paths on Windows by default
2016-10-18 14:41:52 -07:00
Joffrey F
db5d2bcb10 Merge pull request #3990 from shin-/fix-osx-build
Fix openssl dependency in OSX binary build
2016-10-18 14:14:30 -07:00
Joffrey F
cd94c37f5d Fix merge error (missing Network.labels attribute)
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-18 14:09:31 -07:00
Joffrey F
efb09af271 Do not normalize volume paths on Windows by default
Add environment variable to enable normalization if needed.
Do not normalize internal paths

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-18 12:17:56 -07:00
Joffrey F
f60c60205b Merge branch 'dbdd4us-master' 2016-10-17 14:09:40 -07:00
Joffrey F
14716bc2da Merge branch 'master' of https://github.com/dbdd4us/compose into dbdd4us-master 2016-10-17 14:09:09 -07:00
Joffrey F
882084932d Upgrade docker-py to latest version
Adjust required requests version

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-17 14:03:21 -07:00
Joffrey F
a5c1e4b0cd Merge pull request #3991 from shin-/3906-isolation-config
Add support for "isolation" in config
2016-10-17 11:02:11 -07:00
Joffrey F
95c6cc0420 Merge pull request #3994 from shin-/3430-enable-ipv6
Add support for enable_ipv6 in network definition.
2016-10-17 11:02:00 -07:00
Joffrey F
50faddb683 Merge pull request #4034 from realab/fix-restart-with-null-string
fix serialize restart spec with null string
2016-10-14 14:34:35 -07:00
Aanand Prasad
925915eb25 Show clear error when docker binary can't be found
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-10-14 17:31:21 +01:00
Aanand Prasad
8314a48a2e Attach interactively on Windows by shelling out
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-10-14 17:31:21 +01:00
Aanand Prasad
8b383ad795 Refactor "docker not found" message generation, add Windows message
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-10-14 17:31:21 +01:00
realityone
22d91f60be
fix serialize restart spec with null string
Signed-off-by: realityone <realityone@me.com>
2016-10-14 18:20:55 +08:00
dbdd
bdcce13f4a add support for creating volume and network with label definition
Signed-off-by: dbdd <wangtong2712@gmail.com>
2016-10-12 10:35:14 +08:00
Joffrey F
e4bb9bde30 Merge pull request #3964 from shin-/3963-unicode-env
Don't break when interpolating environment with unicode characters
2016-10-11 12:00:36 -07:00
Joffrey F
7f1606545d Merge pull request #4004 from shin-/4000-extend-logging
Properly merge logging dictionaries in overriding configs
2016-10-11 12:00:06 -07:00
Joffrey F
0603b445e2 Properly merge logging dictionaries in overriding configs
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-10 15:39:05 -07:00
Joffrey F
9248298a4a Merge pull request #4016 from shin-/4008-unicode-formatter
Handle formatter case where logrecord message is binary containing unicode
2016-10-06 16:49:03 -07:00
Joffrey F
bc3ed6dead Merge pull request #3992 from shin-/3701-npipe-windows-default
Use docker-py's default behavior when no explicit host on Windows
2016-10-06 16:48:35 -07:00
Joffrey F
e5ded6ff9b Add support for enable_ipv6 in network definition.
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-06 15:49:08 -07:00
Joffrey F
804555bc4d Merge pull request #4015 from dnephin/fix-inline-defaults
Support non-alphanumeric default values.
2016-10-06 15:46:35 -07:00
Joffrey F
17c5b45641 Handle formatter case where logrecord message is binary containing
unicode characters.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-06 15:39:47 -07:00
Daniel Nephin
2bce81508e Support non-alphanumeric default values.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-10-06 17:04:19 -04:00
Victoria Bialas
8f636d8279 Merge pull request #4010 from londoncalling/add-vnext-info
updated README per vnext branch plan
2016-10-05 18:47:00 -07:00
Joffrey F
b50b14f937 Fix openssl dependency in OSX binary build
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-10-05 17:08:14 -07:00
Victoria Bialas
a8ff4285d1 updated README per vnext branch plan
Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
2016-10-05 16:19:09 -07:00
Joffrey F
eac01a7cd5 Merge pull request #3108 from dnephin/inplace_var_defaults
Support inline default values for interpolation
2016-10-05 14:22:02 -07:00
John Mulhausen
85d6d7955f Merge pull request #4005 from johndmulhausen/master
Remove old documentation source, add README on migration
2016-10-04 19:08:36 -07:00
John Mulhausen
1a4e81920b Remove old documentation source, add README on migration
Signed-off-by: John Mulhausen <john@docker.com>
2016-10-04 17:58:44 -07:00
Matt Bray
a37d99f201 Zsh completion: change --file description text
Signed-off-by: Matt Bray <mattjbray@gmail.com>
2016-09-30 00:45:46 +01:00
Daniel Nephin
fe08be698d Support inline default values.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-09-29 12:46:11 -04:00
Joffrey F
007cf96452 Use docker-py's default behavior when no explicit host on Windows
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-28 15:36:57 -07:00
Joffrey F
dc8a39f70d Add support for "isolation" in config
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-28 15:31:58 -07:00
Matthew Bray
90356b7040 Zsh completion: permit multiple --file arguments
Before this change:

```
$ docker-compose --file docker-compose.yml -<TAB>
 -- option --
--help                 -h  -- Get help
--host                 -H  -- Daemon socket to connect to
--project-name         -p  -- Specify an alternate project name (default: directory name)
--skip-hostname-check      -- Don't check the daemon's hostname against the name specified in the client certificate (for example if your docker host is an IP address)
--tls                      -- Use TLS; implied by --tlsverify
--tlscacert                -- Trust certs signed only by this CA
--tlscert                  -- Path to TLS certificate file
--tlskey                   -- Path to TLS key file
--tlsverify                -- Use TLS and verify the remote
--verbose                  -- Show more output
--version              -v  -- Print version and exit
```

(Note the `--file` argument is no longer available to complete.)

After this change:

```
docker-compose --file docker-compose.yml -<TAB>
 -- option --
--file                 -f  -- Specify an alternate docker-compose file (default: docker-compose.yml)
--help                 -h  -- Get help
--host                 -H  -- Daemon socket to connect to
--project-name         -p  -- Specify an alternate project name (default: directory name)
--skip-hostname-check      -- Don't check the daemon's hostname against the name specified in the client certificate (for example if your docker host is an IP address)
--tls                      -- Use TLS; implied by --tlsverify
--tlscacert                -- Trust certs signed only by this CA
--tlscert                  -- Path to TLS certificate file
--tlskey                   -- Path to TLS key file
--tlsverify                -- Use TLS and verify the remote
--verbose                  -- Show more output
--version              -v  -- Print version and exit
```

Signed-off-by: Matt Bray <mattjbray@gmail.com>
2016-09-28 12:04:13 +01:00
Joffrey F
5667de87e8 Fix the contributors script to show only contributors on the current branch
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-22 12:34:59 -07:00
Joffrey F
f65f89ad8c Merge pull request #3653 from shin-/3637-link-local-ips
Add support for link-local IPs in service.networks definition
2016-09-22 11:58:29 -07:00
Daniel Nephin
5b27389571 Merge pull request #3956 from shin-/update_dockerpy_version
Bump docker-py dependency
2016-09-21 10:08:48 -04:00
Joffrey F
53fa44c01e Don't break when interpolating environment with unicode characters
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-20 18:05:59 -07:00
Joffrey F
7687412e03 Merge pull request #3922 from shin-/3897-volumespec_parse_win32
Improve volumespec parsing on windows platforms
2016-09-20 13:09:37 -07:00
Joffrey F
33424189d4 Denormalize function defaults to latest version
Minor docs fix

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-20 11:47:14 -07:00
Joffrey F
7911659266 Improve volumespec parsing on windows platforms
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-20 11:24:24 -07:00
Andreas Kohn
cb3bf869f4 Fix typo
Signed-off-by: Andreas Kohn <andreas.kohn@gmail.com>
2016-09-20 13:59:17 +02:00
Joffrey F
1648a3e257 Merge pull request #3709 from Knetic/groupadd
Supported group_add
2016-09-19 17:18:06 -07:00
Joffrey F
fc6791f3f0 Bump docker-py dependency
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-16 14:12:15 -07:00
Joffrey F
1d03baa9b1 Merge pull request #3954 from shin-/windows_tcp_default
Force default host on windows to the default TCP host (instead of npipe)
2016-09-16 14:09:10 -07:00
Joffrey F
64517e31fc Force default host on windows to the default TCP host (instead of npipe)
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-16 11:43:25 -07:00
Joffrey F
66b395d950 Include docker-py link-local fix and improve integration test
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-15 14:55:42 -07:00
Joffrey F
fd254caa68 Add support for link-local IPs in service.networks definition
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-15 14:55:14 -07:00
Joffrey F
651283eef9 Merge pull request #3941 from shin-/3888-recover-apierror-logs
Catch APIError while printing container logs
2016-09-13 12:58:40 -07:00
Joffrey F
f065ce0f73 Merge pull request #3942 from shin-/3873-syslog-logs-error
Only allow log streaming if logdriver is json-file
2016-09-13 12:28:27 -07:00
Joffrey F
3fcd648ba2 Catch APIError while printing container logs
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-13 12:10:41 -07:00
Joffrey F
7dd2e33057 Only allow log streaming if logdriver is json-file or journald
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-13 11:56:26 -07:00
Joffrey F
1b2354c6f4 Merge pull request #3943 from aanand/fix-integration-test-on-docker-for-mac
Fix integration test on Docker for Mac
2016-09-13 11:54:16 -07:00
Daniel Nephin
ac9198e638 Merge pull request #3930 from shin-/update_dockerpy_version
Update docker-py dependency to latest release
2016-09-13 10:35:56 -04:00
Daniel Nephin
9faa852d41 Merge pull request #3921 from shin-/3890-pull-services
Fix command hint in bundle to pull services instead of images
2016-09-13 10:32:14 -04:00
Aanand Prasad
9759f27fa6 Fix integration test on Docker for Mac
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-09-13 14:50:37 +01:00
Joffrey F
b64bd07f22 Update docker-py dependency to latest release
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-12 14:34:07 -07:00
George Lester
dada36f732 Supported group_add
Signed-off-by: George Lester <glester491@gmail.com>
2016-09-11 23:10:49 -07:00
Joffrey F
817c76c8e9 Fix command hint in bundle to pull services instead of images
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-09-08 11:17:39 -07:00
Joffrey F
3dec600d82 Merge pull request #3830 from shin-/3534-machine-config-args
Remove surrounding quotes from TLS paths, if present
2016-09-07 18:35:43 -07:00
Ben Firshman
c197e02ecc Merge pull request #3814 from aanand/disambiguate-swarm
Disambiguate 'Swarm' in integration doc
2016-09-07 10:46:14 +01:00
Joffrey F
267a243f80 Merge pull request #3799 from aanand/handle-connection-error-on-project-init
Handle connection errors on project initialization
2016-09-06 10:25:48 -07:00
Sven Dowideit
08179fc7e3 Merge pull request #3865 from SvenDowideit/add-jenkinsfile
Add docs checking Jenkinsfile
2016-08-24 15:01:36 +10:00
Sven Dowideit
bf91c64983 Add docs checking Jenkinsfile
Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
2016-08-22 12:18:07 +10:00
Ben Firshman
acfe100686 Merge pull request #3542 from jfroche/add_swappiness
Add support for swappiness constraint
2016-08-16 13:58:33 +01:00
Jean-François Roche
d824cb9b06 Add support for swappiness constraint
Run a service using `docker run --memory-swappiness=0` (see
https://docs.docker.com/engine/reference/run/)

refs #2383

Signed-off-by: Jean-François Roche <jfroche@affinitic.be>
2016-08-16 11:02:51 +02:00
Joffrey F
13bcd85eb3 Merge pull request #3808 from jgsqware/patch-1
Update rm.md
2016-08-09 15:16:48 -07:00
Joffrey F
c0305024f5 Remove surrounding quotes from TLS paths, if present
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-08-09 15:13:01 -07:00
JG²
17f46f8999 Update rm.md
Receiving this message when using the -a flag : `--all flag is obsolete. This is now the default behavior of `docker-compose rm`, I proposed to mark it in the docs but I don't know which way is the best

Signed-off-by: jgsqware <garciagonzalez.julien@gmail.com>
2016-08-05 13:41:20 +02:00
Aanand Prasad
4cba653eeb Disambiguate 'Swarm' in integration doc
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-08-04 15:19:02 +01:00
Aanand Prasad
d29f8e1022 Merge pull request #3789 from shin-/3788-json-splitter-fix
json_splitter: Don't break when buffer contains leading whitespace.
2016-08-03 13:23:52 +01:00
Joffrey F
9abbe1b7f8 Catchable error for parse failures in split_buffer
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-08-02 12:48:32 -07:00
Aanand Prasad
b3a4d76d4f Handle connection errors on project initialization
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-08-02 11:44:25 +01:00
Victoria
589fb4925e Merge pull request #3797 from aanand/note-about-experimental-build
Add note to bundle docs about requiring an experimental Engine build
2016-08-01 12:25:38 -07:00
Aanand Prasad
48258e2b46 Add note to bundle docs about requiring an experimental Engine build
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-08-01 12:25:49 +01:00
Joffrey F
6ce066274e Merge pull request #3784 from aanand/fix-timeout-error
Fix stacktrace when handling timeout error
2016-07-29 14:09:21 -07:00
Joffrey F
6f4be1cffc json_splitter: Don't break when buffer contains leading whitespace.
Add error logging with detailed output for decode errors

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-07-29 14:05:59 -07:00
Aanand Prasad
5aeeecb6f2 Fix stacktrace when handling timeout error
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-29 17:12:46 +01:00
Daniel Nephin
dec2c83014 Merge pull request #3778 from shin-/1.8.0-release-master-changes
1.8.0 release master changes
2016-07-27 18:04:43 -04:00
Joffrey F
d5765b7856 Merge pull request #3771 from aanand/shell-completion-for-push-images
Shell completion for --push-images
2016-07-27 13:35:05 -07:00
Joffrey F
6ab0607e61 Switch back to dev version
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-07-27 13:30:52 -07:00
Joffrey F
1110af1bae Bump 1.8.0
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-07-27 13:30:06 -07:00
Aanand Prasad
7fafd72c1e Bump 1.8.0-rc3
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-27 13:22:20 -07:00
Aanand Prasad
60622026fa Bump 1.8.0-rc2
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-27 13:22:07 -07:00
Joffrey F
22c0779a49 Bump 1.8.0-rc1
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-07-27 13:21:47 -07:00
Joffrey F
647f260b0a Merge pull request #3774 from aanand/fix-tls-version-error-message
Fix error message for unrecognised TLS version
2016-07-27 10:35:21 -07:00
Aanand Prasad
ec825af3d3 Fix error message for unrecognised TLS version
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-27 18:26:40 +01:00
Aanand Prasad
6633f1962c Shell completion for --push-images
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-27 16:00:53 +01:00
Aanand Prasad
e9d62e8404 Merge pull request #3676 from aanand/warn-for-swarm-mode
Show a warning when engine is in swarm mode
2016-07-27 15:38:09 +01:00
Aanand Prasad
ef4ad93d1e Merge pull request #3760 from bfirsh/useragent
Add user agent to API calls
2016-07-27 14:55:18 +01:00
Aanand Prasad
69b91ef6ba Merge pull request #3636 from dnephin/add_missing_ref_docs
Add missing reference docs for push and bundle
2016-07-27 14:30:17 +01:00
Ben Firshman
1877a41b92
Add user agent to API calls
Signed-off-by: Ben Firshman <ben@firshman.co.uk>
2016-07-27 14:26:15 +01:00
Aanand Prasad
5f0186e008 Merge pull request #3769 from shin-/upgrade-dockerpy-1.9.0
Update to docker-py 1.9.0
2016-07-27 11:56:13 +01:00
Joffrey F
7f3375c2ce Update docker-py requirement to the latest release
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-07-26 13:07:38 -07:00
Daniel Nephin
2fec6966d4 Add reference docs for push and bundle.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-07-26 15:18:09 -04:00
Ben Firshman
4a8b88bc2e Merge pull request #3763 from aanand/remove-experimental-networking-doc
Remove doc on experimental networking support
2016-07-26 14:24:04 +01:00
Aanand Prasad
8ffbe8e083 Remove note about .dsb
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-26 11:59:04 +01:00
Aanand Prasad
28e6508f4a Add note about missing volume mount support
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-26 11:51:30 +01:00
Aanand Prasad
8924f6c05c Fix example image hash
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-26 11:51:16 +01:00
Aanand Prasad
4598dfc79f Merge pull request #3762 from aanand/pull-flag-on-bundle
Rename --fetch-digests to --push-images and remove auto-pull
2016-07-26 11:01:32 +01:00
Aanand Prasad
887ed8d1b6 Rename --fetch-digests to --push-images and remove auto-pull
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-25 17:36:24 +01:00
Aanand Prasad
583bbb4635 Copy experimental bundle docs into Compose docs so URL is stable
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-25 13:46:56 +01:00
Aanand Prasad
2c9e46f60f Show a warning when engine is in swarm mode
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-25 13:46:56 +01:00
Aanand Prasad
07e2426d89 Remove doc on experimental networking support
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-25 13:38:04 +01:00
Daniel Nephin
619bf4c4df Merge pull request #3705 from aanand/fix-timeout-message
Fix timeout value in error message
2016-07-22 10:57:41 -04:00
Daniel Nephin
10749e187c Merge pull request #3718 from aanand/fix-run-entrypoint
Fix bugs with entrypoint/command in docker-compose run
2016-07-22 10:55:25 -04:00
Aanand Prasad
7f65caa97b Merge pull request #3747 from aanand/clarify-env-docs
Clarify environment, env_file and build.args docs
2016-07-21 16:14:26 +01:00
Daniel Nephin
a9b5e5abe0 Merge pull request #3751 from ijc25/master
Tidy up remaining lingering docker.client.Client objects in test suite
2016-07-21 11:13:29 -04:00
Ian Campbell
d6f70dddc7 Call the superclass tearDown in VolumeTest
Currently it doesn't actually seem to make any practical difference that this
is missing, but it seems like good practice to do so anyway, to be robust
against future test case changes which might require cleanup done in the super
class.

Signed-off-by: Ian Campbell <ian.campbell@docker.com>
2016-07-21 13:17:53 +01:00
Ian Campbell
3124fec01a tearDown tmp_volumes array itself in VolumeTest
Each volume in the array holds a reference to a docker.client.Client object and
therefore a connection pool which leaves fds open once the test has completed.

Signed-off-by: Ian Campbell <ian.campbell@docker.com>
2016-07-21 13:17:53 +01:00
Ian Campbell
5cdf30fc12 Teardown project and db in ResilienceTest
These hold a reference to a docker.client.Client object and therefore a
connection pool which leaves fds open once the test has completed.

Signed-off-by: Ian Campbell <ian.campbell@docker.com>
2016-07-21 13:17:53 +01:00
Aanand Prasad
26b819ca67 Merge pull request #3748 from ijc25/master
tearDown the project override at the end of each test case
2016-07-20 16:28:45 +01:00
Ian Campbell
0483bcb472 delete DockerClientTestCase.client class attribute on tearDownClass
This is a docker.client.Client and therefore contains a connection pool, so
each subclass of DockerClientTestCase can end up holding on to up to 10 Unix
socket file descriptors after the tests contained in the sub-class are
complete.

Before this by the end of a test run I was seeing ~100 open file descriptors,
~80 of which were Unix domain sockets. By cleaning these up only 15 Unix
sockets remain at the end (out of ~25 fds, the rest of which are the Python
interpretter, opened libraries etc).

Signed-off-by: Ian Campbell <ian.campbell@docker.com>
2016-07-20 15:51:22 +01:00
Ian Campbell
6649e9aba3 tearDown the project override at the end of each test case
self._project.client is a docker.client.Client, so creating a new self._project
leaks (via the embedded connection pool) a bunch of Unix socket file
descriptors for each test which overrides self.project using this mechanism.

In my tests I observed the test harness using 800-900 file descriptor, which is
OK on Linux with the default limit of 1024 but breaks on OSX (e.g. with
Docker4Mac) where the default limit is only 256. The failure can be provoked on
Linux too with `ulimit -n 256`.

With this fix I have observed the process ending with ~100 file descriptors
open, including 83 Unix sockets, so I think there is likely at least one more
leak lurking.

Signed-off-by: Ian Campbell <ian.campbell@docker.com>
2016-07-20 14:34:12 +01:00
Aanand Prasad
425303992c Reorder/clarify args docs
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-20 12:47:47 +01:00
Jarrod Pooler
9ab1d55d06 Updating arg docs in the proper place
Signed-off-by: Jarrod Pooler <jarrod.pooler@homesite.com>
2016-07-20 12:45:11 +01:00
Aanand Prasad
907b0690e6 Clarify environment and env_file docs
Add note to say that environment variables will not be automatically
made available at build time, and point to the `args` documentation.

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-20 12:23:51 +01:00
Aanand Prasad
d7db15ce94 Merge pull request #3364 from TomasTomecek/3355-detailed-error-messages
service: detailed error messages for create and start
2016-07-11 16:29:35 -04:00
Aanand Prasad
593d1aeb09 Fix bugs with entrypoint/command in docker-compose run
- When no command is passed but `--entrypoint` is, set Cmd to `[]`
- When command is a single empty string, set Cmd to `[""]`

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-11 16:15:13 -04:00
Aanand Prasad
1e60030b94 Merge pull request #3488 from jgiannuzzi/internal_networks
Add support for creating internal networks
2016-07-11 15:24:29 -04:00
Jonathan Giannuzzi
83f35e132b Add support for creating internal networks
Signed-off-by: Jonathan Giannuzzi <jonathan@giannuzzi.be>
2016-07-11 11:34:01 +02:00
Tomas Tomecek
fea970dff3 service: detailed error messages for create and start
Fixes: #3355

Signed-off-by: Tomas Tomecek <ttomecek@redhat.com>
2016-07-11 10:45:27 +02:00
Aanand Prasad
c3fd6a8f4d Merge pull request #3704 from aanand/update-install-and-changelog-for-1.7.1
Update install.md and CHANGELOG.md for 1.7.1
2016-07-07 16:01:55 -07:00
Aanand Prasad
4207d43b85 Fix timeout value in error message
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-07 12:08:47 -07:00
Aanand Prasad
576a2ee7ae Stop checking the deprecated DOCKER_CLIENT_TIMEOUT variable
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-07 11:58:10 -07:00
Aanand Prasad
49d4fd2795 Update install.md and CHANGELOG.md for 1.7.1
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-07 11:41:11 -07:00
Joffrey F
79ddf06267 Merge pull request #3662 from albers/completion-bundle--fetch-digests
bash completion for `docker-compose bundle --fetch-digests`
2016-07-07 10:39:18 -07:00
Aanand Prasad
89c9aed339 Merge pull request #3697 from aanand/pin-alpine-base-image
Pin base image to alpine:3.4 in Dockerfile.run
2016-07-06 18:04:47 -07:00
Aanand Prasad
08127625a0 Pin base image to alpine:3.4 in Dockerfile.run
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-06 18:01:27 -07:00
Aanand Prasad
1e176b58c5 Merge pull request #3592 from stakodiak/fix-privilege-typo
Fix a typo in a test's name.
2016-07-06 15:22:05 -07:00
Aanand Prasad
98818d4e50 Merge pull request #3591 from staticshock/togather
Fix a typo (togather -> together)
2016-07-06 11:45:22 -07:00
Aanand Prasad
554dc2496a Merge pull request #3590 from Knetic/oomscore
Added support for oom_score_adj
2016-07-06 11:45:09 -07:00
Aanand Prasad
dcc09b677b Merge pull request #3691 from aanand/fix-alias-tests-on-1.11
Fix alias tests on 1.11
2016-07-06 11:03:54 -07:00
Aanand Prasad
949b88fff9 Fix alias tests on 1.11
The fix in 8e04582052 caused a regression
when testing against 1.11.

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-07-06 09:56:25 -07:00
Aanand Prasad
e659cd139b Merge pull request #3689 from bfirsh/docker-mac-not-running-error
Suggest to run Docker for Mac if it isn't running
2016-07-06 09:55:19 -07:00
Ben Firshman
5dabc81c16 Suggest to run Docker for Mac if it isn't running
Instead of suggesting docker-machine.

Signed-off-by: Ben Firshman <ben@firshman.co.uk>
2016-07-06 15:43:22 +01:00
George Lester
6fe5d2b543 Implemented oom_score_adj
Signed-off-by: George Lester <glester491@gmail.com>
2016-07-05 23:43:32 -07:00
Aanand Prasad
967dce5807 Merge pull request #3671 from dnephin/fix_pip_version_osx
Update pip in travis osx build
2016-07-05 16:08:51 -07:00
Aanand Prasad
edd3637b9b Merge pull request #3669 from chrisclark/master
Docs: Typo leading to possible extreme agony
2016-07-05 16:08:08 -07:00
Ben Firshman
f9f151a51f Merge pull request #3679 from allencloud/make-output-consistent-typo
make-output-consistent-typo
2016-07-05 17:36:59 +01:00
allencloud
931b01acf9 make-output-consistent-typo
Signed-off-by: allencloud <allen.sun@daocloud.io>
2016-07-02 23:33:13 +08:00
Aanand Prasad
f1974f6c5e Merge pull request #3670 from aanand/3343-run-with-env-values-from-system
[Carry #3373] Unset env vars behavior in 'run' mirroring engine
2016-07-01 12:12:29 -07:00
Daniel Nephin
3d0a1de023 Upgrade pip on osx
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-06-30 20:52:15 -04:00
Aanand Prasad
50d5aab8ad Fix test: check container's Env array instead of the output of 'env'
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-06-30 17:00:30 -07:00
Aanand Prasad
10ae81f8cf Post-merge fix - restore Environment import in main.py
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-06-30 15:49:16 -07:00
Joffrey F
5d244ef6d8 Unset env vars behavior in 'run' mirroring engine
Unset env vars passed to `run` via command line options take the
value of the system's var with the same name.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-06-30 15:48:23 -07:00
Chris Clark
a62739b906 Signed-off-by: Chris Clark <chris@untrod.com>
The postgres image expects a specific volume path. The docs had a typo in that path. This can cause a lot of agony. This is not hypothetical agony, but very real agony that was very recently experienced :)
2016-06-30 15:30:22 -07:00
Daniel Nephin
3d20e25bf8 Merge pull request #3661 from dnephin/fix_requirements
Add missing deps to requirements.txt
2016-06-30 18:21:40 -04:00
Aanand Prasad
bc0939dcf0 Merge pull request #3645 from leonhartX/zsh-completion-bundle
add zsh completion support for bundle
2016-06-30 10:32:44 -07:00
Aanand Prasad
c0237a487b Merge pull request #3221 from aeriksson/fix-zsh-autocomplete
Fix zsh autocomplete
2016-06-29 11:08:08 -07:00
Aanand Prasad
3c8fdb8752 Merge pull request #3615 from shin-/docker-py-bump190
Update docker-py version in requirements
2016-06-29 10:49:59 -07:00
Harald Albers
622de27c1e bash completion for docker-compose bundle --fetch-digests
Signed-off-by: Harald Albers <github@albersweb.de>
2016-06-29 08:45:36 -07:00
Daniel Nephin
2b6ea847b9 Update requirements.txt
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-06-29 10:38:01 -04:00
Ben Firshman
da2aae2a29 Merge pull request #3570 from davidjb/patch-1
Fix minor YAML typo
2016-06-29 15:20:16 +01:00
Ke Xu
edd28f09d1 change dsb to dab
Signed-off-by: Ke Xu <leonhartx.k@gmail.com>
2016-06-29 11:01:50 +09:00
Joffrey F
93cc2675c8 Merge pull request #3625 from albers/completion-bundle
bash completion for `docker-compose bundle`
2016-06-28 15:52:37 -07:00
Joffrey F
3649df83ab Merge pull request #3626 from albers/completion-push
bash completion for `docker-compose push`
2016-06-28 15:52:14 -07:00
Joffrey F
b89dc99e8e Merge pull request #3646 from leonhartX/zsh-completion-push
add zsh completion for push
2016-06-28 15:50:32 -07:00
Joffrey F
a822406eb0 Update docker-py version in requirements
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-06-28 15:49:06 -07:00
Aanand Prasad
72d3d5d84b Merge pull request #3612 from dnephin/tests_for_bundle
Add some unit tests and an acceptance test for bundle
2016-06-28 14:47:29 -07:00
Aanand Prasad
55e20d1727 Merge pull request #3652 from aanand/fix-tests-for-1.12
Fix tests to accommodate short-id container alias
2016-06-28 13:27:40 -07:00
Daniel Nephin
7c06f60573 Merge pull request #3563 from adamchainz/readthedocs.io
Convert readthedocs links for their .org -> .io migration for hosted projects
2016-06-28 12:35:19 -04:00
Daniel Nephin
00decf8677 Merge pull request #3638 from aanand/update-bundle-extension
Update bundle extension
2016-06-28 11:43:58 -04:00
Daniel Nephin
5640bd42a8 Add an acceptance test for bundle.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-06-28 10:18:59 -04:00
Daniel Nephin
95207561bb Add some unit tests for new bundle and push commands.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-06-28 10:18:20 -04:00
Aanand Prasad
8e04582052 Fix tests to accommodate short-id container alias
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-06-27 16:21:19 -07:00
Aanand Prasad
058a7659ba Update bundle extension
It's now .dab, for Distributed Application Bundle

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-06-27 14:16:44 -07:00
Aanand Prasad
fe0654603c Merge pull request #3619 from jgiannuzzi/fix_tests
Fix assertion that was always true
2016-06-27 14:16:00 -07:00
Andre Eriksson
c3247e7af8 zsh autocomplete: update misleading comment
Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:07:59 -07:00
Andre Eriksson
b3d4e9c9d7 zsh autocomplete: break out duplicated flag messages into variables
Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Andre Eriksson
0058b4ba0c zsh autocomplete: replace use of sed with cut
Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Andre Eriksson
612d263d74 zsh autocomplete: fix issue when filtering on already selected services
Previously, the filtering on already selected services would break when
one service was a substring of another.

This commit fixes that.

Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Andre Eriksson
048408af48 zsh autocomplete: fix missing services issue for build/pull commands
Previously, the autocomplete for the build/pull commands would only add
services for which build/image were the _first_ keys, respectively, in
the docker-compose file.

This commit fixes this, so the appropriate services are listed
regardless of the order in which they appear

Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Andre Eriksson
d990f7899c zsh autocomplete: pass all relevant flags to docker-compose/docker
For autocomplete to work properly, we need to pass along some flags when
calling docker (--host, --tls, …) and docker-compose (--file, --tls, …).

Previously flags would only be passed to docker-compose, and the only
flags passed were --file and --project-name.

This commit makes sure that all relevant flags are passed to both
docker-compose and docker.

Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Andre Eriksson
97ba14c82a zsh autocomplete: use two underscores for all function names
Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Andre Eriksson
1b5a94f4e4 zsh autocomplete: bring flag help texts up to date
Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Andre Eriksson
8d2fbe3a55 zsh autocomplete: add 'build' flag for 'create' and 'up'
Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Andre Eriksson
eb10f41d13 zsh autocomplete: fix incorrect flag exclusions for 'create' and 'up'
Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Andre Eriksson
73a1b60ced zsh autocomplete: add missing 'remove-orphans' flag for 'up' and 'down'
Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Andre Eriksson
b3d9652cc3 zsh autocomplete: add missing docker-compose base flags
Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Andre Eriksson
cbb44b1a14 fix broken zsh autocomplete for version 2 docker-compose files
This has the added benefit of making autocompletion work when the
docker-compose config file is in a parent directory.

Signed-off-by: Andre Eriksson <aepubemail@gmail.com>
2016-06-27 11:00:17 -07:00
Ke Xu
a0a90b2352 add zsh completion for push
Signed-off-by: Ke Xu <leonhartx.k@gmail.com>
2016-06-27 18:00:52 +09:00
Ke Xu
aa7f522ab0 add zsh completion support for bundle
Signed-off-by: Ke Xu <leonhartx.k@gmail.com>
2016-06-27 17:48:14 +09:00
Sven Dowideit
5c1abe2e29 Merge pull request #3631 from jamesottaway/patch-1
Document `tmpfs` being v2 only
2016-06-27 11:50:15 +10:00
James Ottaway
f77dbc06cc Document tmpfs being v2 only
Signed-off-by: James Ottaway <git@james.ottaway.io>
2016-06-24 10:54:51 +10:00
Harald Albers
f49b624d95 bash completion for docker-compose push
Signed-off-by: Harald Albers <github@albersweb.de>
2016-06-22 17:19:20 +02:00
Harald Albers
e5c5dc09f8 bash completion for docker-compose bundle
Signed-off-by: Harald Albers <github@albersweb.de>
2016-06-22 17:06:30 +02:00
Jonathan Giannuzzi
3c77db709f Fix assertion that was always true
Signed-off-by: Jonathan Giannuzzi <jonathan@giannuzzi.be>
2016-06-20 14:48:45 +02:00
Anton Backer
80af26d2bb togather -> together
Signed-off-by: Anton Backer <anton.backer@newsela.com>
2016-06-15 15:55:45 -07:00
Aanand Prasad
352cdf0a80 Merge pull request #3601 from aanand/warn-on-missing-digests
Warn on missing digests, don't push/pull by default
2016-06-15 14:28:49 -07:00
Aanand Prasad
020d46ff21 Warn on missing digests, don't push/pull by default
Add a --fetch-digests flag to automatically push/pull

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-06-14 16:37:32 -07:00
Joffrey F
317cd98c0d Merge pull request #3599 from shin-/tls-version-unavailable-test
Skip TLS version test if TLSv1_2 is not available on platform
2016-06-14 12:34:43 -07:00
Victoria
f8f582f349 Merge pull request #3600 from londoncalling/fix-broken-links-PR-23492
fixes broken links in 3 Compose docs files due to topic re-org in PR#…

Merging to address broken links. One more to go in (DTR).
2016-06-14 12:30:41 -07:00
Victoria Bialas
a56e44f96e fixes broken links in 3 Compose docs files due to topic re-org in PR#23492
Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
2016-06-14 12:24:30 -07:00
Joffrey F
ee68a51e28 Skip TLS version test if TLSv1_2 is not available on platform
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-06-14 12:23:04 -07:00
Joffrey F
0fe82614a6 Merge pull request #3595 from dnephin/add-push-and-bundle
Add docker-compose push and docker-compose bundle
2016-06-14 10:57:32 -07:00
Aanand Prasad
8f8c17bf66 Merge pull request #3549 from shin-/KalleDK-master
Add support for COMPOSE_TLS_VERSION config option
2016-06-14 10:57:12 -07:00
Daniel Nephin
9b7bd69cfc Support entrypoint, labels, and user in the bundle.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-06-14 13:00:12 -04:00
Aanand Prasad
1ea9dda1d3 Implement 'docker-compose push' and 'docker-compose bundle'
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-06-14 12:06:14 -04:00
Aanand Prasad
21f20cbc9b Merge pull request #3449 from Andrey9kin/ready/3281
Fix #3281: Unexpected result when using build args with default values
2016-06-14 08:05:07 -07:00
alex
68d73183eb Fix a typo in a test's name. 2016-06-13 23:36:34 -04:00
Aanand Prasad
2123906586 Merge pull request #3577 from sanmai-NL/3576-byte_str_fix
Fix byte/str typing error
2016-06-14 01:58:27 +01:00
Aanand Prasad
59e96fea4f Merge pull request #3588 from shin-/3285-root-mount
Fix split_path_mapping behavior when mounting "/"
2016-06-14 01:45:20 +01:00
Joffrey F
60f7e021ad Fix split_path_mapping behavior when mounting "/"
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-06-13 15:32:10 -07:00
Sander Maijers
61324ef308
Fix byte/str typing error
Signed-off-by: Sander Maijers <S.N.Maijers@gmail.com>
2016-06-10 16:30:46 +02:00
David Beitey
0287486b14 Fix minor YAML typo
Signed-off-by: David Beitey <david@davidjb.com>
2016-06-09 17:00:31 +10:00
Adam Chainz
9ddb7f3c90 Convert readthedocs links for their .org -> .io migration for hosted projects
As per [their blog post of the 27th April](https://blog.readthedocs.com/securing-subdomains/) ‘Securing subdomains’:

> Starting today, Read the Docs will start hosting projects from subdomains on the domain readthedocs.io, instead of on readthedocs.org. This change addresses some security concerns around site cookies while hosting user generated data on the same domain as our dashboard.

Test Plan: Manually visited all the links I’ve modified.

Signed-off-by: Adam Chainz <adam@adamj.eu>
2016-06-08 03:52:12 +01:00
Aanand Prasad
e502417df2 Merge pull request #3475 from shin-/3429-networks-config-serialize
Output valid config in config command
2016-06-07 18:01:39 +02:00
Ben Firshman
6e2d1eb80e Merge pull request #3516 from albers/completion-rm--all
remove command completion for `docker-compose rm --a`
2016-06-06 22:23:56 +01:00
Joffrey F
ea640f3821 Remove external_name from serialized config output
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-06-03 12:10:09 -07:00
Joffrey F
427ec899df Merge pull request #3504 from denismakogon/issue-3503
Issue-3503: Improve timestamp validation in tests
2016-06-03 11:57:55 -07:00
Joffrey F
e7a8b2fed5 Update TLS version configuration code. Tests.
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-06-03 11:45:22 -07:00
Sven Dowideit
17b219454f Merge pull request #3522 from SvenDowideit/fix-links
Fix links
2016-05-31 16:36:29 -07:00
Sven Dowideit
dd3590180d more fixes
Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
2016-05-31 21:18:42 +00:00
Andrey Devyatkin
a67ba5536d Fix #3281: Unexpected result when using build args with default values
Fix the issue when build arg is set to None instead of empty string. Usecase:

cat docker-compose.yml
  .... args:
  - http_proxy
  - https_proxy
  - no_proxy

If http_proxy, https_proxy, no_proxy environment variables are not defined then http_proxy,
https_proxy, no_proxy build args will be set to string None which breaks all downloads

With this change undefined build args will be set to empty string instead of string None

Signed-off-by: Andrey Devyatkin <andrey.a.devyatkin@gmail.com>
2016-05-28 11:39:41 +02:00
Sven Dowideit
90fba58df9 Fix links
Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
2016-05-27 21:29:47 +00:00
Andrey Devyatkin
c148849f0e Fix #3281: Unexpected result when using build args with default values
Fix the issue when build arg is set to None instead of empty string. Usecase:

cat docker-compose.yml
.... args:
- http_proxy
- https_proxy
- no_proxy

If http_proxy, https_proxy, no_proxy environment variables are not defined then http_proxy,
https_proxy, no_proxy build args will be set to string None which breaks all downloads

With this change undefined build args will be set to empty string instead of string None

Signed-off-by: Andrey Devyatkin <andrey.a.devyatkin@gmail.com>
2016-05-27 20:16:52 +02:00
Denis Makogon
1298b9aa5d Issue-3503: Improve timestamp validation in tests
CLITestCase.test_events_human_readable fails due to
 wrong assumption that host where tests were launched
 will have the same date time as Docker daemon.

 This fix introduces internal method for validating
 timestamp in Docker logs

Signed-off-by: Denys Makogon <lildee1991@gmail.com>
2016-05-27 14:50:13 +03:00
Andrey Devyatkin
e3e8a619cc Fix #3281: Unexpected result when using build args with default values
Fix the issue when build arg is set to None instead of empty string.
Usecase:

cat docker-compose.yml
....
args:
- http_proxy
- https_proxy
- no_proxy

If http_proxy, https_proxy, no_proxy environment variables are not defined
then http_proxy, https_proxy, no_proxy build args will be set to string None which breaks all downloads

With this change build args will not passed to docker engine if they are equal to string None

Signed-off-by: Andrey Devyatkin <andrey.a.devyatkin@gmail.com>
2016-05-27 07:48:13 +02:00
Harald Albers
c46737ed02 remove command completion for docker-compose rm --a
As `--all|-a` is deprecated, there's no use to suggest it any
more in command completion.

Signed-off-by: Harald Albers <github@albersweb.de>
2016-05-26 12:48:53 -07:00
Aanand Prasad
86b5ed1a84 Merge pull request #3473 from shin-/3461-merge-port-mappings
Eliminate duplicates when merging port mappings from config files
2016-05-26 16:57:43 +01:00
Joffrey F
4bb80c25d3 Merge pull request #3483 from aanand/env-disambiguation
Add "disambiguation" page for environment variables
2016-05-24 13:29:22 -07:00
Joffrey F
048360d1ed Merge pull request #3489 from aanand/update-openssl-mac
Use latest OpenSSL version when building Mac binary on Travis
2016-05-23 13:52:51 -07:00
Aanand Prasad
a34cd5ed54 Add "disambiguation" page for environment variables
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-05-23 15:03:25 +01:00
Joffrey F
c4229b469a Improve merging for several service config attributes
All uniqueItems lists in the config now receive the same treatment removing
duplicates.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-05-20 15:29:04 -07:00
Joffrey F
842e372258 Eliminate duplicates when merging port mappings from config files
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-05-20 15:28:35 -07:00
Aanand Prasad
33bed5c706 Use latest OpenSSL version (1.0.2h) when building Mac binary on Travis
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-05-20 12:04:37 +01:00
Aanand Prasad
7763122ecb Merge pull request #3459 from shin-/2487-split-volume-path
Always use the Windows version of splitdrive when parsing volume mappings
2016-05-20 11:42:43 +01:00
Joffrey F
2b5b665d3a Add test for path mapping with Windows containers
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-05-19 14:53:37 -07:00
Joffrey F
9a39208741 Merge pull request #3482 from aanand/fix-prompt-buffering
Fix bug where confirmation prompt doesn't show due to line buffering
2016-05-19 08:52:34 -07:00
Aanand Prasad
ce8df9e789 Merge pull request #3466 from shin-/3330-rm-all-default
Update rm command to always remove one-off containers.
2016-05-19 16:46:31 +01:00
Aanand Prasad
0c8aeb9e05 Fix bug where confirmation prompt doesn't show due to line buffering
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-05-19 15:44:17 +01:00
Joffrey F
db0a6cf2bb Always use the Windows version of splitdrive when parsing volume mappings
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-05-17 16:33:59 -07:00
Joffrey F
844b7d463f Update rm command to always remove one-off containers.
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-05-16 14:59:33 -07:00
Joffrey F
ca3aef0c84 Merge pull request #3436 from shin-/3374-exec-windows
Fail gracefully when -d is not provided for exec command on Win32
2016-05-12 15:14:15 -07:00
Joffrey F
e5645595e3 Fail gracefully when -d is not provided for exec command on Win32
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-05-12 14:00:54 -07:00
Joffrey F
c9fe8920c9 Merge pull request #3457 from dnephin/fix_versions_script
Skip invalid git tags in versions.py
2016-05-12 13:52:20 -07:00
Daniel Nephin
4bf5271ae2 Skip invalid git tags in versions.py
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-05-12 14:41:40 -04:00
Aanand Prasad
72f6a5c8d3 Merge pull request #3433 from anton44eg/issue_3432
add msg attribute to ProjectError class
2016-05-12 16:55:11 +01:00
Joffrey F
dc88e54010 Merge pull request #3399 from yorkedork/fix/env-file-validation
Adds additional validation to 'env_vars_from_file'.
2016-05-12 08:53:25 -07:00
Anton Simernia
4b01f6dcd6 add msg attribute to ProjectError class
Signed-off-by: Anton Simernia <anton.simernya@gmail.com>
2016-05-09 18:26:20 +07:00
Sven Dowideit
f1603a3ee2 Merge pull request #3092 from wenchma/service_image
Update image format for service conf reference
2016-05-09 10:16:37 +10:00
Sven Dowideit
5fa81c4044 Merge pull request #3417 from spectralsun/patch-1
Small typo
2016-05-09 10:15:56 +10:00
Garrett Seward
3b7191f246 Small typo
Signed-off-by: spectralsun <garrett@spectralsun.com>
2016-05-04 10:47:01 -07:00
Daniel Nephin
3bf75b7330 Merge pull request #3398 from shin-/docker-py-1.8.1
Require latest docker-py version
2016-05-03 15:47:47 -04:00
Sven Dowideit
c1c8c70800 Merge pull request #3392 from SvenDowideit/use-docs-base-oss
convert docs Dockerfiles to use docs/base:oss
2016-05-03 10:47:00 +10:00
Joffrey F
94bcbd1fb6 Merge pull request #3388 from andrerom/patch-1
Clarify env-file doc that .env is read from cwd
2016-05-02 16:04:03 -07:00
Joffrey F
3e11a95056 Merge pull request #3400 from shin-/3333-raise-up-errors
Properly handle APIError failures in Project.up
2016-05-02 14:34:12 -07:00
Joffrey F
310b3d9441 Properly handle APIError failures in Project.up
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-05-02 13:42:05 -07:00
Thom Linton
28fb91b344 Adds additional validation to 'env_vars_from_file'.
The 'env_file' directive and feature precludes the use of the name
'.env' in the path shared with 'docker-config.yml', regardless of
whether or not it is enabled.

This change adds an additional validation to allow the use of this
path provided it is not a file.

Signed-off-by: Thom Linton <thom.linton@gmail.com>
2016-04-29 17:53:31 -07:00
Joffrey F
c41f30c3ff Merge pull request #3385 from shin-/3316-skip-statusless-events
Skip event objects that don't contain a status field
2016-04-29 17:50:32 -07:00
Joffrey F
fe17e0f948 Skip event objects that don't contain a status field
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-04-29 16:39:42 -07:00
Joffrey F
bd7ec24e25 Merge pull request #3384 from shin-/3264-shorthand-host-support
Support combination of shorthand flag and equal sign for host option
2016-04-29 16:39:16 -07:00
Joffrey F
e4bb678875 Require latest docker-py version
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-04-29 16:37:26 -07:00
André R
84aa39e978 Clarify env-file doc that .env is read from cwd
Closes #3381

Signed-off-by: André R <ar@ez.no>
2016-04-28 23:14:06 +02:00
Joffrey F
8cc7d68a00 Merge pull request #3390 from aronahl/master
Add missing log event filter when using docker-compose logs.
2016-04-28 12:53:04 -07:00
Joffrey F
0b24883cef Support combination of shorthand flag and equal sign for host option
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-04-28 12:52:00 -07:00
Aaron Nall
2efcec776c Add missing log event filter when using docker-compose logs.
Signed-off-by: Aaron Nall <aronahl@hotmail.com>
2016-04-28 15:14:44 +00:00
Daniel Nephin
61794ba97c Merge pull request #3377 from shin-/3372-windowserror
Define WindowsError on non-win32 platforms
2016-04-28 10:33:18 -04:00
Sven Dowideit
87ee38ed2c convert docs Dockerfiles to use docs/base:oss
Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
2016-04-28 12:57:02 +00:00
Aanand Prasad
7ad7eb71ca Merge pull request #3164 from aanand/fix-config-v1
WIP: Fix output of 'config' for v1 files
2016-04-26 20:34:18 +01:00
Joffrey F
d3e645488a Define WindowsError on non-win32 platforms
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-04-26 11:40:31 -07:00
Aanand Prasad
756ef14edc Fix format of 'restart' option in 'config' output
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-26 19:21:03 +01:00
Aanand Prasad
6064d200f9 Fix output of 'config' for v1 files
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-26 19:21:03 +01:00
Aanand Prasad
84a3e2fe79 Check full error message in test_up_with_net_is_invalid
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-26 19:21:03 +01:00
Aanand Prasad
a4d3dd6197 Remove v2_only decorators on config tests
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-26 19:21:03 +01:00
Joffrey F
0cd35913c3 Merge pull request #3382 from dnephin/upgrade_pip
Upgade pip to latest - attempt to fix jenkins builds
2016-04-26 09:38:12 -07:00
Daniel Nephin
26fe8213aa Upgade pip to latest
Hopefully fixes our builds.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-04-26 11:58:41 -04:00
Daniel Nephin
ac82597ac1 Merge pull request #3360 from bfirsh/better-validation-error-messages
Make validation errors less robotic
2016-04-21 11:32:23 -04:00
Daniel Nephin
1988dfeaf0 Merge pull request #3359 from bfirsh/clarify-compose-file-networks-documentation
Clarify service networks documentation
2016-04-21 11:19:32 -04:00
Joffrey F
da1d603463 Merge pull request #3351 from shin-/3342-setup-requirements
Force docker-py 1.8.0 or above
2016-04-20 17:40:51 -07:00
Joffrey F
75bcc382d9 Force docker-py 1.8.0 or above
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-04-20 16:56:48 -07:00
Ben Firshman
b67f110620 Explain the explanation about file versions
This explanation looked like it was part of the error. Added an
extra new line and a bit of copy to explain the explanation.

Signed-off-by: Ben Firshman <ben@firshman.co.uk>
2016-04-20 16:40:16 -07:00
Ben Firshman
27628f8655 Make validation error less robotic
"ERROR: Validation failed in file './docker-compose.yml', reason(s):"

is now:

"ERROR: The Compose file './docker-compose.yml' is invalid because:"

Signed-off-by: Ben Firshman <ben@firshman.co.uk>
2016-04-20 16:38:09 -07:00
Ben Firshman
55fcd1c3e3 Clarify service networks documentation
When jumping straight to this bit of the docs, it's not clear
that these are options under a service rather than the top-level
`networks` key. Added a service to make this super clear.

Signed-off-by: Ben Firshman <ben@firshman.co.uk>
2016-04-20 15:58:12 -07:00
Ben Firshman
a0aea42f75 Merge pull request #3326 from CRogers/patch-1
Readme should use new docker compose format instead of the old one
2016-04-20 23:06:35 +01:00
Ben Firshman
6ff3c47630 Merge pull request #3222 from jonlemmon/patch-1
Rails Docs: Add nodejs to apt-get install command
2016-04-20 22:57:50 +01:00
Daniel Nephin
8a34ee0eaa Merge pull request #3356 from metal3d/fix-help-acceptance-test
Fix the tests from jenkins
2016-04-20 12:18:20 -04:00
Patrice FERLET
ba10f1cd55 Fix the tests from jenkins
Acceptance tests didn't set "help" command to return "0" EXIT_CODE.

close #3354
related #3263

Signed-off-by: Patrice Ferlet <metal3d@gmail.com>
2016-04-20 13:23:37 +02:00
Aanand Prasad
cafe1315b2 Merge pull request #3334 from werehuman/fix-config-hash-change
Fix #3248: Accidental config_hash change
2016-04-19 12:42:19 +01:00
Aanand Prasad
984f839d33 Merge pull request #3263 from twitherspoon/3191_2_help_cli_feature
Added code to support no argument help command
2016-04-19 12:14:24 +01:00
Aanand Prasad
d21e1c5a30 Merge pull request #3335 from johnharris85/master
Fix CLI docstring to reflect Docopt behaviour.
2016-04-19 12:13:20 +01:00
Aanand Prasad
52fa010ac7 Merge pull request #3337 from dnephin/check_for_short_id_alias
Check for short id alias, and don't disconnect if it already exists
2016-04-19 12:12:43 +01:00
Daniel Nephin
d4bebbb1ba Merge pull request #3340 from johnharris85/2922-config-does-not-catch-missing-links
Fix #2922: Config does not catch missing links
2016-04-18 10:13:47 -04:00
johnharris85
6d2805917c Account for aliased links
Fix failing tests
Signed-off-by: John Harris <john@johnharris.io>
2016-04-17 15:25:06 -04:00
johnharris85
377be5aa1f Adding tests
Signed-off-by: John Harris <john@johnharris.io>
2016-04-17 14:01:06 -04:00
johnharris85
68272b0216 Config now catches undefined service links
Fixes issue #2922
Signed-off-by: John Harris <john@johnharris.io>
2016-04-17 14:00:07 -04:00
Daniel Nephin
56c6e29819 Unit test for skipping network disconnect.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-04-15 16:28:59 -04:00
Vladimir Lagunov
4702703615 Fix #3248: Accidental config_hash change
Signed-off-by: Vladimir Lagunov <lagunov.vladimir@gmail.com>
2016-04-15 15:34:30 +03:00
johnharris85
ad306f0479 Fix CLI docstring to reflect Docopt behaviour.
Signed-off-by: John Harris <john@johnharris.io>
2016-04-15 13:30:13 +01:00
Daniel Nephin
e1356e1f6f Set networking_config when creating a container.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-04-14 18:09:06 -04:00
Daniel Nephin
abb5ae7fe4 Only disconnect if we don't already have the short id alias.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-04-14 16:05:14 -04:00
Callum Rogers
e71c62b8d1 Readme should use new docker compose format instead of the old one
Signed-off-by: Callum Rogers <callumrogers@hotmail.co.uk>
2016-04-14 10:49:10 +01:00
Aanand Prasad
e2cb7b0237 Merge pull request #3299 from dannyprout/2096-only-show-port-clash-warning-when-starting-multiple-containers
Only show port clash warning if multiple containers are about to be started
2016-04-14 10:40:02 +01:00
Aanand Prasad
aebb3d5d0a Merge pull request #3320 from dnephin/make_it_dev_again
Update release notes and set version to 1.8.0dev
2016-04-14 10:22:01 +01:00
Daniel Nephin
50287722f2 Update release notes and set version to 1.8.0dev
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-04-13 13:27:18 -04:00
Danyal Prout
339ebc0483 Fixes #2096: Only show multiple port clash warning if multiple containers
are about to be started.

Signed-off-by: Danyal Prout <me@dany.al>
2016-04-12 20:58:21 +01:00
Tony Witherspoon
ae46bf8907 Updated StringIO import to support io module
Signed-off-by: Tony Witherspoon <tony.witherspoon@gmail.com>
2016-04-12 12:29:59 -04:00
Tony Witherspoon
276738f733 Updated cli_test.py to validate against the updated help command conditions
Signed-off-by: Tony Witherspoon <tony.witherspoon@gmail.com>
2016-04-12 11:47:15 -04:00
Daniel Nephin
f10bc8072e Merge pull request #3310 from aanand/fix-logs-test
Attempt to fix flaky logs test
2016-04-12 10:44:04 -04:00
Aanand Prasad
7781f62ddf Attempt to fix flaky logs test
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-12 12:07:13 +01:00
Aanand Prasad
3d3f331404 Merge pull request #3303 from aanand/clarify-rm-and-down
Clarify behaviour of rm and down
2016-04-12 11:31:22 +01:00
Daniel Nephin
d05feb1a4d Merge pull request #3302 from aanand/feed-queue-refactor
feed_queue() refactor
2016-04-11 12:58:11 -04:00
Aanand Prasad
7cfb5e7bc9 Fix race condition
If processing of all objects finishes before the queue is drained,
parallel_execute_iter() returns prematurely.

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-11 17:05:52 +01:00
Aanand Prasad
3722bb38c6 Clarify behaviour of rm and down
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-11 16:31:27 +01:00
Aanand Prasad
15c5bc2e6c Rename a couple of functions in parallel.py
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-11 13:05:30 +01:00
Aanand Prasad
0671b8b8c3 Document parallel helper functions
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-11 12:51:27 +01:00
Aanand Prasad
0e3db185cf Small refactor to feed_queue()
Put the event tuple into the results queue rather than yielding it from
the function.

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-11 12:37:00 +01:00
Victoria
97467c7dec Merge pull request #3295 from londoncalling/docs-format-followup-PR3275
added some formatting on the Wordress steps, and made heading levels …
2016-04-08 16:56:57 -07:00
Victoria Bialas
4192a009da added some formatting on the Wordress steps, and made heading levels in these sample app topics consistent
Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
2016-04-08 16:40:07 -07:00
Victoria
80614cff9b Merge pull request #3275 from activatedgeek/patch-1
Updated Wordpress tutorial
2016-04-08 16:12:44 -07:00
Sanyam Kapoor
d4e9a3b6b1 Updated Wordpress tutorial
The new tutorial now uses official Wordpress Docker Image.

Signed-off-by: Sanyam Kapoor <1sanyamkapoor@gmail.com>
2016-04-09 02:05:45 +05:30
Daniel Nephin
3ca8858897 Merge pull request #3292 from dnephin/fix_up_build
Remove extra ensure_image_exists() which causes duplicate builds.
2016-04-08 15:45:37 -04:00
Daniel Nephin
83df95d511 Remove extra ensure_image_exists() which causes duplicate builds.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-04-08 15:21:12 -04:00
Daniel Nephin
e5443717fb Merge pull request #3291 from aanand/parallel-execute-refactor
Parallel execution refactor/fixes
2016-04-08 15:15:41 -04:00
Daniel Nephin
91a545813a Merge pull request #3276 from shin-/bump_docker_py
Use docker-py 1.8.0
2016-04-08 15:15:01 -04:00
Aanand Prasad
be27e266da Reduce queue timeout
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-08 19:07:40 +01:00
Aanand Prasad
5450a67c2d Hold state in an object
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-08 19:06:07 +01:00
Aanand Prasad
54b6fc4219 Refactor so there's only one queue
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-08 18:54:02 +01:00
Aanand Prasad
ffab27c049 Test events coming out of parallel_execute_stream in error case
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-08 18:53:16 +01:00
Aanand Prasad
3720b50c3b Extract get_deps test helper
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-08 18:48:07 +01:00
Aanand Prasad
af9526fb82 Move queue logic out of parallel_execute()
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-08 18:30:28 +01:00
Aanand Prasad
141b96bb31 Abort operations if their dependencies fail
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-08 17:51:09 +01:00
Aanand Prasad
bcdf541c8c Refactor setup_queue()
- Stop sharing set objects across threads
- Use a second queue to signal when producer threads are done
- Use a single consumer thread to check dependencies and kick off new
  producers

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-04-08 16:24:29 +01:00
Tony Witherspoon
f5b80640fe Merge branch '3191_2_help_cli_feature' of https://github.com/twitherspoon/compose into 3191_2_help_cli_feature 2016-04-07 12:46:27 -04:00
twitherspoon
9f47e43b5c Merge branch 'master' into 3191_2_help_cli_feature 2016-04-07 12:43:34 -04:00
Tony Witherspoon
5d0aab4a8e updated cli_test.py to no longer expect raised SystemExit exceptions
Signed-off-by: Tony Witherspoon <tony.witherspoon@gmail.com>
2016-04-07 12:42:14 -04:00
Joffrey F
3ef6b17bfc Use docker-py 1.8.0
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-04-06 13:28:45 -07:00
Daniel Nephin
958f96c78a Merge pull request #3269 from dnephin/fix_logs_and_scale_down
Prevent unnecessary inspection of containers
2016-04-06 12:45:46 -04:00
Daniel Nephin
b33d7b3dd8 Prevent unnecessary inspection of containers when created from an inspect.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-04-06 11:14:42 -04:00
Tony Witherspoon
129fb5b356 Added code to output the top level command options if docker-compose help with no command options provided
Signed-off-by: Tony Witherspoon <tony.witherspoon@gmail.com>
2016-04-04 13:15:28 -04:00
Aanand Prasad
86530287d6 Merge pull request #2627 from bfirsh/update-roadmap
Update roadmap
2016-04-04 12:52:54 +01:00
Ben Firshman
c1026e815a Update roadmap
Bring it inline with current plans:

- Use in production is not necessarily about the command-line
  tool, but also improving file format, integrations, new tools,
  etc.

Signed-off-by: Ben Firshman <ben@firshman.co.uk>
2016-04-01 12:55:16 -07:00
Ben Firshman
c72d62f96d Merge pull request #3187 from bfirsh/update-wordpress-example-to-use-official-images
Update wordpress example to use official images
2016-04-01 20:53:37 +01:00
Daniel Nephin
a63a05964b Merge pull request #3249 from aanand/better-env-substitution-example
Better variable substitution example
2016-04-01 15:12:18 -04:00
Joffrey F
9509508f3e Merge pull request #3226 from shin-/3210-assert-hostname
Fix assert_hostname logic in tls_config_from_options
2016-04-01 10:32:13 -07:00
Joffrey F
1a7a65f84d Include docker-py requirements fix
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-31 18:01:51 -07:00
Aanand Prasad
3034803258 Better variable substitution example
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-31 15:45:14 +01:00
Joffrey F
78a8be07ad Re-enabling assert_hostname when instantiating docker_client from the
environment.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-30 11:11:19 -07:00
Joffrey F
d27b82207c Remove obsolete assert_hostname tests
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-30 10:58:15 -07:00
Joffrey F
71c86acaa4 Update docker-py version to include match_hostname fix
Removed unnecessary assert_hostname computation in tls_config_from_options

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-29 18:01:27 -07:00
Aanand Prasad
85e2fb63b3 Merge pull request #3218 from sdurrheimer/zsh-completion-run-workdir
Add zsh completion for 'docker-compose run -w --workdir'
2016-03-29 16:50:12 +01:00
Aanand Prasad
024a810617 Merge pull request #3217 from sdurrheimer/zsh-completion-up-build
Add zsh completion for 'docker-compose up --build'
2016-03-29 16:49:49 +01:00
Aanand Prasad
668d45c7cc Merge pull request #3216 from sdurrheimer/zsh-completion-logs
Add zsh completion for 'docker-compose logs -f --follow --tail -t --t…
2016-03-29 16:49:36 +01:00
Aanand Prasad
09ea74245d Merge pull request #3215 from sdurrheimer/zsh-completion-exec-command
Add zsh completion for 'docker-compose exec' command
2016-03-29 16:49:15 +01:00
Aanand Prasad
386edd892c Merge pull request #3214 from sdurrheimer/zsh-completion-rm-all
Add zsh completion for 'docker-compose rm -a --all'
2016-03-29 16:48:53 +01:00
Joffrey F
7116aefe43 Fix assert_hostname logic in tls_config_from_options
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-28 17:39:20 -07:00
Jon Lemmon
93901ec480 Rails Docs: Add nodejs to apt-get install command
When using the latest version of Rails, the tutorial currently errors when running `docker-compose up` with the following error:

```
/usr/local/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:80:in `rescue in block (2 levels) in require': There was an error while trying to load the gem 'uglifier'. (Bundler::GemRequireError)
```

Installing nodejs in the build fixes the issue.

Signed-off-by: Jon Lemmon <jon.lemmon@enspiral.com>
2016-03-28 13:31:40 +13:00
Steve Durrheimer
8ae8f7ed4b Add zsh completion for 'docker-compose run -w --workdir'
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2016-03-25 19:25:33 +01:00
Steve Durrheimer
9729c0d3c7 Add zsh completion for 'docker-compose up --build'
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2016-03-25 19:15:34 +01:00
Steve Durrheimer
9d58b19ecc Add zsh completion for 'docker-compose logs -f --follow --tail -t --timestamps'
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2016-03-25 19:09:53 +01:00
Steve Durrheimer
63b448120a Add zsh completion for 'docker-compose exec' command
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2016-03-25 19:03:36 +01:00
Steve Durrheimer
0f1fb42326 Add zsh completion for 'docker-compose rm -a --all'
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2016-03-25 18:52:28 +01:00
Daniel Nephin
aa50023507 Merge pull request #3057 from shin-/2636-env-file
Add support for a default environment file
2016-03-24 14:26:03 -04:00
Joffrey F
12ad3ff301 Injecting os.environ in Environment instance happens outside of init method
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:28 -07:00
Joffrey F
1506f997de Better windows support for Environment class
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:28 -07:00
Joffrey F
b99037b4a6 Add support for DOCKER_* variables in .env file
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:28 -07:00
Joffrey F
c7afe16419 Account for case-insensitive env on windows platform
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
36f1b4589c Limit occurrences of creating an environment object.
.env file is always read from the project_dir

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
0ff53d9668 Less verbose environment invocation
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
dcdcf4869b Mention environment file in envvars.md
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
21aa7a0448 Documentation for .env file
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
f48da96e8b Test get_project_name from env file
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
d55fc85fea Added default env file test.
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
1801f83bb8 Environment class cleanup
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
fd020ed2cf Tests use updated get_config_paths_from_options signature
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
5831b869e8 Update tests for new environment handling
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
b9ca5188a2 Remove Environment singleton, instead carry instance during config processing
Project name and compose file detection also updated

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
bf8e501b5e Fix pre-commit config
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Joffrey F
c69d8a3bd2 Implement environment singleton to be accessed throughout the code
Load and parse environment file from working dir

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:57:01 -07:00
Daniel Nephin
d1d8df7f72 Merge pull request #3192 from shin-/use-dockerpy-1.8
Require docker-py 1.8.0rc2
2016-03-24 13:55:59 -04:00
Joffrey F
d78b013bb0 Merge pull request #3204 from albers/completion-rm--all
bash completion for `docker-compose rm --all`
2016-03-24 10:44:36 -07:00
Joffrey F
aabeb56527 Merge pull request #3206 from albers/completion-exec
bash completion for `docker-compose exec`
2016-03-24 10:44:19 -07:00
Joffrey F
60470fb9f1 Require docker-py 1.8.0rc2
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-24 10:13:56 -07:00
Daniel Nephin
84a2e634a8 Merge pull request #3200 from dnephin/disable_broken_test
Disable a test that is failing against 1.11.0rc1.
2016-03-24 13:09:35 -04:00
Harald Albers
c9b02b7b34 bash completion for docker-compose exec
Signed-off-by: Harald Albers <github@albersweb.de>
2016-03-24 18:02:12 +01:00
Joffrey F
87231a25be Merge pull request #3202 from albers/completion-logs
bash completion for new `docker logs` options
2016-03-24 09:56:12 -07:00
Joffrey F
353c4deb19 Merge pull request #3203 from albers/completion-up--build
bash completion for `docker-compose up --build`
2016-03-24 09:55:58 -07:00
Daniel Nephin
732531b722 Disable a test that is failing against 1.11.0rc1.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-24 12:32:13 -04:00
Harald Albers
b030c3928a bash completion for docker-compose rm --all
Signed-off-by: Harald Albers <github@albersweb.de>
2016-03-24 17:29:04 +01:00
Harald Albers
5416e4c99b bash completion for docker-compose up --build
Signed-off-by: Harald Albers <github@albersweb.de>
2016-03-24 17:21:56 +01:00
Harald Albers
d8fb9d8831 bash completion for new docker logs options
Signed-off-by: Harald Albers <github@albersweb.de>
2016-03-24 17:11:10 +01:00
Aanand Prasad
2b063d332e Merge pull request #3196 from albers/completion-daemon-options
bash completion for new TLS options
2016-03-24 15:11:55 +00:00
Daniel Nephin
b09b6e390f Merge pull request #3199 from aanand/add-tls-flags-to-overview
Add TLS flags to CLI reference
2016-03-24 10:48:50 -04:00
Aanand Prasad
8282bb1b24 Add TLS flags to CLI reference
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-24 14:41:51 +00:00
Harald Albers
5b2c2e332f bash completion for TLS options
Signed-off-by: Harald Albers <github@albersweb.de>
2016-03-24 12:06:10 +01:00
Harald Albers
9094c4d97d prepare bash completion for new TLS options
Up to now there were two special top-level options that required special
treatment: --project-name and --file (and their short forms).
For 1.7.0, several TLS related options were added that have to be passed
to secondary docker-compose invocations as well.
This commit introduces a scalable treatment of those options.

Signed-off-by: Harald Albers <github@albersweb.de>
2016-03-24 12:05:59 +01:00
Victoria
2a09fb02db Merge pull request #3182 from londoncalling/docs-fix-links-build-errors
fixed links showing as build errors per PR #3180
2016-03-23 15:08:25 -07:00
Victoria Bialas
d1ea4d72ac fixed links showing as build errors per PR #3180
fixed links per build errors

Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
2016-03-23 14:58:45 -07:00
Aanand Prasad
c3eca82749 Merge pull request #3128 from dnephin/add_network_settings_to_config_hash
Include network settings as part of the service config hash.
2016-03-23 17:01:32 +00:00
Ben Firshman
a53b29467a Update wordpress example to use official images
The orchardup images are very old and not maintained.

Signed-off-by: Ben Firshman <ben@firshman.co.uk>
2016-03-22 17:19:50 -07:00
Daniel Nephin
2be2029791 Merge pull request #3139 from shin-/1716-tls-flags-support
Add support for TLS config command-line options
2016-03-22 18:24:52 -04:00
Joffrey F
2cc87555cb tls_config_from_options unit tests
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-22 11:57:45 -07:00
Joffrey F
4727115317 Bump docker-py version to include tcp host fix
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-22 11:47:53 -07:00
Joffrey F
442dff72b4 Improve assert_hostname setting in tls_config_from_options
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-22 11:47:53 -07:00
Joffrey F
26f3861791 Specifying --tls no longer overrides all other TLS options
Add an option to skip hostname verification

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-22 11:47:53 -07:00
Joffrey F
7166408d2a Fixed typos + simplified TLSConfig creation process.
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-22 11:47:53 -07:00
Joffrey F
1ac33ea7e5 Add support for TLS config command-line options
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-22 11:47:53 -07:00
Aanand Prasad
4f5123bda9 Merge pull request #3168 from dnephin/fix_tty_timeout
Handle all timeout errors consistently
2016-03-22 10:14:52 +00:00
Aanand Prasad
aaa7b09369 Merge pull request #3181 from dnephin/fix_partial_change_test_failure
Fix flaky partial_change state test
2016-03-22 10:14:28 +00:00
Aanand Prasad
a20b84e6d2 Merge pull request #3178 from aanand/2774-off-one-offs
Remove one-off containers in `rm` and `down`
2016-03-22 10:12:21 +00:00
Daniel Nephin
5c968f9e15 Fix flaky partial_change state test.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-21 19:07:50 -04:00
Daniel Nephin
6718e82966 Merge pull request #3179 from dnephin/fix_tmpfs_test_failure
Only allow tmpfs with the v2 format
2016-03-21 18:40:51 -04:00
Daniel Nephin
be1476f24b Only allow tmpfs on v2.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-21 14:41:28 -04:00
Aanand Prasad
2bf5e46857 Stop and remove still-running one-off containers in 'down'
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-21 18:08:07 +00:00
Aanand Prasad
a2317dfac2 Remove one-off containers in 'docker-compose down'
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-21 16:15:49 +00:00
Aanand Prasad
81f6d86ad9 Warn when --all is not passed to rm
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-21 15:14:31 +00:00
Aanand Prasad
1bc9469674 Don't allow boolean values for one_off in Project methods
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-21 14:42:57 +00:00
Joffrey F
5826a2147b Use enum to represent 3 possible states of the one_off filter
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-21 12:12:52 +00:00
Joffrey F
187ea4cd81 Add --all option to rm command - remove one-off containers
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-21 12:12:52 +00:00
Aanand Prasad
28120148f4 Merge pull request #3137 from dnephin/add_tmpfs_to_config
Add support for docker run --tmpfs flag.
2016-03-21 12:10:12 +00:00
Kalle Møller
7fc40dd7cc Adding ssl_version to docker_clients kwargs
Select tls version based of COMPOSE_TLS_VERSION

Changed from SSL to TLS

Also did docs - missing default value

Using getattr and raises AttributeError in case of unsupported version

Signed-off-by: Kalle Møller <github.com@k-moeller.dk>
2016-03-19 01:15:03 +01:00
Daniel Nephin
dfac48f3f5 Make a new flaky test less flaky.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-18 18:20:03 -04:00
Daniel Nephin
089ec66522 Include network settings as part of the service config hash.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-18 18:20:03 -04:00
Philip Walls
85c7d3e5ce Add support for docker run --tmpfs flag.
Signed-off-by: Philip Walls <pawalls@rabidgeek.com>
2016-03-18 18:19:48 -04:00
Daniel Nephin
f1dce50b3d Handle all timeout errors consistently.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-18 18:19:35 -04:00
Daniel Nephin
25cbc2aae9 Fix flaky network test.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-18 18:19:16 -04:00
Daniel Nephin
d5ef0dfa92 Merge pull request #3162 from albers/completion-workdir
bash completion for `docker-compose run --workdir`
2016-03-18 11:25:41 -04:00
Harald Albers
e3c1b5886a bash completion for docker-compose run --workdir
Signed-off-by: Harald Albers <github@albersweb.de>
2016-03-18 10:47:17 +01:00
Daniel Nephin
3a63a0815d Merge pull request #3158 from aanand/windows-install-docs
Windows install docs
2016-03-17 14:40:22 -04:00
Aanand Prasad
50fe014ba9 Remove hardcoded host from Engine install URLs
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-17 18:10:32 +00:00
Aanand Prasad
10dfd54ebe Update install page with link to Windows Toolbox install instructions
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-17 18:09:38 +00:00
Aanand Prasad
72ed4d3f97 Merge pull request #3152 from aanand/update-mac-install-url
Update Mac Engine install URL in error message
2016-03-17 17:56:34 +00:00
Joffrey F
312d764c9c Merge pull request #3156 from graingert/fix-type-error-in-exc-handling
Fix TypeError in Exception handling
2016-03-17 08:51:33 -07:00
Daniel Nephin
b2b58402b3 Merge pull request #3154 from aanand/move-ip-docs-to-reference
Move ipv4_address/ipv6_address docs to reference section
2016-03-17 11:44:42 -04:00
Thomas Grainger
20bf05a6e3 Fix TypeError in Exception handling
Traceback (most recent call last):
  File "/tmp/tmp.02tgGaAGtW/docker-compose/bin/docker-compose", line 11, in <module>
    sys.exit(main())
  File "/tmp/tmp.02tgGaAGtW/docker-compose/lib/python3.4/site-packages/compose/cli/main.py", line 68, in main
    log_api_error(e)
  File "/tmp/tmp.02tgGaAGtW/docker-compose/lib/python3.4/site-packages/compose/cli/main.py", line 89, in log_api_error
    if 'client is newer than server' in e.explanation:
TypeError: 'str' does not support the buffer interface

Signed-off-by: Thomas Grainger <tagrain@gmail.com>
2016-03-17 15:13:01 +00:00
Aanand Prasad
7424938fc8 Move ipv4_address/ipv6_address docs to reference section
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-17 11:32:36 +00:00
Aanand Prasad
92d69b0cb6 Update Mac Engine install URL in error message
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-17 09:56:44 +00:00
Aanand Prasad
371ea479f5 Merge pull request #3075 from dnephin/reactive_logs
Display logs for new containers started after the command is run
2016-03-16 21:03:25 +00:00
Aanand Prasad
abddabfb0a Merge pull request #3135 from dnephin/fix_down_idempotency
Make down idempotent, continue to remove resources if one is missing
2016-03-16 20:26:18 +00:00
Joffrey F
dd40331b44 Merge pull request #3102 from shin-/1477-a-modest-proposal
Add flag to up/down to remove orphaned containers
2016-03-16 10:58:15 -07:00
Aanand Prasad
1696506ff4 Merge pull request #3136 from dnephin/add_workdir_to_run
Add workdir to run
2016-03-16 12:45:00 +00:00
Joffrey F
20c29f7e47 Add flag to up/down to remove orphaned containers
Add --remove-orphans to CLI reference docs
Add --remove-orphans to bash completion file
Test orphan warning and remove_orphan option in up

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-15 16:11:49 -07:00
Daniel Nephin
52b791a264 Split off build_container_options() to reduce the complexity of run
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-15 15:29:24 -04:00
Simon van der Veldt
658803edf8 Add -w or --workdir to compose run to override workdir from commandline
Signed-off-by: Simon van der Veldt <simon.vanderveldt@gmail.com>
2016-03-15 15:28:32 -04:00
Daniel Nephin
bf96edfe11 Reduce the args of some functions by including presenters as part of the thread_args.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-15 15:15:00 -04:00
Daniel Nephin
e5529a89e1 Make down idempotent, continue to remove resources if one is missing.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-15 13:26:29 -04:00
Daniel Nephin
e8a93821d4 Fix race condition where a container stopping and starting again would cause logs to miss logs.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-15 13:17:11 -04:00
Daniel Nephin
8d9adc0902 Fix flaky log test by using container status, instead of boolean state.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-15 13:17:10 -04:00
Daniel Nephin
3f7e5bf768 Filter logs by service names.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-15 13:17:10 -04:00
Daniel Nephin
48ed68eeaa Fix geneartors for python3.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-15 13:17:10 -04:00
Daniel Nephin
4312c93eae Add an acceptance test to show logs behaves properly for stopped containers.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-15 13:17:10 -04:00
Daniel Nephin
4cad2a0c5f Handle events for removed containers.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-15 13:17:10 -04:00
Daniel Nephin
44c1747127 Add tests for reactive log printing.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-15 13:17:10 -04:00
Daniel Nephin
65797558f8 Refactor log printing to support containers that are started later.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-15 13:17:10 -04:00
Aanand Prasad
94b1862579 Merge pull request #2679 from IlyaSkriblovsky/dependency-ordered-start-stop
Parallel up/start/stop
2016-03-15 11:51:44 +00:00
Ilya Skriblovsky
34de1f0a4c Removed unused parallel.parallel_stop
Signed-off-by: Ilya Skriblovsky <IlyaSkriblovsky@gmail.com>
2016-03-14 22:56:58 +03:00
Ilya Skriblovsky
5df774bd10 Fixed testing error handling by up
Signed-off-by: Ilya Skriblovsky <IlyaSkriblovsky@gmail.com>
2016-03-14 22:55:42 +03:00
Ilya Skriblovsky
f933381a12 Dependency-ordered start/stop/up
Signed-off-by: Ilya Skriblovsky <IlyaSkriblovsky@gmail.com>
2016-03-14 22:55:42 +03:00
Aanand Prasad
e5cd869c61 Merge pull request #3095 from dnephin/refactor_command_dispatch
Refactor command dispatch and fix api version mismatch error
2016-03-14 16:18:29 +00:00
Aanand Prasad
9853b876af Merge pull request #3101 from bfirsh/less-scary-swarm-compose-docs
Better Compose in production docs
2016-03-14 16:12:46 +00:00
Ben Firshman
1485a56c75 Better Compose in production docs
The Compose/Swarm integration has been working really well for
users, so it seems pretty safe to remove the scary warnings about
it not being ready.

Signed-off-by: Ben Firshman <ben@firshman.co.uk>
2016-03-10 08:55:07 -08:00
Daniel Nephin
99d68be815 Merge pull request #3011 from mdaue/2804
Fix #2804: Add ipv4 and ipv6 static addressing
2016-03-09 16:28:15 -08:00
Matt Daue
ee136446a2 Fix #2804: Add ipv4 and ipv6 static addressing
- Added ipv4_network and ipv6_network to the networks section in the
  service section for each configured network
- Added feature documentation
- Added unit tests

Signed-off-by: Matt Daue <mattdaue@gmail.com>
2016-03-09 18:37:52 -05:00
Daniel Nephin
8a86e204a0 Merge pull request #3063 from albers/completion-multiple-compose-files
add support for multiple compose files to bash completion
2016-03-09 11:12:34 -08:00
Joffrey F
7a30fc0983 Merge pull request #3089 from ltiao/patch-1
Fixed indentation level in example.
2016-03-09 10:56:50 -08:00
Joffrey F
7033042656 Merge pull request #3039 from dbonev/3020-build-arguments-object-syntax
Allowing null for build args
2016-03-09 10:55:05 -08:00
Daniel Nephin
7de9b08ca5 Merge pull request #3066 from shin-/3062-dont-log-noop-volume-create
Don't call create on existing volumes
2016-03-08 15:04:59 -08:00
Daniel Nephin
0a091055d2 Improve handling of connection errors and error messages.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-08 15:39:11 -05:00
Daniel Nephin
886328640f Convert some cli tests to pytest.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-08 14:42:51 -05:00
Daniel Nephin
9f9dcc098a Make TopLevelCommand use the project field.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-08 14:36:53 -05:00
Daniel Nephin
53bea8a720 Refactor command dispatch to improve unit testing and support better error messages.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-08 14:23:27 -05:00
Daniel Nephin
a6649b308e Merge pull request #3094 from aanand/fix-version-in-docs-example
Fix version in aliases example
2016-03-08 11:18:45 -08:00
Aanand Prasad
e700d7ca6a Fix version in docs example
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-08 18:15:18 +01:00
wenchma
000eaee16a Update image format for service conf reference
Signed-off-by: Wen Cheng Ma <wenchma@cn.ibm.com>
2016-03-08 17:14:38 +08:00
Louis Tiao
88a719b4b6 Fixed indentation level in example.
Signed-off-by: Louis Tiao <louistiao@gmail.com>
2016-03-08 15:53:55 +11:00
Joffrey F
d2b065e615 Don't raise ConfigurationError for volume driver mismatch
when driver is unspecified

Add testcase

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-07 18:07:41 -08:00
Joffrey F
698998c410 Don't call create on existing volumes
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-03-07 18:00:27 -08:00
Dimitar Bonev
81b7fba33e Allowing null for build args
Signed-off-by: Dimitar Bonev <dimitar.bonev@gmail.com>
2016-03-05 15:57:06 +02:00
Aanand Prasad
9e242cdc75 Merge pull request #3032 from dnephin/multiple_files_from_env_var
Support multiple files in COMPOSE_FILE env var
2016-03-03 17:23:22 +00:00
Aanand Prasad
4ae71f41dd Merge pull request #2832 from aanand/refactor-cli-unit-tests
Refactor CLI initialization and unit tests
2016-03-02 16:10:44 -08:00
Daniel Nephin
53a3d14046 Support multiple files in COMPOSE_FILE env var.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-02 18:47:58 -05:00
Aanand Prasad
20caf02bf6 Create real Project objects in CLI unit tests
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-02 15:11:34 -08:00
Aanand Prasad
4644f2c0f9 Remove environment-overriding unit test for 'run'
There's already an acceptance test for it

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-02 15:11:32 -08:00
Aanand Prasad
575b48749d Remove unused global_options arg from dispatch()
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-02 15:09:48 -08:00
Aanand Prasad
2c75a8fdf5 Extract helper methods for building config objects from dicts
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-02 15:09:48 -08:00
Aanand Prasad
f75408923e Merge pull request #3053 from dnephin/handle_booleans_in_mappings
Don't allow booleans for mapping types
2016-03-02 15:04:20 -08:00
Aanand Prasad
3f98c0716e Merge pull request #3052 from dnephin/merge_v1_logging
Fix merging of logging options in v1 config
2016-03-02 15:03:36 -08:00
Aanand Prasad
f84ebf9b18 Merge pull request #3048 from dnephin/osx_bin_from_travis
Build OSX binary on Travis
2016-03-02 15:02:57 -08:00
Aanand Prasad
1655be6c5b Merge pull request #2601 from dnephin/dont_build_on_up
Only build as part of `up` if `--build` flag is set
2016-03-02 15:02:18 -08:00
Daniel Nephin
e1b87d7be0 Update reference docs for the new flag.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-02 15:32:51 -05:00
Daniel Nephin
b7fb3a6d9b Add --build flag for up and create
Also adds a warning when up builds an image without the --build flag
so that users know it wont happen on the next up.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-02 15:32:51 -05:00
Harald Albers
0049743615 add support for multiple compose files to bash completion
Since 1.6.0, Compose supports multiple compose files specified with `-f`.
These need to be passed to the docker invocations done by the
completion.

Signed-off-by: Harald Albers <github@albersweb.de>
2016-03-02 21:18:33 +01:00
Aanand Prasad
3f3c05e465 Merge pull request #3049 from aanand/clarify-depends-on
Clarify depends_on logic
2016-03-02 11:59:06 -08:00
Aanand Prasad
aa7b862f4c Clarify depends_on logic
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-03-02 10:29:24 -08:00
Aanand Prasad
0b3561a7d5 Merge pull request #2720 from seguins/2227-improvements-logs
Add flags on logs
2016-03-01 17:41:31 -08:00
Aanand Prasad
af12c78915 Merge pull request #3056 from dnephin/fix_shutdown_errors
Fix signal handling with pyinstaller.
2016-03-01 14:56:27 -08:00
Daniel Nephin
ed4473c849 Fix signal handling with pyinstaller.
Raise a ShutdownException instead of a KeyboardInterupt when a thread.error
is caught. This thread.error is only raised when run from a pyinstaller
binary (for reasons unknown).

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-01 16:39:43 -05:00
Stéphane Seguin
038da4eea3 Logs args of LogPrinter as a dictionary
Signed-off-by: Stéphane Seguin <stephseguin93@gmail.com>
2016-03-01 20:24:15 +01:00
Stéphane Seguin
9b36dc5c54 Add --tail flag as option on logs.
Closes #265
Signed-off-by: Stéphane Seguin <stephseguin93@gmail.com>
2016-03-01 20:23:46 +01:00
Stéphane Seguin
d9b4286f91 Add -t, --timestamps flag as option on logs.
Signed-off-by: Stéphane Seguin <stephseguin93@gmail.com>
2016-03-01 20:23:46 +01:00
Stéphane Seguin
82632098a3 Add -f, --follow flag as option on logs.
Closes #2187
Signed-off-by: Stéphane Seguin <stephseguin93@gmail.com>
2016-03-01 20:23:43 +01:00
Aanand Prasad
7684604830 Merge pull request #3023 from londoncalling/fix-note-3019
WIP: updated note format for dockerfile per Aanand's comments on PR #…
2016-03-01 11:11:55 -08:00
Daniel Nephin
18510b4024 Don't allow booleans for mapping types.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-01 11:57:35 -05:00
Daniel Nephin
b726f508a6 Fix merging of logging options in v1 config.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-01 11:43:26 -05:00
Daniel Nephin
04877d47aa Build osx binary on travis and upload to bintray.
This requires a change to the make-branch script, to have it push the bump branch
to the docker remote instead of the user remote. Pushing to the docker remote
triggers the travis build, which builds the binary.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-03-01 11:34:54 -05:00
Aanand Prasad
fc99c7ee19 Merge pull request #2584 from mjgpy3/patch-1
Update `volumes_from` docs to state default
2016-02-29 15:37:46 -08:00
Aanand Prasad
210856179d Merge pull request #3036 from JesusTinoco/master
Display in the log output the name of those containers created using …
2016-02-29 15:17:14 -08:00
Daniel Nephin
f5ce31d43e Merge pull request #3024 from aanand/update-build-image-docs
Update docs about using build and image together
2016-02-29 14:03:54 -08:00
Daniel Nephin
4db1fef58c Merge pull request #3022 from aanand/update-build-image-extends-note
Update note about build + image with extends
2016-02-29 14:03:28 -08:00
Daniel Nephin
8d24af92e0 Merge pull request #3030 from aanand/document-startup-order-workarounds
Document ways to make services wait for dependencies
2016-02-29 13:01:32 -08:00
Aanand Prasad
97c9c12660 Merge pull request #2023 from TomasTomecek/593-implement-exec
implement exec
2016-02-29 12:21:41 -08:00
Aanand Prasad
6b947ee478 Document ways to make services wait for dependencies
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-29 11:24:58 -08:00
Jesus
6bfb23baaa Display containers name when scale a container
Display in the log output the name of those containers created using the scale command and
change the test_scale_with_api_error test to support the containers name when scale

Signed-off-by: Jesus Rodriguez Tinoco <jesus.rodriguez.tinoco@gmail.com>
2016-02-29 20:19:03 +01:00
Tomas Tomecek
d28c5dda92 implement exec
Resolves #593

Signed-off-by: Tomas Tomecek <ttomecek@redhat.com>
2016-02-29 10:50:09 +01:00
Aanand Prasad
62fb6b99eb Update FAQ regarding long stop times
- It happens on recreate, not just stop

- We now support `stop_signal`, which can help in some cases

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-26 14:34:44 -08:00
Aanand Prasad
1502c5a14d Merge pull request #3025 from aanand/release-notes-1.6.2
Add release notes for 1.6.2
2016-02-26 10:36:26 -08:00
Aanand Prasad
c72e9b3843 Add release notes for 1.6.2
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-25 17:55:04 -08:00
Aanand Prasad
5be48ba1ed Update docs about using build and image together
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-25 17:19:58 -08:00
Aanand Prasad
adb8de367e Merge pull request #2388 from dnephin/fix_long_lines
Wrap long lines
2016-02-25 16:52:33 -08:00
Aanand Prasad
42f4d814d7 Merge pull request #2880 from dnephin/merge_jsonschemas
Merge jsonschemas to a single schema file per version
2016-02-25 16:51:56 -08:00
Victoria Bialas
5cc420e727 WIP: updated note format for dockerfile per Aanand's comments on PR #3019
Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
2016-02-25 16:47:46 -08:00
Aanand Prasad
c2c8c41ef2 Merge pull request #2608 from dnephin/more_cyclomatic_reduction
More cyclomatic complexity reduction
2016-02-25 16:41:49 -08:00
Aanand Prasad
2cd1b94dd3 Update note about build + image with extends
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-25 15:15:18 -08:00
Aanand Prasad
5111d0862c Merge pull request #2672 from dnephin/organize_scripts
Organize scripts into directories
2016-02-25 14:09:03 -08:00
Daniel Nephin
11dc720752 Move test scripts to script/test.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-24 16:24:13 -08:00
Daniel Nephin
ec6bb1660d Move run scripts to script/run
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-24 16:24:13 -08:00
Daniel Nephin
a87d482a3b Move all build scripts to script/build
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-24 16:24:13 -08:00
Daniel Nephin
dc3a5ce624 Refactor config validation to support constraints in the same jsonschema
Reworked the two schema validation functions to read from the same schema but
use different parts of it. Error handling is now split as well by the
schema that is being used to validate.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-24 16:20:17 -08:00
Daniel Nephin
43ecf8793a Address old TODO, and small refactor of container name logic in service.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-24 16:19:38 -08:00
Daniel Nephin
cdda616d6b Reduce complexity of sort_service_dicts.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-24 16:19:38 -08:00
Daniel Nephin
84a1822e40 Reduce complexity of _get_container_create_options
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-24 16:19:38 -08:00
Daniel Nephin
be554c3a74 Merge v1 config jsonschemas into a single file.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-24 15:59:10 -08:00
Daniel Nephin
adb64ef8d5 Merge v2 config jsonschemas into a single file.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-24 15:59:10 -08:00
Daniel Nephin
38dd342b7b Merge pull request #3009 from dnephin/update_release_notes
Add release notes for 1.6.1
2016-02-23 16:02:18 -08:00
Joffrey F
f48d321b5b Merge pull request #3008 from shin-/update_dockerpy_version
Update docker-py version in requirements to 1.7.2
2016-02-23 15:41:11 -08:00
Daniel Nephin
49ef8a271d Add release notes for 1.6.1
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-23 15:13:01 -08:00
Daniel Nephin
0467bc3dcf Merge pull request #2998 from londoncalling/docs-wordpress-example
updated Wordpress example to be easier to follow, added/updated images
2016-02-23 15:10:11 -08:00
Joffrey F
97bbee19b7 Update docker-py version in requirements to 1.7.2
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-23 14:55:06 -08:00
Victoria Bialas
e6797e1166 updated Wordpress example to be easier to follow, added/updated images
docs update per Mary's comments on the PR

Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
2016-02-23 11:59:19 -08:00
Daniel Nephin
f2ccbeff76 Merge pull request #2997 from dnephin/fix_env_var_without_value
Fix env var without value
2016-02-23 11:58:30 -08:00
Daniel Nephin
d451578152 Make environment variables without a value the same as docker-cli.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-23 11:14:59 -08:00
Daniel Nephin
4b04280db8 Revert "Change special case from '_', None to ()"
This reverts commit 677c50650c.

Revert "Modify service_test.py::ServiceTest::test_resolve_env to reflect new behavior"

This reverts commit 0019037712.

Revert "Mangle the tests. They pass for better or worse!"

This reverts commit 7ab9509ce6.

Revert "If an env var is passthrough but not defined on the host don't set it."

This reverts commit 6540efb3d3.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-23 11:13:57 -08:00
Daniel Nephin
1d67e6f0f0 Merge pull request #2995 from dnephin/fix_warning_about_bools
Fix warning about boolean values
2016-02-23 11:11:54 -08:00
Daniel Nephin
ba799d2e86 Merge pull request #2996 from dnephin/fix_abort_on_container_exit
Fix abort on container exit
2016-02-23 10:52:12 -08:00
Joffrey F
a7fd578b14 Merge pull request #2962 from shin-/2960-volume-driver
Update docs for volume_driver option
2016-02-22 17:23:07 -08:00
Joffrey F
176b966486 Update documentation for volume_driver option.
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-22 16:51:33 -08:00
Daniel Nephin
7e3d756a18 Merge pull request #2992 from shin-/update_dockerpy_version
Use docker-py 1.7.1
2016-02-22 16:50:36 -08:00
Daniel Nephin
15b2094bad Stop other containers if the flag is set.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-22 16:48:46 -08:00
Richard Bann
bf2bf21720 Add failing test for --abort-on-container-exit
Handle --abort-on-container-exit. Fixes #2940

Signed-off-by: Richard Bann <richardbann@gmail.com>
2016-02-22 16:39:40 -08:00
Daniel Nephin
0a06d827fa Fix warning about boolean values.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-22 14:56:01 -08:00
Joffrey F
ba39d4cc77 Use docker-py 1.7.1
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-22 12:56:54 -08:00
Daniel Nephin
d5514965d5 Merge pull request #2975 from dnephin/fix_crash_on_none_in_config
Fix validation message when there are multiple nested oneOf validations.
2016-02-19 15:53:26 -05:00
Daniel Nephin
02535f0cf1 Fix validation message when there are multiple ested oneOf validations.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-19 14:22:55 -05:00
Daniel Nephin
c7ceacfeae Merge pull request #2948 from dnephin/validate_top_level
Validate that each section of the config is a mapping
2016-02-19 13:41:50 -05:00
Aanand Prasad
bed0cfeb32 Merge pull request #2807 from aanand/swarm-doc
Update Swarm integration guide and make it an official part of the docs
2016-02-19 10:25:28 -08:00
Daniel Nephin
0d218c34c7 Make config validation error messages more consistent.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-19 13:12:57 -05:00
Daniel Nephin
4b2a666231 Validate that each section of the config is a mapping before running interpolation.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-19 12:38:52 -05:00
Aanand Prasad
520c695bf4 Update Swarm integration guide and make it an official part of the docs
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-19 09:32:43 -08:00
Aanand Prasad
1f2c2942d7 Merge pull request #2963 from londoncalling/docs-alias-repr2829
corrected description of network aliases, added real-world example pe…
2016-02-19 09:26:40 -08:00
Victoria Bialas
753c953870 Merge branch 'docs-alias-repr2829' of github.com:londoncalling/compose into docs-alias-repr2829
Fixed file format of one word, legacy, adding signature to that commit.

Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
2016-02-18 18:32:44 -08:00
Victoria Bialas
eb4a98c0d1 corrected description of network aliases, added real-world example per #2907
copyedit to make  show as file format

Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
2016-02-18 18:05:52 -08:00
Victoria Bialas
630a50295b copyedit to make show as file format
Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
2016-02-18 18:05:30 -08:00
Victoria Bialas
068a56eb97 corrected description of network aliases, added real-world example per #2907
Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
2016-02-18 17:49:28 -08:00
Joffrey F
5fc0df4be2 Merge pull request #2907 from shin-/2829-net-alias
Allow user to specify custom network aliases
2016-02-18 16:01:30 -08:00
Joffrey F
0cb8ba3775 Use modern set notation in _get_aliases
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-18 15:28:12 -08:00
Joffrey F
7152f7ea76 Handle mismatched network formats in config files
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-18 15:24:41 -08:00
Joffrey F
825a0941f0 Network aliases are now part of the network dictionary
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-18 15:23:47 -08:00
Joffrey F
4b99b32ffb Add v2_only decorator to network aliases test
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-18 15:23:47 -08:00
Joffrey F
41e399be98 Fix network list serialization in py3
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-18 15:23:47 -08:00
Joffrey F
7801cfc5d1 Document network_aliases config
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-18 15:23:47 -08:00
Joffrey F
633e349ab9 Test network_aliases feature
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-18 15:23:46 -08:00
Joffrey F
2b5d3f51cb Allow user to specify custom network aliases
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-18 15:23:46 -08:00
Joffrey F
d3a95c2892 Merge pull request #2938 from shin-/2927-buildargs-types
Constraint build argument types. Numbers are cast into strings.
2016-02-18 15:07:09 -08:00
Joffrey F
93a02e497d Apply driver_opts processing to network configs
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-18 10:53:40 -08:00
Aanand Prasad
85ba08bb13 Merge pull request #2932 from AvdN/patch-1
reset colors after warning
2016-02-18 09:25:02 -08:00
Aanand Prasad
50dc27aed7 Merge pull request #2913 from clkao/container-install-fixes
A few fixes to the container-based install, which is broken on:
2016-02-18 09:24:10 -08:00
Aanand Prasad
bd72670947 Merge pull request #2894 from dnephin/only_set_constraint_with_volumes
Only set a container affinity if there are volumes to copy over
2016-02-18 08:46:29 -08:00
Daniel Nephin
4f7530c480 Only set a container affinity if there are volumes to copy over.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-17 22:35:14 -05:00
Joffrey F
1952b52392 Constraint build argument types. Numbers are cast into strings
Numerical driver_opts are also valid and typecast into strings.
Additional config tests.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-17 11:53:29 -08:00
Joffrey F
706062ad16 Merge pull request #2934 from dnephin/fix_volume_copy
Fix copying of volumes by using the name of the volume
2016-02-17 11:52:18 -08:00
Daniel Nephin
d4f2f54cf8 Merge pull request #2936 from dnephin/update_docs_for_161
Update docs, fix broken link, use v2 compose file format
2016-02-17 13:34:39 -05:00
Daniel Nephin
4a09da43ea Fix copying of volumes by using the name of the volume instead of the host path.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-17 13:34:14 -05:00
Joffrey F
89108f2a0f Merge pull request #2939 from AvdN/patch-2
for 1.6.0 the version value needs to be a string
2016-02-17 09:42:41 -08:00
Anthon van der Neut
1512793b30 for 1.6.0 the version value needs to be a string
After conversion a file would immediately not load in docker-compose 1.6.0 with the message:

  ERROR: Version in "./converted.yml" is invalid - it should be a string.

Signed-off-by: Anthon van der Neut anthon@mnt.org
Signed-off-by: Anthon van der Neut <a.van.der.neut@ruamel.eu>
2016-02-17 10:01:16 +01:00
Daniel Nephin
471264239f Update guides to use v2 config format.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-16 16:43:26 -05:00
Daniel Nephin
4de12ad7a1 Update link to docker volume create docs.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-16 16:43:22 -05:00
Joffrey F
ec3af7d491 Merge pull request #2920 from londoncalling/docs-examples
update to description of files generated from examples, which are no …
2016-02-16 11:51:14 -08:00
Victoria Bialas
8af0a0f85b update to description of files generated from examples, which are no longer owned by root w/new release
updated descriptions of changing file ownership and images per Seb's comments

fixed line wraps

fixed line breaks per Joffrey's comments

Signed-off-by: Victoria Bialas <victoria.bialas@docker.com>
2016-02-16 11:34:59 -08:00
moxiegirl
b8c35e1298 Merge pull request #2884 from moxiegirl/remove-tutorials
Updating Dockerfile
2016-02-16 08:09:49 -08:00
Anthon van der Neut
69d0154718 reset colors after warning
If a warning is shown, and you happen to have no color setting in your (bash) prompt, the \033[37m setting, stays active. With the message hardly readable (light grey on my default light yellow background), that means the prompt is barely visible and you need to do `tput reset`.
Would probably be better if the background color was set as well in case you have dark on light theme by default in your terminal.

Signed-off-by: Anthon van der Neut <a.van.der.neut@ruamel.eu>
2016-02-16 15:42:43 +01:00
Chia-liang Kao
2204b642ef Quote argv as they are
Signed-off-by: Chia-liang Kao <clkao@clkao.org>
2016-02-14 01:57:04 +08:00
Chia-liang Kao
e6a675f338 Detect -t and -i separately
Signed-off-by: Chia-liang Kao <clkao@clkao.org>
2016-02-14 01:56:26 +08:00
Chia-liang Kao
dd55415d4f Don't mount pwd if it is /
Signed-off-by: Chia-liang Kao <clkao@clkao.org>
2016-02-14 01:56:17 +08:00
Daniel Nephin
74dc1b1411 Merge pull request #2893 from shin-/2833-run-dependencies
Bring up all dependencies when running a single service.
2016-02-12 16:33:01 -05:00
Daniel Nephin
16200b0bce Merge pull request #2903 from shin-/2899-invalid-driver-opts
driver_opts can only be of type string
2016-02-12 14:41:05 -05:00
Joffrey F
a8fda480e3 driver_opts can only be of type string
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-12 10:51:11 -08:00
Joffrey F
367fabdbfa Bring up all dependencies when running a single service.
Added test for running a depends_on service

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-12 09:46:10 -08:00
Joffrey F
e1d67ad68a Merge pull request #2882 from shin-/2715-old-server-error
Detailed error message when daemon version is too old.
2016-02-11 16:03:20 -08:00
Daniel Nephin
b6812b8600 Merge pull request #2877 from dnephin/fix_merging_build
Fix build section without context
2016-02-11 18:53:23 -05:00
Joffrey F
79f993f52c Detailed error message when daemon version is too old.
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-11 15:20:32 -08:00
Joffrey F
77cf67ba8a Merge pull request #2888 from dnephin/upgrade_pyinstaller
Upgrade pyinstaller.
2016-02-11 12:11:57 -08:00
Joffrey F
5eb45a31e6 Merge pull request #2883 from shin-/2849-log-volume-creation
Add logging when initializing a volume.
2016-02-11 12:11:28 -08:00
Joffrey F
e225f12551 Add logging when initializing a volume.
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-02-11 11:40:22 -08:00
Joffrey F
830a9fc118 Merge pull request #2889 from dnephin/fix_test_broken_on_master
Shm_size requires docker 1.10
2016-02-11 11:18:45 -08:00
Daniel Nephin
532dffd688 Fix build section without context.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-11 14:12:02 -05:00
Daniel Nephin
1e7dd2e740 Upgrade pyinstaller.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-11 13:50:41 -05:00
Daniel Nephin
740329a131 Shm_size requires docker 1.10.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-11 13:50:23 -05:00
Daniel Nephin
7bae4cdbb2 Merge pull request #2875 from aanand/fix-version-in-install-guide
Fix version in install guide
2016-02-11 12:43:51 -05:00
Aanand Prasad
23ab2c7e44 Merge pull request #2878 from dnephin/merge_build_args
Merge build.args when merging services
2016-02-11 17:41:41 +00:00
Aanand Prasad
b8f7bbb84e Merge pull request #2830 from nubs/master
Add support for shm_size.  Fixes #2823.
2016-02-11 17:34:44 +00:00
Joffrey F
a5d95612e0 Merge pull request #2881 from humitos/patch-1
Typo fixed
2016-02-11 09:28:08 -08:00
Mary Anthony
643166ae98 Updating Dockerfile
Signed-off-by: Mary Anthony <mary@docker.com>
2016-02-10 20:47:15 -08:00
Manuel Kaufmann
ac14642d94 Typo fixed
Signed-off-by: Manuel Kaufmann <humitos@gmail.com>
2016-02-10 19:00:17 -05:00
Spencer Rinehart
ab40d389d0 Fix sorting of DOCKER_START_KEYS.
Make sure it's sorted!

Signed-off-by: Spencer Rinehart <anubis@overthemonkey.com>
2016-02-10 15:25:18 -06:00
Spencer Rinehart
5e6dc3521c Add support for shm_size. Fixes #2823.
shm_size controls the size of /dev/shm in the container and requires
Docker 1.10 or newer (API version 1.22).  This requires docker-py 1.8.0
(docker/docker-py#923).

Similar to fields like `mem_limit`, `shm_size` may be specified as
either an integer or a string (e.g., `64M`).

Updating docker-py to the master branch in order to get the unreleased
dependency on `shm_size` there in place.

Signed-off-by: Spencer Rinehart <anubis@overthemonkey.com>
2016-02-10 15:25:18 -06:00
Daniel Nephin
37564a73c3 Merge build.args when merging services.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-10 13:54:40 -05:00
Aanand Prasad
7b5bad6050 Merge pull request #2851 from cr7pt0gr4ph7/2839-fix-networks-merging
Fix merge behavior for 'networks' and 'network_mode'.
2016-02-10 17:51:01 +00:00
Aanand Prasad
c43b25b0cf Merge pull request #2827 from loic/patch-1
Fixed typo in compose-file.md
2016-02-10 15:58:54 +00:00
Aanand Prasad
ab9d82b400 Merge pull request #2842 from michael-k/links
Fixed broken links on pypi
2016-02-10 15:58:39 +00:00
Aanand Prasad
88b11afde2 Merge pull request #2858 from dnephin/fix_upgrading_url_in_changelog
Fix upgrading url in changelog
2016-02-10 15:58:02 +00:00
Aanand Prasad
28689a57a7 Merge pull request #2871 from yograterol/patch-1
Typo into the doc with `networks` in yaml
2016-02-10 15:57:45 +00:00
Aanand Prasad
ab6e07da7d Fix version in install guide
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-10 15:56:50 +00:00
Yohan Graterol
59a2920758 Typo into the doc with networks in yaml
Signed-off-by: Yohan Graterol <yohangraterol92@gmail.com>
2016-02-09 18:45:04 -05:00
Daniel Nephin
6f06b3bd30 Merge pull request #2853 from dnephin/fix_short_id_alias
Use 12 characters for the short id
2016-02-09 14:56:24 -05:00
Michael Käufl
481caa8e48 Used absolute links in readme
This prevents links being broken on pypi
(e.g. https://pypi.python.org/pypi/docs/index.md#features)

Signed-off-by: Michael Käufl <docker-compose@c.michael-kaeufl.de>
2016-02-09 13:29:14 +01:00
Daniel Nephin
63870fbccd Fix upgrading url.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-08 18:15:21 -05:00
cr7pt0gr4ph7
582de19a5a Simplify unit tests in config/config_test.py by using class variables instead of methods for parametrizing tests.
Signed-off-by: cr7pt0gr4ph7 <cr7pt0gr4ph7@gmail.com>
2016-02-08 21:57:15 +01:00
Daniel Nephin
859cc2348c Merge pull request #2744 from aanand/pytest-ini
Add pytest.ini
2016-02-08 14:19:40 -05:00
Joffrey F
fdf4a2e89e Merge pull request #2734 from jrabbit/empty-env-var-2359
Empty env var #2359
2016-02-08 11:17:54 -08:00
Daniel Nephin
421981e7d2 Use 12 characters for the short id to match docker and fix backwards compatibility.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-08 12:18:48 -05:00
Lukas Waslowski
5bd88f634f Handle the 'network_mode' key when merging multiple compose files.
Fixes docker/compose#2840.

Signed-off-by: Lukas Waslowski <cr7pt0gr4ph7@gmail.com>
2016-02-08 15:33:26 +01:00
Lukas Waslowski
5a3a10d43b Correctly merge the 'services/<service>/networks' key in the case of multiple compose files.
Fixes docker/compose#2839.

Signed-off-by: Lukas Waslowski <cr7pt0gr4ph7@gmail.com>
2016-02-08 15:17:21 +01:00
Lukas Waslowski
e929086c49 Separate MergePortsTest from MergeListsTest and add MergeNetworksTest.
Signed-off-by: Lukas Waslowski <cr7pt0gr4ph7@gmail.com>
2016-02-08 14:29:03 +01:00
jrabbit
677c50650c Change special case from '_', None to ()
Signed-off-by: jrabbit <jackjrabbit@gmail.com>
2016-02-06 02:54:06 -05:00
Aanand Prasad
8acb5e17e8 Add pytest section to tox.ini
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-05 13:07:01 +00:00
Loïc Bistuer
b635647105 Fixed typo in compose-file.md
Signed-off-by: Loïc Bistuer <loic.bistuer@gmail.com>
2016-02-05 09:50:22 +07:00
Daniel Nephin
57fc85b457 Wrap long lines and restrict lines to 105 characters.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-04 19:05:39 -05:00
Daniel Nephin
28e652daec Merge pull request #2826 from aanand/bump-1.7.0dev
Bump 1.7.0dev
2016-02-04 18:56:27 -05:00
Aanand Prasad
869e815213 Bump 1.7.0dev
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-04 23:46:41 +00:00
Aanand Prasad
422ff623b4 Merge pull request #2819 from bfirsh/improve-names-in-compose-file-2-example
Improve names in Compose file 2 example
2016-02-04 19:42:22 +00:00
Aanand Prasad
c2db1a24bf Merge pull request #2822 from aanand/update-docker-py-and-dockerpty
Update docker-py and dockerpty
2016-02-04 19:40:41 +00:00
Aanand Prasad
be236d8801 Update docker-py and dockerpty
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-04 19:16:01 +00:00
Aanand Prasad
93426cec4c Merge pull request #2824 from dnephin/docs_version_is_a_string
Update docs for version being a string
2016-02-04 17:20:32 +00:00
Daniel Nephin
a7c2987991 Update docs for version being a string.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-04 12:19:43 -05:00
Aanand Prasad
386974f831 Merge pull request #2814 from nubs/patch-1
Fix example formatting for depends_on.
2016-02-04 15:56:27 +00:00
Daniel Nephin
80d02e84e2 Merge pull request #2808 from aanand/connect-before-start
Connect container to networks before starting it
2016-02-03 23:49:56 -05:00
Ben Firshman
bdddbe3a73 Improve names in Compose file 2 example
Just makes it a bit clearer what's going on.

Signed-off-by: Ben Firshman <ben@firshman.co.uk>
2016-02-03 17:42:57 -08:00
Spencer Rinehart
f612bc98d9 Fix example formatting for depends_on.
Markdown was acting against expectations here by merging the example indented YAML into the previous list item instead of treating it as a code block.

I decided that a better way of handling this would be to add a "Simple example:" line that is also used elsewhere in this file.  It resets the markdown indentation in a way that works.

Signed-off-by: Spencer Rinehart <anubis@overthemonkey.com>
2016-02-03 14:36:46 -06:00
Daniel Nephin
89c5b800e6 Merge pull request #2782 from dbonev/2772-compose-project-name-empty
Falling back to default project name on empty COMPOSE_PROJECT_NAME
2016-02-02 20:37:38 -05:00
Sven Dowideit
bd1c8973ab Merge pull request #2809 from moxiegirl/fixing-dup-identifier
Fixing duplicate identifiers for 1.10
2016-02-02 15:43:09 -08:00
Mary Anthony
a713447e0b Fixing duplicate identifiers
Signed-off-by: Mary Anthony <mary@docker.com>
2016-02-02 12:04:13 -08:00
Aanand Prasad
2651c00f0c Connect container to networks before starting it
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-02 19:31:49 +00:00
Daniel Nephin
4c4e94bc19 Merge pull request #2785 from dnephin/depends_on_with_extends
Fix list options when used with extends and multiple files
2016-02-02 13:36:46 -05:00
Daniel Nephin
1cb67b781c Merge pull request #2777 from dnephin/reorder_docs
Re-order docs in menu, fix menu title capitalization, cleanup command reference
2016-02-02 11:26:26 -05:00
Daniel Nephin
c290e560cb Merge pull request #2786 from dnephin/refactor_project
Fix a few bugs around networking and project initilization
2016-02-02 11:19:34 -05:00
Aanand Prasad
7a197e5a69 Merge pull request #2802 from dnephin/appveyor_to_bintray_deploy
Deploying to bintray from appveyor using the new bintray support
2016-02-02 16:13:07 +00:00
Daniel Nephin
c81cc24e72 Merge pull request #2806 from aanand/run-tests-with-tty
Run test containers in TTY mode
2016-02-02 10:56:21 -05:00
Daniel Nephin
3d3388d59b Extract volume init and removal from project.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:53:04 -05:00
Daniel Nephin
e551988616 Include networks in the config_hash.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:52:03 -05:00
Daniel Nephin
0810eeba10 Don't initialize networks that aren't used by any services.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:52:03 -05:00
Daniel Nephin
8e838968fe Refactor project network initlization.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:51:31 -05:00
Daniel Nephin
3ec87adccc Update merge docs with depends_on, and correction about how links and volumes_from are merged.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:49:43 -05:00
Daniel Nephin
e32863f89e Make links unique-by-alias when merging
Factor out MergeDict from merge_service_dicts to reduce complexity below limit.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:48:47 -05:00
Daniel Nephin
bf6a5d3e49 Fix merging of lists with multiple files.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:48:18 -05:00
Ryan Taylor Long
c70c72f49a Add depends_on to ALLOWED_KEYS
This ensures and already existing `depends_on` is not deleted when the service on which it is defined also employs `extends`.

Signed-off-by: Ryan Taylor Long <ryan@rtlong.com>
2016-02-02 10:48:18 -05:00
Daniel Nephin
7b03de7d01 Move command reference to overview.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:46:52 -05:00
Daniel Nephin
cf24c36c55 Rename the old environment variable page to link environment variables.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:46:29 -05:00
Daniel Nephin
2df5593e8f Cleanup command-line reference docs by renaming overview to envvars.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:46:28 -05:00
Daniel Nephin
5e30f089e3 Use the same capitalization for all menu items in the docs.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:46:28 -05:00
Daniel Nephin
4f92004d9a Re-order compose docs so that quickstart guides come before other documentation.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-02 10:46:28 -05:00
Aanand Prasad
60a5b39f6f Merge pull request #2783 from aanand/fix-validation-v2
Fix validation and version checking
2016-02-02 15:19:50 +00:00
Aanand Prasad
1152c5b25b Tweak and test warning shown when version is a dict
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-02 13:58:34 +00:00
Aanand Prasad
ef8db3650a Improve error messages for invalid versions
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-02 13:58:34 +00:00
Aanand Prasad
aeef61fcd8 Make 'version' a string
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-02 13:58:34 +00:00
Aanand Prasad
a8de582425 Remove redundant check - self.config should never be None
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-02 13:47:44 +00:00
Aanand Prasad
4ac004059a Normalise/fix config field designators in validation messages
- Instead of "Service 'web' configuration key 'image'", just say
  "web.image"

- Fix the "Service 'services'" bug in the v2 file format

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-02 13:47:43 +00:00
Aanand Prasad
d40bc6e4a0 Convert validation error tests to pytest style
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-02 13:47:43 +00:00
Aanand Prasad
e8756905ba Run test containers in TTY mode
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-02-02 13:31:28 +00:00
Daniel Nephin
6928c24323 Deploying to bintray from appveyor using the new bintray support.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-02-01 16:44:45 -05:00
Daniel Nephin
9c6c50c607 Merge pull request #2796 from mustafau/patch-1
Update link to "Common Use Cases" title
2016-02-01 11:24:18 -05:00
Aanand Prasad
1816147d57 Merge pull request #2740 from albers/completion-create
bash completion for `docker-compose create`
2016-02-01 15:44:07 +00:00
Aanand Prasad
c1cb75cc4f Merge pull request #2741 from sdurrheimer/zsh-completion-create-command
Add zsh completion for 'docker-compose create'
2016-02-01 15:43:47 +00:00
Aanand Prasad
b912b306f1 Merge pull request #2784 from dnephin/signal_race
Fix race condition with up and setting signal handlers
2016-02-01 15:15:59 +00:00
Mustafa Ulu
0b7877d82a Update link to "Common Use Cases" title
It is now under overview.md

Signed-off-by: Mustafa Ulu <mustafau@sabanciuniv.edu>
2016-02-01 00:17:18 +02:00
Dimitar Bonev
34ccb90d7e Falling back to default project name when COMPOSE_PROJECT_NAME is set to empty
Signed-off-by: Dimitar Bonev <dimitar.bonev@gmail.com>
2016-01-30 10:14:45 +02:00
Daniel Nephin
b4868d0259 Fix race condition with up and setting signal handlers.
Also print stdout on wait_for_container().

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-29 13:04:04 -05:00
Daniel Nephin
40d69675f3 Merge pull request #2745 from albers/completion-services
Fix computation of service lists in bash completion
2016-01-28 16:08:46 -05:00
Daniel Nephin
517d3a581c Merge pull request #2768 from aanand/fix-make-branch
Fixes to make-branch script
2016-01-28 15:05:21 -05:00
Daniel Nephin
883e45626f Merge pull request #2706 from dnephin/dont_copy_host_volumes
Don't copy host volumes on recreate
2016-01-28 15:02:53 -05:00
Aanand Prasad
12af889e26 Merge pull request #2737 from moxiegirl/new-navigation
New navigation for 1.10 release
2016-01-28 12:38:28 +00:00
Mary Anthony
3fc72038c5 New navigation for 1.10 release
Updating with Joffrey's comments

Signed-off-by: Mary Anthony <mary@docker.com>
2016-01-27 12:05:56 -08:00
Aanand Prasad
634ae7daa5 Let the user specify any repo as their fork
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-27 15:40:28 +00:00
Aanand Prasad
3547c55523 Default to vim if EDITOR is not set
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-27 15:40:28 +00:00
Aanand Prasad
8c250e220c Merge pull request #2754 from aanand/upgrading-improvements
Improvements to upgrade guide and script
2016-01-27 13:48:23 +00:00
Aanand Prasad
888f4b43c9 Merge pull request #2762 from aanand/remove-links-warnings
Remove outdated warnings about links from docs
2016-01-27 13:08:15 +00:00
Aanand Prasad
d3a1cea170 Remove outdated warnings about links from docs
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-27 02:34:59 +00:00
Aanand Prasad
3aa545eb8e Merge pull request #2755 from aanand/fix-rebase-script
Fix rebase-bump-commit script
2016-01-27 02:05:24 +00:00
Aanand Prasad
ca81672b82 Merge pull request #2761 from aanand/fix-bridge-plus-host
Remove ability to join bridge network + user-defined networks
2016-01-27 01:41:07 +00:00
Aanand Prasad
650b0cec38 Remove ability to join bridge network + user-defined networks
Containers connected to the bridge network can't have aliases, so it's
simpler to rule that they can *either* be connected to the bridge
network (via `network_mode: bridge`) *or* be connected to user-defined
networks (via `networks` or the default network).

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-27 00:42:09 +00:00
Joffrey F
e69ef1c456 Bump docker-py version to latest RC
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-27 00:36:38 +00:00
Aanand Prasad
d3d09ceb08 Merge pull request #2756 from aanand/external-links-v2
Add back external links in v2
2016-01-27 00:34:17 +00:00
Aanand Prasad
cd4cc8b8c6 Merge pull request #2760 from aanand/fix-docs-whitespace
Fix trailing whitespace in docker-compose.md
2016-01-26 23:39:59 +00:00
Aanand Prasad
b84da7c78b Fix trailing whitespace in docker-compose.md
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-26 23:22:21 +00:00
Aanand Prasad
0ba02b4a18 Add back external links in v2
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-26 18:48:43 +00:00
Aanand Prasad
e40a46349f Fix rebase-bump-commit script
Trim whitespace from wc's output before constructing arguments to `git rebase`

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-26 17:42:44 +00:00
Aanand Prasad
bacc2b730e Merge pull request #2748 from schmunk42/master
fixed documentation about traversing yml files
2016-01-26 17:20:40 +00:00
Aanand Prasad
7d403d09cf Extract helper methods
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-26 16:08:34 +00:00
Aanand Prasad
aa4d43af0b Create declarations for named volumes
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-26 16:07:26 +00:00
Aanand Prasad
f86fe11825 Make sure version line is at the top of the file
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-26 15:54:18 +00:00
Aanand Prasad
47b22e90f9 Make warnings a bit more readable
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-26 15:53:25 +00:00
Aanand Prasad
4736b4409a Update for links, external_links, network_mode
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-26 15:53:02 +00:00
Aanand Prasad
c39d5a3f06 Add note about named volumes to upgrade guide
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-26 15:51:09 +00:00
Joffrey F
4b84d088e0 Merge pull request #2743 from aanand/network-mode
Implement network_mode option
2016-01-25 18:26:35 -08:00
Aanand Prasad
ed1b204804 Rename 'net' to 'network mode' in various classes/methods
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-25 23:55:20 +00:00
Aanand Prasad
a9c623fdf2 Test that net can be extended
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-25 23:55:20 +00:00
Aanand Prasad
e566a4dc1c Implement network_mode in v2
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-25 23:24:55 +00:00
Aanand Prasad
a267d8fe3c Merge pull request #2728 from shin-/2709_service_volumes
Match named volumes in service definitions with declared volumes
2016-01-25 23:24:09 +00:00
Joffrey F
af6b18cad8 Merge pull request #2746 from aanand/alias-containers-by-short-id
Alias containers by short id
2016-01-25 13:55:30 -08:00
Tobias Munk
5fe0b57e5c fixed documentation about traversing yml files
Signed-off-by: Tobias Munk <schmunk@usrbin.de>
2016-01-25 19:33:39 +01:00
Aanand Prasad
313c584185 Alias containers by short id
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-25 16:14:21 +00:00
Harald Albers
73a0d83075 Fix computation of service list in bash completion
The previous approach assumed that the service list could be extracted
from a single file. It did not follow extends and overrides.

Signed-off-by: Harald Albers <github@albersweb.de>
2016-01-25 15:51:58 +01:00
Aanand Prasad
3fff286e1a Merge pull request #2727 from dbonev/2703-strict-validation-of-networks
Network fields schema validation
2016-01-25 14:39:54 +00:00
Steve Durrheimer
381d58bc66 Add zsh completion for 'docker-compose create'
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2016-01-25 10:27:21 +01:00
Harald Albers
7f3a319ecc bash completion for docker-compose create
Signed-off-by: Harald Albers <github@albersweb.de>
2016-01-25 10:15:14 +01:00
jrabbit
0019037712 Modify service_test.py::ServiceTest::test_resolve_env to reflect new behavior
Signed-off-by: jrabbit <jackjrabbit@gmail.com>
2016-01-24 15:25:06 -05:00
jrabbit
7ab9509ce6 Mangle the tests. They pass for better or worse!
Signed-off-by: jrabbit <jackjrabbit@gmail.com>
2016-01-23 16:19:17 -05:00
jrabbit
6540efb3d3 If an env var is passthrough but not defined on the host don't set it.
This doesn't change too much code and keeps the generators.

Signed-off-by: jrabbit <jackjrabbit@gmail.com>
2016-01-23 15:58:06 -05:00
Joffrey F
139c7f7830 Move named volumes matching to config validation phase
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-22 17:42:24 -08:00
Joffrey F
48377a354f is_named_volume also tests for home paths ~
Fix bug with VolumeSpec not being updated
Fix integration test

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-22 16:05:21 -08:00
Dimitar Bonev
3a72edb906 Network fields schema validation
Signed-off-by: Dimitar Bonev <dimitar.bonev@gmail.com>
2016-01-22 16:42:10 +02:00
Aanand Prasad
35788f47ff Merge pull request #2729 from shin-/bump_docker_py
Use latest docker-py rc
2016-01-22 11:40:35 +00:00
Aanand Prasad
49c83b16c2 Merge pull request #2726 from aanand/no-logs-on-interactive-run
Pass logs=False to dockerpty
2016-01-22 11:37:58 +00:00
Joffrey F
9e67eae311 Match named volumes in service definitions with declared volumes
Raise ConfigurationError for undeclared named volumes
Test new behavior

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-21 18:10:53 -08:00
Joffrey F
77b435f4fe Use latest docker-py rc
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-21 18:07:14 -08:00
Daniel Nephin
963ec1ceda Merge pull request #2707 from dnephin/add_stop_signal_to_docs
Add stop signal to the docs
2016-01-21 18:41:28 -05:00
Aanand Prasad
da2b6329ae Add test for logs=False
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>

Conflicts:
	compose/cli/main.py
2016-01-21 19:20:50 +00:00
Alf Lervag
6e73fb38ea Fixes #2448
Signed-off-by: Alf Lervag <alf.lervag@bouvet.no>

Conflicts:
	compose/cli/main.py
	requirements.txt
2016-01-21 19:19:37 +00:00
Aanand Prasad
8662ce8e21 Merge pull request #2723 from aanand/fix-run-with-networking
Fix 'run' behaviour with networks
2016-01-21 19:07:53 +00:00
Aanand Prasad
730c33b28c Merge pull request #2699 from aanand/update-compose-file-docs
Update Compose file documentation for version 2
2016-01-21 18:57:16 +00:00
Joffrey F
fec8cc9f80 Update documentation for external param
Signed-off-by: Joffrey F <joffrey@docker.com>

Conflicts:
	docs/compose-file.md
2016-01-21 18:51:28 +00:00
Aanand Prasad
59493dd7aa Add links to networks key references
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-21 18:51:28 +00:00
Aanand Prasad
2f41f3aa7e Update documentation for links
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-21 18:51:28 +00:00
Aanand Prasad
9a3378930f Document depends_on
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-21 18:50:44 +00:00
Aanand Prasad
0554c6e6fd Update Compose file documentation for version 2
- Explain each version in its own section
- Explain how to upgrade from version 1 to 2
- Note which keys are restricted to particular versions
- A few corrections to the docs for version-specific keys

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-21 18:50:44 +00:00
Aanand Prasad
f3e55568d1 Fix interactive run with networking
Make sure we connect the container to all required networks *after*
starting the container and *before* hijacking the terminal.

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-21 18:42:59 +00:00
Aanand Prasad
09dbc7b4cb Stop connecting to all networks on container creation
This relies on an Engine behaviour which is a bug, not an intentional
feature - we have to connect to networks one at a time

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-21 18:04:50 +00:00
Aanand Prasad
a14906fd35 Fix 'run' behaviour with networks
- Test that one-off containers join all networks
- Don't set any aliases

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-21 17:28:55 +00:00
Aanand Prasad
1e51b7e88b Merge pull request #2722 from aanand/fix-scale-race-condition
Fix scale race condition
2016-01-21 17:08:15 +00:00
Aanand Prasad
013c5ea3f9 Merge pull request #2713 from aanand/links-v2
Support links in v2 files
2016-01-21 17:08:05 +00:00
Aanand Prasad
7a4fdfd034 Merge pull request #2712 from jzvelc/fix_v2_service_extend
Fix `extends` when using v2 config format
2016-01-21 17:06:21 +00:00
Aanand Prasad
642e71b4c7 Stop and remove containers in parallel when scaling down
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-21 15:28:40 +00:00
Aanand Prasad
755c49b500 Fix scale when containers exit immediately
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-21 15:19:55 +00:00
Aanand Prasad
ee63075a34 Support links in v2 files
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-21 14:34:26 +00:00
Aanand Prasad
5a249bd9f5 Fix Windows build failures when installing dependencies from git
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-21 11:39:08 +00:00
Jure Žvelc
907c3ce42b Fix for extending services written in v2 format.
Signed-off-by: Jure Žvelc <jzvelc@gmail.com>
2016-01-20 18:46:16 +01:00
Aanand Prasad
e35bf47a7f Merge pull request #2708 from dnephin/implement_depends_on
Implement depends_on
2016-01-20 17:46:10 +00:00
Aanand Prasad
fd6b7d1747 Merge pull request #2693 from dnephin/migrate_v1_to_v2
Add a migration script for v1 to v2 compose format
2016-01-20 17:45:01 +00:00
Daniel Nephin
3b1a0e6fc9 Add stop signal to the docs.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-19 21:33:04 -05:00
Daniel Nephin
5aadf5a187 Update tests in sort_services_test.py to use pytest.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-19 15:52:17 -05:00
Daniel Nephin
146587643c Move ulimits validation to validation.py and improve the error message.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-19 15:47:57 -05:00
Daniel Nephin
0bce467782 Implement depends_on to define an order for services in the v2 format.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-19 15:41:45 -05:00
Daniel Nephin
85619842be Add migration script.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-19 14:50:41 -05:00
Daniel Nephin
c39489f540 Don't copy over volumes that were previously host volumes, and are now container volumes.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-19 14:41:21 -05:00
Daniel Nephin
c47aea9c12 Merge pull request #2698 from aanand/fix-name-is-reserved
Fix "name is reserved" with Engine 1.10 RC1
2016-01-19 10:15:06 -05:00
Daniel Nephin
1be147f775 Merge pull request #2696 from aanand/test-external-default
Test that you can set the default network to be external
2016-01-19 10:09:42 -05:00
Aanand Prasad
2106481c23 Fix "name is reserved" with Engine 1.10 RC1
Ensure link aliases are unique (this deduping was previously performed
on the server).

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-19 11:27:27 +00:00
Aanand Prasad
5b2b4cbb07 Merge pull request #2692 from aanand/fix-tls-paramater-error
Catch TLSParameterErrors from docker-py
2016-01-19 11:25:21 +00:00
Aanand Prasad
746033ed9d Test that you can set the default network to be external
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-19 10:57:12 +00:00
Aanand Prasad
413cdbcb81 Merge pull request #2675 from sdurrheimer/zsh-completion-up-abort-on-container-exit
Add zsh completion for 'docker-compose up --abort-on-container-exit'
2016-01-19 10:41:08 +00:00
Aanand Prasad
683c8b0067 Merge pull request #2676 from sdurrheimer/zsh-completion-down-command
Add zsh completion for 'docker-compose down'
2016-01-19 10:40:29 +00:00
Aanand Prasad
9d2e1f58d9 Merge pull request #2677 from sdurrheimer/zsh-completion-fix-invalid-commands-cache
Fix zsh completion to ensure we have enough commands to store in the …
2016-01-19 10:40:03 +00:00
Aanand Prasad
adedbee41b Merge pull request #2694 from dnephin/release_script_fixes
Fix some bugs in release scripts
2016-01-19 10:39:06 +00:00
Aanand Prasad
9ccef1ea91 Catch TLSParameterErrors from docker-py
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-18 21:48:12 +00:00
Daniel Nephin
66dd9ae9a4 Fix some bugs in release scripts.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-18 15:59:40 -05:00
Aanand Prasad
341fa58b21 Merge pull request #2690 from aanand/ipam-config
Allow custom ipam config
2016-01-18 19:44:07 +00:00
Aanand Prasad
b863fe5723 Merge pull request #2687 from aanand/update-networking-docs
Update networking docs
2016-01-18 18:59:33 +00:00
Aanand Prasad
afae365050 Allow custom ipam config
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-18 18:56:18 +00:00
Aanand Prasad
6b105a6e92 Update networking docs
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-18 18:45:29 +00:00
Aanand Prasad
da490f5b0a Merge pull request #2686 from aanand/fix-custom-default-network
Allow overriding of config for the default network
2016-01-18 17:08:25 +00:00
Aanand Prasad
e7673bf920 Allow overriding of config for the default network
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-18 16:17:39 +00:00
Aanand Prasad
53d56ea245 Quote network names in error messages
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-18 16:15:52 +00:00
Steve Durrheimer
d54190167a Fix zsh completion to ensure we have enough commands to store in the cache
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2016-01-16 13:53:16 +01:00
Steve Durrheimer
f6561f1290 Add zsh completion for 'docker-compose down'
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2016-01-16 13:47:48 +01:00
Steve Durrheimer
e7180982aa Add zsh completion for 'docker-compose up --abort-on-container-exit'
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2016-01-16 13:22:02 +01:00
Joffrey F
a677a2c1f0 Merge pull request #2674 from dnephin/use-1.10-rc1
Test against docker 1.10.0-rc1
2016-01-15 17:13:56 -08:00
Daniel Nephin
ab927b986f Test against 1.10rc1.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-15 19:04:01 -05:00
Daniel Nephin
cce3b29688 Merge pull request #2665 from dnephin/check_extends_use_same_version
Validate that an extended config file has the same version as the base
2016-01-15 18:07:56 -05:00
Daniel Nephin
9e805731e7 Merge pull request #2671 from dnephin/fix_linux_master_build
Fix linux master build
2016-01-15 15:23:24 -05:00
Daniel Nephin
82b288b25b Fix linux master build.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-15 15:02:19 -05:00
Daniel Nephin
0f1a798f28 Increase the timeout for all acceptance tests.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-15 10:14:55 -05:00
Aanand Prasad
a104e11191 Merge pull request #2659 from aanand/default-network-alias
Containers join each network aliased to their service's name
2016-01-15 03:30:07 +00:00
Daniel Nephin
dc1104649f Validate that an extended config file has the same version as the base.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 22:28:20 -05:00
Aanand Prasad
de6d6a42d7 Tag some more v2-dependent tests
Not clear why the config tests are v2-dependent; needs investigating

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-15 02:46:24 +00:00
Aanand Prasad
4772815491 Disable tests until Engine 1.10 change has been worked around
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-15 02:46:24 +00:00
Aanand Prasad
fbc275e06b Work around error message change in Engine
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-15 02:46:24 +00:00
Aanand Prasad
cba75627e1 Fix error when joining host/bridge network
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-15 02:46:24 +00:00
Aanand Prasad
ab2d18851f Test against a dev build of Engine 1.10
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-15 02:46:20 +00:00
Aanand Prasad
406b6b28f4 Tag v2-only tests
- Don't run them against Engine < 1.10
- Set the API version appropriately for the Engine version, so all tests
  use API version 1.22 against Engine 1.10

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-15 02:08:20 +00:00
Aanand Prasad
abd031cb3d Containers join each network aliased to their service's name
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-15 02:08:20 +00:00
Daniel Nephin
2a2eb81215 Merge pull request #2662 from dnephin/fix_config_printing_unicode
Fix config printing unicode objects
2016-01-14 19:26:39 -05:00
Aanand Prasad
493df49d55 Merge pull request #2658 from dnephin/warn_on_caps
Error when the project name is invalid for the default image name
2016-01-14 23:41:04 +00:00
Daniel Nephin
1bfbba36b2 Ensure that the config output by config command never contains python objects.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 18:33:58 -05:00
Daniel Nephin
3021ee12fe Fix config command to print the new sections of the config
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 18:28:17 -05:00
Daniel Nephin
0f234154c2 Remove all non-external networks on down.
Also moves the shutdown test fixtures to be a more general v2-full fixture.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 18:28:17 -05:00
Daniel Nephin
b98e2169e6 Error when the project name is invalid for the image name.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 18:25:23 -05:00
Daniel Nephin
b689c4a218 Move service validation to validate_service().
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 18:25:22 -05:00
Joffrey F
796d97e394 Merge pull request #2617 from gutweiler/extra-hosts-ipv6
Extra hosts ipv6
2016-01-14 15:19:12 -08:00
Joffrey F
842dc14417 Merge pull request #2660 from albers/completion-down
bash completion for `docker-compose down`
2016-01-14 15:17:45 -08:00
Joffrey F
07c5103fe1 Merge pull request #2661 from albers/completion--abort-on-container-exit
bash completion for `docker-compose up --abort-on-container-exit`
2016-01-14 15:17:22 -08:00
Aanand Prasad
47e53b49c2 Merge pull request #2653 from shin-/Runscope-build-args
Support for build arguments
2016-01-14 23:13:54 +00:00
Joffrey F
1ae57d92d4 Remove duplicate functions
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-14 14:39:06 -08:00
Aanand Prasad
ee7a51c179 Merge pull request #2650 from dnephin/interpolate_config_in_volumes
Interpolate variables in the new sections of the Compose file
2016-01-14 22:04:46 +00:00
Clemens Gutweiler
ce9f2681a2 Fixes #1422: ipv6 addr contains colons, so we split only by the first char.
Signed-off-by: Clemens Gutweiler <cg@vioma.de>
2016-01-14 22:26:35 +01:00
Joffrey F
13063a96cb Fix handling of service.dockerfile key
Made invalid in v2 format
Doesn't break build config anymore

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-14 12:15:37 -08:00
Garrett Heel
9cfa71ceee Add support for build arguments
Allows 'build' configuration option to be specified as an
object and adds support for build args.

Signed-off-by: Garrett Heel <garrettheel@gmail.com>
2016-01-14 12:14:56 -08:00
Daniel Nephin
77b4ebc31f Merge pull request #2591 from moxiegirl/remove-todo
Fixing TODO visible in docs
2016-01-14 15:06:38 -05:00
Daniel Nephin
79df2ebe1b Support variable interpolation for volumes and networks sections.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 14:04:57 -05:00
Harald Albers
fca3e47a75 bash completion for docker-compose up --abort-on-container-exit
Signed-off-by: Harald Albers <github@albersweb.de>
2016-01-14 10:43:53 -08:00
Aanand Prasad
3750811eed Merge pull request #2564 from aanand/2478-networks-in-compose-file
Declare networks in Compose file
2016-01-14 18:32:29 +00:00
Harald Albers
a7be0afa5b bash completion for docker-compose down
Signed-off-by: Harald Albers <github@albersweb.de>
2016-01-14 10:32:06 -08:00
Aanand Prasad
d98b64f6e7 Remove duplicated logic from initialize_networks()
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-14 18:09:45 +00:00
Aanand Prasad
4e61377c6d Move get_networks() out of Project class
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-14 18:01:44 +00:00
Aanand Prasad
87326c00eb Python 3 fixes
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-14 18:00:39 +00:00
Aanand Prasad
73fbd01cfe Support the 'external' option for networks
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-14 18:00:39 +00:00
Aanand Prasad
ca68c9faa4 Services can join 'bridge' or 'host'
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-14 18:00:39 +00:00
Aanand Prasad
e75629392d Don't join the bridge network by default in v2
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-14 18:00:39 +00:00
Aanand Prasad
9c91cf2967 Test discoverability across multiple networks
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-14 17:59:37 +00:00
Aanand Prasad
3eafdbb01b Connect services to networks with the 'networks' key
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-14 17:59:37 +00:00
Aanand Prasad
3f9038aea9 Remove test duplication
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-14 17:59:37 +00:00
Aanand Prasad
35e347cf92 Disable the use of 'net' in v2
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-14 17:59:37 +00:00
Aanand Prasad
69ed5f9c48 Specify networks in Compose file
There's not yet a proper way for services to join networks

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-14 17:59:36 +00:00
Aanand Prasad
8fca4f1628 Merge pull request #2649 from dnephin/make_volumes_from_more_explicit
Make volumes from more explicit in V2 config format
2016-01-14 17:15:27 +00:00
Daniel Nephin
172b955d79 Merge pull request #2646 from dnephin/docker_compose_down
docker-compose down
2016-01-14 11:59:02 -05:00
Daniel Nephin
b76dc1e05e Require volumes_from a container to be explicit in V2 config.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 11:45:16 -05:00
Daniel Nephin
c3968a439f Refactor config loading to move version check into ConfigFile.
Adds the cached_property package.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 11:45:15 -05:00
Daniel Nephin
de949284f5 Refactor config loading for handling volumes_from in v2.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 11:43:47 -05:00
Aanand Prasad
dbe04a70f0 Merge pull request #2655 from shin-/updated_volume_definition
Properly validate volume definition
2016-01-14 16:37:39 +00:00
Daniel Nephin
c64af0a459 Add an acceptance test and docs for the down subcommand
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 11:11:08 -05:00
Daniel Nephin
c8ed156806 Adding docker-compose down
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-14 10:59:53 -05:00
Aanand Prasad
18df1e170d Merge pull request #2625 from kojiromike/allow-list-entrypoints
Allow Entrypoints to be Lists
2016-01-14 12:48:13 +00:00
Aanand Prasad
7733600262 Merge pull request #2508 from jstewmon/stop_signal
add support for stop_signal to compose file
2016-01-14 12:46:04 +00:00
Aanand Prasad
1ffd172084 Merge pull request #2654 from dnephin/fix_multiplex_test
Fix flaky multiplex test
2016-01-14 12:27:46 +00:00
Joffrey F
e41e6c1241 Properly validate volume definition
Test valid empty volume definitions

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-13 18:22:29 -08:00
Daniel Nephin
6877c6ca06 Fix flaky multiplex test.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-13 20:58:44 -05:00
Joffrey F
153185eadb Merge pull request #2647 from shin-/preexisting_volume_detection_rb1
Support for external volumes
2016-01-13 17:02:36 -08:00
Michael A. Smith
9bff308251 Document Entrypoints and Commands as Lists
Signed-off-by: Michael A. Smith <msmith3@ebay.com>
2016-01-13 17:47:30 -05:00
Michael A. Smith
59a4ab9634 Allow Entrypoints to be Lists
Signed-off-by: Michael A. Smith <msmith3@ebay.com>
2016-01-13 17:45:56 -05:00
Jonathan Stewmon
b6618815b9 update docker-py requirement to use master branch
Signed-off-by: Jonathan Stewmon <jstewmon@rmn.com>
2016-01-13 16:18:00 -06:00
Joffrey F
e76b2679eb external volume disallows other config keys
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-13 14:12:03 -08:00
Aanand Prasad
fa01883cb2 Merge pull request #2632 from hourliert/master
Mount $HOME in /root to share docker config between containers.
2016-01-13 21:17:18 +00:00
Aanand Prasad
a08e02f3bd Merge pull request #2643 from sdurrheimer/zsh-completion-events
Add zsh completion for 'docker-compose events'
2016-01-13 21:10:36 +00:00
Aanand Prasad
9f34354c19 Merge pull request #2638 from albers/completion-events
Add bash completion for `docker-compose events`
2016-01-13 21:10:09 +00:00
Joffrey F
c260eb910b Merge pull request #2629 from dbonev/2611-support-port-range-in-compose
Port range in exposed ports
2016-01-13 13:09:22 -08:00
Aanand Prasad
3aba5bb67e Merge pull request #2620 from dbonev/2607-ulimits-not-merged-in-extended-services
Ulimits are now merged into extended services
2016-01-13 21:05:38 +00:00
Daniel Nephin
d56f64c30a Merge pull request #2130 from scipetr/master
Add flag for stops all containers if any container was stopped.
2016-01-13 15:55:19 -05:00
Daniel Nephin
eced525317 Merge pull request #2651 from aanand/increase-signal-test-timeout
Increase timeout on signal-handling tests
2016-01-13 15:45:34 -05:00
Aanand Prasad
85a210d9eb Increase timeout on signal-handling tests
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-13 20:34:07 +00:00
Joffrey F
d601199eb5 Normalize external_name
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-13 12:07:08 -08:00
Joffrey F
8616b2de51 Update error message when external volume is missing
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-13 11:23:06 -08:00
Evgeniy Dobrohvalov
bf48a781db Add flag for stops all containers if any container was stopped.
Signed-off-by: Evgeniy Dobrohvalov <scipetr@gmail.com>
2016-01-13 13:12:09 +03:00
Joffrey F
f774422d18 Test Volume.exists() behavior
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-12 16:58:24 -08:00
Joffrey F
9cb58b796e Implement ability to specify external volumes
External volumes are created and managed by the user.
They are not namespaced.
They are expected to exist at the beginning of the up phase.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-12 16:53:49 -08:00
Joffrey F
05935b5e54 Don't recreate pre-existing volumes.
During the initialize_volumes phase, if a volume using the
non-namespaced name already exists, don't create the namespaced
equivalent.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-12 15:42:42 -08:00
Jonathan Stewmon
5d8c2d3cec add support for stop_signal to compose file
Signed-off-by: Jonathan Stewmon <jstewmon@rmn.com>
2016-01-12 17:21:49 -06:00
Joffrey F
ad8faad296 Merge pull request #2579 from vdemeester/update-reference-with-config-and-create
Add config and create to docs/reference
2016-01-12 15:16:45 -08:00
Aanand Prasad
d4b4b126fb Merge pull request #2635 from aanand/use-networking
Use networking for version 2 Compose files
2016-01-12 22:19:50 +00:00
Dimitar Bonev
3a46abd17f Allowed port range in exposed ports
Signed-off-by: Dimitar Bonev <dimitar.bonev@gmail.com>
2016-01-13 00:13:04 +02:00
Dimitar Bonev
2f07e2ac36 Ulimits are now merged into extended services
Signed-off-by: Dimitar Bonev <dimitar.bonev@gmail.com>
2016-01-12 23:59:23 +02:00
Aanand Prasad
70cce961a8 Don't allow links or external_links in v2 files
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-12 21:29:45 +00:00
Aanand Prasad
9e17cff0ef Refactor API version switching logic
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-12 21:29:45 +00:00
Aanand Prasad
a027a0079c Use networking for version 2 Compose files
- Remove --x-networking and --x-network-driver
- There's now no way to set a network driver - this will be added back
  with the 'networks' key

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-12 21:29:40 +00:00
Aanand Prasad
1a66543461 Make the default network name '{project name}_default'
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-12 21:08:28 +00:00
Aanand Prasad
b786b47bc8 Remove version checks from tests requiring API v1.21
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-12 21:08:28 +00:00
Aanand Prasad
0c626e63bc Merge pull request #2458 from dnephin/image_and_build_together
Image and build together
2016-01-12 21:08:00 +00:00
Steve Durrheimer
b59387401c Add zsh completion for 'docker-compose events'
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2016-01-12 22:04:05 +01:00
Daniel Nephin
d32a3ec08f Merge pull request #2639 from dnephin/fix_pep8_errors
Fix pep8 errors from the new pep8 release.
2016-01-12 14:13:23 -05:00
Daniel Nephin
e98ab0e534 Allow both image and build together.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-12 14:10:00 -05:00
Daniel Nephin
ed4db542d6 Fix pep8 errors from the new pep8 release.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-12 14:02:30 -05:00
Aanand Prasad
9e36847eb9 Merge pull request #2637 from dnephin/fix_pre_commit_on_master
Fix pre-commit on master
2016-01-12 18:54:16 +00:00
Harald Albers
6c205a8e01 Add bash completion for docker-compose events
Signed-off-by: Harald Albers <github@albersweb.de>
2016-01-12 10:51:04 -08:00
Daniel Nephin
12b5405420 Fix pre-commit on master.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-12 13:27:18 -05:00
Daniel Nephin
304a44aeab Merge pull request #2585 from dnephin/short_signal_handlers
Fix signal handlers by moving shutdown logic out of handler
2016-01-12 12:55:53 -05:00
Aanand Prasad
52e50a9d9a Merge pull request #2626 from shin-/dbonev-2503-move-logging-config-under-separate-key
Move logging config under separate key in v2 compose files
2016-01-12 15:21:10 +00:00
Aanand Prasad
063a25ae7d Merge pull request #2392 from dnephin/docker_compose_events
docker-compose events
2016-01-12 11:45:27 +00:00
Joffrey F
ca634649bb Changed logging override test into integration test
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-11 16:25:19 -08:00
Joffrey F
46a474ecd9 Move v1-v2 config normalization to separate function.
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-11 15:53:28 -08:00
Joffrey F
c32991a8d4 Remove superfluous service code
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-11 15:39:59 -08:00
Thomas Hourlier
f7a7e68df6 Mount $HOME in /root to share docker config.
Fixes #2630

Signed-off-by: Thomas Hourlier <thomas.hourlier@cnode.fr>
2016-01-11 09:52:51 -08:00
Daniel Nephin
d3cd038b84 Update event field names to match the new API fields.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-11 11:51:17 -05:00
Daniel Nephin
2f8cb55412 Merge pull request #2571 from vdemeester/fix-unpause-typo
Fix typo in unpause reference doc
2016-01-09 12:31:21 -05:00
Daniel Nephin
37d41f22c6 Merge pull request #2572 from vdemeester/fix-run-missing-flag
Add missing --name flag to run reference doc
2016-01-09 12:30:57 -05:00
Joffrey F
46585fb8e1 Support legacy logging options format
Additional test for legacy compose file.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-08 14:37:07 -08:00
Daniel Nephin
fc57fc1dc1 Merge pull request #2609 from dnephin/dont_warn_on_container_volume
Don't warn when the container volume is a compose option
2016-01-08 17:18:02 -05:00
Daniel Nephin
ab98c70dd1 Merge pull request #2612 from dnephin/merge_extends_from_multiple_files
Fix extends with multiple files
2016-01-08 17:17:41 -05:00
Joffrey F
21aae13e77 Move logging config changes to v2 spec
Reorganize JSON schemas
Update fixtures
Update service validation function

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-08 13:21:45 -08:00
Daniel Nephin
d1d3969661 Add docker-compose event
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-08 13:43:30 -05:00
Daniel Nephin
f38c29f37b Merge pull request #2624 from aanand/fix-script-clean
Fix script/clean on systems where `find` requires a path argument
2016-01-08 10:17:01 -05:00
Aanand Prasad
978e9cf38f Fix script/clean on systems where find requires a path argument
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2016-01-08 13:10:05 +00:00
Dimitar Bonev
ed5f7bd394 log_driver and log_opt moved to logging key.
Signed-off-by: Dimitar Bonev <dimitar.bonev@gmail.com>
2016-01-08 01:54:45 +02:00
Aanand Prasad
e7bba2affe Merge pull request #2300 from dnephin/always_unicode_literal
Use "unicode_literals" in all files
2016-01-07 18:28:22 +00:00
Daniel Nephin
bf1552da79 Use json to encode invalid values in configuration errors so that the user sees a proper repr of the value.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-07 13:09:24 -05:00
Daniel Nephin
475a091768 Update pre-commit config to enforace that future imports exist in all files.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-07 13:09:03 -05:00
Aanand Prasad
ed87d1f848 Merge pull request #2421 from shin-/2110-compose_yml_v2
Add support for declaring named volumes in compose files
2016-01-07 16:45:58 +00:00
Vincent Demeester
0bca8d9cb3 Add config and create to docs/reference
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2016-01-06 21:28:52 +01:00
Vincent Demeester
4e75ed4231 Add missing --name flag to run reference doc
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2016-01-06 21:15:11 +01:00
Vincent Demeester
77d2aae72d Fix typo in unpause reference doc
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2016-01-06 21:14:30 +01:00
Daniel Nephin
c7b71422c0 Fix extends with multiple files.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-06 13:30:40 -05:00
Joffrey F
1dcdd98da4 Add TODO note to restore n-1 version testing after 1.10 release
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:24:58 -08:00
Joffrey F
a7689f3da8 Handle volume driver change error in config.
Assume version=1 if file is empty in get_config_version
Empty files are invalid anyway, so this simplifies the algorithm
somewhat.
https://github.com/docker/compose/pull/2421#discussion_r47223144

Don't leak version considerations in interpolation/service validation

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:22:13 -08:00
Joffrey F
f3a9533dc0 version no longer optional arg for process_config_file
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:21:54 -08:00
Joffrey F
661519ac1c Only test latest version in CI script
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:21:53 -08:00
Joffrey F
ec5111f1c2 Volumes are now prefixed with the project name
When created through the compose file, volumes are prefixed
with the name of the project they belong to + underscore,
similarly to how containers are currently handled.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:21:53 -08:00
Joffrey F
ecef5d37a7 Add v2 configuration tests
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:21:53 -08:00
Joffrey F
df6877a277 Use newer docker-py version
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:09:39 -08:00
Joffrey F
abe145bbe7 Update config resolution to always use explicit version numbers
Also includes several bugfixes for resolution and validation.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:09:39 -08:00
Joffrey F
b253efd8a7 Update docs to define and document new compose.yml file format
Add volume configuration reference section.

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:09:39 -08:00
Joffrey F
b4be7b870f Add support for declaring named volumes in compose files
* Bump default API version to 1.21 (required for named volume management)
* Introduce new, versioned compose file format while maintaining support
  for current (legacy) format
* Test updates to reflect changes made to the internal API

Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:09:39 -08:00
Daniel Nephin
4bf2f8c4f9 Fix lookup of linked containers for API version 1.20
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-05 15:09:39 -08:00
Daniel Nephin
97fe2ee40c Don't preserve host volumes on container recreate.
Fixes a regression after the API changed to use Mounts.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-05 15:09:39 -08:00
Daniel Nephin
c64b7cbb10 Ignore errors from API about not being able to kill a container.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-05 15:09:39 -08:00
Joffrey F
afab5c76ea Update service volume tests to use mounts key
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:09:39 -08:00
Joffrey F
3bdcc9d954 Update service tests to use mounts instead of volumes
Signed-off-by: Joffrey F <joffrey@docker.com>
2016-01-05 15:09:39 -08:00
Daniel Nephin
73de81b51c Upgrade tests to use new Mounts in container inspect.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-05 15:09:39 -08:00
Daniel Nephin
ad9011ed96 Don't warn when the container volume is specified as a compose option.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-05 17:30:27 -05:00
Aanand Prasad
4017ea99fe Merge pull request #2599 from dnephin/inject_project_name
Remove support for fig.yaml, FIG_FILE, and FIG_PROJECT_NAME
2016-01-05 12:29:38 +00:00
Aanand Prasad
c1a21d2497 Merge pull request #2577 from TomasTomecek/easier-development
allow running compose from git
2016-01-05 12:27:35 +00:00
Daniel Nephin
2acc29cf1c Remove support for fig.yaml, FIG_FILE, and FIG_PROJECT_NAME.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-01-04 15:37:21 -05:00
Mary Anthony
d4e913e42c Fixing TODO visible in docs
Signed-off-by: Mary Anthony <mary@docker.com>
2015-12-31 19:04:38 -08:00
Daniel Nephin
778c213dfc Fix signal handlers by moving shutdown logic out of handler.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-12-30 11:21:20 -05:00
Michael Gilliland
39af6b653b Update volumes_from docs to state default
[Proof of read-write](cfb1b37da2/compose/config/types.py (L26)).

I found myself wondering what the default was a couple of times, and finally decided to change it :)

Signed-off-by: Michael Gilliland <gillilandmj@upmc.edu>
2015-12-28 16:44:31 -05:00
Tomas Tomecek
adde805829 allow running compose from git
with:

```
$ git clone docker/compose && cd compose
$ export PYTHONPATH="$PWD:$PYTHONPATH"
$ python -m compose --help
```

Signed-off-by: Tomas Tomecek <ttomecek@redhat.com>
2015-12-26 11:03:58 +01:00
Daniel Nephin
ea8cc1c3dc Merge pull request #2562 from thaJeztah/update-links
Update links
2015-12-21 08:31:39 -08:00
Aanand Prasad
a2d2915a64 Merge pull request #2547 from seguins/1125-docker-compose-create
Add docker-compose create command.
2015-12-21 14:20:56 +00:00
Sebastiaan van Stijn
5ed559fa0e Update links
Updates some links to their new locations, and
replaces some http:// with https:// links.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2015-12-21 01:52:54 +01:00
Aanand Prasad
12a08255b5 Merge pull request #2554 from aanand/clarify-rm-behaviour
Clarify behaviour of 'rm'
2015-12-18 16:42:05 +00:00
Stéphane Seguin
3c76d5a467 Add docker-compose create command.
Closes #1125

Signed-off-by: Stéphane Seguin <stephseguin93@gmail.com>
2015-12-18 08:53:26 +01:00
Aanand Prasad
2e9a49b4eb Clarify behaviour of 'rm'
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2015-12-17 17:50:45 +00:00
Aanand Prasad
100d6f2fbb Merge pull request #2552 from dbonev/2452-implement-cpu-quota
Added support for cpu_quota flag
2015-12-17 12:21:15 +00:00
Dimitar Bonev
a542041264 Added support for cpu_quota flag
Signed-off-by: Dimitar Bonev <dimitar.bonev@gmail.com>
2015-12-16 21:25:30 +02:00
Aanand Prasad
c8f63306e0 Merge pull request #2550 from dbonev/1236-restart-to-exit-with-non-zero
Start, restart, pause and unpause exit with non-zero if nothing to do
2015-12-16 15:25:34 +00:00
Aanand Prasad
ae7e48ea2f Merge pull request #2526 from dnephin/remove_extra_coverage_files
Ignore extra coverage files
2015-12-16 15:18:10 +00:00
Dimitar Bonev
bc843d6758 Start, restart, pause and unpause exit with non-zero if nothing to do
Signed-off-by: Dimitar Bonev <dimitar.bonev@gmail.com>
2015-12-15 23:11:11 +02:00
Daniel Nephin
5b32d32b2d Merge pull request #2521 from jeanpralo/master
Add method to get more info about container status
2015-12-15 12:04:42 -08:00
Jean Praloran
c8f266b637 add restarting status for human_readable_state
Signed-off-by: Jean Praloran <jeanpralo@gmail.com>
2015-12-16 08:19:28 +13:00
Daniel Nephin
a1217dc050 Merge pull request #2536 from dbonev/2345-incorrect-network-name
Incorrect network name shown in the log when no driver is specified
2015-12-11 14:39:36 -08:00
Dimitar Bonev
6d709caaa5 Fixes incorrect network name shown in the log when no driver is specified
Signed-off-by: Dimitar Bonev <dimitar.bonev@gmail.com>
2015-12-11 10:14:01 +02:00
Daniel Nephin
1d3aeaaae7 Ignore extra coverge files
These files are created because we run acceptance tests in a subprocess.
They have the process id in their name, so they wont be removed by the
normal coverage cleanup on each run.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-12-10 15:29:36 -08:00
Aanand Prasad
bc09698897 Merge pull request #2527 from dnephin/fix_dns_config_option
Fix dns and dns_search when used strings and without extends.
2015-12-10 11:31:01 +00:00
Daniel Nephin
fa3528ea25 Fix dns and dns_search when used strings and without extends.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-12-09 16:32:39 -08:00
Daniel Nephin
6fe747e0ee Merge pull request #2522 from sdurrheimer/zsh-completion-config-cmd
Add zsh completion for config subcommand
2015-12-09 10:40:44 -08:00
Aanand Prasad
0b7a407055 Merge pull request #2519 from seguins/clean_service
Remove unused functions in service
2015-12-09 13:51:27 +00:00
Aanand Prasad
67829f08b6 Merge pull request #2518 from albers/completion-config
Add bash completion for config subcommand
2015-12-09 12:43:41 +00:00
Steve Durrheimer
01bba5ea23 Add zsh completion for config subcommand
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2015-12-09 08:57:14 +01:00
Stéphane Seguin
999d15b225 Remove unused functions in service
Signed-off-by: Stéphane Seguin <stephseguin93@gmail.com>
2015-12-08 21:11:05 +01:00
Harald Albers
a5b48a3dc2 Add bash completion for config subcommand
Signed-off-by: Harald Albers <github@albersweb.de>
2015-12-08 10:23:55 -08:00
Aanand Prasad
dc39b01e00 Merge pull request #2512 from albers/completion-url
Use more robust download URL for completions
2015-12-08 16:27:09 +00:00
Aanand Prasad
53cc99a822 Merge pull request #2513 from punkstar/detect-tty
Only allocate a tty if we detect one
2015-12-08 15:26:46 +00:00
Aanand Prasad
82dfd465a2 Merge pull request #2407 from dnephin/config_command
New `docker-compose config` command
2015-12-08 15:16:48 +00:00
Daniel Nephin
437f3f8adb Add docker-compose config subcommand.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-12-07 18:51:01 -08:00
Aanand Prasad
ecf2dd11f9 Merge pull request #2467 from dnephin/remove_migrate_to_labels
Remove migrate-to-labels.
2015-12-07 14:31:23 +00:00
Aanand Prasad
9f4e83e456 Merge pull request #2466 from dnephin/remove_insecure_ssl_warning
Removes the deprecated --allow-insecure-ssl flag
2015-12-07 14:29:33 +00:00
Aanand Prasad
50dcb1d7e7 Merge pull request #2468 from dnephin/increase_timeout_in_tests
Increase timeout in tests
2015-12-07 14:29:08 +00:00
Nick Jones
f2c232bb10 Only allocate a tty if we detect one
Signed-off-by: Nick Jones <nick@nicksays.co.uk>
2015-12-07 09:56:28 +00:00
Harald Albers
2525752a05 Use more robust download URL for completions
Signed-off-by: Harald Albers <github@albersweb.de>
2015-12-07 09:10:19 +01:00
Daniel Nephin
509059cdab Merge pull request #2492 from jake-low/no-yaml-warning
Stop warning about ".yaml" file extension
2015-12-04 12:22:56 -08:00
Daniel Nephin
3e7b2ab865 Merge pull request #2506 from dnephin/update_changelog
Cherry-pick release notes for 1.5.2
2015-12-04 12:21:27 -08:00
Daniel Nephin
de4a18ea6c Cherry-pick release notes for 1.5.2
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-12-04 10:26:20 -08:00
Aanand Prasad
0a84833474 Merge pull request #2505 from thaJeztah/update-maintainers
update maintainers file for parsing
2015-12-04 16:16:09 +00:00
Sebastiaan van Stijn
7698da57ca update maintainers file for parsing
this updates the MAINTAINERS file to the new format,
so that it can be parsed and collected in the docker/opensource
repository.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2015-12-04 16:52:29 +01:00
jake-low
e760c42ae0 Stop warning about ".yaml" extension
".yaml" is the preferred extension according to http://www.yaml.org/faq.html

Signed-off-by: jake-low <jakelow42@gmail.com>
2015-12-02 21:45:36 -08:00
Daniel Nephin
707281aadb Merge pull request #2291 from dnephin/compose_faq
FAQ document for Compose
2015-12-02 11:12:37 -08:00
Daniel Nephin
3f39ffe72e FAQ document for Compose
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-12-02 10:47:32 -08:00
moxiegirl
0eba234c54 Merge pull request #2461 from SvenDowideit/move-to-docs-base-latest
Use FROM docs/base:latest again
2015-12-01 08:54:13 -08:00
Daniel Nephin
377f084dfe Increase timeout in tests.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-27 13:54:00 -05:00
Daniel Nephin
a21f9993b3 Remove migrate-to-labels.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-27 12:04:45 -05:00
Daniel Nephin
2f568984f7 Fixes #2368, removes the deprecated --allow-insecure-ssl flag.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-27 11:52:25 -05:00
Aanand Prasad
defcf5a21f Merge pull request #2464 from aanand/validate-expose
Validate `expose`
2015-11-27 14:44:55 +00:00
Aanand Prasad
ccf548b98c Validate the 'expose' option
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2015-11-26 19:27:32 +00:00
Aanand Prasad
042c7048f2 Split out ports validation tests into type, uniqueness, format
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2015-11-26 19:27:31 +00:00
Aanand Prasad
374b16843f Fix ports validation message
- The `raises` kwarg to the `cls_check` decorator was being used
  incorrectly (it should be an exception class, not an object).

- We need to check for `error.cause` and get the message out of the
  exception object.

NB: The particular case where validation fails in the case of `ports` is
only when ranges don't match in length - no further validation is
currently performed client-side.

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2015-11-26 18:54:30 +00:00
Aanand Prasad
d52508e2b1 Refactor ports section of fields schema
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2015-11-26 18:52:14 +00:00
Aanand Prasad
0fedd9969f Merge pull request #2430 from dnephin/build_from_url
Build from url
2015-11-26 18:15:03 +00:00
Daniel Nephin
2ab3cb212a Add integration test and docs for build with a git url.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-26 11:32:39 -05:00
Jonas Eckerström
f7239f41ef Added support for url buid paths
Signed-off-by: Jonas Eckerström <jonaseck@gmail.com>
2015-11-26 11:29:07 -05:00
Aanand Prasad
b85bfce65e Fix ports validation test
We were essentially only testing that *at least one* of the invalid
values fails the validation check, rather than that *all* of them fail.

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2015-11-26 15:06:30 +00:00
Sven Dowideit
fd06d699f2 Use FROM docs/base:latest again
Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
2015-11-26 20:30:12 +10:00
Aanand Prasad
7b893164a4 Merge pull request #2450 from dnephin/fix_env_file_ordering
Fix env_file overrides with extends
2015-11-25 16:35:40 +00:00
Daniel Nephin
e67bc2569c Properly resolve environment from all sources.
Split env resolving into two phases. The first phase is to expand the paths
of env_files, which is done before merging extends. Once all files are merged
together, the final phase is to read the env_files and use them as the base
for environment variables.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-25 11:02:20 -05:00
Aanand Prasad
cfb1b37da2 Merge pull request #2405 from dnephin/move_all_validation_to_config
Move all validation to config
2015-11-25 15:16:21 +00:00
Daniel Nephin
8930fa25d6 Merge pull request #2387 from dnephin/update_release_notes
cherry-pick release notes from 1.5.1
2015-11-24 13:25:21 -05:00
Daniel Nephin
6e89a5708f cherry-pick release notes from 1.5.1
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-24 13:24:46 -05:00
Aanand Prasad
c1c1dceb59 Merge pull request #2453 from dnephin/fix_test_assertion
Add missing assert and autospec
2015-11-24 16:45:04 +00:00
Aanand Prasad
88e9c1ccd9 Merge pull request #2438 from dnephin/fix_flaky_pull_test
Fix `build --pull` test flakes
2015-11-24 16:44:53 +00:00
Aanand Prasad
689f040c97 Merge pull request #2429 from dnephin/fix_links_in_readme
Fix use case link in readme
2015-11-24 15:56:05 +00:00
Daniel Nephin
e40670207f Add missing assert and autospec.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-24 10:42:25 -05:00
Aanand Prasad
50bc734492 Merge pull request #2427 from dnephin/note_about_pip_version
Add note about required pip version.
2015-11-24 15:21:37 +00:00
Daniel Nephin
533f33271a Move service sorting to config package.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-23 13:33:00 -05:00
Daniel Nephin
effa9834a5 Remove unnecessary intermediate variables in get_container_host_config.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-23 13:33:00 -05:00
Daniel Nephin
dac75b07dc Move volume parsing to config.types module
This removes the last of the old service.ConfigError

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-23 13:33:00 -05:00
Daniel Nephin
efec2aae6c Fixes #2008 - re-use list_or_dict schema for all the types
At the same time, moves extra_hosts validation to the config module.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-23 13:31:58 -05:00
Daniel Nephin
12b82a20ff Move restart spec to the config.types module.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-23 13:31:58 -05:00
Daniel Nephin
068edfa313 Move parsing of volumes_from to the last step of config parsing.
Includes creating a new compose.config.types module for all the domain objects.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-23 13:31:58 -05:00
Daniel Nephin
c9ca5e86b0 Remove project name validation
project name is already normalized to a valid name before creating a service.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-23 13:30:54 -05:00
Aanand Prasad
83ddec8df7 Merge pull request #2439 from solarce/sol-matrix-trusty-fix
Fixing matrix include so `os: linux` goes to trusty
2015-11-23 18:01:22 +00:00
Aanand Prasad
665de9a494 Merge pull request #2436 from dnephin/reduce_cyclomatic_complexity
Reduce cyclomatic complexity
2015-11-23 17:51:54 +00:00
Daniel Nephin
b4edf0c454 Move parallel_execute to a new module.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-23 11:34:48 -05:00
Aanand Prasad
aafacd3495 Merge pull request #2418 from dnephin/fix_env_with_extends
Fix env_file and environment when used with extends
2015-11-23 14:48:04 +00:00
Brandon Burton
13081d4516 Fixing matrix include so os: linux goes to trusty
Signed-off-by: Brandon Burton <brandon@inatree.org>
2015-11-20 16:07:37 -08:00
Daniel Nephin
2351e11cc8 Make sure we always have the latest busybox image, so that build --pull tests don't flake.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-20 17:51:36 -05:00
Daniel Nephin
64447879d2 Reduce complexity of merge_service_dicts
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-20 17:09:55 -05:00
Daniel Nephin
d1adbb9b25 Refactor parallel_execute.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-20 17:09:51 -05:00
Daniel Nephin
c4096525c2 Merge pull request #2364 from dnephin/handle_signals_properly
Handle SIGTERM/SIGINT properly for up and run
2015-11-20 11:58:04 -05:00
Daniel Nephin
8bc84c74e7 Merge pull request #2417 from dnephin/inlude_git_sha_in_version
Add the git sha to version output
2015-11-20 11:39:38 -05:00
Daniel Nephin
331450dace Merge pull request #2390 from dnephin/fix_extra_warnings_on_masked_volumes
Fix extra warnings on masked volumes
2015-11-20 11:37:54 -05:00
Daniel Nephin
91fb6156c6 Merge pull request #2393 from seguins/1814-restart-stopped-containers
Fix restart with stopped containers.
2015-11-20 11:35:24 -05:00
Daniel Nephin
46446111e5 Merge pull request #2400 from dnephin/fix_stream_with_empty_object
Fix a bug in progress_stream when an `ADD <url>` was used
2015-11-20 11:33:45 -05:00
Daniel Nephin
6224b6edd9 Fix use case link in readme.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-19 14:53:28 -05:00
Joffrey F
dd1a2b36fa Merge pull request #2389 from hypriot/use-uname-for-target
Use uname to build target name for different platforms
2015-11-19 10:36:33 -08:00
Joffrey F
449cdcc966 Merge pull request #2420 from simonvanderveldt/fix-script-runsh-env-vars
run.sh script: Also pass DOCKER_TLS_VERIFY and DOCKER_CERT_PATH env vars to compose container
2015-11-19 10:35:28 -08:00
Daniel Nephin
3fdf0f43be Add note about required pip version.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-19 12:55:03 -05:00
Daniel Nephin
21a72e350b Merge pull request #2413 from SvenDowideit/stop-docs-validation-errors
2 small changes to clear up docs-validation complaints
2015-11-19 12:52:43 -05:00
Sven Dowideit
acf31181e8 Some small changes to clear up docs-validation complaints
Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
2015-11-19 13:35:09 +10:00
Daniel Nephin
1e8f76767f Fix env_file and environment when used with extends.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-18 16:07:11 -05:00
Daniel Nephin
c78c32c2e8 Fixes #2398 - the build progress stream can contain empty json objects.
Previously these empty objects would hit a bug in splitting objects causing it crash.
With this fix the empty objects are returned properly.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-18 16:04:41 -05:00
Simon van der Veldt
efbfa9e38f run.sh script: Also pass DOCKER_TLS_VERIFY and DOCKER_CERT_PATH
env vars to compose container

Signed-off-by: Simon van der Veldt <simon.vanderveldt@gmail.com>
2015-11-18 21:40:16 +01:00
Daniel Nephin
d4b9845201 Add the git sha to version output
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-18 13:21:14 -05:00
Daniel Nephin
2f20dfe508 Merge pull request #2409 from dnephin/fix_the_build
Fix texttable dep. 0.8.2 was removed from pypi.
2015-11-17 20:06:40 -05:00
Daniel Nephin
265828f4eb Fix texttable dep. 0.8.2 was removed from pypi.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-17 18:36:58 -05:00
Stéphane Seguin
61f91ebff7 Fix restart with stopped containers.
Fixes #1814

Signed-off-by: Stéphane Seguin <stephseguin93@gmail.com>
2015-11-14 12:23:23 +01:00
Daniel Nephin
e1308a8329 Fix extra warnings on masked volumes.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-13 10:49:17 -05:00
Stefan Scherer
c99f2f8efd Use uname to build target name for different platforms
Signed-off-by: Stefan Scherer <scherer_stefan@icloud.com>
2015-11-13 08:33:51 +01:00
Daniel Nephin
6236bb0019 Handle both SIGINT and SIGTERM for docker-compose run.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-12 17:41:44 -05:00
Daniel Nephin
ea4230e7a2 Handle both SIGINT and SIGTERM for docker-compose up.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-12 17:41:44 -05:00
Daniel Nephin
9f6a5a964a Merge pull request #2355 from dnephin/refactor_handle_error
Refactor process_error and include a filename as part of the validation error messages
2015-11-12 15:01:32 -05:00
Daniel Nephin
9c305ac10f Remove name field from the list of ALLOWED_KEYS
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-12 13:26:13 -05:00
Daniel Nephin
589755d034 Inclide the filename in validation errors.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-12 12:44:45 -05:00
Daniel Nephin
fa96484d28 Refactor process_errors into smaller functions
So that it passed new max-complexity requirement

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-12 12:44:24 -05:00
Daniel Nephin
f7d8087694 Add ids to config schemas
Also enforce a max complexity for functions and add some new tests for config.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-12 12:40:36 -05:00
Joffrey F
0a35fd93cd Merge pull request #2373 from shin-/2370-env_vars_with_dashes
Allow dashes in environment variable names
2015-11-11 13:20:22 -08:00
Joffrey F
d6b44905f2 Add test for environment variable dashes support
Signed-off-by: Joffrey F <joffrey@docker.com>
2015-11-11 12:52:30 -08:00
Joffrey F
513dfda218 Allow dashes in environment variable names
See http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
Environment variable names used by the utilities in the Shell and
Utilities volume of POSIX.1-2008 consist solely of uppercase letters,
digits, and the <underscore> ( '_' ) from the characters defined in
Portable Character Set and do not begin with a digit. Other characters may
be permitted by an implementation; applications shall tolerate the
presence of such names.

Signed-off-by: Joffrey F <joffrey@docker.com>
2015-11-11 12:45:02 -08:00
Daniel Nephin
a746d673b1 Merge pull request #2350 from dnephin/remove_name_from_schema
Remove name field from the config schema
2015-11-11 15:43:03 -05:00
Daniel Nephin
76f3c9c739 Merge pull request #2349 from dnephin/validate_all_files
Validate all files before merging them
2015-11-11 15:27:47 -05:00
Daniel Nephin
08bd2a318f Merge pull request #2371 from shin-/yvespp-master
Removed unneeded newlines on docker-compose pull with no tty (#2311 update)
2015-11-11 15:20:31 -05:00
Joffrey F
c573fcc70a Reorganize conditional branches to improve readability
Signed-off-by: Joffrey F <joffrey@docker.com>
2015-11-11 11:21:24 -08:00
Yves Peter
b8b4c84573 Fixes #1490
progress_stream would print a lot of new lines on "docker-compose pull" if there's no tty.

Signed-off-by: Yves Peter <ypdraw@gmail.com>
2015-11-11 11:20:59 -08:00
Aanand Prasad
2063b39868 Merge pull request #2336 from dnephin/warn_on_volume_masking
Add a warning when the host volume in the compose file is masked by a data volume
2015-11-11 17:21:29 +00:00
Daniel Nephin
19b2c41c7e Add a test for invalid field 'name', and fix an existing test for invalid service names.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-11 11:00:11 -05:00
Daniel Nephin
1f7faadc77 Remove name from config schema.
Refactors config validation of a service to use a ServiceConfig data object.
Instead of passing around a bunch of related scalars, we can use the
ServiceConfig object as a parameter to most of the service validation functions.

This allows for a fix to the config schema, where the name is a field in the
schema, but not actually in the configuration. My passing the name around as
part of the ServiceConfig object, we don't need to add it to the config options.
Fixes #2299

validate_against_service_schema() is moved from a conditional branch in
ServiceExtendsResolver() to happen as one of the last steps after all
configuration is merged. This schema only contains constraints which only need
to be true at the very end of merging.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-11 11:00:11 -05:00
Daniel Nephin
5e97b806d5 Fix a bug in ExtendsResolver where the service name of the extended service was wrong.
This bug can be seen by the change to the test case. When the extended service
uses a different name, the error was reported incorrectly.

By fixing this bug we can simplify self.signature and self.detect_cycles to
always use self.service_name.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-11 10:58:07 -05:00
Daniel Nephin
a92d86308f Rename ServiceLoader to ServiceExtendsResolver
ServiceLoader has evolved to be not really all that related to "loading" a
service. It's responsibility is more to do with handling the `extends`
field, which is only part of loading.  The class and its primary method
(make_service_dict()) were renamed to better reflect their responsibility.

As part of that change process_container_options() was removed from
make_service_dict() and renamed to process_service().  It contains logic for
handling the non-extends options.

This change allows us to remove the hacks from testcase.py and only call
the functions we need to format a service dict correctly for integration tests.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-11 10:58:07 -05:00
Daniel Nephin
98ad5a05e4 Validate additional files before merging them.
Consolidates all the top level config handling into `process_config_file` which
is now used for both files and merge sources.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-11 10:56:15 -05:00
Aanand Prasad
7466d14826 Merge pull request #2363 from dnephin/pr-2261
Rebase of PR 2261
2015-11-11 15:48:28 +00:00
Daniel Nephin
c006c6ea09 Merge pull request #2341 from dnephin/dont_create_default_network_sometimes
Only create the default network if at least one service needs it
2015-11-11 10:48:08 -05:00
Daniel Nephin
7365a398b3 Update doc wording for ulimits.
and move tests to the correct module

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-10 15:03:20 -05:00
Kevin Greene
22d90d2180 Added ulimits functionality to docker compose
Signed-off-by: Kevin Greene <kevin@spantree.net>
2015-11-10 14:07:04 -05:00
Daniel Nephin
a8ac6e6f93 Add a warning when the host volume config is being ignored.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-10 13:48:53 -05:00
Daniel Nephin
7d6c63d1b7 Merge pull request #2361 from dnephin/pr-2262
Rebase of PR 2262
2015-11-10 13:42:08 -05:00
Joffrey F
2c2b8a8322 Merge pull request #2360 from shin-/2357-http_timeout_exit_1
Use exit code 1 when encountering a ReadTimeout
2015-11-10 10:31:58 -08:00
Daniel Nephin
338bbb5063 Re-order flags in bash completion
and remove unnecessary variables from build command.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-10 13:11:59 -05:00
Joffrey F
133d213e78 Use exit code 1 when encountering a ReadTimeout
Signed-off-by: Joffrey F <joffrey@docker.com>
2015-11-10 10:11:20 -08:00
Adrian Budau
c5c36d8b00 Added --force-rm to compose build.
It's a flag passed to docker build that removes the intermediate
containers left behind on fail builds.

Signed-off-by: Adrian Budau <budau.adi@gmail.com>
2015-11-10 13:05:04 -05:00
Daniel Nephin
45724fc667 Only create the default network if at least one service needs it.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-10 12:43:55 -05:00
Daniel Nephin
3474bb6cf5 Cleanup workaround in testcase.py
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-10 12:43:55 -05:00
Aanand Prasad
0017f43d7f Merge pull request #2339 from dnephin/recreate_deps_on_create
Recreate dependents when a dependency is created
2015-11-10 17:36:23 +00:00
Daniel Nephin
c8fa0a902a Merge pull request #2331 from dnephin/flush_log_buffer_when_printing_logs
Flush the log stream after writing each line
2015-11-10 12:34:42 -05:00
Aanand Prasad
917b885a44 Merge pull request #2334 from dnephin/dont_set_hostname
Don't set the hostname to the service name with networking.
2015-11-10 17:34:02 +00:00
Daniel Nephin
b09cf86dd6 Merge pull request #2326 from dnephin/unicode_decode_error
Unicode decode error
2015-11-10 12:29:52 -05:00
Joffrey F
774d852f93 Merge pull request #2335 from dnephin/volumes_refactoring
Some small refactoring around volumes
2015-11-09 14:05:52 -08:00
Daniel Nephin
e5fbf35ce1 Merge pull request #2351 from shin-/2322_config_hash_volumes_from
Update service config_dict computation to include volumes_from mode
2015-11-09 16:26:47 -05:00
Joffrey F
a1e140f5a3 Update service config_dict computation to include volumes_from mode
Ensure config_hash is updated when volumes_from mode is changed, and
service is recreated on next up as a result.

Signed-off-by: Joffrey F <joffrey@docker.com>
2015-11-09 13:07:26 -08:00
Daniel Nephin
b7fe86b99a Merge pull request #2348 from aanand/fix-parallel-output
Fix parallel output
2015-11-09 13:09:50 -05:00
Aanand Prasad
1bfb710326 Fix parallel output
We were outputting an extra line, which in *some* cases, on *some*
terminals, was causing the output of parallel actions to get messed up.

In particular, it would happen when the terminal had just been cleared
or hadn't yet filled up with a screen's worth of text.

Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2015-11-09 17:24:21 +00:00
Daniel Nephin
7c2a16234f Recreate dependents when a dependency is created (not just when it's recreated).
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-06 12:29:52 -05:00
Daniel Nephin
ec22d98377 Use VolumeSpec instead of re-parsing the volume string.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-05 18:11:56 -05:00
Daniel Nephin
0e19c92e82 Make working_dir consistent in the config package.
- make it a positional arg, since it's required
- make it the first argument for all functions that require it
- remove an unnecessary one-line function that was only called in one place

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-05 18:11:56 -05:00
Daniel Nephin
3456002aef Don't set the hostname to the service name with networking.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-05 17:50:32 -05:00
Daniel Nephin
d32bb8efee Fix #1549 - flush after each line of logs.
Includes some refactoring of log_printer_test to support checking for flush(), and so that each test calls the unit-under-test directly, instead of through a helper function.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-05 15:33:42 -05:00
Daniel Nephin
26c7dd3712 Handle non-utf8 unicode without raising an error.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-05 12:56:36 -05:00
Aanand Prasad
67dc90ec0e Merge pull request #2314 from dnephin/fix_up_require_build_error
Fix `up` "requires build" error
2015-11-05 15:52:56 +00:00
Aanand Prasad
97dee9d54a Merge pull request #2310 from dnephin/update_release_notes
Update release notes
2015-11-05 15:52:41 +00:00
Daniel Nephin
8ff960afd1 Fix service recreate when image changes to build.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-05 10:27:11 -05:00
Daniel Nephin
ce322047a0 Move config hash tests to service_test.py
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-05 10:27:11 -05:00
Daniel Nephin
0227b3adbd Upgrade pyyaml to 3.11
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-05 10:26:54 -05:00
Daniel Nephin
d18ad4c812 Fix rebase-bump-commit script when used with a final release.
Previously it would find commits for RC releases, which broke the rebase.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-05 10:25:46 -05:00
Daniel Nephin
6b002fb922 Cherry-pick release notes froim 1.5.0
And bump version to 1.6.0dev

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-05 10:25:46 -05:00
Daniel Nephin
50f06c6ba2 Merge pull request #2325 from dnephin/fix_jenkins_build
Fix jenkins CI
2015-11-04 17:25:17 -05:00
Daniel Nephin
385b4280a1 Fix jenkins CI by using an older docker version to match the host.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-04 15:33:37 -05:00
Aanand Prasad
6a8806fe8d Merge pull request #2304 from dnephin/remove_start_container
Remove service.start_container()
2015-11-04 10:19:33 +00:00
Aanand Prasad
4ebe68e612 Merge pull request #2290 from dnephin/docs_multi_file_compose
Docs for using multiple compose files
2015-11-03 17:14:57 +00:00
Daniel Nephin
e503e085ac Re-order extends docs.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-03 11:52:44 -05:00
Daniel Nephin
8bdde9a731 Replace composition with Compose app.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-03 11:28:51 -05:00
Daniel Nephin
eab265befa Document using multiple Compose files use cases.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-03 11:28:51 -05:00
Daniel Nephin
c5cf5cfad4 Changes to production.md for working with multiple Compose files.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-03 11:28:51 -05:00
Daniel Nephin
1c4c7ccfac Support a volume to the docs directory and add --watch, so docs can be refreshed.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-03 11:28:51 -05:00
Daniel Nephin
7014cabb04 Remove duplication from extends docs.
Start restructuring extends docs in preparation for adding documentation about using multiple compose files.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-03 11:28:51 -05:00
Aanand Prasad
767a13f771 Merge pull request #2165 from dnephin/more_user_docs
Restructure intro docs
2015-11-03 16:22:28 +00:00
Daniel Nephin
3d9e3d0877 Remove service.start_container()
It has been an unnecessary wrapper around container.start() for a little while now, so we can call it directly.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-03 10:17:09 -05:00
Aanand Prasad
19a41997c2 Merge pull request #2306 from dnephin/cli_tests_use_cli
Update cli test suite to run the executable in a child process
2015-11-03 15:05:47 +00:00
Daniel Nephin
45635f7097 Move cli tests to a new testing package.
These cli tests are now a different kind of that that run the compose binary. They are not the same as integration tests that test some internal interface.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-02 19:28:58 -05:00
Daniel Nephin
8057bb3fcc Update cli tests to use subprocess.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-02 17:35:00 -05:00
Daniel Nephin
c58cf036e3 Touch up intro paragraph with feedback from @moxiegirl.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-02 15:16:23 -05:00
Daniel Nephin
a3fb13e141 Add another feature to the docs - multiple environments per host.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-02 15:16:23 -05:00
Daniel Nephin
d9bc91b7cc Update intro docs based on feedback.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-02 15:16:23 -05:00
Daniel Nephin
db3b90b84e Updates to gettingstarted guide from PR feedback.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-02 15:16:23 -05:00
Daniel Nephin
86d845fde3 Flush out features and use cases.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-02 15:16:23 -05:00
Daniel Nephin
186d43c59f Extract the getting started guide from the index page.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-02 15:16:23 -05:00
Daniel Nephin
53a0de7cf2 Add missing title to compose file reference.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-02 15:16:23 -05:00
Daniel Nephin
3738da09e2 Merge pull request #2298 from dnephin/update_networking_test_for_rc4
Fix networking tests to work with new API in engine rc4
2015-11-02 15:10:17 -05:00
Daniel Nephin
abde64d610 On a test failure only show the last 100 lines of daemon output.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-02 14:16:52 -05:00
Daniel Nephin
1b5b407619 Fix networking tests to work with new API in engine rc4 (https://github.com/docker/docker/pull/17536)
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-11-02 13:40:56 -05:00
Daniel Nephin
77e1fe1915 Merge pull request #2295 from dnephin/default_network_should_be_none
Don't set a default network driver, let the server decide
2015-10-30 15:29:30 -04:00
Daniel Nephin
66ef2519d3 Merge pull request #2265 from dnephin/volumes_in_guides_doc
Update tutorials and small fix with rails tutorial
2015-10-30 13:30:00 -04:00
Daniel Nephin
c7d164d01c Fixes #1843, #1936 - chown files back to host user in django example.
Also add a missing 'touch Gemfile.lock' to fix the rails tutorial.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-30 12:42:15 -04:00
Daniel Nephin
491d052088 Don't set a default network driver, let the server decide.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-30 11:53:36 -04:00
Daniel Nephin
c439e056a0 Merge pull request #2288 from dnephin/warning_about_vars
Add console color to warnings and errors so they are more obvious
2015-10-30 10:58:00 -04:00
Daniel Nephin
04a76dc284 Merge pull request #2287 from shin-/2284-ensure-network-exists-run
Ensure network exists when calling run before up
2015-10-30 10:41:55 -04:00
Joffrey F
072e7687ae Integration test for run command with networking enabled
Signed-off-by: Joffrey F <joffrey@docker.com>
2015-10-30 14:15:47 +01:00
Daniel Nephin
eb9b8dc592 Merge pull request #2283 from dnephin/fix_not_none_log_driver
Logs are available for all log drivers except for none.
2015-10-29 15:01:05 -04:00
Daniel Nephin
841ed4ed21 Remove the duplicate 'Warning' prefix now that the logger adds the prefix.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-29 14:18:28 -04:00
Daniel Nephin
d836973a04 Use colors when logging warnings or errors, so they are more obvious.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-29 14:06:50 -04:00
mnowster
057b8e291c Merge pull request #2286 from mnowster/2281-docs-curl-command
Clarify the command is an example
2015-10-29 17:20:59 +00:00
Joffrey F
596261e759 Ensure network exists when calling run before up
Otherwise the daemon will error out because the network doesn't exist
yet.

Signed-off-by: Joffrey F <joffrey@docker.com>
2015-10-29 17:56:01 +01:00
Mazz Mosley
983dc12160 Clarify the command is an example
Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-29 16:52:00 +00:00
Daniel Nephin
eab9d86a3d Logs are available for all log drivers except for none.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-29 11:28:17 -04:00
mnowster
6cd9bab35b Merge pull request #2276 from dnephin/update_networking_docs
Update docs about networking for current release
2015-10-29 15:19:02 +00:00
mnowster
64a2713714 Merge pull request #2264 from mnowster/2259-unicode-error-volume-paths
Handle non-ascii volume directories
2015-10-29 14:42:29 +00:00
Mazz Mosley
5dc14f3925 Handle non-ascii chars in volume directories
Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-29 12:05:51 +00:00
mnowster
0b25014020 Merge pull request #2278 from dnephin/disable_flaky_test
Disable flaky test against 1.8.3
2015-10-29 12:04:54 +00:00
mnowster
3a2df57f3d Merge pull request #2273 from mnowster/cross-ref-docs
Add cross references for env/cli
2015-10-29 12:04:10 +00:00
Daniel Nephin
a71d9af522 Disable a test against docker 1.8.3 because it fails due to a bug in docker engine.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-28 17:54:38 -04:00
Daniel Nephin
0ef3b47f74 Update docs about networking for current release.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-28 15:17:11 -04:00
mnowster
66f1c8e6c0 Merge pull request #2272 from dnephin/update_release_docs_and_scripts
Another release, another round of fixes to the release scripts
2015-10-28 17:54:48 +00:00
mnowster
dfaa18ebc5 Merge pull request #2274 from mnowster/docs-key-dependency-clarification
Clarify `dockerfile` requires `build` key
2015-10-28 17:45:27 +00:00
Mazz Mosley
e13b8949b0 Add cross references for env/cli
Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-28 17:42:30 +00:00
Mazz Mosley
c341860d11 Clarify dockerfile requires build key
Credit to @funkyfuture for the first PR addressing the clarification.
https://github.com/docker/compose/pull/1767

Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-28 17:27:38 +00:00
Daniel Nephin
8306405340 On error print daemon logs
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-28 12:40:59 -04:00
Daniel Nephin
bbc76e6034 Convert the README to rst and fix the logo url before packaging it up for pypi.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-28 12:11:29 -04:00
Daniel Nephin
c4f0f24c57 Fix release script notes about software and typos.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-28 12:10:30 -04:00
mnowster
7e48b0b289 Merge pull request #2271 from mnowster/2270-pypi-page-info
Include link to github for code & issues
2015-10-28 15:30:07 +00:00
Mazz Mosley
379af594da Include link to github for code&issues
Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-28 14:59:43 +00:00
Daniel Nephin
b6b9b002e5 Merge pull request #2254 from mnowster/1756-dont-display-output-from-previous-runs
1756 dont display output from previous runs
2015-10-27 18:45:47 -04:00
Mazz Mosley
76d52b1c5f Remove redundant try/except
Code cleanup. We no longer need this as the api returns a 304 for any
stopped containers, which doesn't raise an error.

Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-27 17:12:18 +00:00
Mazz Mosley
30a84f1be6 Move rename functionality into Container
Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-27 17:12:18 +00:00
Mazz Mosley
bee063c07d Fix tests
Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-27 17:12:18 +00:00
Mazz Mosley
7603ebea9b Attach to a container's log_stream before they're started
So we're not displaying output of all previous logs for a container, we attach,
if possible, to a container before the container is started.

LogPrinter checks if a container has a log_stream already attached and
print from that rather than always attempting to attach one itself.

Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-27 17:12:18 +00:00
mnowster
ffa2b08dbb Merge pull request #2258 from dnephin/dont_link_when_using_networking
Fix running one-off containers with --x-networking
2015-10-27 15:32:20 +00:00
Daniel Nephin
7878d38dee Fix running one-off containers with --x-networking by disabling linking to self.
docker create fails if networking and links are used together.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-27 11:11:15 -04:00
mnowster
a4b002a76e Merge pull request #2257 from mnowster/2226-additional-classifiers
Include additional classifiers
2015-10-27 11:12:38 +00:00
Mazz Mosley
fe760a7b62 Include additional classifiers
I've included Python 2/3 as they are not parent classifiers but
sibling classifiers. They denote that this project will work with
*some* versions of python and by having them, they'll show up for
people searching for python 2 or 3 projects.

According to the internet :)

Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-26 17:08:45 +00:00
mnowster
f3d49e38c0 Merge pull request #2245 from dnephin/upgrade_to_pyinstaller_3
Upgrade to pyinstaller 3
2015-10-26 11:54:02 +00:00
Daniel Nephin
0340361f56 Upgrade pyinstaller to 3.0
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-23 13:34:49 -04:00
mnowster
986036b6f9 Merge pull request #2223 from au-phiware/master
Powershell script to run compose in a container.
2015-10-23 18:10:18 +01:00
mnowster
5d60fbe31e Merge pull request #1659 from viranch/hostip-random-port
Allow scaling services that have port binding of the form `host_ip::container_port`
2015-10-23 17:11:28 +01:00
mnowster
e6f3946c17 Merge pull request #2239 from dnephin/fix_unicode_in_env
Fix unicode in environment variables for python2
2015-10-23 11:03:59 +01:00
moxiegirl
e2af02b158 Merge pull request #2238 from SvenDowideit/possible-link-fixes
Possible link fixes
2015-10-22 16:27:44 -07:00
Sven Dowideit
cf197253cd Possible link fixes
Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
2015-10-23 09:00:08 +10:00
Daniel Nephin
ae47435425 Fix unicode in environment variables for python2.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-22 12:12:43 -04:00
mnowster
6f78271b82 Merge pull request #2236 from dnephin/use_inspect_network
Use inspect network to query for an existing network
2015-10-22 13:37:27 +01:00
Daniel Nephin
cf40a38820 Merge pull request #2237 from dnephin/env_ci_storage_graph
Make storage driver configurable in CI
2015-10-21 16:29:40 -04:00
Daniel Nephin
f7100b2ef3 Change version check from engine version to api version.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-21 15:40:50 -04:00
Daniel Nephin
1bc3c97f2a Make storage driver configurable in CI
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-21 15:26:44 -04:00
Daniel Nephin
0fed5e6864 Use inspect network to query for an existing network.
And more tests for get_network()

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-21 13:05:14 -04:00
mnowster
c34a9f165d Merge pull request #2207 from dnephin/make_config_loader_immutable
Refactor of ServiceLoader to make it immutable
2015-10-21 17:14:40 +01:00
Daniel Nephin
b500fa2351 Refactor ServiceLoader to be immutable.
Mutable objects are harder to debug and harder to reason about. ServiceLoader was almost immutable. There was just a single function which set fields for a second function. Instead of mutating the object, we can pass those values as parameters to the next function.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-21 11:14:35 -04:00
Daniel Nephin
4505632274 Some minor style cleanup
- fixed a docstring to make it PEP257 compliant
- wrapped some long lines
- used a more specific error

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-21 11:13:00 -04:00
mnowster
fb69391889 Merge pull request #2233 from dnephin/some_unit_test_cleanup
Cleanup some unit tests and whitespace
2015-10-21 10:39:28 +01:00
mnowster
44e1fc3a32 Merge pull request #2230 from dnephin/lowercase_windows_drive
Lowercase windows drive letter
2015-10-21 10:36:46 +01:00
Daniel Nephin
b1f8ed84a3 Cleanup some unit tests and whitespace.
Remove some unnecessary newlines.
Remove a unittest that was attempting to test behaviour that was removed a while ago, so isn't testing anything.
Updated some unit tests to use mocks instead of a custom fake.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-20 14:23:56 -04:00
Daniel Nephin
5523c3d745 Minor refactor to use guard and replace instead of split+join
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-20 12:09:01 -04:00
Daniel Nephin
3f0e083585 Force windows drives to be lowercase.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-20 11:39:06 -04:00
mnowster
5ed9f9bdf7 Merge pull request #2206 from dnephin/fix_extends_from_second_file
extends must be copied from override file
2015-10-20 10:22:58 +01:00
Daniel Nephin
3725c3ab7e Merge pull request #2225 from mnowster/2221-blank-env-vars
2221 allow empty environment keys
2015-10-19 14:06:31 -04:00
Daniel Nephin
938d49cbdc Fixes #2205 - extends must be copied from override file.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-19 13:41:58 -04:00
mnowster
f1f3acd070 Merge pull request #2210 from dnephin/fix_empty_override
Properly validate files when multiple files are used
2015-10-19 18:32:48 +01:00
Daniel Nephin
937e087c6c Fixes #2203 - properly validate files when multiple files are used.
Remove the single-use decorators so the functionality can be used directly as a function.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-19 12:39:45 -04:00
Daniel Nephin
cd0b63879b Merge pull request #2208 from dnephin/another_release_script_fix
Fix check for tags in release script `make-branch`
2015-10-19 12:34:25 -04:00
Daniel Nephin
129e2f9482 Fix check for tags.
If there is a branch with the same name as a tag it fails without the
--tags. This was only a problem when we're branching from a git tag.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-19 12:33:25 -04:00
mnowster
a75bdfe11c Merge pull request #2220 from ticosax/trove-classifire
Add trove classifier to declare supported python versions.
2015-10-19 17:20:31 +01:00
Mazz Mosley
08add665e9 Environment keys can contain empty values
Environment keys that contain no value, get populated with values taken
from the environment not from the build phase but from running the command `up`.

Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-19 16:32:12 +01:00
mnowster
159cddf563 Merge pull request #2209 from dnephin/fix_error_on_invalid_yaml
Give the user a better error message when the yaml file is invalid
2015-10-19 16:29:36 +01:00
Daniel Nephin
076b5bc31c Merge pull request #2197 from sdurrheimer/zsh-completion-network-options
Add zsh completion for 'docker-compose --x-networking --x-network-dri…
2015-10-19 10:37:57 -04:00
Mazz Mosley
ff83c459d0 Improve error message for type constraints
It was missing a space between the different types, when there
were 3 possible type values.

Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-19 14:36:56 +01:00
Corin Lawson
4d8e667c3e Powershell script to run compose in a container.
This script assumes the typical environment that Windows users operate,
namely, VirtualBox running the boot2docker ISO, managed by
docker-machine. I wrote this script for my Windows using colleagues and
first placed it in the public domain as a gist:
https://gist.github.com/au-phiware/25213e72c80040f398ba
In short, that script works for me.

I have adapted that script to use the (yet to be) official image
(docker/compose:latest) and also added an extra environment variable to
provide additional options to docker run.

Signed-off-by: Corin Lawson <corin@phiware.com.au>
2015-10-19 22:32:35 +11:00
mnowster
1a97a8ef86 Merge pull request #2213 from viranch/trim-dockerfile
Trim Dockerfile
2015-10-19 12:08:20 +01:00
Steve Durrheimer
ac06366ef9 Add zsh completion for 'docker-compose --x-networking --x-network-driver'
Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com>
2015-10-19 12:31:17 +02:00
mnowster
bca018c50a Merge pull request #2211 from albers/completion-networking
bash completion for networking options
2015-10-19 11:23:03 +01:00
mnowster
2516aa8e08 Merge pull request #2212 from albers/completion-nospace
fix problem with bash completion in old bash
2015-10-19 11:22:44 +01:00
Nicolas Delaby
37921b40dd Add trove classifier to declare supported python versions.
Signed-off-by: Nicolas Delaby <nicolas.delaby@lock8.me>
2015-10-19 10:52:39 +02:00
Viranch Mehta
07e9f6500c Pipe curl's download directly to extract/execute program to reduce number of commands
Signed-off-by: Viranch Mehta <viranch.mehta@gmail.com>
2015-10-18 01:06:50 +05:30
Viranch Mehta
258c8bc54d Fix specifies_host_port() to handle port binding with host IP but no host port
Signed-off-by: Viranch Mehta <viranch.mehta@gmail.com>
2015-10-18 00:40:51 +05:30
Harald Albers
fa44a5fac2 fix problem with bash completion in old bash
Signed-off-by: Harald Albers <github@albersweb.de>
2015-10-17 09:51:37 -07:00
Harald Albers
43a89e1702 bash completion for networking options
Signed-off-by: Harald Albers <github@albersweb.de>
2015-10-17 09:30:53 -07:00
Daniel Nephin
ae3c66baed Merge pull request #2204 from mnowster/2123-escaping-env-variables
Attempt to document escaping env vars
2015-10-16 15:51:58 -04:00
Daniel Nephin
26dc0b785b Give the user a better error message (without a stack trace) when there is a yaml error.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-16 15:05:06 -04:00
mnowster
4b939d3560 Merge pull request #2199 from cweagans/1752-docker-compose-pull-service-nodeps
docker-compose pull SERVICE should not pull SERVICE's dependencies
2015-10-16 17:12:28 +01:00
mnowster
a712d828d4 Merge pull request #2200 from aanand/revert-tutorials
Revert networking-related changes to getting started guides
2015-10-16 17:06:31 +01:00
Mazz Mosley
7b109bc026 Attempt to document escaping env vars
People are likely to run into their env vars being set to empty strings,
if they're not aware that they need to escape them for Compose to not
interpolate them.

Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
2015-10-16 15:32:02 +01:00
mnowster
b0c895c5f5 Merge pull request #2193 from mrfuxi/less-verbose-extends-docs
Docs for shorthand notation of extends. Issue #1989
2015-10-16 10:25:10 +01:00
Aanand Prasad
1ed23fb2de Revert networking-related changes to getting started guides
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
2015-10-16 11:58:27 +05:30
Cameron Eagans
53fc6d06f6 docker-compose pull SERVICE should not pull SERVICE's dependencies
Signed-off-by: Cameron Eagans <me@cweagans.net>
2015-10-15 17:33:32 -06:00
Karol Duleba
ccfb6e6fa8 Docs for shorthand notation of extends. Issue #1989
Signed-off-by: Karol Duleba <mr.fuxi@gmail.com>
2015-10-15 22:17:13 +01:00
Daniel Nephin
8f840a55de Merge pull request #2194 from dnephin/update_release_docs
Update release docs
2015-10-15 15:40:13 -04:00
mnowster
4d8b184b14 Merge pull request #2196 from md2perpe/patch-1
Remove incorrectly placed comment
2015-10-15 15:31:49 +01:00
mnowster
971bfd403e Merge pull request #2195 from timbutler/master
Fix link to Release Process doc in README.md
2015-10-15 15:30:00 +01:00
Per Persson
c6ff81fe30 Remove incorrectly placed comment
I'm not sure if it should be there at all, but at least it should hardly be where it currently is located.

Signed-off-by: Per Persson <per.persson@exertisztorm.com>
2015-10-15 15:25:52 +02:00
Tim Butler
7e59a7ea32 Fix link to Release Process doc in README.md
Signed-off-by: Tim Butler <tim.butler.au@gmail.com>
2015-10-15 17:09:57 +10:00
Daniel Nephin
fbe8e76902 Add missing merge for release branch.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-14 15:24:05 -04:00
Daniel Nephin
58e6d4487a Fix some release docs.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-14 15:16:58 -04:00
Daniel Nephin
338f2f4507 Add a script to generate contributor list.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2015-10-14 15:14:04 -04:00
228 changed files with 17853 additions and 7693 deletions

3
.gitignore vendored
View file

@ -1,6 +1,6 @@
*.egg-info
*.pyc
/.coverage
.coverage*
/.tox
/build
/coverage-html
@ -8,3 +8,4 @@
/docs/_site
/venv
README.rst
compose/GITSHA

View file

@ -10,11 +10,16 @@
- id: end-of-file-fixer
- id: flake8
- id: name-tests-test
exclude: 'tests/integration/testcases.py'
exclude: 'tests/(integration/testcases\.py|helpers\.py)'
- id: requirements-txt-fixer
- id: trailing-whitespace
- repo: git://github.com/asottile/reorder_python_imports
sha: 3d86483455ab5bd06cc1069fdd5ac57be5463f10
sha: v0.1.0
hooks:
- id: reorder-python-imports
language_version: 'python2.7'
args:
- --add-import
- from __future__ import absolute_import
- --add-import
- from __future__ import unicode_literals

View file

@ -2,16 +2,14 @@ sudo: required
language: python
services:
- docker
matrix:
include:
- os: linux
services:
- docker
- os: osx
language: generic
install: ./script/travis/install
script:
@ -27,3 +25,5 @@ deploy:
key: '$BINTRAY_API_KEY'
file: ./bintray.json
skip_cleanup: true
on:
all_branches: true

View file

@ -1,7 +1,646 @@
Change log
==========
1.5.0 (2015-11-02)
1.11.0 (2017-02-08)
-------------------
### New Features
#### Compose file version 3.1
- Introduced version 3.1 of the `docker-compose.yml` specification. This
version requires Docker Engine 1.13.0 or above. It introduces support
for secrets. See the documentation for more information
#### Compose file version 2.0 and up
- Introduced the `docker-compose top` command that displays processes running
for the different services managed by Compose.
### Bugfixes
- Fixed a bug where extending a service defining a healthcheck dictionary
would cause `docker-compose` to error out.
- Fixed an issue where the `pid` entry in a service definition was being
ignored when using multiple Compose files.
1.10.1 (2017-02-01)
------------------
### Bugfixes
- Fixed an issue where presence of older versions of the docker-py
package would cause unexpected crashes while running Compose
- Fixed an issue where healthcheck dependencies would be lost when
using multiple compose files for a project
- Fixed a few issues that made the output of the `config` command
invalid
- Fixed an issue where adding volume labels to v3 Compose files would
result in an error
- Fixed an issue on Windows where build context paths containing unicode
characters were being improperly encoded
- Fixed a bug where Compose would occasionally crash while streaming logs
when containers would stop or restart
1.10.0 (2017-01-18)
-------------------
### New Features
#### Compose file version 3.0
- Introduced version 3.0 of the `docker-compose.yml` specification. This
version requires to be used with Docker Engine 1.13 or above and is
specifically designed to work with the `docker stack` commands.
#### Compose file version 2.1 and up
- Healthcheck configuration can now be done in the service definition using
the `healthcheck` parameter
- Containers dependencies can now be set up to wait on positive healthchecks
when declared using `depends_on`. See the documentation for the updated
syntax.
**Note:** This feature will not be ported to version 3 Compose files.
- Added support for the `sysctls` parameter in service definitions
- Added support for the `userns_mode` parameter in service definitions
- Compose now adds identifying labels to networks and volumes it creates
#### Compose file version 2.0 and up
- Added support for the `stop_grace_period` option in service definitions.
### Bugfixes
- Colored output now works properly on Windows.
- Fixed a bug where docker-compose run would fail to set up link aliases
in interactive mode on Windows.
- Networks created by Compose are now always made attachable
(Compose files v2.1 and up).
- Fixed a bug where falsy values of `COMPOSE_CONVERT_WINDOWS_PATHS`
(`0`, `false`, empty value) were being interpreted as true.
- Fixed a bug where forward slashes in some .dockerignore patterns weren't
being parsed correctly on Windows
1.9.0 (2016-11-16)
-----------------
**Breaking changes**
- When using Compose with Docker Toolbox/Machine on Windows, volume paths are
no longer converted from `C:\Users` to `/c/Users`-style by default. To
re-enable this conversion so that your volumes keep working, set the
environment variable `COMPOSE_CONVERT_WINDOWS_PATHS=1`. Users of
Docker for Windows are not affected and do not need to set the variable.
New Features
- Interactive mode for `docker-compose run` and `docker-compose exec` is
now supported on Windows platforms. Please note that the `docker` binary
is required to be present on the system for this feature to work.
- Introduced version 2.1 of the `docker-compose.yml` specification. This
version requires to be used with Docker Engine 1.12 or above.
- Added support for setting volume labels and network labels in
`docker-compose.yml`.
- Added support for the `isolation` parameter in service definitions.
- Added support for link-local IPs in the service networks definitions.
- Added support for shell-style inline defaults in variable interpolation.
The supported forms are `${FOO-default}` (fall back if FOO is unset) and
`${FOO:-default}` (fall back if FOO is unset or empty).
- Added support for the `group_add` and `oom_score_adj` parameters in
service definitions.
- Added support for the `internal` and `enable_ipv6` parameters in network
definitions.
- Compose now defaults to using the `npipe` protocol on Windows.
- Overriding a `logging` configuration will now properly merge the `options`
mappings if the `driver` values do not conflict.
Bug Fixes
- Fixed several bugs related to `npipe` protocol support on Windows.
- Fixed an issue with Windows paths being incorrectly converted when
using Docker on Windows Server.
- Fixed a bug where an empty `restart` value would sometimes result in an
exception being raised.
- Fixed an issue where service logs containing unicode characters would
sometimes cause an error to occur.
- Fixed a bug where unicode values in environment variables would sometimes
raise a unicode exception when retrieved.
- Fixed an issue where Compose would incorrectly detect a configuration
mismatch for overlay networks.
1.8.1 (2016-09-22)
-----------------
Bug Fixes
- Fixed a bug where users using a credentials store were not able
to access their private images.
- Fixed a bug where users using identity tokens to authenticate
were not able to access their private images.
- Fixed a bug where an `HttpHeaders` entry in the docker configuration
file would cause Compose to crash when trying to build an image.
- Fixed a few bugs related to the handling of Windows paths in volume
binding declarations.
- Fixed a bug where Compose would sometimes crash while trying to
read a streaming response from the engine.
- Fixed an issue where Compose would crash when encountering an API error
while streaming container logs.
- Fixed an issue where Compose would erroneously try to output logs from
drivers not handled by the Engine's API.
- Fixed a bug where options from the `docker-machine config` command would
not be properly interpreted by Compose.
- Fixed a bug where the connection to the Docker Engine would
sometimes fail when running a large number of services simultaneously.
- Fixed an issue where Compose would sometimes print a misleading
suggestion message when running the `bundle` command.
- Fixed a bug where connection errors would not be handled properly by
Compose during the project initialization phase.
- Fixed a bug where a misleading error would appear when encountering
a connection timeout.
1.8.0 (2016-06-14)
-----------------
**Breaking Changes**
- As announced in 1.7.0, `docker-compose rm` now removes containers
created by `docker-compose run` by default.
- Setting `entrypoint` on a service now empties out any default
command that was set on the image (i.e. any `CMD` instruction in the
Dockerfile used to build it). This makes it consistent with
the `--entrypoint` flag to `docker run`.
New Features
- Added `docker-compose bundle`, a command that builds a bundle file
to be consumed by the new *Docker Stack* commands in Docker 1.12.
- Added `docker-compose push`, a command that pushes service images
to a registry.
- Compose now supports specifying a custom TLS version for
interaction with the Docker Engine using the `COMPOSE_TLS_VERSION`
environment variable.
Bug Fixes
- Fixed a bug where Compose would erroneously try to read `.env`
at the project's root when it is a directory.
- `docker-compose run -e VAR` now passes `VAR` through from the shell
to the container, as with `docker run -e VAR`.
- Improved config merging when multiple compose files are involved
for several service sub-keys.
- Fixed a bug where volume mappings containing Windows drives would
sometimes be parsed incorrectly.
- Fixed a bug in Windows environment where volume mappings of the
host's root directory would be parsed incorrectly.
- Fixed a bug where `docker-compose config` would output an invalid
Compose file if external networks were specified.
- Fixed an issue where unset buildargs would be assigned a string
containing `'None'` instead of the expected empty value.
- Fixed a bug where yes/no prompts on Windows would not show before
receiving input.
- Fixed a bug where trying to `docker-compose exec` on Windows
without the `-d` option would exit with a stacktrace. This will
still fail for the time being, but should do so gracefully.
- Fixed a bug where errors during `docker-compose up` would show
an unrelated stacktrace at the end of the process.
- `docker-compose create` and `docker-compose start` show more
descriptive error messages when something goes wrong.
1.7.1 (2016-05-04)
-----------------
Bug Fixes
- Fixed a bug where the output of `docker-compose config` for v1 files
would be an invalid configuration file.
- Fixed a bug where `docker-compose config` would not check the validity
of links.
- Fixed an issue where `docker-compose help` would not output a list of
available commands and generic options as expected.
- Fixed an issue where filtering by service when using `docker-compose logs`
would not apply for newly created services.
- Fixed a bug where unchanged services would sometimes be recreated in
in the up phase when using Compose with Python 3.
- Fixed an issue where API errors encountered during the up phase would
not be recognized as a failure state by Compose.
- Fixed a bug where Compose would raise a NameError because of an undefined
exception name on non-Windows platforms.
- Fixed a bug where the wrong version of `docker-py` would sometimes be
installed alongside Compose.
- Fixed a bug where the host value output by `docker-machine config default`
would not be recognized as valid options by the `docker-compose`
command line.
- Fixed an issue where Compose would sometimes exit unexpectedly while
reading events broadcasted by a Swarm cluster.
- Corrected a statement in the docs about the location of the `.env` file,
which is indeed read from the current directory, instead of in the same
location as the Compose file.
1.7.0 (2016-04-13)
------------------
**Breaking Changes**
- `docker-compose logs` no longer follows log output by default. It now
matches the behaviour of `docker logs` and exits after the current logs
are printed. Use `-f` to get the old default behaviour.
- Booleans are no longer allows as values for mappings in the Compose file
(for keys `environment`, `labels` and `extra_hosts`). Previously this
was a warning. Boolean values should be quoted so they become string values.
New Features
- Compose now looks for a `.env` file in the directory where it's run and
reads any environment variables defined inside, if they're not already
set in the shell environment. This lets you easily set defaults for
variables used in the Compose file, or for any of the `COMPOSE_*` or
`DOCKER_*` variables.
- Added a `--remove-orphans` flag to both `docker-compose up` and
`docker-compose down` to remove containers for services that were removed
from the Compose file.
- Added a `--all` flag to `docker-compose rm` to include containers created
by `docker-compose run`. This will become the default behavior in the next
version of Compose.
- Added support for all the same TLS configuration flags used by the `docker`
client: `--tls`, `--tlscert`, `--tlskey`, etc.
- Compose files now support the `tmpfs` and `shm_size` options.
- Added the `--workdir` flag to `docker-compose run`
- `docker-compose logs` now shows logs for new containers that are created
after it starts.
- The `COMPOSE_FILE` environment variable can now contain multiple files,
separated by the host system's standard path separator (`:` on Mac/Linux,
`;` on Windows).
- You can now specify a static IP address when connecting a service to a
network with the `ipv4_address` and `ipv6_address` options.
- Added `--follow`, `--timestamp`, and `--tail` flags to the
`docker-compose logs` command.
- `docker-compose up`, and `docker-compose start` will now start containers
in parallel where possible.
- `docker-compose stop` now stops containers in reverse dependency order
instead of all at once.
- Added the `--build` flag to `docker-compose up` to force it to build a new
image. It now shows a warning if an image is automatically built when the
flag is not used.
- Added the `docker-compose exec` command for executing a process in a running
container.
Bug Fixes
- `docker-compose down` now removes containers created by
`docker-compose run`.
- A more appropriate error is shown when a timeout is hit during `up` when
using a tty.
- Fixed a bug in `docker-compose down` where it would abort if some resources
had already been removed.
- Fixed a bug where changes to network aliases would not trigger a service
to be recreated.
- Fix a bug where a log message was printed about creating a new volume
when it already existed.
- Fixed a bug where interrupting `up` would not always shut down containers.
- Fixed a bug where `log_opt` and `log_driver` were not properly carried over
when extending services in the v1 Compose file format.
- Fixed a bug where empty values for build args would cause file validation
to fail.
1.6.2 (2016-02-23)
------------------
- Fixed a bug where connecting to a TLS-enabled Docker Engine would fail with
a certificate verification error.
1.6.1 (2016-02-23)
------------------
Bug Fixes
- Fixed a bug where recreating a container multiple times would cause the
new container to be started without the previous volumes.
- Fixed a bug where Compose would set the value of unset environment variables
to an empty string, instead of a key without a value.
- Provide a better error message when Compose requires a more recent version
of the Docker API.
- Add a missing config field `network.aliases` which allows setting a network
scoped alias for a service.
- Fixed a bug where `run` would not start services listed in `depends_on`.
- Fixed a bug where `networks` and `network_mode` where not merged when using
extends or multiple Compose files.
- Fixed a bug with service aliases where the short container id alias was
only contained 10 characters, instead of the 12 characters used in previous
versions.
- Added a missing log message when creating a new named volume.
- Fixed a bug where `build.args` was not merged when using `extends` or
multiple Compose files.
- Fixed some bugs with config validation when null values or incorrect types
were used instead of a mapping.
- Fixed a bug where a `build` section without a `context` would show a stack
trace instead of a helpful validation message.
- Improved compatibility with swarm by only setting a container affinity to
the previous instance of a services' container when the service uses an
anonymous container volume. Previously the affinity was always set on all
containers.
- Fixed the validation of some `driver_opts` would cause an error if a number
was used instead of a string.
- Some improvements to the `run.sh` script used by the Compose container install
option.
- Fixed a bug with `up --abort-on-container-exit` where Compose would exit,
but would not stop other containers.
- Corrected the warning message that is printed when a boolean value is used
as a value in a mapping.
1.6.0 (2016-01-15)
------------------
Major Features:
- Compose 1.6 introduces a new format for `docker-compose.yml` which lets
you define networks and volumes in the Compose file as well as services. It
also makes a few changes to the structure of some configuration options.
You don't have to use it - your existing Compose files will run on Compose
1.6 exactly as they do today.
Check the upgrade guide for full details:
https://docs.docker.com/compose/compose-file#upgrading
- Support for networking has exited experimental status and is the recommended
way to enable communication between containers.
If you use the new file format, your app will use networking. If you aren't
ready yet, just leave your Compose file as it is and it'll continue to work
just the same.
By default, you don't have to configure any networks. In fact, using
networking with Compose involves even less configuration than using links.
Consult the networking guide for how to use it:
https://docs.docker.com/compose/networking
The experimental flags `--x-networking` and `--x-network-driver`, introduced
in Compose 1.5, have been removed.
- You can now pass arguments to a build if you're using the new file format:
build:
context: .
args:
buildno: 1
- You can now specify both a `build` and an `image` key if you're using the
new file format. `docker-compose build` will build the image and tag it with
the name you've specified, while `docker-compose pull` will attempt to pull
it.
- There's a new `events` command for monitoring container events from
the application, much like `docker events`. This is a good primitive for
building tools on top of Compose for performing actions when particular
things happen, such as containers starting and stopping.
- There's a new `depends_on` option for specifying dependencies between
services. This enforces the order of startup, and ensures that when you run
`docker-compose up SERVICE` on a service with dependencies, those are started
as well.
New Features:
- Added a new command `config` which validates and prints the Compose
configuration after interpolating variables, resolving relative paths, and
merging multiple files and `extends`.
- Added a new command `create` for creating containers without starting them.
- Added a new command `down` to stop and remove all the resources created by
`up` in a single command.
- Added support for the `cpu_quota` configuration option.
- Added support for the `stop_signal` configuration option.
- Commands `start`, `restart`, `pause`, and `unpause` now exit with an
error status code if no containers were modified.
- Added a new `--abort-on-container-exit` flag to `up` which causes `up` to
stop all container and exit once the first container exits.
- Removed support for `FIG_FILE`, `FIG_PROJECT_NAME`, and no longer reads
`fig.yml` as a default Compose file location.
- Removed the `migrate-to-labels` command.
- Removed the `--allow-insecure-ssl` flag.
Bug Fixes:
- Fixed a validation bug that prevented the use of a range of ports in
the `expose` field.
- Fixed a validation bug that prevented the use of arrays in the `entrypoint`
field if they contained duplicate entries.
- Fixed a bug that caused `ulimits` to be ignored when used with `extends`.
- Fixed a bug that prevented ipv6 addresses in `extra_hosts`.
- Fixed a bug that caused `extends` to be ignored when included from
multiple Compose files.
- Fixed an incorrect warning when a container volume was defined in
the Compose file.
- Fixed a bug that prevented the force shutdown behaviour of `up` and
`logs`.
- Fixed a bug that caused `None` to be printed as the network driver name
when the default network driver was used.
- Fixed a bug where using the string form of `dns` or `dns_search` would
cause an error.
- Fixed a bug where a container would be reported as "Up" when it was
in the restarting state.
- Fixed a confusing error message when DOCKER_CERT_PATH was not set properly.
- Fixed a bug where attaching to a container would fail if it was using a
non-standard logging driver (or none at all).
1.5.2 (2015-12-03)
------------------
- Fixed a bug which broke the use of `environment` and `env_file` with
`extends`, and caused environment keys without values to have a `None`
value, instead of a value from the host environment.
- Fixed a regression in 1.5.1 that caused a warning about volumes to be
raised incorrectly when containers were recreated.
- Fixed a bug which prevented building a `Dockerfile` that used `ADD <url>`
- Fixed a bug with `docker-compose restart` which prevented it from
starting stopped containers.
- Fixed handling of SIGTERM and SIGINT to properly stop containers
- Add support for using a url as the value of `build`
- Improved the validation of the `expose` option
1.5.1 (2015-11-12)
------------------
- Add the `--force-rm` option to `build`.
- Add the `ulimit` option for services in the Compose file.
- Fixed a bug where `up` would error with "service needs to be built" if
a service changed from using `image` to using `build`.
- Fixed a bug that would cause incorrect output of parallel operations
on some terminals.
- Fixed a bug that prevented a container from being recreated when the
mode of a `volumes_from` was changed.
- Fixed a regression in 1.5.0 where non-utf-8 unicode characters would cause
`up` or `logs` to crash.
- Fixed a regression in 1.5.0 where Compose would use a success exit status
code when a command fails due to an HTTP timeout communicating with the
docker daemon.
- Fixed a regression in 1.5.0 where `name` was being accepted as a valid
service option which would override the actual name of the service.
- When using `--x-networking` Compose no longer sets the hostname to the
container name.
- When using `--x-networking` Compose will only create the default network
if at least one container is using the network.
- When printings logs during `up` or `logs`, flush the output buffer after
each line to prevent buffering issues from hiding logs.
- Recreate a container if one of its dependencies is being created.
Previously a container was only recreated if it's dependencies already
existed, but were being recreated as well.
- Add a warning when a `volume` in the Compose file is being ignored
and masked by a container volume from a previous container.
- Improve the output of `pull` when run without a tty.
- When using multiple Compose files, validate each before attempting to merge
them together. Previously invalid files would result in not helpful errors.
- Allow dashes in keys in the `environment` service option.
- Improve validation error messages by including the filename as part of the
error message.
1.5.0 (2015-11-03)
------------------
**Breaking changes:**
@ -102,7 +741,6 @@ Bug fixes:
- `docker-compose build` can now be run successfully against a Swarm cluster.
1.4.2 (2015-09-22)
------------------
@ -227,8 +865,8 @@ Several new configuration keys have been added to `docker-compose.yml`:
- `pid: host`, like `docker run --pid=host`, lets you reuse the same PID namespace as the host machine.
- `cpuset`, like `docker run --cpuset-cpus`, lets you specify which CPUs to allow execution in.
- `read_only`, like `docker run --read-only`, lets you mount a container's filesystem as read-only.
- `security_opt`, like `docker run --security-opt`, lets you specify [security options](https://docs.docker.com/reference/run/#security-configuration).
- `log_driver`, like `docker run --log-driver`, lets you specify a [log driver](https://docs.docker.com/reference/run/#logging-drivers-log-driver).
- `security_opt`, like `docker run --security-opt`, lets you specify [security options](https://docs.docker.com/engine/reference/run/#security-configuration).
- `log_driver`, like `docker run --log-driver`, lets you specify a [log driver](https://docs.docker.com/engine/reference/run/#logging-drivers-log-driver).
Many bugs have been fixed, including the following:
@ -271,7 +909,7 @@ Fig has been renamed to Docker Compose, or just Compose for short. This has seve
- The command you type is now `docker-compose`, not `fig`.
- You should rename your fig.yml to docker-compose.yml.
- If you’re installing via PyPi, the package is now `docker-compose`, so install it with `pip install docker-compose`.
- If you’re installing via PyPI, the package is now `docker-compose`, so install it with `pip install docker-compose`.
Besides that, there’s a lot of new stuff in this release:

View file

@ -35,7 +35,7 @@ that should get you started.
This step is optional, but recommended. Pre-commit hooks will run style checks
and in some cases fix style issues for you, when you commit code.
Install the git pre-commit hooks using [tox](https://tox.readthedocs.org) by
Install the git pre-commit hooks using [tox](https://tox.readthedocs.io) by
running `tox -e pre-commit` or by following the
[pre-commit install guide](http://pre-commit.com/#install).
@ -43,29 +43,29 @@ To run the style checks at any time run `tox -e pre-commit`.
## Submitting a pull request
See Docker's [basic contribution workflow](https://docs.docker.com/project/make-a-contribution/#the-basic-contribution-workflow) for a guide on how to submit a pull request for code or documentation.
See Docker's [basic contribution workflow](https://docs.docker.com/opensource/workflow/make-a-contribution/#the-basic-contribution-workflow) for a guide on how to submit a pull request for code or documentation.
## Running the test suite
Use the test script to run linting checks and then the full test suite against
different Python interpreters:
$ script/test
$ script/test/default
Tests are run against a Docker daemon inside a container, so that we can test
against multiple Docker versions. By default they'll run against only the latest
Docker version - set the `DOCKER_VERSIONS` environment variable to "all" to run
against all supported versions:
$ DOCKER_VERSIONS=all script/test
$ DOCKER_VERSIONS=all script/test/default
Arguments to `script/test` are passed through to the `nosetests` executable, so
Arguments to `script/test/default` are passed through to the `tox` executable, so
you can specify a test directory, file, module, class or method:
$ script/test tests/unit
$ script/test tests/unit/cli_test.py
$ script/test tests/unit/config_test.py::ConfigTest
$ script/test tests/unit/config_test.py::ConfigTest::test_load
$ script/test/default tests/unit
$ script/test/default tests/unit/cli_test.py
$ script/test/default tests/unit/config_test.py::ConfigTest
$ script/test/default tests/unit/config_test.py::ConfigTest::test_load
## Finding things to work on

View file

@ -13,55 +13,40 @@ RUN set -ex; \
ca-certificates \
curl \
libsqlite3-dev \
libbz2-dev \
; \
rm -rf /var/lib/apt/lists/*
RUN curl https://get.docker.com/builds/Linux/x86_64/docker-latest \
RUN curl https://get.docker.com/builds/Linux/x86_64/docker-1.8.3 \
-o /usr/local/bin/docker && \
chmod +x /usr/local/bin/docker
# Build Python 2.7.9 from source
# Build Python 2.7.13 from source
RUN set -ex; \
curl -LO https://www.python.org/ftp/python/2.7.9/Python-2.7.9.tgz; \
tar -xzf Python-2.7.9.tgz; \
cd Python-2.7.9; \
curl -L https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tgz | tar -xz; \
cd Python-2.7.13; \
./configure --enable-shared; \
make; \
make install; \
cd ..; \
rm -rf /Python-2.7.9; \
rm Python-2.7.9.tgz
rm -rf /Python-2.7.13
# Build python 3.4 from source
RUN set -ex; \
curl -LO https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tgz; \
tar -xzf Python-3.4.3.tgz; \
cd Python-3.4.3; \
curl -L https://www.python.org/ftp/python/3.4.6/Python-3.4.6.tgz | tar -xz; \
cd Python-3.4.6; \
./configure --enable-shared; \
make; \
make install; \
cd ..; \
rm -rf /Python-3.4.3; \
rm Python-3.4.3.tgz
rm -rf /Python-3.4.6
# Make libpython findable
ENV LD_LIBRARY_PATH /usr/local/lib
# Install setuptools
RUN set -ex; \
curl -LO https://bootstrap.pypa.io/ez_setup.py; \
python ez_setup.py; \
rm ez_setup.py
# Install pip
RUN set -ex; \
curl -LO https://pypi.python.org/packages/source/p/pip/pip-7.0.1.tar.gz; \
tar -xzf pip-7.0.1.tar.gz; \
cd pip-7.0.1; \
python setup.py install; \
cd ..; \
rm -rf pip-7.0.1; \
rm pip-7.0.1.tar.gz
curl -L https://bootstrap.pypa.io/get-pip.py | python
# Python3 requires a valid locale
RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen

View file

@ -1,5 +1,6 @@
FROM alpine:edge
FROM alpine:3.4
ARG version
RUN apk -U add \
python \
py-pip
@ -7,7 +8,7 @@ RUN apk -U add \
COPY requirements.txt /code/requirements.txt
RUN pip install -r /code/requirements.txt
ADD dist/docker-compose-release.tar.gz /code/docker-compose
RUN pip install /code/docker-compose/docker-compose-*
COPY dist/docker_compose-${version}-py2.py3-none-any.whl /code/
RUN pip install --no-deps /code/docker_compose-${version}-py2.py3-none-any.whl
ENTRYPOINT ["/usr/bin/docker-compose"]

64
Jenkinsfile vendored Normal file
View file

@ -0,0 +1,64 @@
#!groovy
def image
def buildImage = { ->
wrappedNode(label: "ubuntu && !zfs", cleanWorkspace: true) {
stage("build image") {
checkout(scm)
def imageName = "dockerbuildbot/compose:${gitCommit()}"
image = docker.image(imageName)
try {
image.pull()
} catch (Exception exc) {
image = docker.build(imageName, ".")
image.push()
}
}
}
}
def runTests = { Map settings ->
def dockerVersions = settings.get("dockerVersions", null)
def pythonVersions = settings.get("pythonVersions", null)
if (!pythonVersions) {
throw new Exception("Need Python versions to test. e.g.: `runTests(pythonVersions: 'py27,py34')`")
}
if (!dockerVersions) {
throw new Exception("Need Docker versions to test. e.g.: `runTests(dockerVersions: 'all')`")
}
{ ->
wrappedNode(label: "ubuntu && !zfs", cleanWorkspace: true) {
stage("test python=${pythonVersions} / docker=${dockerVersions}") {
checkout(scm)
def storageDriver = sh(script: 'docker info | awk -F \': \' \'$1 == "Storage Driver" { print $2; exit }\'', returnStdout: true).trim()
echo "Using local system's storage driver: ${storageDriver}"
sh """docker run \\
-t \\
--rm \\
--privileged \\
--volume="\$(pwd)/.git:/code/.git" \\
--volume="/var/run/docker.sock:/var/run/docker.sock" \\
-e "TAG=${image.id}" \\
-e "STORAGE_DRIVER=${storageDriver}" \\
-e "DOCKER_VERSIONS=${dockerVersions}" \\
-e "BUILD_NUMBER=\$BUILD_TAG" \\
-e "PY_TEST_VERSIONS=${pythonVersions}" \\
--entrypoint="script/ci" \\
${image.id} \\
--verbose
"""
}
}
}
}
buildImage()
// TODO: break this out into meaningful "DOCKER_VERSIONS" values instead of all
parallel(
failFast: true,
all_py27: runTests(pythonVersions: "py27", dockerVersions: "all"),
all_py34: runTests(pythonVersions: "py34", dockerVersions: "all"),
)

View file

@ -1,4 +1,46 @@
Aanand Prasad <aanand.prasad@gmail.com> (@aanand)
Ben Firshman <ben@firshman.co.uk> (@bfirsh)
Daniel Nephin <dnephin@gmail.com> (@dnephin)
Mazz Mosley <mazz@houseofmnowster.com> (@mnowster)
# Compose maintainers file
#
# This file describes who runs the docker/compose project and how.
# This is a living document - if you see something out of date or missing, speak up!
#
# It is structured to be consumable by both humans and programs.
# To extract its contents programmatically, use any TOML-compliant parser.
#
# This file is compiled into the MAINTAINERS file in docker/opensource.
#
[Org]
[Org."Core maintainers"]
people = [
"aanand",
"bfirsh",
"dnephin",
"mnowster",
]
[people]
# A reference list of all people associated with the project.
# All other sections should refer to people by their canonical key
# in the people section.
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
[people.aanand]
Name = "Aanand Prasad"
Email = "aanand.prasad@gmail.com"
GitHub = "aanand"
[people.bfirsh]
Name = "Ben Firshman"
Email = "ben@firshman.co.uk"
GitHub = "bfirsh"
[people.dnephin]
Name = "Daniel Nephin"
Email = "dnephin@gmail.com"
GitHub = "dnephin"
[people.mnowster]
Name = "Mazz Mosley"
Email = "mazz@houseofmnowster.com"
GitHub = "mnowster"

View file

@ -7,6 +7,7 @@ include *.md
exclude README.md
include README.rst
include compose/config/*.json
include compose/GITSHA
recursive-include contrib/completion *
recursive-include tests *
global-exclude *.pyc

View file

@ -2,15 +2,15 @@ Docker Compose
==============
![Docker Compose](logo.png?raw=true "Docker Compose Logo")
*(Previously known as Fig)*
Compose is a tool for defining and running multi-container Docker applications.
With Compose, you use a Compose file to configure your application's services.
Then, using a single command, you create and start all the services
from your configuration. To learn more about all the features of Compose
see [the list of features](https://github.com/docker/docker.github.io/blob/master/compose/overview.md#features).
Compose is a tool for defining and running multi-container 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.
Compose is great for development environments, staging servers, and CI. We don't
recommend that you use it in production yet.
Compose is great for development, testing, and staging environments, as well as
CI workflows. You can learn more about each case in
[Common Use Cases](https://github.com/docker/docker.github.io/blob/master/compose/overview.md#common-use-cases).
Using Compose is basically a three-step process.
@ -22,17 +22,21 @@ they can be run together in an isolated environment:
A `docker-compose.yml` looks like this:
version: '2'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
links:
- redis
redis:
image: redis
For more information about the Compose file, see the
[Compose file reference](https://github.com/docker/docker.github.io/blob/master/compose/compose-file/compose-versioning.md)
Compose has commands for managing the whole lifecycle of your application:
* Start, stop and rebuild services
@ -43,8 +47,10 @@ Compose has commands for managing the whole lifecycle of your application:
Installation and documentation
------------------------------
- Full documentation is available on [Docker's website](http://docs.docker.com/compose/).
- Full documentation is available on [Docker's website](https://docs.docker.com/compose/).
- If you have any questions, you can talk in real-time with other developers in the #docker-compose IRC channel on Freenode. [Click here to join using IRCCloud.](https://www.irccloud.com/invite?hostname=irc.freenode.net&channel=%23docker-compose)
- Code repository for Compose is on [Github](https://github.com/docker/compose)
- If you find any problems please fill out an [issue](https://github.com/docker/compose/issues/new)
Contributing
------------

View file

@ -1,13 +1,21 @@
# Roadmap
## An even better tool for development environments
Compose is a great tool for development environments, but it could be even better. For example:
- It should be possible to define hostnames for containers which work from the host machine, e.g. “mywebcontainer.local”. This is needed by apps comprising multiple web services which generate links to one another (e.g. a frontend website and a separate admin webapp)
## More than just development environments
Over time we will extend Compose's remit to cover test, staging and production environments. This is not a simple task, and will take many incremental improvements such as:
Compose currently works really well in development, but we want to make the Compose file format better for test, staging, and production environments. To support these use cases, there will need to be improvements to the file format, improvements to the command-line tool, integrations with other tools, and perhaps new tools altogether.
Some specific things we are considering:
- Compose currently will attempt to get your application into the correct state when running `up`, but it has a number of shortcomings:
- It should roll back to a known good state if it fails.
- It should allow a user to check the actions it is about to perform before running them.
- It should be possible to partially modify the config file for different environments (dev/test/staging/prod), passing in e.g. custom ports or volume mount paths. ([#1377](https://github.com/docker/compose/issues/1377))
- It should be possible to partially modify the config file for different environments (dev/test/staging/prod), passing in e.g. custom ports, volume mount paths, or volume drivers. ([#1377](https://github.com/docker/compose/issues/1377))
- Compose should recommend a technique for zero-downtime deploys.
- It should be possible to continuously attempt to keep an application in the correct state, instead of just performing `up` a single time.
@ -22,10 +30,3 @@ The current state of integration is documented in [SWARM.md](SWARM.md).
Compose works well for applications that are in a single repository and depend on services that are hosted on Docker Hub. If your application depends on another application within your organisation, Compose doesn't work as well.
There are several ideas about how this could work, such as [including external files](https://github.com/docker/fig/issues/318).
## An even better tool for development environments
Compose is a great tool for development environments, but it could be even better. For example:
- [Compose could watch your code and automatically kick off builds when something changes.](https://github.com/docker/fig/issues/184)
- It should be possible to define hostnames for containers which work from the host machine, e.g. “mywebcontainer.local”. This is needed by apps comprising multiple web services which generate links to one another (e.g. a frontend website and a separate admin webapp)

View file

@ -1,39 +1 @@
Docker Compose/Swarm integration
================================
Eventually, Compose and Swarm aim to have full integration, meaning you can point a Compose app at a Swarm cluster and have it all just work as if you were using a single Docker host.
However, integration is currently incomplete: Compose can create containers on a Swarm cluster, but the majority of Compose apps won’t work out of the box unless all containers are scheduled on one host, because links between containers do not work across hosts.
Docker networking is [getting overhauled](https://github.com/docker/libnetwork) in such a way that it’ll fit the multi-host model much better. For now, linked containers are automatically scheduled on the same host.
Building
--------
Swarm can build an image from a Dockerfile just like a single-host Docker instance can, but the resulting image will only live on a single node and won't be distributed to other nodes.
If you want to use Compose to scale the service in question to multiple nodes, you'll have to build it yourself, push it to a registry (e.g. the Docker Hub) and reference it from `docker-compose.yml`:
$ docker build -t myusername/web .
$ docker push myusername/web
$ cat docker-compose.yml
web:
image: myusername/web
$ docker-compose up -d
$ docker-compose scale web=3
Scheduling
----------
Swarm offers a rich set of scheduling and affinity hints, enabling you to control where containers are located. They are specified via container environment variables, so you can use Compose's `environment` option to set them.
environment:
# Schedule containers on a node that has the 'storage' label set to 'ssd'
- "constraint:storage==ssd"
# Schedule containers where the 'redis' image is already pulled
- "affinity:image==redis"
For the full set of available filters and expressions, see the [Swarm documentation](https://docs.docker.com/swarm/scheduler/filter/).
This file has moved to: https://docs.docker.com/compose/swarm/

View file

@ -9,20 +9,16 @@ install:
# Build the binary after tests
build: false
environment:
BINTRAY_USER: "docker-compose-roleuser"
BINTRAY_PATH: "docker-compose/master/windows/master/docker-compose-Windows-x86_64.exe"
test_script:
- "tox -e py27,py34 -- tests/unit"
- ps: ".\\script\\build-windows.ps1"
deploy_script:
- "curl -sS
-u \"%BINTRAY_USER%:%BINTRAY_API_KEY%\"
-X PUT \"https://api.bintray.com/content/%BINTRAY_PATH%?override=1&publish=1\"
--data-binary @dist\\docker-compose-Windows-x86_64.exe"
- ps: ".\\script\\build\\windows.ps1"
artifacts:
- path: .\dist\docker-compose-Windows-x86_64.exe
name: "Compose Windows binary"
deploy:
- provider: Environment
name: master-builds
on:
branch: master

View file

@ -1,3 +1,4 @@
from __future__ import absolute_import
from __future__ import unicode_literals
__version__ = '1.5.0rc3'
__version__ = '1.12.0dev'

6
compose/__main__.py Normal file
View file

@ -0,0 +1,6 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from compose.cli.main import main
main()

258
compose/bundle.py Normal file
View file

@ -0,0 +1,258 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import json
import logging
import six
from docker.utils import split_command
from docker.utils.ports import split_port
from .cli.errors import UserError
from .config.serialize import denormalize_config
from .network import get_network_defs_for_service
from .service import format_environment
from .service import NoSuchImageError
from .service import parse_repository_tag
log = logging.getLogger(__name__)
SERVICE_KEYS = {
'working_dir': 'WorkingDir',
'user': 'User',
'labels': 'Labels',
}
IGNORED_KEYS = {'build'}
SUPPORTED_KEYS = {
'image',
'ports',
'expose',
'networks',
'command',
'environment',
'entrypoint',
} | set(SERVICE_KEYS)
VERSION = '0.1'
class NeedsPush(Exception):
def __init__(self, image_name):
self.image_name = image_name
class NeedsPull(Exception):
def __init__(self, image_name, service_name):
self.image_name = image_name
self.service_name = service_name
class MissingDigests(Exception):
def __init__(self, needs_push, needs_pull):
self.needs_push = needs_push
self.needs_pull = needs_pull
def serialize_bundle(config, image_digests):
return json.dumps(to_bundle(config, image_digests), indent=2, sort_keys=True)
def get_image_digests(project, allow_push=False):
digests = {}
needs_push = set()
needs_pull = set()
for service in project.services:
try:
digests[service.name] = get_image_digest(
service,
allow_push=allow_push,
)
except NeedsPush as e:
needs_push.add(e.image_name)
except NeedsPull as e:
needs_pull.add(e.service_name)
if needs_push or needs_pull:
raise MissingDigests(needs_push, needs_pull)
return digests
def get_image_digest(service, allow_push=False):
if 'image' not in service.options:
raise UserError(
"Service '{s.name}' doesn't define an image tag. An image name is "
"required to generate a proper image digest for the bundle. Specify "
"an image repo and tag with the 'image' option.".format(s=service))
_, _, separator = parse_repository_tag(service.options['image'])
# Compose file already uses a digest, no lookup required
if separator == '@':
return service.options['image']
try:
image = service.image()
except NoSuchImageError:
action = 'build' if 'build' in service.options else 'pull'
raise UserError(
"Image not found for service '{service}'. "
"You might need to run `docker-compose {action} {service}`."
.format(service=service.name, action=action))
if image['RepoDigests']:
# TODO: pick a digest based on the image tag if there are multiple
# digests
return image['RepoDigests'][0]
if 'build' not in service.options:
raise NeedsPull(service.image_name, service.name)
if not allow_push:
raise NeedsPush(service.image_name)
return push_image(service)
def push_image(service):
try:
digest = service.push()
except:
log.error(
"Failed to push image for service '{s.name}'. Please use an "
"image tag that can be pushed to a Docker "
"registry.".format(s=service))
raise
if not digest:
raise ValueError("Failed to get digest for %s" % service.name)
repo, _, _ = parse_repository_tag(service.options['image'])
identifier = '{repo}@{digest}'.format(repo=repo, digest=digest)
# only do this if RepoDigests isn't already populated
image = service.image()
if not image['RepoDigests']:
# Pull by digest so that image['RepoDigests'] is populated for next time
# and we don't have to pull/push again
service.client.pull(identifier)
log.info("Stored digest for {}".format(service.image_name))
return identifier
def to_bundle(config, image_digests):
if config.networks:
log.warn("Unsupported top level key 'networks' - ignoring")
if config.volumes:
log.warn("Unsupported top level key 'volumes' - ignoring")
config = denormalize_config(config)
return {
'Version': VERSION,
'Services': {
name: convert_service_to_bundle(
name,
service_dict,
image_digests[name],
)
for name, service_dict in config['services'].items()
},
}
def convert_service_to_bundle(name, service_dict, image_digest):
container_config = {'Image': image_digest}
for key, value in service_dict.items():
if key in IGNORED_KEYS:
continue
if key not in SUPPORTED_KEYS:
log.warn("Unsupported key '{}' in services.{} - ignoring".format(key, name))
continue
if key == 'environment':
container_config['Env'] = format_environment({
envkey: envvalue for envkey, envvalue in value.items()
if envvalue
})
continue
if key in SERVICE_KEYS:
container_config[SERVICE_KEYS[key]] = value
continue
set_command_and_args(
container_config,
service_dict.get('entrypoint', []),
service_dict.get('command', []))
container_config['Networks'] = make_service_networks(name, service_dict)
ports = make_port_specs(service_dict)
if ports:
container_config['Ports'] = ports
return container_config
# See https://github.com/docker/swarmkit/blob/agent/exec/container/container.go#L95
def set_command_and_args(config, entrypoint, command):
if isinstance(entrypoint, six.string_types):
entrypoint = split_command(entrypoint)
if isinstance(command, six.string_types):
command = split_command(command)
if entrypoint:
config['Command'] = entrypoint + command
return
if command:
config['Args'] = command
def make_service_networks(name, service_dict):
networks = []
for network_name, network_def in get_network_defs_for_service(service_dict).items():
for key in network_def.keys():
log.warn(
"Unsupported key '{}' in services.{}.networks.{} - ignoring"
.format(key, name, network_name))
networks.append(network_name)
return networks
def make_port_specs(service_dict):
ports = []
internal_ports = [
internal_port
for port_def in service_dict.get('ports', [])
for internal_port in split_port(port_def)[0]
]
internal_ports += service_dict.get('expose', [])
for internal_port in internal_ports:
spec = make_port_spec(internal_port)
if spec not in ports:
ports.append(spec)
return ports
def make_port_spec(value):
components = six.text_type(value).partition('/')
return {
'Protocol': components[2] or 'tcp',
'Port': int(components[0]),
}

View file

@ -0,0 +1,37 @@
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
import subprocess
import sys
# Attempt to detect https://github.com/docker/compose/issues/4344
try:
# We don't try importing pip because it messes with package imports
# on some Linux distros (Ubuntu, Fedora)
# https://github.com/docker/compose/issues/4425
# https://github.com/docker/compose/issues/4481
# https://github.com/pypa/pip/blob/master/pip/_vendor/__init__.py
s_cmd = subprocess.Popen(
['pip', 'freeze'], stderr=subprocess.PIPE, stdout=subprocess.PIPE
)
packages = s_cmd.communicate()[0].splitlines()
dockerpy_installed = len(
list(filter(lambda p: p.startswith(b'docker-py=='), packages))
) > 0
if dockerpy_installed:
from .colors import red
print(
red('ERROR:'),
"Dependency conflict: an older version of the 'docker-py' package "
"is polluting the namespace. "
"Run the following command to remedy the issue:\n"
"pip uninstall docker docker-py; pip install docker",
file=sys.stderr
)
sys.exit(1)
except OSError:
# pip command is not available, which indicates it's probably the binary
# distribution of Compose which is not affected
pass

View file

@ -1,4 +1,8 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import colorama
NAMES = [
'grey',
'red',
@ -29,6 +33,7 @@ def make_color_fn(code):
return lambda s: ansi_color(code, s)
colorama.init(strip=False)
for (name, code) in get_pairs():
globals()[name] = make_color_fn(code)

View file

@ -1,77 +1,90 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import contextlib
import logging
import os
import re
import ssl
import six
from requests.exceptions import ConnectionError
from requests.exceptions import SSLError
from . import errors
from . import verbose_proxy
from .. import __version__
from .. import config
from ..config.environment import Environment
from ..const import API_VERSIONS
from ..project import Project
from ..service import ConfigError
from .docker_client import docker_client
from .utils import call_silently
from .utils import is_mac
from .utils import is_ubuntu
from .docker_client import tls_config_from_options
from .utils import get_version_info
log = logging.getLogger(__name__)
@contextlib.contextmanager
def friendly_error_message():
try:
yield
except SSLError as e:
raise errors.UserError('SSL error: %s' % e)
except ConnectionError:
if call_silently(['which', 'docker']) != 0:
if is_mac():
raise errors.DockerNotFoundMac()
elif is_ubuntu():
raise errors.DockerNotFoundUbuntu()
else:
raise errors.DockerNotFoundGeneric()
elif call_silently(['which', 'docker-machine']) == 0:
raise errors.ConnectionErrorDockerMachine()
else:
raise errors.ConnectionErrorGeneric(get_client().base_url)
def project_from_options(base_dir, options):
def project_from_options(project_dir, options):
environment = Environment.from_env_file(project_dir)
host = options.get('--host')
if host is not None:
host = host.lstrip('=')
return get_project(
base_dir,
get_config_path(options.get('--file')),
project_dir,
get_config_path_from_options(project_dir, options, environment),
project_name=options.get('--project-name'),
verbose=options.get('--verbose'),
use_networking=options.get('--x-networking'),
network_driver=options.get('--x-network-driver'),
host=host,
tls_config=tls_config_from_options(options),
environment=environment
)
def get_config_path(file_option):
def get_config_from_options(base_dir, options):
environment = Environment.from_env_file(base_dir)
config_path = get_config_path_from_options(
base_dir, options, environment
)
return config.load(
config.find(base_dir, config_path, environment)
)
def get_config_path_from_options(base_dir, options, environment):
file_option = options.get('--file')
if file_option:
return file_option
if 'FIG_FILE' in os.environ:
log.warn('The FIG_FILE environment variable is deprecated.')
log.warn('Please use COMPOSE_FILE instead.')
config_file = os.environ.get('COMPOSE_FILE') or os.environ.get('FIG_FILE')
return [config_file] if config_file else None
config_files = environment.get('COMPOSE_FILE')
if config_files:
return config_files.split(os.pathsep)
return None
def get_client(verbose=False, version=None):
client = docker_client(version=version)
def get_tls_version(environment):
compose_tls_version = environment.get('COMPOSE_TLS_VERSION', None)
if not compose_tls_version:
return None
tls_attr_name = "PROTOCOL_{}".format(compose_tls_version)
if not hasattr(ssl, tls_attr_name):
log.warn(
'The "{}" protocol is unavailable. You may need to update your '
'version of Python or OpenSSL. Falling back to TLSv1 (default).'
.format(compose_tls_version)
)
return None
return getattr(ssl, tls_attr_name)
def get_client(environment, verbose=False, version=None, tls_config=None, host=None,
tls_version=None):
client = docker_client(
version=version, tls_config=tls_config, host=host,
environment=environment, tls_version=get_tls_version(environment)
)
if verbose:
version_info = six.iteritems(client.version())
log.info("Compose version %s", __version__)
log.info(get_version_info('full'))
log.info("Docker base_url: %s", client.base_url)
log.info("Docker version: %s",
", ".join("%s=%s" % item for item in version_info))
@ -79,36 +92,37 @@ def get_client(verbose=False, version=None):
return client
def get_project(base_dir, config_path=None, project_name=None, verbose=False,
use_networking=False, network_driver=None):
config_details = config.find(base_dir, config_path)
api_version = '1.21' if use_networking else None
try:
return Project.from_dicts(
get_project_name(config_details.working_dir, project_name),
config.load(config_details),
get_client(verbose=verbose, version=api_version),
use_networking=use_networking,
network_driver=network_driver,
def get_project(project_dir, config_path=None, project_name=None, verbose=False,
host=None, tls_config=None, environment=None):
if not environment:
environment = Environment.from_env_file(project_dir)
config_details = config.find(project_dir, config_path, environment)
project_name = get_project_name(
config_details.working_dir, project_name, environment
)
except ConfigError as e:
raise errors.UserError(six.text_type(e))
config_data = config.load(config_details)
api_version = environment.get(
'COMPOSE_API_VERSION',
API_VERSIONS[config_data.version])
client = get_client(
verbose=verbose, version=api_version, tls_config=tls_config,
host=host, environment=environment
)
with errors.handle_connection_errors(client):
return Project.from_config(project_name, config_data, client)
def get_project_name(working_dir, project_name=None):
def get_project_name(working_dir, project_name=None, environment=None):
def normalize_name(name):
return re.sub(r'[^a-z0-9]', '', name.lower())
if 'FIG_PROJECT_NAME' in os.environ:
log.warn('The FIG_PROJECT_NAME environment variable is deprecated.')
log.warn('Please use COMPOSE_PROJECT_NAME instead.')
project_name = (
project_name or
os.environ.get('COMPOSE_PROJECT_NAME') or
os.environ.get('FIG_PROJECT_NAME'))
if project_name is not None:
if not environment:
environment = Environment.from_env_file(working_dir)
project_name = project_name or environment.get('COMPOSE_PROJECT_NAME')
if project_name:
return normalize_name(project_name)
project = os.path.basename(os.path.abspath(working_dir))

View file

@ -1,28 +1,74 @@
import logging
import os
from __future__ import absolute_import
from __future__ import unicode_literals
from docker import Client
import logging
from docker import APIClient
from docker.errors import TLSParameterError
from docker.tls import TLSConfig
from docker.utils import kwargs_from_env
from ..const import HTTP_TIMEOUT
from .errors import UserError
from .utils import generate_user_agent
from .utils import unquote_path
log = logging.getLogger(__name__)
DEFAULT_API_VERSION = '1.19'
def tls_config_from_options(options):
tls = options.get('--tls', False)
ca_cert = unquote_path(options.get('--tlscacert'))
cert = unquote_path(options.get('--tlscert'))
key = unquote_path(options.get('--tlskey'))
verify = options.get('--tlsverify')
skip_hostname_check = options.get('--skip-hostname-check', False)
advanced_opts = any([ca_cert, cert, key, verify])
if tls is True and not advanced_opts:
return True
elif advanced_opts: # --tls is a noop
client_cert = None
if cert or key:
client_cert = (cert, key)
return TLSConfig(
client_cert=client_cert, verify=verify, ca_cert=ca_cert,
assert_hostname=False if skip_hostname_check else None
)
return None
def docker_client(version=None):
def docker_client(environment, version=None, tls_config=None, host=None,
tls_version=None):
"""
Returns a docker-py client configured using environment variables
according to the same logic as the official Docker client.
"""
if 'DOCKER_CLIENT_TIMEOUT' in os.environ:
log.warn('The DOCKER_CLIENT_TIMEOUT environment variable is deprecated. Please use COMPOSE_HTTP_TIMEOUT instead.')
try:
kwargs = kwargs_from_env(environment=environment, ssl_version=tls_version)
except TLSParameterError:
raise UserError(
"TLS configuration is invalid - make sure your DOCKER_TLS_VERIFY "
"and DOCKER_CERT_PATH are set correctly.\n"
"You might need to run `eval \"$(docker-machine env default)\"`")
kwargs = kwargs_from_env(assert_hostname=False)
kwargs['version'] = version or os.environ.get(
'COMPOSE_API_VERSION',
DEFAULT_API_VERSION)
if host:
kwargs['base_url'] = host
if tls_config:
kwargs['tls'] = tls_config
if version:
kwargs['version'] = version
timeout = environment.get('COMPOSE_HTTP_TIMEOUT')
if timeout:
kwargs['timeout'] = int(timeout)
else:
kwargs['timeout'] = HTTP_TIMEOUT
return Client(**kwargs)
kwargs['user_agent'] = generate_user_agent()
return APIClient(**kwargs)

View file

@ -1,7 +1,6 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import sys
from inspect import getdoc
from docopt import docopt
@ -15,24 +14,21 @@ def docopt_full_help(docstring, *args, **kwargs):
raise SystemExit(docstring)
class DocoptCommand(object):
def docopt_options(self):
return {'options_first': True}
class DocoptDispatcher(object):
def sys_dispatch(self):
self.dispatch(sys.argv[1:], None)
def __init__(self, command_class, options):
self.command_class = command_class
self.options = options
def dispatch(self, argv, global_options):
self.perform_command(*self.parse(argv, global_options))
def parse(self, argv, global_options):
options = docopt_full_help(getdoc(self), argv, **self.docopt_options())
def parse(self, argv):
command_help = getdoc(self.command_class)
options = docopt_full_help(command_help, argv, **self.options)
command = options['COMMAND']
if command is None:
raise SystemExit(getdoc(self))
raise SystemExit(command_help)
handler = self.get_handler(command)
handler = get_handler(self.command_class, command)
docstring = getdoc(handler)
if docstring is None:
@ -41,13 +37,18 @@ class DocoptCommand(object):
command_options = docopt_full_help(docstring, options['ARGS'], options_first=True)
return options, handler, command_options
def get_handler(self, command):
def get_handler(command_class, command):
command = command.replace('-', '_')
# we certainly want to have "exec" command, since that's what docker client has
# but in python exec is a keyword
if command == "exec":
command = "exec_command"
if not hasattr(self, command):
raise NoSuchCommand(command, self)
if not hasattr(command_class, command):
raise NoSuchCommand(command, command_class)
return getattr(self, command)
return getattr(command_class, command)
class NoSuchCommand(Exception):

View file

@ -1,9 +1,30 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import contextlib
import logging
import socket
from distutils.spawn import find_executable
from textwrap import dedent
from docker.errors import APIError
from requests.exceptions import ConnectionError as RequestsConnectionError
from requests.exceptions import ReadTimeout
from requests.exceptions import SSLError
from requests.packages.urllib3.exceptions import ReadTimeoutError
from ..const import API_VERSION_TO_ENGINE_VERSION
from .utils import is_docker_for_mac_installed
from .utils import is_mac
from .utils import is_ubuntu
from .utils import is_windows
log = logging.getLogger(__name__)
class UserError(Exception):
def __init__(self, msg):
self.msg = dedent(msg).strip()
@ -13,44 +34,104 @@ class UserError(Exception):
__str__ = __unicode__
class DockerNotFoundMac(UserError):
def __init__(self):
super(DockerNotFoundMac, self).__init__("""
Couldn't connect to Docker daemon. You might need to install docker-osx:
https://github.com/noplay/docker-osx
""")
class ConnectionError(Exception):
pass
class DockerNotFoundUbuntu(UserError):
def __init__(self):
super(DockerNotFoundUbuntu, self).__init__("""
Couldn't connect to Docker daemon. You might need to install Docker:
http://docs.docker.io/en/latest/installation/ubuntulinux/
""")
@contextlib.contextmanager
def handle_connection_errors(client):
try:
yield
except SSLError as e:
log.error('SSL error: %s' % e)
raise ConnectionError()
except RequestsConnectionError as e:
if e.args and isinstance(e.args[0], ReadTimeoutError):
log_timeout_error(client.timeout)
raise ConnectionError()
exit_with_error(get_conn_error_message(client.base_url))
except APIError as e:
log_api_error(e, client.api_version)
raise ConnectionError()
except (ReadTimeout, socket.timeout) as e:
log_timeout_error(client.timeout)
raise ConnectionError()
class DockerNotFoundGeneric(UserError):
def __init__(self):
super(DockerNotFoundGeneric, self).__init__("""
Couldn't connect to Docker daemon. You might need to install Docker:
http://docs.docker.io/en/latest/installation/
""")
def log_timeout_error(timeout):
log.error(
"An HTTP request took too long to complete. Retry with --verbose to "
"obtain debug information.\n"
"If you encounter this issue regularly because of slow network "
"conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher "
"value (current value: %s)." % timeout)
class ConnectionErrorDockerMachine(UserError):
def __init__(self):
super(ConnectionErrorDockerMachine, self).__init__("""
def log_api_error(e, client_version):
if b'client is newer than server' not in e.explanation:
log.error(e.explanation)
return
version = API_VERSION_TO_ENGINE_VERSION.get(client_version)
if not version:
# They've set a custom API version
log.error(e.explanation)
return
log.error(
"The Docker Engine version is less than the minimum required by "
"Compose. Your current project requires a Docker Engine of "
"version {version} or greater.".format(version=version))
def exit_with_error(msg):
log.error(dedent(msg).strip())
raise ConnectionError()
def get_conn_error_message(url):
if find_executable('docker') is None:
return docker_not_found_msg("Couldn't connect to Docker daemon.")
if is_docker_for_mac_installed():
return conn_error_docker_for_mac
if find_executable('docker-machine') is not None:
return conn_error_docker_machine
return conn_error_generic.format(url=url)
def docker_not_found_msg(problem):
return "{} You might need to install Docker:\n\n{}".format(
problem, docker_install_url())
def docker_install_url():
if is_mac():
return docker_install_url_mac
elif is_ubuntu():
return docker_install_url_ubuntu
elif is_windows():
return docker_install_url_windows
else:
return docker_install_url_generic
docker_install_url_mac = "https://docs.docker.com/engine/installation/mac/"
docker_install_url_ubuntu = "https://docs.docker.com/engine/installation/ubuntulinux/"
docker_install_url_windows = "https://docs.docker.com/engine/installation/windows/"
docker_install_url_generic = "https://docs.docker.com/engine/installation/"
conn_error_docker_machine = """
Couldn't connect to Docker daemon - you might need to run `docker-machine start default`.
""")
"""
conn_error_docker_for_mac = """
Couldn't connect to Docker daemon. You might need to start Docker for Mac.
"""
class ConnectionErrorGeneric(UserError):
def __init__(self, url):
super(ConnectionErrorGeneric, self).__init__("""
Couldn't connect to Docker daemon at %s - is it running?
conn_error_generic = """
Couldn't connect to Docker daemon at {url} - is it running?
If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
""" % url)
"""

View file

@ -4,6 +4,7 @@ from __future__ import unicode_literals
import logging
import os
import six
import texttable
from compose.cli import colors
@ -44,5 +45,7 @@ class ConsoleWarningFormatter(logging.Formatter):
return ''
def format(self, record):
if isinstance(record.msg, six.binary_type):
record.msg = record.msg.decode('utf-8')
message = super(ConsoleWarningFormatter, self).format(record)
return self.get_level_message(record) + message
return '{0}{1}'.format(self.get_level_message(record), message)

View file

@ -2,58 +2,153 @@ from __future__ import absolute_import
from __future__ import unicode_literals
import sys
from collections import namedtuple
from itertools import cycle
from threading import Thread
from docker.errors import APIError
from six.moves import _thread as thread
from six.moves.queue import Empty
from six.moves.queue import Queue
from . import colors
from .multiplexer import Multiplexer
from compose import utils
from compose.cli.signals import ShutdownException
from compose.utils import split_buffer
class LogPrinter(object):
"""Print logs from many containers to a single output stream."""
class LogPresenter(object):
def __init__(self, containers, output=sys.stdout, monochrome=False):
self.containers = containers
self.output = utils.get_output_stream(output)
self.monochrome = monochrome
def __init__(self, prefix_width, color_func):
self.prefix_width = prefix_width
self.color_func = color_func
def run(self):
if not self.containers:
return
def present(self, container, line):
prefix = container.name_without_project.ljust(self.prefix_width)
return '{prefix} {line}'.format(
prefix=self.color_func(prefix + ' |'),
line=line)
prefix_width = max_name_width(self.containers)
generators = list(self._make_log_generators(self.monochrome, prefix_width))
for line in Multiplexer(generators).loop():
self.output.write(line)
def _make_log_generators(self, monochrome, prefix_width):
def build_log_presenters(service_names, monochrome):
"""Return an iterable of functions.
Each function can be used to format the logs output of a container.
"""
prefix_width = max_name_width(service_names)
def no_color(text):
return text
if monochrome:
color_funcs = cycle([no_color])
else:
color_funcs = cycle(colors.rainbow())
for color_func, container in zip(color_funcs, self.containers):
generator_func = get_log_generator(container)
prefix = color_func(build_log_prefix(container, prefix_width))
yield generator_func(container, prefix, color_func)
for color_func in cycle([no_color] if monochrome else colors.rainbow()):
yield LogPresenter(prefix_width, color_func)
def build_log_prefix(container, prefix_width):
return container.name_without_project.ljust(prefix_width) + ' | '
def max_name_width(containers):
def max_name_width(service_names, max_index_width=3):
"""Calculate the maximum width of container names so we can make the log
prefixes line up like so:
db_1 | Listening
web_1 | Listening
"""
return max(len(container.name_without_project) for container in containers)
return max(len(name) for name in service_names) + max_index_width
class LogPrinter(object):
"""Print logs from many containers to a single output stream."""
def __init__(self,
containers,
presenters,
event_stream,
output=sys.stdout,
cascade_stop=False,
log_args=None):
self.containers = containers
self.presenters = presenters
self.event_stream = event_stream
self.output = utils.get_output_stream(output)
self.cascade_stop = cascade_stop
self.log_args = log_args or {}
def run(self):
if not self.containers:
return
queue = Queue()
thread_args = queue, self.log_args
thread_map = build_thread_map(self.containers, self.presenters, thread_args)
start_producer_thread((
thread_map,
self.event_stream,
self.presenters,
thread_args))
for line in consume_queue(queue, self.cascade_stop):
remove_stopped_threads(thread_map)
if not line:
if not thread_map:
# There are no running containers left to tail, so exit
return
# We got an empty line because of a timeout, but there are still
# active containers to tail, so continue
continue
self.output.write(line)
self.output.flush()
def remove_stopped_threads(thread_map):
for container_id, tailer_thread in list(thread_map.items()):
if not tailer_thread.is_alive():
thread_map.pop(container_id, None)
def build_thread(container, presenter, queue, log_args):
tailer = Thread(
target=tail_container_logs,
args=(container, presenter, queue, log_args))
tailer.daemon = True
tailer.start()
return tailer
def build_thread_map(initial_containers, presenters, thread_args):
return {
container.id: build_thread(container, next(presenters), *thread_args)
for container in initial_containers
}
class QueueItem(namedtuple('_QueueItem', 'item is_stop exc')):
@classmethod
def new(cls, item):
return cls(item, None, None)
@classmethod
def exception(cls, exc):
return cls(None, None, exc)
@classmethod
def stop(cls):
return cls(None, True, None)
def tail_container_logs(container, presenter, queue, log_args):
generator = get_log_generator(container)
try:
for item in generator(container, log_args):
queue.put(QueueItem.new(presenter.present(container, item)))
except Exception as e:
queue.put(QueueItem.exception(e))
return
if log_args.get('follow'):
queue.put(QueueItem.new(presenter.color_func(wait_on_exit(container))))
queue.put(QueueItem.stop())
def get_log_generator(container):
@ -62,30 +157,81 @@ def get_log_generator(container):
return build_no_log_generator
def build_no_log_generator(container, prefix, color_func):
def build_no_log_generator(container, log_args):
"""Return a generator that prints a warning about logs and waits for
container to exit.
"""
yield "{} WARNING: no logs are available with the '{}' log driver\n".format(
prefix,
yield "WARNING: no logs are available with the '{}' log driver\n".format(
container.log_driver)
yield color_func(wait_on_exit(container))
def build_log_generator(container, prefix, color_func):
def build_log_generator(container, log_args):
# if the container doesn't have a log_stream we need to attach to container
# before log printer starts running
if container.log_stream is None:
stream = container.attach(stdout=True, stderr=True, stream=True, logs=True)
line_generator = split_buffer(stream)
stream = container.logs(stdout=True, stderr=True, stream=True, **log_args)
else:
line_generator = split_buffer(container.log_stream)
stream = container.log_stream
for line in line_generator:
yield prefix + line
yield color_func(wait_on_exit(container))
return split_buffer(stream)
def wait_on_exit(container):
try:
exit_code = container.wait()
return "%s exited with code %s\n" % (container.name, exit_code)
except APIError as e:
return "Unexpected API error for %s (HTTP code %s)\nResponse body:\n%s\n" % (
container.name, e.response.status_code,
e.response.text or '[empty]'
)
def start_producer_thread(thread_args):
producer = Thread(target=watch_events, args=thread_args)
producer.daemon = True
producer.start()
def watch_events(thread_map, event_stream, presenters, thread_args):
for event in event_stream:
if event['action'] == 'stop':
thread_map.pop(event['id'], None)
if event['action'] != 'start':
continue
if event['id'] in thread_map:
if thread_map[event['id']].is_alive():
continue
# Container was stopped and started, we need a new thread
thread_map.pop(event['id'], None)
thread_map[event['id']] = build_thread(
event['container'],
next(presenters),
*thread_args)
def consume_queue(queue, cascade_stop):
"""Consume the queue by reading lines off of it and yielding them."""
while True:
try:
item = queue.get(timeout=0.1)
except Empty:
yield None
continue
# See https://github.com/docker/compose/issues/189
except thread.error:
raise ShutdownException()
if item.exc:
raise item.exc
if item.is_stop:
if cascade_stop:
raise StopIteration
else:
continue
yield item.item

File diff suppressed because it is too large Load diff

View file

@ -1,60 +0,0 @@
from __future__ import absolute_import
from threading import Thread
from six.moves import _thread as thread
try:
from Queue import Queue, Empty
except ImportError:
from queue import Queue, Empty # Python 3.x
STOP = object()
class Multiplexer(object):
"""
Create a single iterator from several iterators by running all of them in
parallel and yielding results as they come in.
"""
def __init__(self, iterators):
self.iterators = iterators
self._num_running = len(iterators)
self.queue = Queue()
def loop(self):
self._init_readers()
while self._num_running > 0:
try:
item, exception = self.queue.get(timeout=0.1)
if exception:
raise exception
if item is STOP:
self._num_running -= 1
else:
yield item
except Empty:
pass
# See https://github.com/docker/compose/issues/189
except thread.error:
raise KeyboardInterrupt()
def _init_readers(self):
for iterator in self.iterators:
t = Thread(target=_enqueue_output, args=(iterator, self.queue))
t.daemon = True
t.start()
def _enqueue_output(iterator, queue):
try:
for item in iterator:
queue.put((item, None))
queue.put((STOP, None))
except Exception as e:
queue.put((None, e))

21
compose/cli/signals.py Normal file
View file

@ -0,0 +1,21 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import signal
class ShutdownException(Exception):
pass
def shutdown(signal, frame):
raise ShutdownException()
def set_signal_handler(handler):
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)
def set_signal_handler_to_shutdown():
set_signal_handler(shutdown)

View file

@ -6,11 +6,19 @@ import os
import platform
import ssl
import subprocess
import sys
from docker import version as docker_py_version
from six.moves import input
import docker
from .. import __version__
import compose
from ..const import IS_WINDOWS_PLATFORM
# WindowsError is not defined on non-win32 platforms. Avoid runtime errors by
# defining it as OSError (its parent class) if missing.
try:
WindowsError
except NameError:
WindowsError = OSError
def yesno(prompt, default=None):
@ -35,6 +43,16 @@ def yesno(prompt, default=None):
return None
def input(prompt):
"""
Version of input (raw_input in Python 2) which forces a flush of sys.stdout
to avoid problems where the prompt fails to appear due to line buffering
"""
sys.stdout.write(prompt)
sys.stdout.flush()
return sys.stdin.readline().rstrip('\n')
def call_silently(*args, **kwargs):
"""
Like subprocess.call(), but redirects stdout and stderr to /dev/null.
@ -56,14 +74,64 @@ def is_ubuntu():
return platform.system() == 'Linux' and platform.linux_distribution()[0] == 'Ubuntu'
def is_windows():
return IS_WINDOWS_PLATFORM
def get_version_info(scope):
versioninfo = 'docker-compose version: %s' % __version__
versioninfo = 'docker-compose version {}, build {}'.format(
compose.__version__,
get_build_version())
if scope == 'compose':
return versioninfo
elif scope == 'full':
return versioninfo + '\n' \
+ "docker-py version: %s\n" % docker_py_version \
+ "%s version: %s\n" % (platform.python_implementation(), platform.python_version()) \
+ "OpenSSL version: %s" % ssl.OPENSSL_VERSION
if scope == 'full':
return (
"{}\n"
"docker-py version: {}\n"
"{} version: {}\n"
"OpenSSL version: {}"
).format(
versioninfo,
docker.version,
platform.python_implementation(),
platform.python_version(),
ssl.OPENSSL_VERSION)
raise ValueError("{} is not a valid version scope".format(scope))
def get_build_version():
filename = os.path.join(os.path.dirname(compose.__file__), 'GITSHA')
if not os.path.exists(filename):
return 'unknown'
with open(filename) as fh:
return fh.read().strip()
def is_docker_for_mac_installed():
return is_mac() and os.path.isdir('/Applications/Docker.app')
def generate_user_agent():
parts = [
"docker-compose/{}".format(compose.__version__),
"docker-py/{}".format(docker.__version__),
]
try:
p_system = platform.system()
p_release = platform.release()
except IOError:
pass
else:
raise RuntimeError('passed unallowed value to `cli.utils.get_version_info`')
parts.append("{}/{}".format(p_system, p_release))
return " ".join(parts)
def unquote_path(s):
if not s:
return s
if s[0] == '"' and s[-1] == '"':
return s[1:-1]
return s

View file

@ -1,3 +1,6 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import functools
import logging
import pprint

View file

@ -1,9 +1,11 @@
# flake8: noqa
from .config import ConfigDetails
from __future__ import absolute_import
from __future__ import unicode_literals
from . import environment
from .config import ConfigurationError
from .config import DOCKER_CONFIG_KEYS
from .config import find
from .config import get_service_name_from_net
from .config import load
from .config import merge_environment
from .config import parse_environment

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "config_schema_v1.json",
"type": "object",
@ -9,8 +10,11 @@
}
},
"additionalProperties": false,
"definitions": {
"service": {
"id": "#/definitions/service",
"type": "object",
"properties": {
@ -26,34 +30,28 @@
},
"container_name": {"type": "string"},
"cpu_shares": {"type": ["number", "string"]},
"cpu_quota": {"type": ["number", "string"]},
"cpuset": {"type": "string"},
"devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"dns": {"$ref": "#/definitions/string_or_list"},
"dns_search": {"$ref": "#/definitions/string_or_list"},
"dockerfile": {"type": "string"},
"domainname": {"type": "string"},
"entrypoint": {"$ref": "#/definitions/string_or_list"},
"env_file": {"$ref": "#/definitions/string_or_list"},
"environment": {
"entrypoint": {
"oneOf": [
{
"type": "object",
"patternProperties": {
"^[^-]+$": {
"type": ["string", "number", "boolean", "null"],
"format": "environment"
}
},
"additionalProperties": false
},
{"type": "array", "items": {"type": "string"}, "uniqueItems": true}
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"env_file": {"$ref": "#/definitions/string_or_list"},
"environment": {"$ref": "#/definitions/list_or_dict"},
"expose": {
"type": "array",
"items": {"type": ["string", "number"]},
"items": {
"type": ["string", "number"],
"format": "expose"
},
"uniqueItems": true
},
@ -82,31 +80,21 @@
"ipc": {"type": "string"},
"labels": {"$ref": "#/definitions/list_or_dict"},
"links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"log_driver": {"type": "string"},
"log_opt": {"type": "object"},
"mac_address": {"type": "string"},
"mem_limit": {"type": ["number", "string"]},
"memswap_limit": {"type": ["number", "string"]},
"name": {"type": "string"},
"mem_swappiness": {"type": "integer"},
"net": {"type": "string"},
"pid": {"type": ["string", "null"]},
"ports": {
"type": "array",
"items": {
"oneOf": [
{
"type": "string",
"type": ["string", "number"],
"format": "ports"
},
{
"type": "number",
"format": "ports"
}
]
},
"uniqueItems": true
},
@ -114,8 +102,29 @@
"read_only": {"type": "boolean"},
"restart": {"type": "string"},
"security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"shm_size": {"type": ["number", "string"]},
"stdin_open": {"type": "boolean"},
"stop_signal": {"type": "string"},
"tty": {"type": "boolean"},
"ulimits": {
"type": "object",
"patternProperties": {
"^[a-z]+$": {
"oneOf": [
{"type": "integer"},
{
"type":"object",
"properties": {
"hard": {"type": "integer"},
"soft": {"type": "integer"}
},
"required": ["soft", "hard"],
"additionalProperties": false
}
]
}
}
},
"user": {"type": "string"},
"volumes": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"volume_driver": {"type": "string"},
@ -144,11 +153,36 @@
"list_or_dict": {
"oneOf": [
{"type": "array", "items": {"type": "string"}, "uniqueItems": true},
{"type": "object"}
]
{
"type": "object",
"patternProperties": {
".+": {
"type": ["string", "number", "null"]
}
},
"additionalProperties": false
},
{"type": "array", "items": {"type": "string"}, "uniqueItems": true}
]
},
"constraints": {
"service": {
"id": "#/definitions/constraints/service",
"anyOf": [
{
"required": ["build"],
"not": {"required": ["image"]}
},
{
"required": ["image"],
"not": {"anyOf": [
{"required": ["build"]},
{"required": ["dockerfile"]}
]}
}
]
}
}
}
}

View file

@ -0,0 +1,329 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "config_schema_v2.0.json",
"type": "object",
"properties": {
"version": {
"type": "string"
},
"services": {
"id": "#/properties/services",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/service"
}
},
"additionalProperties": false
},
"networks": {
"id": "#/properties/networks",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/network"
}
}
},
"volumes": {
"id": "#/properties/volumes",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/volume"
}
},
"additionalProperties": false
}
},
"additionalProperties": false,
"definitions": {
"service": {
"id": "#/definitions/service",
"type": "object",
"properties": {
"build": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"properties": {
"context": {"type": "string"},
"dockerfile": {"type": "string"},
"args": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
}
]
},
"cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cgroup_parent": {"type": "string"},
"command": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"container_name": {"type": "string"},
"cpu_shares": {"type": ["number", "string"]},
"cpu_quota": {"type": ["number", "string"]},
"cpuset": {"type": "string"},
"depends_on": {"$ref": "#/definitions/list_of_strings"},
"devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"dns": {"$ref": "#/definitions/string_or_list"},
"dns_search": {"$ref": "#/definitions/string_or_list"},
"domainname": {"type": "string"},
"entrypoint": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"env_file": {"$ref": "#/definitions/string_or_list"},
"environment": {"$ref": "#/definitions/list_or_dict"},
"expose": {
"type": "array",
"items": {
"type": ["string", "number"],
"format": "expose"
},
"uniqueItems": true
},
"extends": {
"oneOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"service": {"type": "string"},
"file": {"type": "string"}
},
"required": ["service"],
"additionalProperties": false
}
]
},
"external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"extra_hosts": {"$ref": "#/definitions/list_or_dict"},
"hostname": {"type": "string"},
"image": {"type": "string"},
"ipc": {"type": "string"},
"labels": {"$ref": "#/definitions/list_or_dict"},
"links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"logging": {
"type": "object",
"properties": {
"driver": {"type": "string"},
"options": {"type": "object"}
},
"additionalProperties": false
},
"mac_address": {"type": "string"},
"mem_limit": {"type": ["number", "string"]},
"memswap_limit": {"type": ["number", "string"]},
"mem_swappiness": {"type": "integer"},
"network_mode": {"type": "string"},
"networks": {
"oneOf": [
{"$ref": "#/definitions/list_of_strings"},
{
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"oneOf": [
{
"type": "object",
"properties": {
"aliases": {"$ref": "#/definitions/list_of_strings"},
"ipv4_address": {"type": "string"},
"ipv6_address": {"type": "string"}
},
"additionalProperties": false
},
{"type": "null"}
]
}
},
"additionalProperties": false
}
]
},
"oom_score_adj": {"type": "integer", "minimum": -1000, "maximum": 1000},
"group_add": {
"type": "array",
"items": {
"type": ["string", "number"]
},
"uniqueItems": true
},
"pid": {"type": ["string", "null"]},
"ports": {
"type": "array",
"items": {
"type": ["string", "number"],
"format": "ports"
},
"uniqueItems": true
},
"privileged": {"type": "boolean"},
"read_only": {"type": "boolean"},
"restart": {"type": "string"},
"security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"shm_size": {"type": ["number", "string"]},
"stdin_open": {"type": "boolean"},
"stop_grace_period": {"type": "string", "format": "duration"},
"stop_signal": {"type": "string"},
"tmpfs": {"$ref": "#/definitions/string_or_list"},
"tty": {"type": "boolean"},
"ulimits": {
"type": "object",
"patternProperties": {
"^[a-z]+$": {
"oneOf": [
{"type": "integer"},
{
"type":"object",
"properties": {
"hard": {"type": "integer"},
"soft": {"type": "integer"}
},
"required": ["soft", "hard"],
"additionalProperties": false
}
]
}
}
},
"user": {"type": "string"},
"volumes": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"volume_driver": {"type": "string"},
"volumes_from": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"working_dir": {"type": "string"}
},
"dependencies": {
"memswap_limit": ["mem_limit"]
},
"additionalProperties": false
},
"network": {
"id": "#/definitions/network",
"type": "object",
"properties": {
"driver": {"type": "string"},
"driver_opts": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number"]}
}
},
"ipam": {
"type": "object",
"properties": {
"driver": {"type": "string"},
"config": {
"type": "array"
}
},
"additionalProperties": false
},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
},
"additionalProperties": false
},
"internal": {"type": "boolean"}
},
"additionalProperties": false
},
"volume": {
"id": "#/definitions/volume",
"type": ["object", "null"],
"properties": {
"driver": {"type": "string"},
"driver_opts": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number"]}
}
},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"string_or_list": {
"oneOf": [
{"type": "string"},
{"$ref": "#/definitions/list_of_strings"}
]
},
"list_of_strings": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": true
},
"list_or_dict": {
"oneOf": [
{
"type": "object",
"patternProperties": {
".+": {
"type": ["string", "number", "null"]
}
},
"additionalProperties": false
},
{"type": "array", "items": {"type": "string"}, "uniqueItems": true}
]
},
"constraints": {
"service": {
"id": "#/definitions/constraints/service",
"anyOf": [
{"required": ["build"]},
{"required": ["image"]}
],
"properties": {
"build": {
"required": ["context"]
}
}
}
}
}
}

View file

@ -0,0 +1,376 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "config_schema_v2.1.json",
"type": "object",
"properties": {
"version": {
"type": "string"
},
"services": {
"id": "#/properties/services",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/service"
}
},
"additionalProperties": false
},
"networks": {
"id": "#/properties/networks",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/network"
}
}
},
"volumes": {
"id": "#/properties/volumes",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/volume"
}
},
"additionalProperties": false
}
},
"additionalProperties": false,
"definitions": {
"service": {
"id": "#/definitions/service",
"type": "object",
"properties": {
"build": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"properties": {
"context": {"type": "string"},
"dockerfile": {"type": "string"},
"args": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
}
]
},
"cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cgroup_parent": {"type": "string"},
"command": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"container_name": {"type": "string"},
"cpu_shares": {"type": ["number", "string"]},
"cpu_quota": {"type": ["number", "string"]},
"cpuset": {"type": "string"},
"depends_on": {
"oneOf": [
{"$ref": "#/definitions/list_of_strings"},
{
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"condition": {
"type": "string",
"enum": ["service_started", "service_healthy"]
}
},
"required": ["condition"]
}
}
}
]
},
"devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"dns": {"$ref": "#/definitions/string_or_list"},
"dns_search": {"$ref": "#/definitions/string_or_list"},
"domainname": {"type": "string"},
"entrypoint": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"env_file": {"$ref": "#/definitions/string_or_list"},
"environment": {"$ref": "#/definitions/list_or_dict"},
"expose": {
"type": "array",
"items": {
"type": ["string", "number"],
"format": "expose"
},
"uniqueItems": true
},
"extends": {
"oneOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"service": {"type": "string"},
"file": {"type": "string"}
},
"required": ["service"],
"additionalProperties": false
}
]
},
"external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"extra_hosts": {"$ref": "#/definitions/list_or_dict"},
"healthcheck": {"$ref": "#/definitions/healthcheck"},
"hostname": {"type": "string"},
"image": {"type": "string"},
"ipc": {"type": "string"},
"isolation": {"type": "string"},
"labels": {"$ref": "#/definitions/list_or_dict"},
"links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"logging": {
"type": "object",
"properties": {
"driver": {"type": "string"},
"options": {"type": "object"}
},
"additionalProperties": false
},
"mac_address": {"type": "string"},
"mem_limit": {"type": ["number", "string"]},
"memswap_limit": {"type": ["number", "string"]},
"mem_swappiness": {"type": "integer"},
"network_mode": {"type": "string"},
"networks": {
"oneOf": [
{"$ref": "#/definitions/list_of_strings"},
{
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"oneOf": [
{
"type": "object",
"properties": {
"aliases": {"$ref": "#/definitions/list_of_strings"},
"ipv4_address": {"type": "string"},
"ipv6_address": {"type": "string"},
"link_local_ips": {"$ref": "#/definitions/list_of_strings"}
},
"additionalProperties": false
},
{"type": "null"}
]
}
},
"additionalProperties": false
}
]
},
"oom_score_adj": {"type": "integer", "minimum": -1000, "maximum": 1000},
"group_add": {
"type": "array",
"items": {
"type": ["string", "number"]
},
"uniqueItems": true
},
"pid": {"type": ["string", "null"]},
"ports": {
"type": "array",
"items": {
"type": ["string", "number"],
"format": "ports"
},
"uniqueItems": true
},
"privileged": {"type": "boolean"},
"read_only": {"type": "boolean"},
"restart": {"type": "string"},
"security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"shm_size": {"type": ["number", "string"]},
"sysctls": {"$ref": "#/definitions/list_or_dict"},
"stdin_open": {"type": "boolean"},
"stop_grace_period": {"type": "string", "format": "duration"},
"stop_signal": {"type": "string"},
"tmpfs": {"$ref": "#/definitions/string_or_list"},
"tty": {"type": "boolean"},
"ulimits": {
"type": "object",
"patternProperties": {
"^[a-z]+$": {
"oneOf": [
{"type": "integer"},
{
"type":"object",
"properties": {
"hard": {"type": "integer"},
"soft": {"type": "integer"}
},
"required": ["soft", "hard"],
"additionalProperties": false
}
]
}
}
},
"user": {"type": "string"},
"userns_mode": {"type": "string"},
"volumes": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"volume_driver": {"type": "string"},
"volumes_from": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"working_dir": {"type": "string"}
},
"dependencies": {
"memswap_limit": ["mem_limit"]
},
"additionalProperties": false
},
"healthcheck": {
"id": "#/definitions/healthcheck",
"type": "object",
"additionalProperties": false,
"properties": {
"disable": {"type": "boolean"},
"interval": {"type": "string"},
"retries": {"type": "number"},
"test": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"timeout": {"type": "string"}
}
},
"network": {
"id": "#/definitions/network",
"type": "object",
"properties": {
"driver": {"type": "string"},
"driver_opts": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number"]}
}
},
"ipam": {
"type": "object",
"properties": {
"driver": {"type": "string"},
"config": {
"type": "array"
}
},
"additionalProperties": false
},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
},
"additionalProperties": false
},
"internal": {"type": "boolean"},
"enable_ipv6": {"type": "boolean"},
"labels": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
},
"volume": {
"id": "#/definitions/volume",
"type": ["object", "null"],
"properties": {
"driver": {"type": "string"},
"driver_opts": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number"]}
}
},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
},
"additionalProperties": false
},
"labels": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
},
"string_or_list": {
"oneOf": [
{"type": "string"},
{"$ref": "#/definitions/list_of_strings"}
]
},
"list_of_strings": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": true
},
"list_or_dict": {
"oneOf": [
{
"type": "object",
"patternProperties": {
".+": {
"type": ["string", "number", "null"]
}
},
"additionalProperties": false
},
{"type": "array", "items": {"type": "string"}, "uniqueItems": true}
]
},
"constraints": {
"service": {
"id": "#/definitions/constraints/service",
"anyOf": [
{"required": ["build"]},
{"required": ["image"]}
],
"properties": {
"build": {
"required": ["context"]
}
}
}
}
}
}

View file

@ -0,0 +1,383 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "config_schema_v3.0.json",
"type": "object",
"required": ["version"],
"properties": {
"version": {
"type": "string"
},
"services": {
"id": "#/properties/services",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/service"
}
},
"additionalProperties": false
},
"networks": {
"id": "#/properties/networks",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/network"
}
}
},
"volumes": {
"id": "#/properties/volumes",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/volume"
}
},
"additionalProperties": false
}
},
"additionalProperties": false,
"definitions": {
"service": {
"id": "#/definitions/service",
"type": "object",
"properties": {
"deploy": {"$ref": "#/definitions/deployment"},
"build": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"properties": {
"context": {"type": "string"},
"dockerfile": {"type": "string"},
"args": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
}
]
},
"cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cgroup_parent": {"type": "string"},
"command": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"container_name": {"type": "string"},
"depends_on": {"$ref": "#/definitions/list_of_strings"},
"devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"dns": {"$ref": "#/definitions/string_or_list"},
"dns_search": {"$ref": "#/definitions/string_or_list"},
"domainname": {"type": "string"},
"entrypoint": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"env_file": {"$ref": "#/definitions/string_or_list"},
"environment": {"$ref": "#/definitions/list_or_dict"},
"expose": {
"type": "array",
"items": {
"type": ["string", "number"],
"format": "expose"
},
"uniqueItems": true
},
"external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"extra_hosts": {"$ref": "#/definitions/list_or_dict"},
"healthcheck": {"$ref": "#/definitions/healthcheck"},
"hostname": {"type": "string"},
"image": {"type": "string"},
"ipc": {"type": "string"},
"labels": {"$ref": "#/definitions/list_or_dict"},
"links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"logging": {
"type": "object",
"properties": {
"driver": {"type": "string"},
"options": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number", "null"]}
}
}
},
"additionalProperties": false
},
"mac_address": {"type": "string"},
"network_mode": {"type": "string"},
"networks": {
"oneOf": [
{"$ref": "#/definitions/list_of_strings"},
{
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"oneOf": [
{
"type": "object",
"properties": {
"aliases": {"$ref": "#/definitions/list_of_strings"},
"ipv4_address": {"type": "string"},
"ipv6_address": {"type": "string"}
},
"additionalProperties": false
},
{"type": "null"}
]
}
},
"additionalProperties": false
}
]
},
"pid": {"type": ["string", "null"]},
"ports": {
"type": "array",
"items": {
"type": ["string", "number"],
"format": "ports"
},
"uniqueItems": true
},
"privileged": {"type": "boolean"},
"read_only": {"type": "boolean"},
"restart": {"type": "string"},
"security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"shm_size": {"type": ["number", "string"]},
"sysctls": {"$ref": "#/definitions/list_or_dict"},
"stdin_open": {"type": "boolean"},
"stop_grace_period": {"type": "string", "format": "duration"},
"stop_signal": {"type": "string"},
"tmpfs": {"$ref": "#/definitions/string_or_list"},
"tty": {"type": "boolean"},
"ulimits": {
"type": "object",
"patternProperties": {
"^[a-z]+$": {
"oneOf": [
{"type": "integer"},
{
"type":"object",
"properties": {
"hard": {"type": "integer"},
"soft": {"type": "integer"}
},
"required": ["soft", "hard"],
"additionalProperties": false
}
]
}
}
},
"user": {"type": "string"},
"userns_mode": {"type": "string"},
"volumes": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"working_dir": {"type": "string"}
},
"additionalProperties": false
},
"healthcheck": {
"id": "#/definitions/healthcheck",
"type": "object",
"additionalProperties": false,
"properties": {
"disable": {"type": "boolean"},
"interval": {"type": "string"},
"retries": {"type": "number"},
"test": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"timeout": {"type": "string"}
}
},
"deployment": {
"id": "#/definitions/deployment",
"type": ["object", "null"],
"properties": {
"mode": {"type": "string"},
"replicas": {"type": "integer"},
"labels": {"$ref": "#/definitions/list_or_dict"},
"update_config": {
"type": "object",
"properties": {
"parallelism": {"type": "integer"},
"delay": {"type": "string", "format": "duration"},
"failure_action": {"type": "string"},
"monitor": {"type": "string", "format": "duration"},
"max_failure_ratio": {"type": "number"}
},
"additionalProperties": false
},
"resources": {
"type": "object",
"properties": {
"limits": {"$ref": "#/definitions/resource"},
"reservations": {"$ref": "#/definitions/resource"}
}
},
"restart_policy": {
"type": "object",
"properties": {
"condition": {"type": "string"},
"delay": {"type": "string", "format": "duration"},
"max_attempts": {"type": "integer"},
"window": {"type": "string", "format": "duration"}
},
"additionalProperties": false
},
"placement": {
"type": "object",
"properties": {
"constraints": {"type": "array", "items": {"type": "string"}}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"resource": {
"id": "#/definitions/resource",
"type": "object",
"properties": {
"cpus": {"type": "string"},
"memory": {"type": "string"}
},
"additionalProperties": false
},
"network": {
"id": "#/definitions/network",
"type": ["object", "null"],
"properties": {
"driver": {"type": "string"},
"driver_opts": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number"]}
}
},
"ipam": {
"type": "object",
"properties": {
"driver": {"type": "string"},
"config": {
"type": "array",
"items": {
"type": "object",
"properties": {
"subnet": {"type": "string"}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
},
"additionalProperties": false
},
"internal": {"type": "boolean"},
"labels": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
},
"volume": {
"id": "#/definitions/volume",
"type": ["object", "null"],
"properties": {
"driver": {"type": "string"},
"driver_opts": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number"]}
}
},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
},
"additionalProperties": false
},
"labels": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
},
"string_or_list": {
"oneOf": [
{"type": "string"},
{"$ref": "#/definitions/list_of_strings"}
]
},
"list_of_strings": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": true
},
"list_or_dict": {
"oneOf": [
{
"type": "object",
"patternProperties": {
".+": {
"type": ["string", "number", "null"]
}
},
"additionalProperties": false
},
{"type": "array", "items": {"type": "string"}, "uniqueItems": true}
]
},
"constraints": {
"service": {
"id": "#/definitions/constraints/service",
"anyOf": [
{"required": ["build"]},
{"required": ["image"]}
],
"properties": {
"build": {
"required": ["context"]
}
}
}
}
}
}

View file

@ -0,0 +1,428 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "config_schema_v3.1.json",
"type": "object",
"required": ["version"],
"properties": {
"version": {
"type": "string"
},
"services": {
"id": "#/properties/services",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/service"
}
},
"additionalProperties": false
},
"networks": {
"id": "#/properties/networks",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/network"
}
}
},
"volumes": {
"id": "#/properties/volumes",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/volume"
}
},
"additionalProperties": false
},
"secrets": {
"id": "#/properties/secrets",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/secret"
}
},
"additionalProperties": false
}
},
"additionalProperties": false,
"definitions": {
"service": {
"id": "#/definitions/service",
"type": "object",
"properties": {
"deploy": {"$ref": "#/definitions/deployment"},
"build": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"properties": {
"context": {"type": "string"},
"dockerfile": {"type": "string"},
"args": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
}
]
},
"cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cgroup_parent": {"type": "string"},
"command": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"container_name": {"type": "string"},
"depends_on": {"$ref": "#/definitions/list_of_strings"},
"devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"dns": {"$ref": "#/definitions/string_or_list"},
"dns_search": {"$ref": "#/definitions/string_or_list"},
"domainname": {"type": "string"},
"entrypoint": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"env_file": {"$ref": "#/definitions/string_or_list"},
"environment": {"$ref": "#/definitions/list_or_dict"},
"expose": {
"type": "array",
"items": {
"type": ["string", "number"],
"format": "expose"
},
"uniqueItems": true
},
"external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"extra_hosts": {"$ref": "#/definitions/list_or_dict"},
"healthcheck": {"$ref": "#/definitions/healthcheck"},
"hostname": {"type": "string"},
"image": {"type": "string"},
"ipc": {"type": "string"},
"labels": {"$ref": "#/definitions/list_or_dict"},
"links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"logging": {
"type": "object",
"properties": {
"driver": {"type": "string"},
"options": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number", "null"]}
}
}
},
"additionalProperties": false
},
"mac_address": {"type": "string"},
"network_mode": {"type": "string"},
"networks": {
"oneOf": [
{"$ref": "#/definitions/list_of_strings"},
{
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"oneOf": [
{
"type": "object",
"properties": {
"aliases": {"$ref": "#/definitions/list_of_strings"},
"ipv4_address": {"type": "string"},
"ipv6_address": {"type": "string"}
},
"additionalProperties": false
},
{"type": "null"}
]
}
},
"additionalProperties": false
}
]
},
"pid": {"type": ["string", "null"]},
"ports": {
"type": "array",
"items": {
"type": ["string", "number"],
"format": "ports"
},
"uniqueItems": true
},
"privileged": {"type": "boolean"},
"read_only": {"type": "boolean"},
"restart": {"type": "string"},
"security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"shm_size": {"type": ["number", "string"]},
"secrets": {
"type": "array",
"items": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"properties": {
"source": {"type": "string"},
"target": {"type": "string"},
"uid": {"type": "string"},
"gid": {"type": "string"},
"mode": {"type": "number"}
}
}
]
}
},
"sysctls": {"$ref": "#/definitions/list_or_dict"},
"stdin_open": {"type": "boolean"},
"stop_grace_period": {"type": "string", "format": "duration"},
"stop_signal": {"type": "string"},
"tmpfs": {"$ref": "#/definitions/string_or_list"},
"tty": {"type": "boolean"},
"ulimits": {
"type": "object",
"patternProperties": {
"^[a-z]+$": {
"oneOf": [
{"type": "integer"},
{
"type":"object",
"properties": {
"hard": {"type": "integer"},
"soft": {"type": "integer"}
},
"required": ["soft", "hard"],
"additionalProperties": false
}
]
}
}
},
"user": {"type": "string"},
"userns_mode": {"type": "string"},
"volumes": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"working_dir": {"type": "string"}
},
"additionalProperties": false
},
"healthcheck": {
"id": "#/definitions/healthcheck",
"type": "object",
"additionalProperties": false,
"properties": {
"disable": {"type": "boolean"},
"interval": {"type": "string"},
"retries": {"type": "number"},
"test": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"timeout": {"type": "string"}
}
},
"deployment": {
"id": "#/definitions/deployment",
"type": ["object", "null"],
"properties": {
"mode": {"type": "string"},
"replicas": {"type": "integer"},
"labels": {"$ref": "#/definitions/list_or_dict"},
"update_config": {
"type": "object",
"properties": {
"parallelism": {"type": "integer"},
"delay": {"type": "string", "format": "duration"},
"failure_action": {"type": "string"},
"monitor": {"type": "string", "format": "duration"},
"max_failure_ratio": {"type": "number"}
},
"additionalProperties": false
},
"resources": {
"type": "object",
"properties": {
"limits": {"$ref": "#/definitions/resource"},
"reservations": {"$ref": "#/definitions/resource"}
}
},
"restart_policy": {
"type": "object",
"properties": {
"condition": {"type": "string"},
"delay": {"type": "string", "format": "duration"},
"max_attempts": {"type": "integer"},
"window": {"type": "string", "format": "duration"}
},
"additionalProperties": false
},
"placement": {
"type": "object",
"properties": {
"constraints": {"type": "array", "items": {"type": "string"}}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"resource": {
"id": "#/definitions/resource",
"type": "object",
"properties": {
"cpus": {"type": "string"},
"memory": {"type": "string"}
},
"additionalProperties": false
},
"network": {
"id": "#/definitions/network",
"type": ["object", "null"],
"properties": {
"driver": {"type": "string"},
"driver_opts": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number"]}
}
},
"ipam": {
"type": "object",
"properties": {
"driver": {"type": "string"},
"config": {
"type": "array",
"items": {
"type": "object",
"properties": {
"subnet": {"type": "string"}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
},
"additionalProperties": false
},
"internal": {"type": "boolean"},
"labels": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
},
"volume": {
"id": "#/definitions/volume",
"type": ["object", "null"],
"properties": {
"driver": {"type": "string"},
"driver_opts": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number"]}
}
},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
},
"additionalProperties": false
},
"labels": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
},
"secret": {
"id": "#/definitions/secret",
"type": "object",
"properties": {
"file": {"type": "string"},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
}
},
"labels": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
},
"string_or_list": {
"oneOf": [
{"type": "string"},
{"$ref": "#/definitions/list_of_strings"}
]
},
"list_of_strings": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": true
},
"list_or_dict": {
"oneOf": [
{
"type": "object",
"patternProperties": {
".+": {
"type": ["string", "number", "null"]
}
},
"additionalProperties": false
},
{"type": "array", "items": {"type": "string"}, "uniqueItems": true}
]
},
"constraints": {
"service": {
"id": "#/definitions/constraints/service",
"anyOf": [
{"required": ["build"]},
{"required": ["image"]}
],
"properties": {
"build": {
"required": ["context"]
}
}
}
}
}
}

View file

@ -0,0 +1,120 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import codecs
import contextlib
import logging
import os
import six
from ..const import IS_WINDOWS_PLATFORM
from .errors import ConfigurationError
log = logging.getLogger(__name__)
def split_env(env):
if isinstance(env, six.binary_type):
env = env.decode('utf-8', 'replace')
if '=' in env:
return env.split('=', 1)
else:
return env, None
def env_vars_from_file(filename):
"""
Read in a line delimited file of environment variables.
"""
if not os.path.exists(filename):
raise ConfigurationError("Couldn't find env file: %s" % filename)
elif not os.path.isfile(filename):
raise ConfigurationError("%s is not a file." % (filename))
env = {}
with contextlib.closing(codecs.open(filename, 'r', 'utf-8')) as fileobj:
for line in fileobj:
line = line.strip()
if line and not line.startswith('#'):
k, v = split_env(line)
env[k] = v
return env
class Environment(dict):
def __init__(self, *args, **kwargs):
super(Environment, self).__init__(*args, **kwargs)
self.missing_keys = []
@classmethod
def from_env_file(cls, base_dir):
def _initialize():
result = cls()
if base_dir is None:
return result
env_file_path = os.path.join(base_dir, '.env')
try:
return cls(env_vars_from_file(env_file_path))
except ConfigurationError:
pass
return result
instance = _initialize()
instance.update(os.environ)
return instance
@classmethod
def from_command_line(cls, parsed_env_opts):
result = cls()
for k, v in parsed_env_opts.items():
# Values from the command line take priority, unless they're unset
# in which case they take the value from the system's environment
if v is None and k in os.environ:
result[k] = os.environ[k]
else:
result[k] = v
return result
def __getitem__(self, key):
try:
return super(Environment, self).__getitem__(key)
except KeyError:
if IS_WINDOWS_PLATFORM:
try:
return super(Environment, self).__getitem__(key.upper())
except KeyError:
pass
if key not in self.missing_keys:
log.warn(
"The {} variable is not set. Defaulting to a blank string."
.format(key)
)
self.missing_keys.append(key)
return ""
def __contains__(self, key):
result = super(Environment, self).__contains__(key)
if IS_WINDOWS_PLATFORM:
return (
result or super(Environment, self).__contains__(key.upper())
)
return result
def get(self, key, *args, **kwargs):
if IS_WINDOWS_PLATFORM:
return super(Environment, self).get(
key,
super(Environment, self).get(key.upper(), *args, **kwargs)
)
return super(Environment, self).get(key, *args, **kwargs)
def get_boolean(self, key):
# Convert a value to a boolean using "common sense" rules.
# Unset, empty, "0" and "false" (i-case) yield False.
# All other values yield True.
value = self.get(key)
if not value:
return False
if value.lower() in ['0', 'false']:
return False
return True

View file

@ -1,3 +1,16 @@
from __future__ import absolute_import
from __future__ import unicode_literals
VERSION_EXPLANATION = (
'You might be seeing this error because you\'re using the wrong Compose file version. '
'Either specify a supported version ("2.0", "2.1", "3.0") and place your '
'service definitions under the `services` key, or omit the `version` key '
'and place your service definitions at the root of the file to use '
'version 1.\nFor more on the Compose file format versions, see '
'https://docs.docker.com/compose/compose-file/')
class ConfigurationError(Exception):
def __init__(self, msg):
self.msg = msg
@ -6,6 +19,10 @@ class ConfigurationError(Exception):
return self.msg
class DependencyError(ConfigurationError):
pass
class CircularReference(ConfigurationError):
def __init__(self, trail):
self.trail = trail
@ -22,7 +39,8 @@ class CircularReference(ConfigurationError):
class ComposeFileNotFound(ConfigurationError):
def __init__(self, supported_filenames):
super(ComposeFileNotFound, self).__init__("""
Can't find a suitable configuration file in this directory or any parent. Are you in the right directory?
Can't find a suitable configuration file in this directory or any
parent. Are you in the right directory?
Supported filenames: %s
""" % ", ".join(supported_filenames))

View file

@ -1,89 +1,101 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import logging
import os
from string import Template
import six
from .errors import ConfigurationError
from compose.const import COMPOSEFILE_V1 as V1
from compose.const import COMPOSEFILE_V2_0 as V2_0
log = logging.getLogger(__name__)
def interpolate_environment_variables(config):
mapping = BlankDefaultDict(os.environ)
class Interpolator(object):
return dict(
(service_name, process_service(service_name, service_dict, mapping))
for (service_name, service_dict) in config.items()
)
def __init__(self, templater, mapping):
self.templater = templater
self.mapping = mapping
def process_service(service_name, service_dict, mapping):
if not isinstance(service_dict, dict):
raise ConfigurationError(
'Service "%s" doesn\'t have any configuration options. '
'All top level keys in your docker-compose.yml must map '
'to a dictionary of configuration options.' % service_name
)
return dict(
(key, interpolate_value(service_name, key, val, mapping))
for (key, val) in service_dict.items()
)
def interpolate_value(service_name, config_key, value, mapping):
def interpolate(self, string):
try:
return recursive_interpolate(value, mapping)
except InvalidInterpolation as e:
raise ConfigurationError(
'Invalid interpolation format for "{config_key}" option '
'in service "{service_name}": "{string}"'
.format(
config_key=config_key,
service_name=service_name,
string=e.string,
)
)
def recursive_interpolate(obj, mapping):
if isinstance(obj, six.string_types):
return interpolate(obj, mapping)
elif isinstance(obj, dict):
return dict(
(key, recursive_interpolate(val, mapping))
for (key, val) in obj.items()
)
elif isinstance(obj, list):
return [recursive_interpolate(val, mapping) for val in obj]
else:
return obj
def interpolate(string, mapping):
try:
return Template(string).substitute(mapping)
return self.templater(string).substitute(self.mapping)
except ValueError:
raise InvalidInterpolation(string)
class BlankDefaultDict(dict):
def __init__(self, *args, **kwargs):
super(BlankDefaultDict, self).__init__(*args, **kwargs)
self.missing_keys = []
def interpolate_environment_variables(version, config, section, environment):
if version in (V2_0, V1):
interpolator = Interpolator(Template, environment)
else:
interpolator = Interpolator(TemplateWithDefaults, environment)
def __getitem__(self, key):
try:
return super(BlankDefaultDict, self).__getitem__(key)
except KeyError:
if key not in self.missing_keys:
log.warn(
"The {} variable is not set. Defaulting to a blank string."
.format(key)
def process_item(name, config_dict):
return dict(
(key, interpolate_value(name, key, val, section, interpolator))
for key, val in (config_dict or {}).items()
)
self.missing_keys.append(key)
return ""
return dict(
(name, process_item(name, config_dict or {}))
for name, config_dict in config.items()
)
def interpolate_value(name, config_key, value, section, interpolator):
try:
return recursive_interpolate(value, interpolator)
except InvalidInterpolation as e:
raise ConfigurationError(
'Invalid interpolation format for "{config_key}" option '
'in {section} "{name}": "{string}"'.format(
config_key=config_key,
name=name,
section=section,
string=e.string))
def recursive_interpolate(obj, interpolator):
if isinstance(obj, six.string_types):
return interpolator.interpolate(obj)
if isinstance(obj, dict):
return dict(
(key, recursive_interpolate(val, interpolator))
for (key, val) in obj.items()
)
if isinstance(obj, list):
return [recursive_interpolate(val, interpolator) for val in obj]
return obj
class TemplateWithDefaults(Template):
idpattern = r'[_a-z][_a-z0-9]*(?::?-[^}]+)?'
# Modified from python2.7/string.py
def substitute(self, mapping):
# Helper function for .sub()
def convert(mo):
# Check the most common path first.
named = mo.group('named') or mo.group('braced')
if named is not None:
if ':-' in named:
var, _, default = named.partition(':-')
return mapping.get(var) or default
if '-' in named:
var, _, default = named.partition('-')
return mapping.get(var, default)
val = mapping[named]
return '%s' % (val,)
if mo.group('escaped') is not None:
return self.delimiter
if mo.group('invalid') is not None:
self._invalid(mo)
raise ValueError('Unrecognized named group in pattern',
self.pattern)
return self.pattern.sub(convert, self.template)
class InvalidInterpolation(Exception):

108
compose/config/serialize.py Normal file
View file

@ -0,0 +1,108 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import six
import yaml
from compose.config import types
from compose.config.config import V1
from compose.config.config import V2_1
def serialize_config_type(dumper, data):
representer = dumper.represent_str if six.PY3 else dumper.represent_unicode
return representer(data.repr())
yaml.SafeDumper.add_representer(types.VolumeFromSpec, serialize_config_type)
yaml.SafeDumper.add_representer(types.VolumeSpec, serialize_config_type)
def denormalize_config(config):
denormalized_services = [
denormalize_service_dict(service_dict, config.version)
for service_dict in config.services
]
services = {
service_dict.pop('name'): service_dict
for service_dict in denormalized_services
}
networks = config.networks.copy()
for net_name, net_conf in networks.items():
if 'external_name' in net_conf:
del net_conf['external_name']
volumes = config.volumes.copy()
for vol_name, vol_conf in volumes.items():
if 'external_name' in vol_conf:
del vol_conf['external_name']
version = config.version
if version == V1:
version = V2_1
return {
'version': version,
'services': services,
'networks': networks,
'volumes': volumes,
}
def serialize_config(config):
return yaml.safe_dump(
denormalize_config(config),
default_flow_style=False,
indent=2,
width=80)
def serialize_ns_time_value(value):
result = (value, 'ns')
table = [
(1000., 'us'),
(1000., 'ms'),
(1000., 's'),
(60., 'm'),
(60., 'h')
]
for stage in table:
tmp = value / stage[0]
if tmp == int(value / stage[0]):
value = tmp
result = (int(value), stage[1])
else:
break
return '{0}{1}'.format(*result)
def denormalize_service_dict(service_dict, version):
service_dict = service_dict.copy()
if 'restart' in service_dict:
service_dict['restart'] = types.serialize_restart_spec(
service_dict['restart']
)
if version == V1 and 'network_mode' not in service_dict:
service_dict['network_mode'] = 'bridge'
if 'depends_on' in service_dict and version != V2_1:
service_dict['depends_on'] = sorted([
svc for svc in service_dict['depends_on'].keys()
])
if 'healthcheck' in service_dict:
if 'interval' in service_dict['healthcheck']:
service_dict['healthcheck']['interval'] = serialize_ns_time_value(
service_dict['healthcheck']['interval']
)
if 'timeout' in service_dict['healthcheck']:
service_dict['healthcheck']['timeout'] = serialize_ns_time_value(
service_dict['healthcheck']['timeout']
)
if 'secrets' in service_dict:
service_dict['secrets'] = map(lambda s: s.repr(), service_dict['secrets'])
return service_dict

View file

@ -1,39 +0,0 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"}
},
"required": ["name"],
"allOf": [
{"$ref": "fields_schema.json#/definitions/service"},
{"$ref": "#/definitions/service_constraints"}
],
"definitions": {
"service_constraints": {
"anyOf": [
{
"required": ["build"],
"not": {"required": ["image"]}
},
{
"required": ["image"],
"not": {"anyOf": [
{"required": ["build"]},
{"required": ["dockerfile"]}
]}
},
{
"required": ["extends"],
"not": {"required": ["build", "image"]}
}
]
}
}
}

View file

@ -0,0 +1,72 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from compose.config.errors import DependencyError
def get_service_name_from_network_mode(network_mode):
return get_source_name_from_network_mode(network_mode, 'service')
def get_container_name_from_network_mode(network_mode):
return get_source_name_from_network_mode(network_mode, 'container')
def get_source_name_from_network_mode(network_mode, source_type):
if not network_mode:
return
if not network_mode.startswith(source_type+':'):
return
_, net_name = network_mode.split(':', 1)
return net_name
def get_service_names(links):
return [link.split(':')[0] for link in links]
def get_service_names_from_volumes_from(volumes_from):
return [volume_from.source for volume_from in volumes_from]
def get_service_dependents(service_dict, services):
name = service_dict['name']
return [
service for service in services
if (name in get_service_names(service.get('links', [])) or
name in get_service_names_from_volumes_from(service.get('volumes_from', [])) or
name == get_service_name_from_network_mode(service.get('network_mode')) or
name in service.get('depends_on', []))
]
def sort_service_dicts(services):
# Topological sort (Cormen/Tarjan algorithm).
unmarked = services[:]
temporary_marked = set()
sorted_services = []
def visit(n):
if n['name'] in temporary_marked:
if n['name'] in get_service_names(n.get('links', [])):
raise DependencyError('A service can not link to itself: %s' % n['name'])
if n['name'] in n.get('volumes_from', []):
raise DependencyError('A service can not mount itself as volume: %s' % n['name'])
if n['name'] in n.get('depends_on', []):
raise DependencyError('A service can not depend on itself: %s' % n['name'])
raise DependencyError('Circular dependency between %s' % ' and '.join(temporary_marked))
if n in unmarked:
temporary_marked.add(n['name'])
for m in get_service_dependents(n, services):
visit(m)
temporary_marked.remove(n['name'])
unmarked.remove(n)
sorted_services.insert(0, n)
while unmarked:
visit(unmarked[-1])
return sorted_services

260
compose/config/types.py Normal file
View file

@ -0,0 +1,260 @@
"""
Types for objects parsed from the configuration.
"""
from __future__ import absolute_import
from __future__ import unicode_literals
import os
import re
from collections import namedtuple
import six
from ..const import COMPOSEFILE_V1 as V1
from .errors import ConfigurationError
from compose.const import IS_WINDOWS_PLATFORM
from compose.utils import splitdrive
win32_root_path_pattern = re.compile(r'^[A-Za-z]\:\\.*')
class VolumeFromSpec(namedtuple('_VolumeFromSpec', 'source mode type')):
# TODO: drop service_names arg when v1 is removed
@classmethod
def parse(cls, volume_from_config, service_names, version):
func = cls.parse_v1 if version == V1 else cls.parse_v2
return func(service_names, volume_from_config)
@classmethod
def parse_v1(cls, service_names, volume_from_config):
parts = volume_from_config.split(':')
if len(parts) > 2:
raise ConfigurationError(
"volume_from {} has incorrect format, should be "
"service[:mode]".format(volume_from_config))
if len(parts) == 1:
source = parts[0]
mode = 'rw'
else:
source, mode = parts
type = 'service' if source in service_names else 'container'
return cls(source, mode, type)
@classmethod
def parse_v2(cls, service_names, volume_from_config):
parts = volume_from_config.split(':')
if len(parts) > 3:
raise ConfigurationError(
"volume_from {} has incorrect format, should be one of "
"'<service name>[:<mode>]' or "
"'container:<container name>[:<mode>]'".format(volume_from_config))
if len(parts) == 1:
source = parts[0]
return cls(source, 'rw', 'service')
if len(parts) == 2:
if parts[0] == 'container':
type, source = parts
return cls(source, 'rw', type)
source, mode = parts
return cls(source, mode, 'service')
if len(parts) == 3:
type, source, mode = parts
if type not in ('service', 'container'):
raise ConfigurationError(
"Unknown volumes_from type '{}' in '{}'".format(
type,
volume_from_config))
return cls(source, mode, type)
def repr(self):
return '{v.type}:{v.source}:{v.mode}'.format(v=self)
def parse_restart_spec(restart_config):
if not restart_config:
return None
parts = restart_config.split(':')
if len(parts) > 2:
raise ConfigurationError(
"Restart %s has incorrect format, should be "
"mode[:max_retry]" % restart_config)
if len(parts) == 2:
name, max_retry_count = parts
else:
name, = parts
max_retry_count = 0
return {'Name': name, 'MaximumRetryCount': int(max_retry_count)}
def serialize_restart_spec(restart_spec):
if not restart_spec:
return ''
parts = [restart_spec['Name']]
if restart_spec['MaximumRetryCount']:
parts.append(six.text_type(restart_spec['MaximumRetryCount']))
return ':'.join(parts)
def parse_extra_hosts(extra_hosts_config):
if not extra_hosts_config:
return {}
if isinstance(extra_hosts_config, dict):
return dict(extra_hosts_config)
if isinstance(extra_hosts_config, list):
extra_hosts_dict = {}
for extra_hosts_line in extra_hosts_config:
# TODO: validate string contains ':' ?
host, ip = extra_hosts_line.split(':', 1)
extra_hosts_dict[host.strip()] = ip.strip()
return extra_hosts_dict
def normalize_path_for_engine(path):
"""Windows paths, c:\my\path\shiny, need to be changed to be compatible with
the Engine. Volume paths are expected to be linux style /c/my/path/shiny/
"""
drive, tail = splitdrive(path)
if drive:
path = '/' + drive.lower().rstrip(':') + tail
return path.replace('\\', '/')
class VolumeSpec(namedtuple('_VolumeSpec', 'external internal mode')):
@classmethod
def _parse_unix(cls, volume_config):
parts = volume_config.split(':')
if len(parts) > 3:
raise ConfigurationError(
"Volume %s has incorrect format, should be "
"external:internal[:mode]" % volume_config)
if len(parts) == 1:
external = None
internal = os.path.normpath(parts[0])
else:
external = os.path.normpath(parts[0])
internal = os.path.normpath(parts[1])
mode = 'rw'
if len(parts) == 3:
mode = parts[2]
return cls(external, internal, mode)
@classmethod
def _parse_win32(cls, volume_config, normalize):
# relative paths in windows expand to include the drive, eg C:\
# so we join the first 2 parts back together to count as one
mode = 'rw'
def separate_next_section(volume_config):
drive, tail = splitdrive(volume_config)
parts = tail.split(':', 1)
if drive:
parts[0] = drive + parts[0]
return parts
parts = separate_next_section(volume_config)
if len(parts) == 1:
internal = parts[0]
external = None
else:
external = parts[0]
parts = separate_next_section(parts[1])
external = os.path.normpath(external)
internal = parts[0]
if len(parts) > 1:
if ':' in parts[1]:
raise ConfigurationError(
"Volume %s has incorrect format, should be "
"external:internal[:mode]" % volume_config
)
mode = parts[1]
if normalize:
external = normalize_path_for_engine(external) if external else None
return cls(external, internal, mode)
@classmethod
def parse(cls, volume_config, normalize=False):
"""Parse a volume_config path and split it into external:internal[:mode]
parts to be returned as a valid VolumeSpec.
"""
if IS_WINDOWS_PLATFORM:
return cls._parse_win32(volume_config, normalize)
else:
return cls._parse_unix(volume_config)
def repr(self):
external = self.external + ':' if self.external else ''
return '{ext}{v.internal}:{v.mode}'.format(ext=external, v=self)
@property
def is_named_volume(self):
res = self.external and not self.external.startswith(('.', '/', '~'))
if not IS_WINDOWS_PLATFORM:
return res
return (
res and not self.external.startswith('\\') and
not win32_root_path_pattern.match(self.external)
)
class ServiceLink(namedtuple('_ServiceLink', 'target alias')):
@classmethod
def parse(cls, link_spec):
target, _, alias = link_spec.partition(':')
if not alias:
alias = target
return cls(target, alias)
def repr(self):
if self.target == self.alias:
return self.target
return '{s.target}:{s.alias}'.format(s=self)
@property
def merge_field(self):
return self.alias
class ServiceSecret(namedtuple('_ServiceSecret', 'source target uid gid mode')):
@classmethod
def parse(cls, spec):
if isinstance(spec, six.string_types):
return cls(spec, None, None, None, None)
return cls(
spec.get('source'),
spec.get('target'),
spec.get('uid'),
spec.get('gid'),
spec.get('mode'),
)
@property
def merge_field(self):
return self.source
def repr(self):
return dict(
[(k, v) for k, v in self._asdict().items() if v is not None]
)

View file

@ -1,6 +1,10 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import json
import logging
import os
import re
import sys
import six
@ -10,7 +14,10 @@ from jsonschema import FormatChecker
from jsonschema import RefResolver
from jsonschema import ValidationError
from ..const import COMPOSEFILE_V1 as V1
from .errors import ConfigurationError
from .errors import VERSION_EXPLANATION
from .sort_services import get_service_name_from_network_mode
log = logging.getLogger(__name__)
@ -34,53 +41,103 @@ DOCKER_CONFIG_HINTS = {
VALID_NAME_CHARS = '[a-zA-Z0-9\._\-]'
VALID_EXPOSE_FORMAT = r'^\d+(\-\d+)?(\/[a-zA-Z]+)?$'
@FormatChecker.cls_checks(
format="ports",
raises=ValidationError(
"Invalid port formatting, it should be "
"'[[remote_ip:]remote_port:]port[/protocol]'"))
@FormatChecker.cls_checks(format="ports", raises=ValidationError)
def format_ports(instance):
try:
split_port(instance)
except ValueError:
return False
except ValueError as e:
raise ValidationError(six.text_type(e))
return True
@FormatChecker.cls_checks(format="environment")
def format_boolean_in_environment(instance):
"""
Check if there is a boolean in the environment and display a warning.
Always return True here so the validation won't raise an error.
"""
if isinstance(instance, bool):
log.warn(
"There is a boolean value in the 'environment' key.\n"
"Environment variables can only be strings.\n"
"Please add quotes to any boolean values to make them string "
"(eg, 'True', 'yes', 'N').\n"
"This warning will become an error in a future release. \r\n"
)
@FormatChecker.cls_checks(format="expose", raises=ValidationError)
def format_expose(instance):
if isinstance(instance, six.string_types):
if not re.match(VALID_EXPOSE_FORMAT, instance):
raise ValidationError(
"should be of the format 'PORT[/PROTOCOL]'")
return True
def validate_service_names(config):
for service_name in config.keys():
if not isinstance(service_name, six.string_types):
def match_named_volumes(service_dict, project_volumes):
service_volumes = service_dict.get('volumes', [])
for volume_spec in service_volumes:
if volume_spec.is_named_volume and volume_spec.external not in project_volumes:
raise ConfigurationError(
"Service name: {} needs to be a string, eg '{}'".format(
service_name,
service_name))
'Named volume "{0}" is used in service "{1}" but no'
' declaration was found in the volumes section.'.format(
volume_spec.repr(), service_dict.get('name')
)
)
def validate_top_level_object(config):
def python_type_to_yaml_type(type_):
type_name = type(type_).__name__
return {
'dict': 'mapping',
'list': 'array',
'int': 'number',
'float': 'number',
'bool': 'boolean',
'unicode': 'string',
'str': 'string',
'bytes': 'string',
}.get(type_name, type_name)
def validate_config_section(filename, config, section):
"""Validate the structure of a configuration section. This must be done
before interpolation so it's separate from schema validation.
"""
if not isinstance(config, dict):
raise ConfigurationError(
"Top level object needs to be a dictionary. Check your .yml file "
"that you have defined a service at the top level.")
validate_service_names(config)
"In file '{filename}', {section} must be a mapping, not "
"{type}.".format(
filename=filename,
section=section,
type=anglicize_json_type(python_type_to_yaml_type(config))))
for key, value in config.items():
if not isinstance(key, six.string_types):
raise ConfigurationError(
"In file '{filename}', the {section} name {name} must be a "
"quoted string, i.e. '{name}'.".format(
filename=filename,
section=section,
name=key))
if not isinstance(value, (dict, type(None))):
raise ConfigurationError(
"In file '{filename}', {section} '{name}' must be a mapping not "
"{type}.".format(
filename=filename,
section=section,
name=key,
type=anglicize_json_type(python_type_to_yaml_type(value))))
def validate_top_level_object(config_file):
if not isinstance(config_file.config, dict):
raise ConfigurationError(
"Top level object in '{}' needs to be an object not '{}'.".format(
config_file.filename,
type(config_file.config)))
def validate_ulimits(service_config):
ulimit_config = service_config.config.get('ulimits', {})
for limit_name, soft_hard_values in six.iteritems(ulimit_config):
if isinstance(soft_hard_values, dict):
if not soft_hard_values['soft'] <= soft_hard_values['hard']:
raise ConfigurationError(
"Service '{s.name}' has invalid ulimit '{ulimit}'. "
"'soft' value can not be greater than 'hard' value ".format(
s=service_config,
ulimit=ulimit_config))
def validate_extends_file_path(service_name, extends_options, filename):
@ -96,228 +153,271 @@ def validate_extends_file_path(service_name, extends_options, filename):
)
def validate_extended_service_exists(extended_service_name, full_extended_config, extended_config_path):
if extended_service_name not in full_extended_config:
msg = (
"Cannot extend service '%s' in %s: Service not found"
) % (extended_service_name, extended_config_path)
raise ConfigurationError(msg)
def validate_network_mode(service_config, service_names):
network_mode = service_config.config.get('network_mode')
if not network_mode:
return
if 'networks' in service_config.config:
raise ConfigurationError("'network_mode' and 'networks' cannot be combined")
dependency = get_service_name_from_network_mode(network_mode)
if not dependency:
return
if dependency not in service_names:
raise ConfigurationError(
"Service '{s.name}' uses the network stack of service '{dep}' which "
"is undefined.".format(s=service_config, dep=dependency))
def get_unsupported_config_msg(service_name, error_key):
msg = "Unsupported config option for '{}' service: '{}'".format(service_name, error_key)
def validate_links(service_config, service_names):
for link in service_config.config.get('links', []):
if link.split(':')[0] not in service_names:
raise ConfigurationError(
"Service '{s.name}' has a link to service '{link}' which is "
"undefined.".format(s=service_config, link=link))
def validate_depends_on(service_config, service_names):
deps = service_config.config.get('depends_on', {})
for dependency in deps.keys():
if dependency not in service_names:
raise ConfigurationError(
"Service '{s.name}' depends on service '{dep}' which is "
"undefined.".format(s=service_config, dep=dependency)
)
def get_unsupported_config_msg(path, error_key):
msg = "Unsupported config option for {}: '{}'".format(path_string(path), error_key)
if error_key in DOCKER_CONFIG_HINTS:
msg += " (did you mean '{}'?)".format(DOCKER_CONFIG_HINTS[error_key])
return msg
def anglicize_validator(validator):
if validator in ["array", "object"]:
return 'an ' + validator
return 'a ' + validator
def anglicize_json_type(json_type):
if json_type.startswith(('a', 'e', 'i', 'o', 'u')):
return 'an ' + json_type
return 'a ' + json_type
def process_errors(errors, service_name=None):
"""
jsonschema gives us an error tree full of information to explain what has
gone wrong. Process each error and pull out relevant information and re-write
helpful error messages that are relevant.
"""
def _parse_key_from_error_msg(error):
def is_service_dict_schema(schema_id):
return schema_id in ('config_schema_v1.json', '#/properties/services')
def handle_error_for_schema_with_id(error, path):
schema_id = error.schema['id']
if is_service_dict_schema(schema_id) and error.validator == 'additionalProperties':
return "Invalid service name '{}' - only {} characters are allowed".format(
# The service_name is the key to the json object
list(error.instance)[0],
VALID_NAME_CHARS)
if error.validator == 'additionalProperties':
if schema_id == '#/definitions/service':
invalid_config_key = parse_key_from_error_msg(error)
return get_unsupported_config_msg(path, invalid_config_key)
if not error.path:
return '{}\n\n{}'.format(error.message, VERSION_EXPLANATION)
def handle_generic_error(error, path):
msg_format = None
error_msg = error.message
if error.validator == 'oneOf':
msg_format = "{path} {msg}"
config_key, error_msg = _parse_oneof_validator(error)
if config_key:
path.append(config_key)
elif error.validator == 'type':
msg_format = "{path} contains an invalid type, it should be {msg}"
error_msg = _parse_valid_types_from_validator(error.validator_value)
elif error.validator == 'required':
error_msg = ", ".join(error.validator_value)
msg_format = "{path} is invalid, {msg} is required."
elif error.validator == 'dependencies':
config_key = list(error.validator_value.keys())[0]
required_keys = ",".join(error.validator_value[config_key])
msg_format = "{path} is invalid: {msg}"
path.append(config_key)
error_msg = "when defining '{}' you must set '{}' as well".format(
config_key,
required_keys)
elif error.cause:
error_msg = six.text_type(error.cause)
msg_format = "{path} is invalid: {msg}"
elif error.path:
msg_format = "{path} value {msg}"
if msg_format:
return msg_format.format(path=path_string(path), msg=error_msg)
return error.message
def parse_key_from_error_msg(error):
return error.message.split("'")[1]
def _clean_error_message(message):
return message.replace("u'", "'")
def _parse_valid_types_from_validator(validator):
"""
A validator value can be either an array of valid types or a string of
def path_string(path):
return ".".join(c for c in path if isinstance(c, six.string_types))
def _parse_valid_types_from_validator(validator):
"""A validator value can be either an array of valid types or a string of
a valid type. Parse the valid types and prefix with the correct article.
"""
if isinstance(validator, list):
if len(validator) >= 2:
first_type = anglicize_validator(validator[0])
last_type = anglicize_validator(validator[-1])
types_from_validator = ", ".join([first_type] + validator[1:-1])
if not isinstance(validator, list):
return anglicize_json_type(validator)
msg = "{} or {}".format(
types_from_validator,
last_type
)
else:
msg = "{}".format(anglicize_validator(validator[0]))
else:
msg = "{}".format(anglicize_validator(validator))
if len(validator) == 1:
return anglicize_json_type(validator[0])
return msg
return "{}, or {}".format(
", ".join([anglicize_json_type(validator[0])] + validator[1:-1]),
anglicize_json_type(validator[-1]))
def _parse_oneof_validator(error):
"""
oneOf has multiple schemas, so we need to reason about which schema, sub
def _parse_oneof_validator(error):
"""oneOf has multiple schemas, so we need to reason about which schema, sub
schema or constraint the validation is failing on.
Inspecting the context value of a ValidationError gives us information about
which sub schema failed and which kind of error it is.
"""
required = [context for context in error.context if context.validator == 'required']
if required:
return required[0].message
types = []
for context in error.context:
additionalProperties = [context for context in error.context if context.validator == 'additionalProperties']
if additionalProperties:
invalid_config_key = _parse_key_from_error_msg(additionalProperties[0])
return "contains unsupported option: '{}'".format(invalid_config_key)
if context.validator == 'oneOf':
_, error_msg = _parse_oneof_validator(context)
return path_string(context.path), error_msg
constraint = [context for context in error.context if len(context.path) > 0]
if constraint:
valid_types = _parse_valid_types_from_validator(constraint[0].validator_value)
invalid_config_key = "".join(
"'{}' ".format(fragment) for fragment in constraint[0].path
if isinstance(fragment, six.string_types)
if context.validator == 'required':
return (None, context.message)
if context.validator == 'additionalProperties':
invalid_config_key = parse_key_from_error_msg(context)
return (None, "contains unsupported option: '{}'".format(invalid_config_key))
if context.path:
return (
path_string(context.path),
"contains {}, which is an invalid type, it should be {}".format(
json.dumps(context.instance),
_parse_valid_types_from_validator(context.validator_value)),
)
msg = "{}contains {}, which is an invalid type, it should be {}".format(
invalid_config_key,
constraint[0].instance,
valid_types
)
return msg
uniqueness = [context for context in error.context if context.validator == 'uniqueItems']
if uniqueness:
msg = "contains non unique items, please remove duplicates from {}".format(
uniqueness[0].instance
if context.validator == 'uniqueItems':
return (
None,
"contains non unique items, please remove duplicates from {}".format(
context.instance),
)
return msg
types = [context.validator_value for context in error.context if context.validator == 'type']
if context.validator == 'type':
types.append(context.validator_value)
valid_types = _parse_valid_types_from_validator(types)
return (None, "contains an invalid type, it should be {}".format(valid_types))
msg = "contains an invalid type, it should be {}".format(valid_types)
return msg
root_msgs = []
invalid_keys = []
required = []
type_errors = []
other_errors = []
for error in errors:
# handle root level errors
if len(error.path) == 0 and not error.instance.get('name'):
if error.validator == 'type':
msg = "Top level object needs to be a dictionary. Check your .yml file that you have defined a service at the top level."
root_msgs.append(msg)
elif error.validator == 'additionalProperties':
invalid_service_name = _parse_key_from_error_msg(error)
msg = "Invalid service name '{}' - only {} characters are allowed".format(invalid_service_name, VALID_NAME_CHARS)
root_msgs.append(msg)
else:
root_msgs.append(_clean_error_message(error.message))
else:
if not service_name:
# field_schema errors will have service name on the path
service_name = error.path[0]
error.path.popleft()
else:
# service_schema errors have the service name passed in, as that
# is not available on error.path or necessarily error.instance
service_name = service_name
if error.validator == 'additionalProperties':
invalid_config_key = _parse_key_from_error_msg(error)
invalid_keys.append(get_unsupported_config_msg(service_name, invalid_config_key))
elif error.validator == 'anyOf':
def process_service_constraint_errors(error, service_name, version):
if version == V1:
if 'image' in error.instance and 'build' in error.instance:
required.append(
"Service '{}' has both an image and build path specified. "
return (
"Service {} has both an image and build path specified. "
"A service can either be built to image or use an existing "
"image, not both.".format(service_name))
elif 'image' not in error.instance and 'build' not in error.instance:
required.append(
"Service '{}' has neither an image nor a build path "
"specified. Exactly one must be provided.".format(service_name))
elif 'image' in error.instance and 'dockerfile' in error.instance:
required.append(
"Service '{}' has both an image and alternate Dockerfile. "
if 'image' in error.instance and 'dockerfile' in error.instance:
return (
"Service {} has both an image and alternate Dockerfile. "
"A service can either be built to image or use an existing "
"image, not both.".format(service_name))
else:
required.append(_clean_error_message(error.message))
elif error.validator == 'oneOf':
config_key = error.path[0]
msg = _parse_oneof_validator(error)
type_errors.append("Service '{}' configuration key '{}' {}".format(
service_name, config_key, msg)
)
elif error.validator == 'type':
msg = _parse_valid_types_from_validator(error.validator_value)
if len(error.path) > 0:
config_key = " ".join(["'%s'" % k for k in error.path])
type_errors.append(
"Service '{}' configuration key {} contains an invalid "
"type, it should be {}".format(
service_name,
config_key,
msg))
else:
root_msgs.append(
"Service '{}' doesn\'t have any configuration options. "
"All top level keys in your docker-compose.yml must map "
"to a dictionary of configuration options.'".format(service_name))
elif error.validator == 'required':
config_key = error.path[0]
required.append(
"Service '{}' option '{}' is invalid, {}".format(
service_name,
config_key,
_clean_error_message(error.message)))
elif error.validator == 'dependencies':
dependency_key = list(error.validator_value.keys())[0]
required_keys = ",".join(error.validator_value[dependency_key])
required.append("Invalid '{}' configuration for '{}' service: when defining '{}' you must set '{}' as well".format(
dependency_key, service_name, dependency_key, required_keys))
else:
config_key = " ".join(["'%s'" % k for k in error.path])
err_msg = "Service '{}' configuration key {} value {}".format(service_name, config_key, error.message)
other_errors.append(err_msg)
return "\n".join(root_msgs + invalid_keys + required + type_errors + other_errors)
if 'image' not in error.instance and 'build' not in error.instance:
return (
"Service {} has neither an image nor a build context specified. "
"At least one must be provided.".format(service_name))
def validate_against_fields_schema(config):
schema_filename = "fields_schema.json"
format_checkers = ["ports", "environment"]
return _validate_against_schema(config, schema_filename, format_checkers)
def process_config_schema_errors(error):
path = list(error.path)
if 'id' in error.schema:
error_msg = handle_error_for_schema_with_id(error, path)
if error_msg:
return error_msg
return handle_generic_error(error, path)
def validate_against_service_schema(config, service_name):
schema_filename = "service_schema.json"
format_checkers = ["ports"]
return _validate_against_schema(config, schema_filename, format_checkers, service_name)
def validate_against_config_schema(config_file):
schema = load_jsonschema(config_file.version)
format_checker = FormatChecker(["ports", "expose"])
validator = Draft4Validator(
schema,
resolver=RefResolver(get_resolver_path(), schema),
format_checker=format_checker)
handle_errors(
validator.iter_errors(config_file.config),
process_config_schema_errors,
config_file.filename)
def _validate_against_schema(config, schema_filename, format_checker=[], service_name=None):
config_source_dir = os.path.dirname(os.path.abspath(__file__))
def validate_service_constraints(config, service_name, version):
def handler(errors):
return process_service_constraint_errors(errors, service_name, version)
schema = load_jsonschema(version)
validator = Draft4Validator(schema['definitions']['constraints']['service'])
handle_errors(validator.iter_errors(config), handler, None)
def get_schema_path():
return os.path.dirname(os.path.abspath(__file__))
def load_jsonschema(version):
filename = os.path.join(
get_schema_path(),
"config_schema_v{0}.json".format(version))
with open(filename, "r") as fh:
return json.load(fh)
def get_resolver_path():
schema_path = get_schema_path()
if sys.platform == "win32":
file_pre_fix = "///"
config_source_dir = config_source_dir.replace('\\', '/')
scheme = "///"
# TODO: why is this necessary?
schema_path = schema_path.replace('\\', '/')
else:
file_pre_fix = "//"
scheme = "//"
return "file:{}{}/".format(scheme, schema_path)
resolver_full_path = "file:{}{}/".format(file_pre_fix, config_source_dir)
schema_file = os.path.join(config_source_dir, schema_filename)
with open(schema_file, "r") as schema_fh:
schema = json.load(schema_fh)
def handle_errors(errors, format_error_func, filename):
"""jsonschema returns an error tree full of information to explain what has
gone wrong. Process each error and pull out relevant information and re-write
helpful error messages that are relevant.
"""
errors = list(sorted(errors, key=str))
if not errors:
return
resolver = RefResolver(resolver_full_path, schema)
validation_output = Draft4Validator(schema, resolver=resolver, format_checker=FormatChecker(format_checker))
errors = [error for error in sorted(validation_output.iter_errors(config), key=str)]
if errors:
error_msg = process_errors(errors, service_name)
raise ConfigurationError("Validation failed, reason(s):\n{}".format(error_msg))
error_msg = '\n'.join(format_error_func(error) for error in errors)
raise ConfigurationError(
"The Compose file{file_msg} is invalid because:\n{error_msg}".format(
file_msg=" '{}'".format(filename) if filename else "",
error_msg=error_msg))

View file

@ -1,12 +1,41 @@
import os
from __future__ import absolute_import
from __future__ import unicode_literals
import sys
DEFAULT_TIMEOUT = 10
HTTP_TIMEOUT = int(os.environ.get('COMPOSE_HTTP_TIMEOUT', os.environ.get('DOCKER_CLIENT_TIMEOUT', 60)))
HTTP_TIMEOUT = 60
IMAGE_EVENTS = ['delete', 'import', 'load', 'pull', 'push', 'save', 'tag', 'untag']
IS_WINDOWS_PLATFORM = (sys.platform == "win32")
LABEL_CONTAINER_NUMBER = 'com.docker.compose.container-number'
LABEL_ONE_OFF = 'com.docker.compose.oneoff'
LABEL_PROJECT = 'com.docker.compose.project'
LABEL_SERVICE = 'com.docker.compose.service'
LABEL_NETWORK = 'com.docker.compose.network'
LABEL_VERSION = 'com.docker.compose.version'
LABEL_VOLUME = 'com.docker.compose.volume'
LABEL_CONFIG_HASH = 'com.docker.compose.config-hash'
SECRETS_PATH = '/run/secrets'
COMPOSEFILE_V1 = '1'
COMPOSEFILE_V2_0 = '2.0'
COMPOSEFILE_V2_1 = '2.1'
COMPOSEFILE_V3_0 = '3.0'
COMPOSEFILE_V3_1 = '3.1'
API_VERSIONS = {
COMPOSEFILE_V1: '1.21',
COMPOSEFILE_V2_0: '1.22',
COMPOSEFILE_V2_1: '1.24',
COMPOSEFILE_V3_0: '1.25',
COMPOSEFILE_V3_1: '1.25',
}
API_VERSION_TO_ENGINE_VERSION = {
API_VERSIONS[COMPOSEFILE_V1]: '1.9.0',
API_VERSIONS[COMPOSEFILE_V2_0]: '1.10.0',
API_VERSIONS[COMPOSEFILE_V2_1]: '1.12.0',
API_VERSIONS[COMPOSEFILE_V3_0]: '1.13.0',
API_VERSIONS[COMPOSEFILE_V3_1]: '1.13.0',
}

View file

@ -39,7 +39,7 @@ class Container(object):
@classmethod
def from_id(cls, client, id):
return cls(client, client.inspect_container(id))
return cls(client, client.inspect_container(id), has_been_inspected=True)
@classmethod
def create(cls, client, **options):
@ -60,7 +60,7 @@ class Container(object):
@property
def short_id(self):
return self.id[:10]
return self.id[:12]
@property
def name(self):
@ -107,6 +107,10 @@ class Container(object):
def labels(self):
return self.get('Config.Labels') or {}
@property
def stop_signal(self):
return self.get('Config.StopSignal')
@property
def log_config(self):
return self.get('HostConfig.LogConfig') or None
@ -115,6 +119,8 @@ class Container(object):
def human_readable_state(self):
if self.is_paused:
return 'Paused'
if self.is_restarting:
return 'Restarting'
if self.is_running:
return 'Ghost' if self.get('State.Ghost') else 'Up'
else:
@ -128,12 +134,24 @@ class Container(object):
@property
def environment(self):
return dict(var.split("=", 1) for var in self.get('Config.Env') or [])
def parse_env(var):
if '=' in var:
return var.split("=", 1)
return var, None
return dict(parse_env(var) for var in self.get('Config.Env') or [])
@property
def exit_code(self):
return self.get('State.ExitCode')
@property
def is_running(self):
return self.get('State.Running')
@property
def is_restarting(self):
return self.get('State.Restarting')
@property
def is_paused(self):
return self.get('State.Paused')
@ -145,7 +163,7 @@ class Container(object):
@property
def has_api_logs(self):
log_type = self.log_driver
return not log_type or log_type != 'none'
return not log_type or log_type in ('json-file', 'journald')
def attach_log_stream(self):
"""A log stream can only be attached if the container uses a json-file
@ -171,6 +189,12 @@ class Container(object):
port = self.ports.get("%s/%s" % (port, protocol))
return "{HostIp}:{HostPort}".format(**port[0]) if port else None
def get_mount(self, mount_dest):
for mount in self.get('Mounts'):
if mount['Destination'] == mount_dest:
return mount
return None
def start(self, **options):
return self.client.start(self.id, **options)
@ -192,6 +216,12 @@ class Container(object):
def remove(self, **options):
return self.client.remove_container(self.id, **options)
def create_exec(self, command, **options):
return self.client.exec_create(self.id, command, **options)
def start_exec(self, exec_id, **options):
return self.client.exec_start(exec_id, **options)
def rename_to_tmp_name(self):
"""Rename the container to a hopefully unique temporary container name
by prepending the short id.
@ -216,16 +246,6 @@ class Container(object):
self.has_been_inspected = True
return self.dictionary
# TODO: only used by tests, move to test module
def links(self):
links = []
for container in self.client.containers():
for name in container['Names']:
bits = name.split('/')
if len(bits) > 2 and bits[1] == self.name:
links.append(bits[2])
return links
def attach(self, *args, **kwargs):
return self.client.attach(self.id, *args, **kwargs)

33
compose/errors.py Normal file
View file

@ -0,0 +1,33 @@
from __future__ import absolute_import
from __future__ import unicode_literals
class OperationFailedError(Exception):
def __init__(self, reason):
self.msg = reason
class StreamParseError(RuntimeError):
def __init__(self, reason):
self.msg = reason
class HealthCheckException(Exception):
def __init__(self, reason):
self.msg = reason
class HealthCheckFailed(HealthCheckException):
def __init__(self, container_id):
super(HealthCheckFailed, self).__init__(
'Container "{}" is unhealthy.'.format(container_id)
)
class NoHealthCheckConfigured(HealthCheckException):
def __init__(self, service_name):
super(NoHealthCheckConfigured, self).__init__(
'Service "{}" is missing a healthcheck configuration'.format(
service_name
)
)

View file

@ -1,182 +0,0 @@
import logging
import re
from .const import LABEL_VERSION
from .container import Container
from .container import get_container_name
log = logging.getLogger(__name__)
# TODO: remove this section when migrate_project_to_labels is removed
NAME_RE = re.compile(r'^([^_]+)_([^_]+)_(run_)?(\d+)$')
ERROR_MESSAGE_FORMAT = """
Compose found the following containers without labels:
{names_list}
As of Compose 1.3.0, containers are identified with labels instead of naming
convention. If you want to continue using these containers, run:
$ docker-compose migrate-to-labels
Alternatively, remove them:
$ docker rm -f {rm_args}
"""
ONE_OFF_ADDENDUM_FORMAT = """
You should also remove your one-off containers:
$ docker rm -f {rm_args}
"""
ONE_OFF_ERROR_MESSAGE_FORMAT = """
Compose found the following containers without labels:
{names_list}
As of Compose 1.3.0, containers are identified with labels instead of naming convention.
Remove them before continuing:
$ docker rm -f {rm_args}
"""
def check_for_legacy_containers(
client,
project,
services,
allow_one_off=True):
"""Check if there are containers named using the old naming convention
and warn the user that those containers may need to be migrated to
using labels, so that compose can find them.
"""
containers = get_legacy_containers(client, project, services, one_off=False)
if containers:
one_off_containers = get_legacy_containers(client, project, services, one_off=True)
raise LegacyContainersError(
[c.name for c in containers],
[c.name for c in one_off_containers],
)
if not allow_one_off:
one_off_containers = get_legacy_containers(client, project, services, one_off=True)
if one_off_containers:
raise LegacyOneOffContainersError(
[c.name for c in one_off_containers],
)
class LegacyError(Exception):
def __unicode__(self):
return self.msg
__str__ = __unicode__
class LegacyContainersError(LegacyError):
def __init__(self, names, one_off_names):
self.names = names
self.one_off_names = one_off_names
self.msg = ERROR_MESSAGE_FORMAT.format(
names_list="\n".join(" {}".format(name) for name in names),
rm_args=" ".join(names),
)
if one_off_names:
self.msg += ONE_OFF_ADDENDUM_FORMAT.format(rm_args=" ".join(one_off_names))
class LegacyOneOffContainersError(LegacyError):
def __init__(self, one_off_names):
self.one_off_names = one_off_names
self.msg = ONE_OFF_ERROR_MESSAGE_FORMAT.format(
names_list="\n".join(" {}".format(name) for name in one_off_names),
rm_args=" ".join(one_off_names),
)
def add_labels(project, container):
project_name, service_name, one_off, number = NAME_RE.match(container.name).groups()
if project_name != project.name or service_name not in project.service_names:
return
service = project.get_service(service_name)
service.recreate_container(container)
def migrate_project_to_labels(project):
log.info("Running migration to labels for project %s", project.name)
containers = get_legacy_containers(
project.client,
project.name,
project.service_names,
one_off=False,
)
for container in containers:
add_labels(project, container)
def get_legacy_containers(
client,
project,
services,
one_off=False):
return list(_get_legacy_containers_iter(
client,
project,
services,
one_off=one_off,
))
def _get_legacy_containers_iter(
client,
project,
services,
one_off=False):
containers = client.containers(all=True)
for service in services:
for container in containers:
if LABEL_VERSION in (container.get('Labels') or {}):
continue
name = get_container_name(container)
if has_container(project, service, name, one_off=one_off):
yield Container.from_ps(client, container)
def has_container(project, service, name, one_off=False):
if not name or not is_valid_name(name, one_off):
return False
container_project, container_service, _container_number = parse_name(name)
return container_project == project and container_service == service
def is_valid_name(name, one_off=False):
match = NAME_RE.match(name)
if match is None:
return False
if one_off:
return match.group(3) == 'run_'
else:
return match.group(3) is None
def parse_name(name):
match = NAME_RE.match(name)
(project, service_name, _, suffix) = match.groups()
return (project, service_name, int(suffix))

231
compose/network.py Normal file
View file

@ -0,0 +1,231 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import logging
from docker.errors import NotFound
from docker.types import IPAMConfig
from docker.types import IPAMPool
from docker.utils import version_gte
from docker.utils import version_lt
from .config import ConfigurationError
from .const import LABEL_NETWORK
from .const import LABEL_PROJECT
log = logging.getLogger(__name__)
OPTS_EXCEPTIONS = [
'com.docker.network.driver.overlay.vxlanid_list',
]
class Network(object):
def __init__(self, client, project, name, driver=None, driver_opts=None,
ipam=None, external_name=None, internal=False, enable_ipv6=False,
labels=None):
self.client = client
self.project = project
self.name = name
self.driver = driver
self.driver_opts = driver_opts
self.ipam = create_ipam_config_from_dict(ipam)
self.external_name = external_name
self.internal = internal
self.enable_ipv6 = enable_ipv6
self.labels = labels
def ensure(self):
if self.external_name:
try:
self.inspect()
log.debug(
'Network {0} declared as external. No new '
'network will be created.'.format(self.name)
)
except NotFound:
raise ConfigurationError(
'Network {name} declared as external, but could'
' not be found. Please create the network manually'
' using `{command} {name}` and try again.'.format(
name=self.external_name,
command='docker network create'
)
)
return
try:
data = self.inspect()
check_remote_network_config(data, self)
except NotFound:
driver_name = 'the default driver'
if self.driver:
driver_name = 'driver "{}"'.format(self.driver)
log.info(
'Creating network "{}" with {}'
.format(self.full_name, driver_name)
)
self.client.create_network(
name=self.full_name,
driver=self.driver,
options=self.driver_opts,
ipam=self.ipam,
internal=self.internal,
enable_ipv6=self.enable_ipv6,
labels=self._labels,
attachable=version_gte(self.client._version, '1.24') or None,
)
def remove(self):
if self.external_name:
log.info("Network %s is external, skipping", self.full_name)
return
log.info("Removing network {}".format(self.full_name))
self.client.remove_network(self.full_name)
def inspect(self):
return self.client.inspect_network(self.full_name)
@property
def full_name(self):
if self.external_name:
return self.external_name
return '{0}_{1}'.format(self.project, self.name)
@property
def _labels(self):
if version_lt(self.client._version, '1.23'):
return None
labels = self.labels.copy() if self.labels else {}
labels.update({
LABEL_PROJECT: self.project,
LABEL_NETWORK: self.name,
})
return labels
def create_ipam_config_from_dict(ipam_dict):
if not ipam_dict:
return None
return IPAMConfig(
driver=ipam_dict.get('driver'),
pool_configs=[
IPAMPool(
subnet=config.get('subnet'),
iprange=config.get('ip_range'),
gateway=config.get('gateway'),
aux_addresses=config.get('aux_addresses'),
)
for config in ipam_dict.get('config', [])
],
)
def check_remote_network_config(remote, local):
if local.driver and remote.get('Driver') != local.driver:
raise ConfigurationError(
'Network "{}" needs to be recreated - driver has changed'
.format(local.full_name)
)
local_opts = local.driver_opts or {}
remote_opts = remote.get('Options') or {}
for k in set.union(set(remote_opts.keys()), set(local_opts.keys())):
if k in OPTS_EXCEPTIONS:
continue
if remote_opts.get(k) != local_opts.get(k):
raise ConfigurationError(
'Network "{}" needs to be recreated - options have changed'
.format(local.full_name)
)
def build_networks(name, config_data, client):
network_config = config_data.networks or {}
networks = {
network_name: Network(
client=client, project=name, name=network_name,
driver=data.get('driver'),
driver_opts=data.get('driver_opts'),
ipam=data.get('ipam'),
external_name=data.get('external_name'),
internal=data.get('internal'),
enable_ipv6=data.get('enable_ipv6'),
labels=data.get('labels'),
)
for network_name, data in network_config.items()
}
if 'default' not in networks:
networks['default'] = Network(client, name, 'default')
return networks
class ProjectNetworks(object):
def __init__(self, networks, use_networking):
self.networks = networks or {}
self.use_networking = use_networking
@classmethod
def from_services(cls, services, networks, use_networking):
service_networks = {
network: networks.get(network)
for service in services
for network in get_network_names_for_service(service)
}
unused = set(networks) - set(service_networks) - {'default'}
if unused:
log.warn(
"Some networks were defined but are not used by any service: "
"{}".format(", ".join(unused)))
return cls(service_networks, use_networking)
def remove(self):
if not self.use_networking:
return
for network in self.networks.values():
try:
network.remove()
except NotFound:
log.warn("Network %s not found.", network.full_name)
def initialize(self):
if not self.use_networking:
return
for network in self.networks.values():
network.ensure()
def get_network_defs_for_service(service_dict):
if 'network_mode' in service_dict:
return {}
networks = service_dict.get('networks', {'default': None})
return dict(
(net, (config or {}))
for net, config in networks.items()
)
def get_network_names_for_service(service_dict):
return get_network_defs_for_service(service_dict).keys()
def get_networks(service_dict, network_definitions):
networks = {}
for name, netdef in get_network_defs_for_service(service_dict).items():
network = network_definitions.get(name)
if network:
networks[network.full_name] = netdef
else:
raise ConfigurationError(
'Service "{}" uses an undefined network "{}"'
.format(service_dict['name'], name))
return networks

259
compose/parallel.py Normal file
View file

@ -0,0 +1,259 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import logging
import operator
import sys
from threading import Thread
from docker.errors import APIError
from six.moves import _thread as thread
from six.moves.queue import Empty
from six.moves.queue import Queue
from compose.cli.signals import ShutdownException
from compose.errors import HealthCheckFailed
from compose.errors import NoHealthCheckConfigured
from compose.errors import OperationFailedError
from compose.utils import get_output_stream
log = logging.getLogger(__name__)
STOP = object()
def parallel_execute(objects, func, get_name, msg, get_deps=None):
"""Runs func on objects in parallel while ensuring that func is
ran on object only after it is ran on all its dependencies.
get_deps called on object must return a collection with its dependencies.
get_name called on object must return its name.
"""
objects = list(objects)
stream = get_output_stream(sys.stderr)
writer = ParallelStreamWriter(stream, msg)
for obj in objects:
writer.initialize(get_name(obj))
events = parallel_execute_iter(objects, func, get_deps)
errors = {}
results = []
error_to_reraise = None
for obj, result, exception in events:
if exception is None:
writer.write(get_name(obj), 'done')
results.append(result)
elif isinstance(exception, APIError):
errors[get_name(obj)] = exception.explanation
writer.write(get_name(obj), 'error')
elif isinstance(exception, (OperationFailedError, HealthCheckFailed, NoHealthCheckConfigured)):
errors[get_name(obj)] = exception.msg
writer.write(get_name(obj), 'error')
elif isinstance(exception, UpstreamError):
writer.write(get_name(obj), 'error')
else:
errors[get_name(obj)] = exception
error_to_reraise = exception
for obj_name, error in errors.items():
stream.write("\nERROR: for {} {}\n".format(obj_name, error))
if error_to_reraise:
raise error_to_reraise
return results, errors
def _no_deps(x):
return []
class State(object):
"""
Holds the state of a partially-complete parallel operation.
state.started: objects being processed
state.finished: objects which have been processed
state.failed: objects which either failed or whose dependencies failed
"""
def __init__(self, objects):
self.objects = objects
self.started = set()
self.finished = set()
self.failed = set()
def is_done(self):
return len(self.finished) + len(self.failed) >= len(self.objects)
def pending(self):
return set(self.objects) - self.started - self.finished - self.failed
def parallel_execute_iter(objects, func, get_deps):
"""
Runs func on objects in parallel while ensuring that func is
ran on object only after it is ran on all its dependencies.
Returns an iterator of tuples which look like:
# if func returned normally when run on object
(object, result, None)
# if func raised an exception when run on object
(object, None, exception)
# if func raised an exception when run on one of object's dependencies
(object, None, UpstreamError())
"""
if get_deps is None:
get_deps = _no_deps
results = Queue()
state = State(objects)
while True:
feed_queue(objects, func, get_deps, results, state)
try:
event = results.get(timeout=0.1)
except Empty:
continue
# See https://github.com/docker/compose/issues/189
except thread.error:
raise ShutdownException()
if event is STOP:
break
obj, _, exception = event
if exception is None:
log.debug('Finished processing: {}'.format(obj))
state.finished.add(obj)
else:
log.debug('Failed: {}'.format(obj))
state.failed.add(obj)
yield event
def producer(obj, func, results):
"""
The entry point for a producer thread which runs func on a single object.
Places a tuple on the results queue once func has either returned or raised.
"""
try:
result = func(obj)
results.put((obj, result, None))
except Exception as e:
results.put((obj, None, e))
def feed_queue(objects, func, get_deps, results, state):
"""
Starts producer threads for any objects which are ready to be processed
(i.e. they have no dependencies which haven't been successfully processed).
Shortcuts any objects whose dependencies have failed and places an
(object, None, UpstreamError()) tuple on the results queue.
"""
pending = state.pending()
log.debug('Pending: {}'.format(pending))
for obj in pending:
deps = get_deps(obj)
try:
if any(dep[0] in state.failed for dep in deps):
log.debug('{} has upstream errors - not processing'.format(obj))
results.put((obj, None, UpstreamError()))
state.failed.add(obj)
elif all(
dep not in objects or (
dep in state.finished and (not ready_check or ready_check(dep))
) for dep, ready_check in deps
):
log.debug('Starting producer thread for {}'.format(obj))
t = Thread(target=producer, args=(obj, func, results))
t.daemon = True
t.start()
state.started.add(obj)
except (HealthCheckFailed, NoHealthCheckConfigured) as e:
log.debug(
'Healthcheck for service(s) upstream of {} failed - '
'not processing'.format(obj)
)
results.put((obj, None, e))
if state.is_done():
results.put(STOP)
class UpstreamError(Exception):
pass
class ParallelStreamWriter(object):
"""Write out messages for operations happening in parallel.
Each operation has it's own line, and ANSI code characters are used
to jump to the correct line, and write over the line.
"""
def __init__(self, stream, msg):
self.stream = stream
self.msg = msg
self.lines = []
def initialize(self, obj_index):
if self.msg is None:
return
self.lines.append(obj_index)
self.stream.write("{} {} ... \r\n".format(self.msg, obj_index))
self.stream.flush()
def write(self, obj_index, status):
if self.msg is None:
return
position = self.lines.index(obj_index)
diff = len(self.lines) - position
# move up
self.stream.write("%c[%dA" % (27, diff))
# erase
self.stream.write("%c[2K\r" % 27)
self.stream.write("{} {} ... {}\r".format(self.msg, obj_index, status))
# move back down
self.stream.write("%c[%dB" % (27, diff))
self.stream.flush()
def parallel_operation(containers, operation, options, message):
parallel_execute(
containers,
operator.methodcaller(operation, **options),
operator.attrgetter('name'),
message)
def parallel_remove(containers, options):
stopped_containers = [c for c in containers if not c.is_running]
parallel_operation(stopped_containers, 'remove', options, 'Removing')
def parallel_start(containers, options):
parallel_operation(containers, 'start', options, 'Starting')
def parallel_pause(containers, options):
parallel_operation(containers, 'pause', options, 'Pausing')
def parallel_unpause(containers, options):
parallel_operation(containers, 'unpause', options, 'Unpausing')
def parallel_kill(containers, options):
parallel_operation(containers, 'kill', options, 'Killing')

View file

@ -1,3 +1,6 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from compose import utils
@ -14,26 +17,33 @@ def stream_output(output, stream):
for event in utils.json_stream(output):
all_events.append(event)
is_progress_event = 'progress' in event or 'progressDetail' in event
if 'progress' in event or 'progressDetail' in event:
if not is_progress_event:
print_output_event(event, stream, is_terminal)
stream.flush()
continue
if not is_terminal:
continue
# if it's a progress event and we have a terminal, then display the progress bars
image_id = event.get('id')
if not image_id:
continue
if image_id in lines:
diff = len(lines) - lines[image_id]
else:
if image_id not in lines:
lines[image_id] = len(lines)
stream.write("\n")
diff = 0
if is_terminal:
diff = len(lines) - lines[image_id]
# move cursor up `diff` rows
stream.write("%c[%dA" % (27, diff))
print_output_event(event, stream, is_terminal)
if 'id' in event and is_terminal:
if 'id' in event:
# move cursor back down
stream.write("%c[%dB" % (27, diff))
@ -80,3 +90,22 @@ def print_output_event(event, stream, is_terminal):
stream.write("%s%s" % (event['stream'], terminator))
else:
stream.write("%s%s\n" % (status, terminator))
def get_digest_from_pull(events):
for event in events:
status = event.get('status')
if not status or 'Digest' not in status:
continue
_, digest = status.split(':', 1)
return digest.strip()
return None
def get_digest_from_push(events):
for event in events:
digest = event.get('aux', {}).get('Digest')
if digest:
return digest
return None

View file

@ -1,120 +1,128 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import datetime
import logging
import operator
from functools import reduce
import enum
from docker.errors import APIError
from docker.errors import NotFound
from . import parallel
from .config import ConfigurationError
from .config import get_service_name_from_net
from .const import DEFAULT_TIMEOUT
from .config.config import V1
from .config.sort_services import get_container_name_from_network_mode
from .config.sort_services import get_service_name_from_network_mode
from .const import IMAGE_EVENTS
from .const import LABEL_ONE_OFF
from .const import LABEL_PROJECT
from .const import LABEL_SERVICE
from .container import Container
from .legacy import check_for_legacy_containers
from .service import ContainerNet
from .network import build_networks
from .network import get_networks
from .network import ProjectNetworks
from .service import BuildAction
from .service import ContainerNetworkMode
from .service import ConvergenceStrategy
from .service import Net
from .service import parse_volume_from_spec
from .service import NetworkMode
from .service import Service
from .service import ServiceNet
from .service import VolumeFromSpec
from .utils import parallel_execute
from .service import ServiceNetworkMode
from .utils import microseconds_from_time_nano
from .volume import ProjectVolumes
log = logging.getLogger(__name__)
def sort_service_dicts(services):
# Topological sort (Cormen/Tarjan algorithm).
unmarked = services[:]
temporary_marked = set()
sorted_services = []
@enum.unique
class OneOffFilter(enum.Enum):
include = 0
exclude = 1
only = 2
def get_service_names(links):
return [link.split(':')[0] for link in links]
def get_service_names_from_volumes_from(volumes_from):
return [
parse_volume_from_spec(volume_from).source
for volume_from in volumes_from
]
def get_service_dependents(service_dict, services):
name = service_dict['name']
return [
service for service in services
if (name in get_service_names(service.get('links', [])) or
name in get_service_names_from_volumes_from(service.get('volumes_from', [])) or
name == get_service_name_from_net(service.get('net')))
]
def visit(n):
if n['name'] in temporary_marked:
if n['name'] in get_service_names(n.get('links', [])):
raise DependencyError('A service can not link to itself: %s' % n['name'])
if n['name'] in n.get('volumes_from', []):
raise DependencyError('A service can not mount itself as volume: %s' % n['name'])
@classmethod
def update_labels(cls, value, labels):
if value == cls.only:
labels.append('{0}={1}'.format(LABEL_ONE_OFF, "True"))
elif value == cls.exclude:
labels.append('{0}={1}'.format(LABEL_ONE_OFF, "False"))
elif value == cls.include:
pass
else:
raise DependencyError('Circular import between %s' % ' and '.join(temporary_marked))
if n in unmarked:
temporary_marked.add(n['name'])
for m in get_service_dependents(n, services):
visit(m)
temporary_marked.remove(n['name'])
unmarked.remove(n)
sorted_services.insert(0, n)
while unmarked:
visit(unmarked[-1])
return sorted_services
raise ValueError("Invalid value for one_off: {}".format(repr(value)))
class Project(object):
"""
A collection of services.
"""
def __init__(self, name, services, client, use_networking=False, network_driver=None):
def __init__(self, name, services, client, networks=None, volumes=None):
self.name = name
self.services = services
self.client = client
self.use_networking = use_networking
self.network_driver = network_driver
self.volumes = volumes or ProjectVolumes({})
self.networks = networks or ProjectNetworks({}, False)
def labels(self, one_off=False):
return [
'{0}={1}'.format(LABEL_PROJECT, self.name),
'{0}={1}'.format(LABEL_ONE_OFF, "True" if one_off else "False"),
]
def labels(self, one_off=OneOffFilter.exclude):
labels = ['{0}={1}'.format(LABEL_PROJECT, self.name)]
OneOffFilter.update_labels(one_off, labels)
return labels
@classmethod
def from_dicts(cls, name, service_dicts, client, use_networking=False, network_driver=None):
def from_config(cls, name, config_data, client):
"""
Construct a ServiceCollection from a list of dicts representing services.
Construct a Project from a config.Config object.
"""
project = cls(name, [], client, use_networking=use_networking, network_driver=network_driver)
use_networking = (config_data.version and config_data.version != V1)
networks = build_networks(name, config_data, client)
project_networks = ProjectNetworks.from_services(
config_data.services,
networks,
use_networking)
volumes = ProjectVolumes.from_config(name, config_data, client)
project = cls(name, [], client, project_networks, volumes)
for service_dict in config_data.services:
service_dict = dict(service_dict)
if use_networking:
remove_links(service_dicts)
service_networks = get_networks(service_dict, networks)
else:
service_networks = {}
for service_dict in sort_service_dicts(service_dicts):
service_dict.pop('networks', None)
links = project.get_links(service_dict)
volumes_from = project.get_volumes_from(service_dict)
net = project.get_net(service_dict)
network_mode = project.get_network_mode(
service_dict, list(service_networks.keys())
)
volumes_from = get_volumes_from(project, service_dict)
if config_data.version != V1:
service_dict['volumes'] = [
volumes.namespace_spec(volume_spec)
for volume_spec in service_dict.get('volumes', [])
]
secrets = get_secrets(
service_dict['name'],
service_dict.pop('secrets', None) or [],
config_data.secrets)
project.services.append(
Service(
service_dict.pop('name'),
client=client,
project=name,
use_networking=use_networking,
networks=service_networks,
links=links,
net=net,
network_mode=network_mode,
volumes_from=volumes_from,
**service_dict))
secrets=secrets,
**service_dict)
)
return project
@property
@ -157,11 +165,8 @@ class Project(object):
Raises NoSuchService if any of the named services do not exist.
"""
if service_names is None or len(service_names) == 0:
return self.get_services(
service_names=self.service_names,
include_deps=include_deps
)
else:
service_names = self.service_names
unsorted = [self.get_service(name) for name in service_names]
services = [s for s in self.services if s in unsorted]
@ -170,8 +175,15 @@ class Project(object):
uniques = []
[uniques.append(s) for s in services if s not in uniques]
return uniques
def get_services_without_duplicate(self, service_names=None, include_deps=False):
services = self.get_services(service_names, include_deps)
for service in services:
service.remove_duplicate_containers()
return services
def get_links(self, service_dict):
links = []
if 'links' in service_dict:
@ -189,131 +201,236 @@ class Project(object):
del service_dict['links']
return links
def get_volumes_from(self, service_dict):
volumes_from = []
if 'volumes_from' in service_dict:
for volume_from_config in service_dict.get('volumes_from', []):
volume_from_spec = parse_volume_from_spec(volume_from_config)
# Get service
def get_network_mode(self, service_dict, networks):
network_mode = service_dict.pop('network_mode', None)
if not network_mode:
if self.networks.use_networking:
return NetworkMode(networks[0]) if networks else NetworkMode('none')
return NetworkMode(None)
service_name = get_service_name_from_network_mode(network_mode)
if service_name:
return ServiceNetworkMode(self.get_service(service_name))
container_name = get_container_name_from_network_mode(network_mode)
if container_name:
try:
service_name = self.get_service(volume_from_spec.source)
volume_from_spec = VolumeFromSpec(service_name, volume_from_spec.mode)
except NoSuchService:
try:
container_name = Container.from_id(self.client, volume_from_spec.source)
volume_from_spec = VolumeFromSpec(container_name, volume_from_spec.mode)
return ContainerNetworkMode(Container.from_id(self.client, container_name))
except APIError:
raise ConfigurationError(
'Service "%s" mounts volumes from "%s", which is '
'not the name of a service or container.' % (
service_dict['name'],
volume_from_spec.source))
volumes_from.append(volume_from_spec)
del service_dict['volumes_from']
return volumes_from
"Service '{name}' uses the network stack of container '{dep}' which "
"does not exist.".format(name=service_dict['name'], dep=container_name))
def get_net(self, service_dict):
net = service_dict.pop('net', None)
if not net:
if self.use_networking:
return Net(self.name)
return Net(None)
net_name = get_service_name_from_net(net)
if not net_name:
return Net(net)
try:
return ServiceNet(self.get_service(net_name))
except NoSuchService:
pass
try:
return ContainerNet(Container.from_id(self.client, net_name))
except APIError:
raise ConfigurationError(
'Service "%s" is trying to use the network of "%s", '
'which is not the name of a service or container.' % (
service_dict['name'],
net_name))
return NetworkMode(network_mode)
def start(self, service_names=None, **options):
for service in self.get_services(service_names):
service.start(**options)
containers = []
def stop(self, service_names=None, **options):
parallel_execute(
objects=self.containers(service_names),
obj_callable=lambda c: c.stop(**options),
msg_index=lambda c: c.name,
msg="Stopping"
)
def start_service(service):
service_containers = service.start(quiet=True, **options)
containers.extend(service_containers)
services = self.get_services(service_names)
def get_deps(service):
return {
(self.get_service(dep), config)
for dep, config in service.get_dependency_configs().items()
}
parallel.parallel_execute(
services,
start_service,
operator.attrgetter('name'),
'Starting',
get_deps)
return containers
def stop(self, service_names=None, one_off=OneOffFilter.exclude, **options):
containers = self.containers(service_names, one_off=one_off)
def get_deps(container):
# actually returning inversed dependencies
return {(other, None) for other in containers
if container.service in
self.get_service(other.service).get_dependency_names()}
parallel.parallel_execute(
containers,
self.build_container_operation_with_timeout_func('stop', options),
operator.attrgetter('name'),
'Stopping',
get_deps)
def pause(self, service_names=None, **options):
for service in reversed(self.get_services(service_names)):
service.pause(**options)
containers = self.containers(service_names)
parallel.parallel_pause(reversed(containers), options)
return containers
def unpause(self, service_names=None, **options):
for service in self.get_services(service_names):
service.unpause(**options)
containers = self.containers(service_names)
parallel.parallel_unpause(containers, options)
return containers
def kill(self, service_names=None, **options):
parallel_execute(
objects=self.containers(service_names),
obj_callable=lambda c: c.kill(**options),
msg_index=lambda c: c.name,
msg="Killing"
)
parallel.parallel_kill(self.containers(service_names), options)
def remove_stopped(self, service_names=None, **options):
all_containers = self.containers(service_names, stopped=True)
stopped_containers = [c for c in all_containers if not c.is_running]
parallel_execute(
objects=stopped_containers,
obj_callable=lambda c: c.remove(**options),
msg_index=lambda c: c.name,
msg="Removing"
)
def remove_stopped(self, service_names=None, one_off=OneOffFilter.exclude, **options):
parallel.parallel_remove(self.containers(
service_names, stopped=True, one_off=one_off
), options)
def down(self, remove_image_type, include_volumes, remove_orphans=False):
self.stop(one_off=OneOffFilter.include)
self.find_orphan_containers(remove_orphans)
self.remove_stopped(v=include_volumes, one_off=OneOffFilter.include)
self.networks.remove()
if include_volumes:
self.volumes.remove()
self.remove_images(remove_image_type)
def remove_images(self, remove_image_type):
for service in self.get_services():
service.remove_image(remove_image_type)
def restart(self, service_names=None, **options):
for service in self.get_services(service_names):
service.restart(**options)
containers = self.containers(service_names, stopped=True)
def build(self, service_names=None, no_cache=False, pull=False):
parallel.parallel_execute(
containers,
self.build_container_operation_with_timeout_func('restart', options),
operator.attrgetter('name'),
'Restarting')
return containers
def build(self, service_names=None, no_cache=False, pull=False, force_rm=False):
for service in self.get_services(service_names):
if service.can_be_built():
service.build(no_cache, pull)
service.build(no_cache, pull, force_rm)
else:
log.info('%s uses an image, skipping' % service.name)
def create(
self,
service_names=None,
strategy=ConvergenceStrategy.changed,
do_build=BuildAction.none,
):
services = self.get_services_without_duplicate(service_names, include_deps=True)
for svc in services:
svc.ensure_image_exists(do_build=do_build)
plans = self._get_convergence_plans(services, strategy)
for service in services:
service.execute_convergence_plan(
plans[service.name],
detached=True,
start=False)
def events(self, service_names=None):
def build_container_event(event, container):
time = datetime.datetime.fromtimestamp(event['time'])
time = time.replace(
microsecond=microseconds_from_time_nano(event['timeNano']))
return {
'time': time,
'type': 'container',
'action': event['status'],
'id': container.id,
'service': container.service,
'attributes': {
'name': container.name,
'image': event['from'],
},
'container': container,
}
service_names = set(service_names or self.service_names)
for event in self.client.events(
filters={'label': self.labels()},
decode=True
):
# The first part of this condition is a guard against some events
# broadcasted by swarm that don't have a status field.
# See https://github.com/docker/compose/issues/3316
if 'status' not in event or event['status'] in IMAGE_EVENTS:
# We don't receive any image events because labels aren't applied
# to images
continue
# TODO: get labels from the API v1.22 , see github issue 2618
try:
# this can fail if the container has been removed
container = Container.from_id(self.client, event['id'])
except APIError:
continue
if container.service not in service_names:
continue
yield build_container_event(event, container)
def up(self,
service_names=None,
start_deps=True,
strategy=ConvergenceStrategy.changed,
do_build=True,
timeout=DEFAULT_TIMEOUT,
detached=False):
do_build=BuildAction.none,
timeout=None,
detached=False,
remove_orphans=False):
services = self.get_services(service_names, include_deps=start_deps)
warn_for_swarm_mode(self.client)
for service in services:
service.remove_duplicate_containers()
self.initialize()
self.find_orphan_containers(remove_orphans)
services = self.get_services_without_duplicate(
service_names,
include_deps=start_deps)
for svc in services:
svc.ensure_image_exists(do_build=do_build)
plans = self._get_convergence_plans(services, strategy)
if self.use_networking:
self.ensure_network_exists()
return [
container
for service in services
for container in service.execute_convergence_plan(
def do(service):
return service.execute_convergence_plan(
plans[service.name],
do_build=do_build,
timeout=timeout,
detached=detached
)
def get_deps(service):
return {
(self.get_service(dep), config)
for dep, config in service.get_dependency_configs().items()
}
results, errors = parallel.parallel_execute(
services,
do,
operator.attrgetter('name'),
None,
get_deps
)
if errors:
raise ProjectError(
'Encountered errors while bringing up the project.'
)
return [
container
for svc_containers in results
if svc_containers is not None
for container in svc_containers
]
def initialize(self):
self.networks.initialize()
self.volumes.initialize()
def _get_convergence_plans(self, services, strategy):
plans = {}
@ -321,8 +438,8 @@ class Project(object):
updated_dependencies = [
name
for name in service.get_dependency_names()
if name in plans
and plans[name].action == 'recreate'
if name in plans and
plans[name].action in ('recreate', 'create')
]
if updated_dependencies and strategy.allows_recreate:
@ -341,49 +458,55 @@ class Project(object):
for service in self.get_services(service_names, include_deps=False):
service.pull(ignore_pull_failures)
def containers(self, service_names=None, stopped=False, one_off=False):
def push(self, service_names=None, ignore_push_failures=False):
for service in self.get_services(service_names, include_deps=False):
service.push(ignore_push_failures)
def _labeled_containers(self, stopped=False, one_off=OneOffFilter.exclude):
return list(filter(None, [
Container.from_ps(self.client, container)
for container in self.client.containers(
all=stopped,
filters={'label': self.labels(one_off=one_off)})])
)
def containers(self, service_names=None, stopped=False, one_off=OneOffFilter.exclude):
if service_names:
self.validate_service_names(service_names)
else:
service_names = self.service_names
containers = list(filter(None, [
Container.from_ps(self.client, container)
for container in self.client.containers(
all=stopped,
filters={'label': self.labels(one_off=one_off)})]))
containers = self._labeled_containers(stopped, one_off)
def matches_service_names(container):
return container.labels.get(LABEL_SERVICE) in service_names
if not containers:
check_for_legacy_containers(
self.client,
self.name,
self.service_names,
)
return [c for c in containers if matches_service_names(c)]
def get_network(self):
try:
return self.client.inspect_network(self.name)
except NotFound:
return None
def ensure_network_exists(self):
# TODO: recreate network if driver has changed?
if self.get_network() is None:
log.info(
'Creating network "{}" with driver "{}"'
.format(self.name, self.network_driver)
def find_orphan_containers(self, remove_orphans):
def _find():
containers = self._labeled_containers()
for ctnr in containers:
service_name = ctnr.labels.get(LABEL_SERVICE)
if service_name not in self.service_names:
yield ctnr
orphans = list(_find())
if not orphans:
return
if remove_orphans:
for ctnr in orphans:
log.info('Removing orphan container "{0}"'.format(ctnr.name))
ctnr.kill()
ctnr.remove(force=True)
else:
log.warning(
'Found orphan containers ({0}) for this project. If '
'you removed or renamed this service in your compose '
'file, you can run this command with the '
'--remove-orphans flag to clean it up.'.format(
', '.join(["{}".format(ctnr.name) for ctnr in orphans])
)
)
self.client.create_network(self.name, driver=self.network_driver)
def remove_network(self):
network = self.get_network()
if network:
self.client.remove_network(network['id'])
def _inject_deps(self, acc, service):
dep_names = service.get_dependency_names()
@ -399,25 +522,84 @@ class Project(object):
dep_services.append(service)
return acc + dep_services
def build_container_operation_with_timeout_func(self, operation, options):
def container_operation_with_timeout(container):
if options.get('timeout') is None:
service = self.get_service(container.service)
options['timeout'] = service.stop_timeout(None)
return getattr(container, operation)(**options)
return container_operation_with_timeout
def remove_links(service_dicts):
services_with_links = [s for s in service_dicts if 'links' in s]
if not services_with_links:
def get_volumes_from(project, service_dict):
volumes_from = service_dict.pop('volumes_from', None)
if not volumes_from:
return []
def build_volume_from(spec):
if spec.type == 'service':
try:
return spec._replace(source=project.get_service(spec.source))
except NoSuchService:
pass
if spec.type == 'container':
try:
container = Container.from_id(project.client, spec.source)
return spec._replace(source=container)
except APIError:
pass
raise ConfigurationError(
"Service \"{}\" mounts volumes from \"{}\", which is not the name "
"of a service or container.".format(
service_dict['name'],
spec.source))
return [build_volume_from(vf) for vf in volumes_from]
def get_secrets(service, service_secrets, secret_defs):
secrets = []
for secret in service_secrets:
secret_def = secret_defs.get(secret.source)
if not secret_def:
raise ConfigurationError(
"Service \"{service}\" uses an undefined secret \"{secret}\" "
.format(service=service, secret=secret.source))
if secret_def.get('external_name'):
log.warn("Service \"{service}\" uses secret \"{secret}\" which is external. "
"External secrets are not available to containers created by "
"docker-compose.".format(service=service, secret=secret.source))
continue
if secret.uid or secret.gid or secret.mode:
log.warn("Service \"{service}\" uses secret \"{secret}\" with uid, "
"gid, or mode. These fields are not supported by this "
"implementation of the Compose file".format(
service=service, secret=secret.source))
secrets.append({'secret': secret, 'file': secret_def.get('file')})
return secrets
def warn_for_swarm_mode(client):
info = client.info()
if info.get('Swarm', {}).get('LocalNodeState') == 'active':
if info.get('ServerVersion', '').startswith('ucp'):
# UCP does multi-node scheduling with traditional Compose files.
return
if len(services_with_links) == 1:
prefix = '"{}" defines'.format(services_with_links[0]['name'])
else:
prefix = 'Some services ({}) define'.format(
", ".join('"{}"'.format(s['name']) for s in services_with_links))
log.warn(
'\n{} links, which are not compatible with Docker networking and will be ignored.\n'
'Future versions of Docker will not support links - you should remove them for '
'forwards-compatibility.\n'.format(prefix))
for s in services_with_links:
del s['links']
"The Docker Engine you're using is running in swarm mode.\n\n"
"Compose does not use swarm mode to deploy services to multiple nodes in a swarm. "
"All containers will be scheduled on the current node.\n\n"
"To deploy your application across the swarm, "
"use `docker stack deploy`.\n"
)
class NoSuchService(Exception):
@ -429,5 +611,6 @@ class NoSuchService(Exception):
return self.msg
class DependencyError(ConfigurationError):
pass
class ProjectError(Exception):
def __init__(self, msg):
self.msg = msg

File diff suppressed because it is too large Load diff

96
compose/timeparse.py Normal file
View file

@ -0,0 +1,96 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
timeparse.py
(c) Will Roberts <wildwilhelm@gmail.com> 1 February, 2014
This is a vendored and modified copy of:
github.com/wroberts/pytimeparse @ cc0550d
It has been modified to mimic the behaviour of
https://golang.org/pkg/time/#ParseDuration
'''
# MIT LICENSE
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import
from __future__ import unicode_literals
import re
HOURS = r'(?P<hours>[\d.]+)h'
MINS = r'(?P<mins>[\d.]+)m'
SECS = r'(?P<secs>[\d.]+)s'
MILLI = r'(?P<milli>[\d.]+)ms'
MICRO = r'(?P<micro>[\d.]+)(?:us|µs)'
NANO = r'(?P<nano>[\d.]+)ns'
def opt(x):
return r'(?:{x})?'.format(x=x)
TIMEFORMAT = r'{HOURS}{MINS}{SECS}{MILLI}{MICRO}{NANO}'.format(
HOURS=opt(HOURS),
MINS=opt(MINS),
SECS=opt(SECS),
MILLI=opt(MILLI),
MICRO=opt(MICRO),
NANO=opt(NANO),
)
MULTIPLIERS = dict([
('hours', 60 * 60),
('mins', 60),
('secs', 1),
('milli', 1.0 / 1000),
('micro', 1.0 / 1000.0 / 1000),
('nano', 1.0 / 1000.0 / 1000.0 / 1000.0),
])
def timeparse(sval):
"""Parse a time expression, returning it as a number of seconds. If
possible, the return value will be an `int`; if this is not
possible, the return will be a `float`. Returns `None` if a time
expression cannot be parsed from the given string.
Arguments:
- `sval`: the string value to parse
>>> timeparse('1m24s')
84
>>> timeparse('1.2 minutes')
72
>>> timeparse('1.2 seconds')
1.2
"""
match = re.match(r'\s*' + TIMEFORMAT + r'\s*$', sval, re.I)
if not match or not match.group(0).strip():
return
mdict = match.groupdict()
return sum(
MULTIPLIERS[k] * cast(v) for (k, v) in mdict.items() if v is not None)
def cast(value):
return int(value, 10) if value.isdigit() else float(value)

View file

@ -1,83 +1,21 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import codecs
import hashlib
import json
import json.decoder
import logging
import sys
from threading import Thread
import ntpath
import six
from docker.errors import APIError
from six.moves.queue import Empty
from six.moves.queue import Queue
from .errors import StreamParseError
from .timeparse import timeparse
log = logging.getLogger(__name__)
json_decoder = json.JSONDecoder()
def parallel_execute(objects, obj_callable, msg_index, msg):
"""
For a given list of objects, call the callable passing in the first
object we give it.
"""
stream = get_output_stream(sys.stdout)
lines = []
for obj in objects:
write_out_msg(stream, lines, msg_index(obj), msg)
q = Queue()
def inner_execute_function(an_callable, parameter, msg_index):
error = None
try:
result = an_callable(parameter)
except APIError as e:
error = e.explanation
result = "error"
except Exception as e:
error = e
result = 'unexpected_exception'
q.put((msg_index, result, error))
for an_object in objects:
t = Thread(
target=inner_execute_function,
args=(obj_callable, an_object, msg_index(an_object)),
)
t.daemon = True
t.start()
done = 0
errors = {}
total_to_execute = len(objects)
while done < total_to_execute:
try:
msg_index, result, error = q.get(timeout=1)
if result == 'unexpected_exception':
errors[msg_index] = result, error
if result == 'error':
errors[msg_index] = result, error
write_out_msg(stream, lines, msg_index, msg, status='error')
else:
write_out_msg(stream, lines, msg_index, msg)
done += 1
except Empty:
pass
if not errors:
return
stream.write("\n")
for msg_index, (result, error) in errors.items():
stream.write("ERROR: for {} {} \n".format(msg_index, error))
if result == 'unexpected_exception':
raise error
log = logging.getLogger(__name__)
def get_output_stream(stream):
@ -95,14 +33,14 @@ def stream_as_text(stream):
"""
for data in stream:
if not isinstance(data, six.text_type):
data = data.decode('utf-8')
data = data.decode('utf-8', 'replace')
yield data
def line_splitter(buffer, separator=u'\n'):
index = buffer.find(six.text_type(separator))
if index == -1:
return None, None
return None
return buffer[:index + 1], buffer[index + 1:]
@ -120,27 +58,35 @@ def split_buffer(stream, splitter=None, decoder=lambda a: a):
for data in stream_as_text(stream):
buffered += data
while True:
item, rest = splitter(buffered)
if not item:
buffer_split = splitter(buffered)
if buffer_split is None:
break
buffered = rest
item, buffered = buffer_split
yield item
if buffered:
try:
yield decoder(buffered)
except Exception as e:
log.error(
'Compose tried decoding the following data chunk, but failed:'
'\n%s' % repr(buffered)
)
raise StreamParseError(e)
def json_splitter(buffer):
"""Attempt to parse a json object from a buffer. If there is at least one
object, return it and the rest of the buffer, otherwise return None.
"""
buffer = buffer.strip()
try:
obj, index = json_decoder.raw_decode(buffer)
rest = buffer[json.decoder.WHITESPACE.match(buffer, index).end():]
return obj, rest
except ValueError:
return None, None
return None
def json_stream(stream):
@ -148,31 +94,7 @@ def json_stream(stream):
This handles streams which are inconsistently buffered (some entries may
be newline delimited, and others are not).
"""
return split_buffer(stream_as_text(stream), json_splitter, json_decoder.decode)
def write_out_msg(stream, lines, msg_index, msg, status="done"):
"""
Using special ANSI code characters we can write out the msg over the top of
a previous status message, if it exists.
"""
obj_index = msg_index
if msg_index in lines:
position = lines.index(obj_index)
diff = len(lines) - position
# move up
stream.write("%c[%dA" % (27, diff))
# erase
stream.write("%c[2K\r" % 27)
stream.write("{} {} ... {}\n".format(msg, obj_index, status))
# move back down
stream.write("%c[%dB" % (27, diff))
else:
diff = 0
lines.append(obj_index)
stream.write("{} {} ... \r\n".format(msg, obj_index))
stream.flush()
return split_buffer(stream, json_splitter, json_decoder.decode)
def json_hash(obj):
@ -180,3 +102,34 @@ def json_hash(obj):
h = hashlib.sha256()
h.update(dump.encode('utf8'))
return h.hexdigest()
def microseconds_from_time_nano(time_nano):
return int(time_nano % 1000000000 / 1000)
def nanoseconds_from_time_seconds(time_seconds):
return time_seconds * 1000000000
def parse_seconds_float(value):
return timeparse(value or '')
def parse_nanoseconds_int(value):
parsed = timeparse(value or '')
if parsed is None:
return None
return int(parsed * 1000000000)
def build_string_dict(source_dict):
return dict((k, str(v if v is not None else '')) for k, v in source_dict.items())
def splitdrive(path):
if len(path) == 0:
return ('', '')
if path[0] in ['.', '\\', '/', '~']:
return ('', path)
return ntpath.splitdrive(path)

151
compose/volume.py Normal file
View file

@ -0,0 +1,151 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import logging
from docker.errors import NotFound
from docker.utils import version_lt
from .config import ConfigurationError
from .const import LABEL_PROJECT
from .const import LABEL_VOLUME
log = logging.getLogger(__name__)
class Volume(object):
def __init__(self, client, project, name, driver=None, driver_opts=None,
external_name=None, labels=None):
self.client = client
self.project = project
self.name = name
self.driver = driver
self.driver_opts = driver_opts
self.external_name = external_name
self.labels = labels
def create(self):
return self.client.create_volume(
self.full_name, self.driver, self.driver_opts, labels=self._labels
)
def remove(self):
if self.external:
log.info("Volume %s is external, skipping", self.full_name)
return
log.info("Removing volume %s", self.full_name)
return self.client.remove_volume(self.full_name)
def inspect(self):
return self.client.inspect_volume(self.full_name)
def exists(self):
try:
self.inspect()
except NotFound:
return False
return True
@property
def external(self):
return bool(self.external_name)
@property
def full_name(self):
if self.external_name:
return self.external_name
return '{0}_{1}'.format(self.project, self.name)
@property
def _labels(self):
if version_lt(self.client._version, '1.23'):
return None
labels = self.labels.copy() if self.labels else {}
labels.update({
LABEL_PROJECT: self.project,
LABEL_VOLUME: self.name,
})
return labels
class ProjectVolumes(object):
def __init__(self, volumes):
self.volumes = volumes
@classmethod
def from_config(cls, name, config_data, client):
config_volumes = config_data.volumes or {}
volumes = {
vol_name: Volume(
client=client,
project=name,
name=vol_name,
driver=data.get('driver'),
driver_opts=data.get('driver_opts'),
external_name=data.get('external_name'),
labels=data.get('labels')
)
for vol_name, data in config_volumes.items()
}
return cls(volumes)
def remove(self):
for volume in self.volumes.values():
try:
volume.remove()
except NotFound:
log.warn("Volume %s not found.", volume.full_name)
def initialize(self):
try:
for volume in self.volumes.values():
volume_exists = volume.exists()
if volume.external:
log.debug(
'Volume {0} declared as external. No new '
'volume will be created.'.format(volume.name)
)
if not volume_exists:
raise ConfigurationError(
'Volume {name} declared as external, but could'
' not be found. Please create the volume manually'
' using `{command}{name}` and try again.'.format(
name=volume.full_name,
command='docker volume create --name='
)
)
continue
if not volume_exists:
log.info(
'Creating volume "{0}" with {1} driver'.format(
volume.full_name, volume.driver or 'default'
)
)
volume.create()
else:
driver = volume.inspect()['Driver']
if volume.driver is not None and driver != volume.driver:
raise ConfigurationError(
'Configuration for volume {0} specifies driver '
'{1}, but a volume with the same name uses a '
'different driver ({3}). If you wish to use the '
'new configuration, please remove the existing '
'volume "{2}" first:\n'
'$ docker volume rm {2}'.format(
volume.name, volume.driver, volume.full_name,
volume.inspect()['Driver']
)
)
except NotFound:
raise ConfigurationError(
'Volume %s specifies nonexistent driver %s' % (volume.name, volume.driver)
)
def namespace_spec(self, volume_spec):
if not volume_spec.is_named_volume:
return volume_spec
volume = self.volumes[volume_spec.external]
return volume_spec._replace(external=volume.full_name)

View file

@ -17,23 +17,34 @@
# . ~/.docker-compose-completion.sh
# For compatibility reasons, Compose and therefore its completion supports several
# stack compositon files as listed here, in descending priority.
# Support for these filenames might be dropped in some future version.
__docker_compose_compose_file() {
local file
for file in docker-compose.y{,a}ml fig.y{,a}ml ; do
[ -e $file ] && {
echo $file
return
}
done
echo docker-compose.yml
__docker_compose_q() {
docker-compose 2>/dev/null $daemon_options "$@"
}
# Transforms a multiline list of strings into a single line string
# with the words separated by "|".
__docker_compose_to_alternatives() {
local parts=( $1 )
local IFS='|'
echo "${parts[*]}"
}
# Transforms a multiline list of options into an extglob pattern
# suitable for use in case statements.
__docker_compose_to_extglob() {
local extglob=$( __docker_compose_to_alternatives "$1" )
echo "@($extglob)"
}
# suppress trailing whitespace
__docker_compose_nospace() {
# compopt is not available in ancient bash versions
type compopt &>/dev/null && compopt -o nospace
}
# Extracts all service names from the compose file.
___docker_compose_all_services_in_compose_file() {
awk -F: '/^[a-zA-Z0-9]/{print $1}' "${compose_file:-$(__docker_compose_compose_file)}" 2>/dev/null
__docker_compose_q config --services
}
# All services, even those without an existing container
@ -43,8 +54,12 @@ __docker_compose_services_all() {
# All services that have an entry with the given key in their compose_file section
___docker_compose_services_with_key() {
# flatten sections to one line, then filter lines containing the key and return section name.
awk '/^[a-zA-Z0-9]/{printf "\n"};{printf $0;next;}' "${compose_file:-$(__docker_compose_compose_file)}" 2>/dev/null | awk -F: -v key=": +$1:" '$0 ~ key {print $1}'
# flatten sections under "services" to one line, then filter lines containing the key and return section name
__docker_compose_q config \
| sed -n -e '/^services:/,/^[^ ]/p' \
| sed -n 's/^ //p' \
| awk '/^[a-zA-Z0-9]/{printf "\n"};{printf $0;next;}' \
| awk -F: -v key=": +$1:" '$0 ~ key {print $1}'
}
# All services that are defined by a Dockerfile reference
@ -61,11 +76,9 @@ __docker_compose_services_from_image() {
# by a boolean expression passed in as argument.
__docker_compose_services_with() {
local containers names
containers="$(docker-compose 2>/dev/null ${compose_file:+-f $compose_file} ${compose_project:+-p $compose_project} ps -q)"
names=( $(docker 2>/dev/null inspect --format "{{if ${1:-true}}} {{ .Name }} {{end}}" $containers) )
names=( ${names[@]%_*} ) # strip trailing numbers
names=( ${names[@]#*_} ) # strip project name
COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") )
containers="$(__docker_compose_q ps -q)"
names=$(docker 2>/dev/null inspect -f "{{if ${1:-true}}}{{range \$k, \$v := .Config.Labels}}{{if eq \$k \"com.docker.compose.service\"}}{{\$v}}{{end}}{{end}}{{end}}" $containers)
COMPREPLY=( $(compgen -W "$names" -- "$cur") )
}
# The services for which at least one paused container exists
@ -87,7 +100,7 @@ __docker_compose_services_stopped() {
_docker_compose_build() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --no-cache --pull" -- "$cur" ) )
COMPREPLY=( $( compgen -W "--force-rm --help --no-cache --pull" -- "$cur" ) )
;;
*)
__docker_compose_services_from_build
@ -96,24 +109,53 @@ _docker_compose_build() {
}
_docker_compose_bundle() {
case "$prev" in
--output|-o)
_filedir
return
;;
esac
COMPREPLY=( $( compgen -W "--push-images --help --output -o" -- "$cur" ) )
}
_docker_compose_config() {
COMPREPLY=( $( compgen -W "--help --quiet -q --services" -- "$cur" ) )
}
_docker_compose_create() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--force-recreate --help --no-build --no-recreate" -- "$cur" ) )
;;
*)
__docker_compose_services_all
;;
esac
}
_docker_compose_docker_compose() {
case "$prev" in
--tlscacert|--tlscert|--tlskey)
_filedir
return
;;
--file|-f)
_filedir "y?(a)ml"
return
;;
--project-name|-p)
return
;;
--x-network-driver)
COMPREPLY=( $( compgen -W "bridge host none overlay" -- "$cur" ) )
$(__docker_compose_to_extglob "$daemon_options_with_args") )
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--file -f --help -h --project-name -p --verbose --version -v --x-networking --x-network-driver" -- "$cur" ) )
COMPREPLY=( $( compgen -W "$daemon_boolean_options $daemon_options_with_args --help -h --verbose --version -v" -- "$cur" ) )
;;
*)
COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
@ -122,6 +164,58 @@ _docker_compose_docker_compose() {
}
_docker_compose_down() {
case "$prev" in
--rmi)
COMPREPLY=( $( compgen -W "all local" -- "$cur" ) )
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --rmi --volumes -v --remove-orphans" -- "$cur" ) )
;;
esac
}
_docker_compose_events() {
case "$prev" in
--json)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --json" -- "$cur" ) )
;;
*)
__docker_compose_services_all
;;
esac
}
_docker_compose_exec() {
case "$prev" in
--index|--user)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "-d --help --index --privileged -T --user" -- "$cur" ) )
;;
*)
__docker_compose_services_running
;;
esac
}
_docker_compose_help() {
COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
}
@ -147,9 +241,15 @@ _docker_compose_kill() {
_docker_compose_logs() {
case "$prev" in
--tail)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --no-color" -- "$cur" ) )
COMPREPLY=( $( compgen -W "--follow -f --help --no-color --tail --timestamps -t" -- "$cur" ) )
;;
*)
__docker_compose_services_all
@ -158,15 +258,6 @@ _docker_compose_logs() {
}
_docker_compose_migrate_to_labels() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
esac
}
_docker_compose_pause() {
case "$cur" in
-*)
@ -225,6 +316,18 @@ _docker_compose_pull() {
}
_docker_compose_push() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --ignore-push-failures" -- "$cur" ) )
;;
*)
__docker_compose_services_all
;;
esac
}
_docker_compose_restart() {
case "$prev" in
--timeout|-t)
@ -259,17 +362,17 @@ _docker_compose_run() {
case "$prev" in
-e)
COMPREPLY=( $( compgen -e -- "$cur" ) )
compopt -o nospace
__docker_compose_nospace
return
;;
--entrypoint|--name|--user|-u)
--entrypoint|--name|--user|-u|--workdir|-w)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --name --no-deps --publish -p --rm --service-ports -T --user -u" -- "$cur" ) )
COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --name --no-deps --publish -p --rm --service-ports -T --user -u --workdir -w" -- "$cur" ) )
;;
*)
__docker_compose_services_all
@ -295,7 +398,7 @@ _docker_compose_scale() {
;;
*)
COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
compopt -o nospace
__docker_compose_nospace
;;
esac
}
@ -331,6 +434,18 @@ _docker_compose_stop() {
}
_docker_compose_top() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
__docker_compose_services_running
;;
esac
}
_docker_compose_unpause() {
case "$cur" in
-*)
@ -352,7 +467,7 @@ _docker_compose_up() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "-d --help --no-build --no-color --no-deps --no-recreate --force-recreate --timeout -t" -- "$cur" ) )
COMPREPLY=( $( compgen -W "--abort-on-container-exit --build -d --force-recreate --help --no-build --no-color --no-deps --no-recreate --timeout -t --remove-orphans" -- "$cur" ) )
;;
*)
__docker_compose_services_all
@ -376,25 +491,48 @@ _docker_compose() {
local commands=(
build
bundle
config
create
down
events
exec
help
kill
logs
migrate-to-labels
pause
port
ps
pull
push
restart
rm
run
scale
start
stop
top
unpause
up
version
)
# options for the docker daemon that have to be passed to secondary calls to
# docker-compose executed by this script
local daemon_boolean_options="
--skip-hostname-check
--tls
--tlsverify
"
local daemon_options_with_args="
--file -f
--host -H
--project-name -p
--tlscacert
--tlscert
--tlskey
"
COMPREPLY=()
local cur prev words cword
_get_comp_words_by_ref -n : cur prev words cword
@ -402,20 +540,19 @@ _docker_compose() {
# search subcommand and invoke its handler.
# special treatment of some top-level options
local command='docker_compose'
local daemon_options=()
local counter=1
local compose_file compose_project
while [ $counter -lt $cword ]; do
case "${words[$counter]}" in
--file|-f)
(( counter++ ))
compose_file="${words[$counter]}"
$(__docker_compose_to_extglob "$daemon_boolean_options") )
local opt=${words[counter]}
daemon_options+=($opt)
;;
--project-name|p)
(( counter++ ))
compose_project="${words[$counter]}"
;;
--x-network-driver)
(( counter++ ))
$(__docker_compose_to_extglob "$daemon_options_with_args") )
local opt=${words[counter]}
local arg=${words[++counter]}
daemon_options+=($opt $arg)
;;
-*)
;;

View file

@ -19,52 +19,49 @@
# * @felixr docker zsh completion script : https://github.com/felixr/docker-zsh-completion
# -------------------------------------------------------------------------
# For compatibility reasons, Compose and therefore its completion supports several
# stack compositon files as listed here, in descending priority.
# Support for these filenames might be dropped in some future version.
__docker-compose_compose_file() {
local file
for file in docker-compose.y{,a}ml fig.y{,a}ml ; do
[ -e $file ] && {
echo $file
return
}
done
echo docker-compose.yml
__docker-compose_q() {
docker-compose 2>/dev/null $compose_options "$@"
}
# Extracts all service names from docker-compose.yml.
___docker-compose_all_services_in_compose_file() {
# All services defined in docker-compose.yml
__docker-compose_all_services_in_compose_file() {
local already_selected
local -a services
already_selected=$(echo $words | tr " " "|")
awk -F: '/^[a-zA-Z0-9]/{print $1}' "${compose_file:-$(__docker-compose_compose_file)}" 2>/dev/null | grep -Ev "$already_selected"
__docker-compose_q config --services \
| grep -Ev "^(${already_selected})$"
}
# All services, even those without an existing container
__docker-compose_services_all() {
[[ $PREFIX = -* ]] && return 1
integer ret=1
services=$(___docker-compose_all_services_in_compose_file)
services=$(__docker-compose_all_services_in_compose_file)
_alternative "args:services:($services)" && ret=0
return ret
}
# All services that have an entry with the given key in their docker-compose.yml section
___docker-compose_services_with_key() {
__docker-compose_services_with_key() {
local already_selected
local -a buildable
already_selected=$(echo $words | tr " " "|")
# flatten sections to one line, then filter lines containing the key and return section name.
awk '/^[a-zA-Z0-9]/{printf "\n"};{printf $0;next;}' "${compose_file:-$(__docker-compose_compose_file)}" 2>/dev/null | awk -F: -v key=": +$1:" '$0 ~ key {print $1}' 2>/dev/null | grep -Ev "$already_selected"
__docker-compose_q config \
| sed -n -e '/^services:/,/^[^ ]/p' \
| sed -n 's/^ //p' \
| awk '/^[a-zA-Z0-9]/{printf "\n"};{printf $0;next;}' \
| grep " \+$1:" \
| cut -d: -f1 \
| grep -Ev "^(${already_selected})$"
}
# All services that are defined by a Dockerfile reference
__docker-compose_services_from_build() {
[[ $PREFIX = -* ]] && return 1
integer ret=1
buildable=$(___docker-compose_services_with_key build)
buildable=$(__docker-compose_services_with_key build)
_alternative "args:buildable services:($buildable)" && ret=0
return ret
@ -74,7 +71,7 @@ __docker-compose_services_from_build() {
__docker-compose_services_from_image() {
[[ $PREFIX = -* ]] && return 1
integer ret=1
pullable=$(___docker-compose_services_with_key image)
pullable=$(__docker-compose_services_with_key image)
_alternative "args:pullable services:($pullable)" && ret=0
return ret
@ -96,7 +93,7 @@ __docker-compose_get_services() {
shift
[[ $kind =~ (stopped|all) ]] && args=($args -a)
lines=(${(f)"$(_call_program commands docker ps $args)"})
lines=(${(f)"$(_call_program commands docker $docker_options ps $args)"})
services=(${(f)"$(_call_program commands docker-compose 2>/dev/null $compose_options ps -q)"})
# Parse header line to find columns
@ -179,23 +176,80 @@ __docker-compose_commands() {
local -a lines
lines=(${(f)"$(_call_program commands docker-compose 2>&1)"})
_docker_compose_subcommands=(${${${lines[$((${lines[(i)Commands:]} + 1)),${lines[(I) *]}]}## #}/ ##/:})
_store_cache docker_compose_subcommands _docker_compose_subcommands
(( $#_docker_compose_subcommands > 0 )) && _store_cache docker_compose_subcommands _docker_compose_subcommands
fi
_describe -t docker-compose-commands "docker-compose command" _docker_compose_subcommands
}
__docker-compose_subcommand() {
local opts_help='(: -)--help[Print usage]'
local opts_help opts_force_recreate opts_no_recreate opts_no_build opts_remove_orphans opts_timeout opts_no_color opts_no_deps
opts_help='(: -)--help[Print usage]'
opts_force_recreate="(--no-recreate)--force-recreate[Recreate containers even if their configuration and image haven't changed. Incompatible with --no-recreate.]"
opts_no_recreate="(--force-recreate)--no-recreate[If containers already exist, don't recreate them. Incompatible with --force-recreate.]"
opts_no_build="(--build)--no-build[Don't build an image, even if it's missing.]"
opts_remove_orphans="--remove-orphans[Remove containers for services not defined in the Compose file]"
opts_timeout=('(-t --timeout)'{-t,--timeout}"[Specify a shutdown timeout in seconds. (default: 10)]:seconds: ")
opts_no_color='--no-color[Produce monochrome output.]'
opts_no_deps="--no-deps[Don't start linked services.]"
integer ret=1
case "$words[1]" in
(build)
_arguments \
$opts_help \
'--no-cache[Do not use cache when building the image]' \
'--force-rm[Always remove intermediate containers.]' \
'--no-cache[Do not use cache when building the image.]' \
'--pull[Always attempt to pull a newer version of the image.]' \
'*:services:__docker-compose_services_from_build' && ret=0
;;
(bundle)
_arguments \
$opts_help \
'--push-images[Automatically push images for any services which have a `build` option specified.]' \
'(--output -o)'{--output,-o}'[Path to write the bundle file to. Defaults to "<project name>.dab".]:file:_files' && ret=0
;;
(config)
_arguments \
$opts_help \
'(--quiet -q)'{--quiet,-q}"[Only validate the configuration, don't print anything.]" \
'--services[Print the service names, one per line.]' && ret=0
;;
(create)
_arguments \
$opts_help \
$opts_force_recreate \
$opts_no_recreate \
$opts_no_build \
"(--no-build)--build[Build images before creating containers.]" \
'*:services:__docker-compose_services_all' && ret=0
;;
(down)
_arguments \
$opts_help \
"--rmi[Remove images. Type must be one of: 'all': Remove all images used by any service. 'local': Remove only images that don't have a custom tag set by the \`image\` field.]:type:(all local)" \
'(-v --volumes)'{-v,--volumes}"[Remove named volumes declared in the \`volumes\` section of the Compose file and anonymous volumes attached to containers.]" \
$opts_remove_orphans && ret=0
;;
(events)
_arguments \
$opts_help \
'--json[Output events as a stream of json objects]' \
'*:services:__docker-compose_services_all' && ret=0
;;
(exec)
_arguments \
$opts_help \
'-d[Detached mode: Run command in the background.]' \
'--privileged[Give extended privileges to the process.]' \
'--user=[Run the command as this user.]:username:_users' \
'-T[Disable pseudo-tty allocation. By default `docker-compose exec` allocates a TTY.]' \
'--index=[Index of the container if there are multiple instances of a service \[default: 1\]]:index: ' \
'(-):running services:__docker-compose_runningservices' \
'(-):command: _command_names -e' \
'*::arguments: _normal' && ret=0
;;
(help)
_arguments ':subcommand:__docker-compose_commands' && ret=0
;;
@ -208,14 +262,12 @@ __docker-compose_subcommand() {
(logs)
_arguments \
$opts_help \
'--no-color[Produce monochrome output.]' \
'(-f --follow)'{-f,--follow}'[Follow log output]' \
$opts_no_color \
'--tail=[Number of lines to show from the end of the logs for each container.]:number of lines: ' \
'(-t --timestamps)'{-t,--timestamps}'[Show timestamps]' \
'*:services:__docker-compose_services_all' && ret=0
;;
(migrate-to-labels)
_arguments -A '-*' \
$opts_help \
'(-):Recreate containers to add labels' && ret=0
;;
(pause)
_arguments \
$opts_help \
@ -224,8 +276,8 @@ __docker-compose_subcommand() {
(port)
_arguments \
$opts_help \
'--protocol=-[tcp or udap (defaults to tcp)]:protocol:(tcp udp)' \
'--index=-[index of the container if there are mutiple instances of a service (defaults to 1)]:index: ' \
'--protocol=[tcp or udp \[default: tcp\]]:protocol:(tcp udp)' \
'--index=[index of the container if there are multiple instances of a service \[default: 1\]]:index: ' \
'1:running services:__docker-compose_runningservices' \
'2:port:_ports' && ret=0
;;
@ -241,26 +293,33 @@ __docker-compose_subcommand() {
'--ignore-pull-failures[Pull what it can and ignores images with pull failures.]' \
'*:services:__docker-compose_services_from_image' && ret=0
;;
(push)
_arguments \
$opts_help \
'--ignore-push-failures[Push what it can and ignores images with push failures.]' \
'*:services:__docker-compose_services' && ret=0
;;
(rm)
_arguments \
$opts_help \
'(-f --force)'{-f,--force}"[Don't ask to confirm removal]" \
'-v[Remove volumes associated with containers]' \
'-v[Remove any anonymous volumes attached to containers]' \
'*:stopped services:__docker-compose_stoppedservices' && ret=0
;;
(run)
_arguments \
$opts_help \
'-d[Detached mode: Run container in the background, print new container name.]' \
'--name[Assign a name to the container]:name: ' \
'--entrypoint[Overwrite the entrypoint of the image.]:entry point: ' \
'*-e[KEY=VAL Set an environment variable (can be used multiple times)]:environment variable KEY=VAL: ' \
'(-u --user)'{-u,--user=-}'[Run as specified username or uid]:username or uid:_users' \
"--no-deps[Don't start linked services.]" \
'--entrypoint[Overwrite the entrypoint of the image.]:entry point: ' \
'--name=[Assign a name to the container]:name: ' \
$opts_no_deps \
'(-p --publish)'{-p,--publish=}"[Publish a container's port(s) to the host]" \
'--rm[Remove container after run. Ignored in detached mode.]' \
"--service-ports[Run command with the service's ports enabled and mapped to the host.]" \
'(-p --publish)'{-p,--publish=-}"[Run command with manually mapped container's port(s) to the host.]" \
'-T[Disable pseudo-tty allocation. By default `docker-compose run` allocates a TTY.]' \
'(-u --user)'{-u,--user=}'[Run as specified username or uid]:username or uid:_users' \
'(-w --workdir)'{-w,--workdir=}'[Working directory inside the container]:workdir: ' \
'(-):services:__docker-compose_services' \
'(-):command: _command_names -e' \
'*::arguments: _normal' && ret=0
@ -268,7 +327,7 @@ __docker-compose_subcommand() {
(scale)
_arguments \
$opts_help \
'(-t --timeout)'{-t,--timeout}"[Specify a shutdown timeout in seconds. (default: 10)]:seconds: " \
$opts_timeout \
'*:running services:__docker-compose_runningservices' && ret=0
;;
(start)
@ -279,7 +338,12 @@ __docker-compose_subcommand() {
(stop|restart)
_arguments \
$opts_help \
'(-t --timeout)'{-t,--timeout}"[Specify a shutdown timeout in seconds. (default: 10)]:seconds: " \
$opts_timeout \
'*:running services:__docker-compose_runningservices' && ret=0
;;
(top)
_arguments \
$opts_help \
'*:running services:__docker-compose_runningservices' && ret=0
;;
(unpause)
@ -290,13 +354,16 @@ __docker-compose_subcommand() {
(up)
_arguments \
$opts_help \
'-d[Detached mode: Run containers in the background, print new container names.]' \
'--no-color[Produce monochrome output.]' \
"--no-deps[Don't start linked services.]" \
"--force-recreate[Recreate containers even if their configuration and image haven't changed. Incompatible with --no-recreate.]" \
"--no-recreate[If containers already exist, don't recreate them.]" \
"--no-build[Don't build an image, even if it's missing]" \
'(-t --timeout)'{-t,--timeout}"[Specify a shutdown timeout in seconds. (default: 10)]:seconds: " \
'(--abort-on-container-exit)-d[Detached mode: Run containers in the background, print new container names. Incompatible with --abort-on-container-exit.]' \
$opts_no_color \
$opts_no_deps \
$opts_force_recreate \
$opts_no_recreate \
$opts_no_build \
"(--no-build)--build[Build images before starting containers.]" \
"(-d)--abort-on-container-exit[Stops all containers if any container was stopped. Incompatible with -d.]" \
'(-t --timeout)'{-t,--timeout}"[Use this timeout in seconds for container shutdown when attached or when containers are already running. (default: 10)]:seconds: " \
$opts_remove_orphans \
'*:services:__docker-compose_services_all' && ret=0
;;
(version)
@ -324,20 +391,67 @@ _docker-compose() {
integer ret=1
typeset -A opt_args
local file_description
if [[ -n ${words[(r)-f]} || -n ${words[(r)--file]} ]] ; then
file_description="Specify an override docker-compose file (default: docker-compose.override.yml)"
else
file_description="Specify an alternate docker-compose file (default: docker-compose.yml)"
fi
_arguments -C \
'(- :)'{-h,--help}'[Get help]' \
'*'{-f,--file}"[${file_description}]:file:_files -g '*.yml'" \
'(-p --project-name)'{-p,--project-name}'[Specify an alternate project name (default: directory name)]:project name:' \
'--verbose[Show more output]' \
'(- :)'{-v,--version}'[Print version and exit]' \
'(-f --file)'{-f,--file}'[Specify an alternate docker-compose file (default: docker-compose.yml)]:file:_files -g "*.yml"' \
'(-p --project-name)'{-p,--project-name}'[Specify an alternate project name (default: directory name)]:project name:' \
'--x-networking[(EXPERIMENTAL) Use new Docker networking functionality. Requires Docker 1.9 or later.]' \
'--x-network-driver[(EXPERIMENTAL) Specify a network driver (default: "bridge"). Requires Docker 1.9 or later.]:Network Driver:(bridge host none overlay)' \
'(-H --host)'{-H,--host}'[Daemon socket to connect to]:host:' \
'--tls[Use TLS; implied by --tlsverify]' \
'--tlscacert=[Trust certs signed only by this CA]:ca path:' \
'--tlscert=[Path to TLS certificate file]:client cert path:' \
'--tlskey=[Path to TLS key file]:tls key path:' \
'--tlsverify[Use TLS and verify the remote]' \
"--skip-hostname-check[Don't check the daemon's hostname against the name specified in the client certificate (for example if your docker host is an IP address)]" \
'(-): :->command' \
'(-)*:: :->option-or-argument' && ret=0
local compose_file=${opt_args[-f]}${opt_args[--file]}
local compose_project=${opt_args[-p]}${opt_args[--project-name]}
local compose_options="${compose_file:+--file $compose_file} ${compose_project:+--project-name $compose_project}"
local -a relevant_compose_flags relevant_docker_flags compose_options docker_options
relevant_compose_flags=(
"--file" "-f"
"--host" "-H"
"--project-name" "-p"
"--tls"
"--tlscacert"
"--tlscert"
"--tlskey"
"--tlsverify"
"--skip-hostname-check"
)
relevant_docker_flags=(
"--host" "-H"
"--tls"
"--tlscacert"
"--tlscert"
"--tlskey"
"--tlsverify"
)
for k in "${(@k)opt_args}"; do
if [[ -n "${relevant_docker_flags[(r)$k]}" ]]; then
docker_options+=$k
if [[ -n "$opt_args[$k]" ]]; then
docker_options+=$opt_args[$k]
fi
fi
if [[ -n "${relevant_compose_flags[(r)$k]}" ]]; then
compose_options+=$k
if [[ -n "$opt_args[$k]" ]]; then
compose_options+=$opt_args[$k]
fi
fi
done
case $state in
(command)

View file

@ -0,0 +1,173 @@
#!/usr/bin/env python
"""
Migrate a Compose file from the V1 format in Compose 1.5 to the V2 format
supported by Compose 1.6+
"""
from __future__ import absolute_import
from __future__ import unicode_literals
import argparse
import logging
import sys
import ruamel.yaml
from compose.config.types import VolumeSpec
log = logging.getLogger('migrate')
def migrate(content):
data = ruamel.yaml.load(content, ruamel.yaml.RoundTripLoader)
service_names = data.keys()
for name, service in data.items():
warn_for_links(name, service)
warn_for_external_links(name, service)
rewrite_net(service, service_names)
rewrite_build(service)
rewrite_logging(service)
rewrite_volumes_from(service, service_names)
services = {name: data.pop(name) for name in data.keys()}
data['version'] = "2"
data['services'] = services
create_volumes_section(data)
return data
def warn_for_links(name, service):
links = service.get('links')
if links:
example_service = links[0].partition(':')[0]
log.warn(
"Service {name} has links, which no longer create environment "
"variables such as {example_service_upper}_PORT. "
"If you are using those in your application code, you should "
"instead connect directly to the hostname, e.g. "
"'{example_service}'."
.format(name=name, example_service=example_service,
example_service_upper=example_service.upper()))
def warn_for_external_links(name, service):
external_links = service.get('external_links')
if external_links:
log.warn(
"Service {name} has external_links: {ext}, which now work "
"slightly differently. In particular, two containers must be "
"connected to at least one network in common in order to "
"communicate, even if explicitly linked together.\n\n"
"Either connect the external container to your app's default "
"network, or connect both the external container and your "
"service's containers to a pre-existing network. See "
"https://docs.docker.com/compose/networking/ "
"for more on how to do this."
.format(name=name, ext=external_links))
def rewrite_net(service, service_names):
if 'net' in service:
network_mode = service.pop('net')
# "container:<service name>" is now "service:<service name>"
if network_mode.startswith('container:'):
name = network_mode.partition(':')[2]
if name in service_names:
network_mode = 'service:{}'.format(name)
service['network_mode'] = network_mode
def rewrite_build(service):
if 'dockerfile' in service:
service['build'] = {
'context': service.pop('build'),
'dockerfile': service.pop('dockerfile'),
}
def rewrite_logging(service):
if 'log_driver' in service:
service['logging'] = {'driver': service.pop('log_driver')}
if 'log_opt' in service:
service['logging']['options'] = service.pop('log_opt')
def rewrite_volumes_from(service, service_names):
for idx, volume_from in enumerate(service.get('volumes_from', [])):
if volume_from.split(':', 1)[0] not in service_names:
service['volumes_from'][idx] = 'container:%s' % volume_from
def create_volumes_section(data):
named_volumes = get_named_volumes(data['services'])
if named_volumes:
log.warn(
"Named volumes ({names}) must be explicitly declared. Creating a "
"'volumes' section with declarations.\n\n"
"For backwards-compatibility, they've been declared as external. "
"If you don't mind the volume names being prefixed with the "
"project name, you can remove the 'external' option from each one."
.format(names=', '.join(list(named_volumes))))
data['volumes'] = named_volumes
def get_named_volumes(services):
volume_specs = [
VolumeSpec.parse(volume)
for service in services.values()
for volume in service.get('volumes', [])
]
names = {
spec.external
for spec in volume_specs
if spec.is_named_volume
}
return {name: {'external': True} for name in names}
def write(stream, new_format, indent, width):
ruamel.yaml.dump(
new_format,
stream,
Dumper=ruamel.yaml.RoundTripDumper,
indent=indent,
width=width)
def parse_opts(args):
parser = argparse.ArgumentParser()
parser.add_argument("filename", help="Compose file filename.")
parser.add_argument("-i", "--in-place", action='store_true')
parser.add_argument(
"--indent", type=int, default=2,
help="Number of spaces used to indent the output yaml.")
parser.add_argument(
"--width", type=int, default=80,
help="Number of spaces used as the output width.")
return parser.parse_args()
def main(args):
logging.basicConfig(format='\033[33m%(levelname)s:\033[37m %(message)s\033[0m\n')
opts = parse_opts(args)
with open(opts.filename, 'r') as fh:
new_format = migrate(fh.read())
if opts.in_place:
output = open(opts.filename, 'w')
else:
output = sys.stdout
write(output, new_format, opts.indent, opts.width)
if __name__ == "__main__":
main(sys.argv)

View file

@ -9,18 +9,48 @@ a = Analysis(['bin/docker-compose'],
runtime_hooks=None,
cipher=block_cipher)
pyz = PYZ(a.pure,
cipher=block_cipher)
pyz = PYZ(a.pure, cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[('compose/config/fields_schema.json', 'compose/config/fields_schema.json', 'DATA')],
[('compose/config/service_schema.json', 'compose/config/service_schema.json', 'DATA')],
[
(
'compose/config/config_schema_v1.json',
'compose/config/config_schema_v1.json',
'DATA'
),
(
'compose/config/config_schema_v2.0.json',
'compose/config/config_schema_v2.0.json',
'DATA'
),
(
'compose/config/config_schema_v2.1.json',
'compose/config/config_schema_v2.1.json',
'DATA'
),
(
'compose/config/config_schema_v3.0.json',
'compose/config/config_schema_v3.0.json',
'DATA'
),
(
'compose/config/config_schema_v3.1.json',
'compose/config/config_schema_v3.1.json',
'DATA'
),
(
'compose/GITSHA',
'compose/GITSHA',
'DATA'
)
],
name='docker-compose',
debug=False,
strip=None,
upx=True,
console=True )
console=True)

View file

@ -1,15 +0,0 @@
FROM docs/base:hugo-github-linking
MAINTAINER Mary Anthony <mary@docker.com> (@moxiegirl)
RUN svn checkout https://github.com/docker/docker/trunk/docs /docs/content/engine
RUN svn checkout https://github.com/docker/swarm/trunk/docs /docs/content/swarm
RUN svn checkout https://github.com/docker/machine/trunk/docs /docs/content/machine
RUN svn checkout https://github.com/docker/distribution/trunk/docs /docs/content/registry
RUN svn checkout https://github.com/kitematic/kitematic/trunk/docs /docs/content/kitematic
RUN svn checkout https://github.com/docker/tutorials/trunk/docs /docs/content/tutorials
RUN svn checkout https://github.com/docker/opensource/trunk/docs /docs/content
# To get the git info for this repo
COPY . /src
COPY . /docs/content/compose/

View file

@ -1,55 +0,0 @@
.PHONY: all binary build cross default docs docs-build docs-shell shell test test-unit test-integration test-integration-cli test-docker-py validate
# env vars passed through directly to Docker's build scripts
# to allow things like `make DOCKER_CLIENTONLY=1 binary` easily
# `docs/sources/contributing/devenvironment.md ` and `project/PACKAGERS.md` have some limited documentation of some of these
DOCKER_ENVS := \
-e BUILDFLAGS \
-e DOCKER_CLIENTONLY \
-e DOCKER_EXECDRIVER \
-e DOCKER_GRAPHDRIVER \
-e TESTDIRS \
-e TESTFLAGS \
-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 DOCSPORT=9000 docs`
DOCSPORT := 8000
# Get the IP ADDRESS
DOCKER_IP=$(shell python -c "import urlparse ; print urlparse.urlparse('$(DOCKER_HOST)').hostname or ''")
HUGO_BASE_URL=$(shell test -z "$(DOCKER_IP)" && echo localhost || echo "$(DOCKER_IP)")
HUGO_BIND_IP=0.0.0.0
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)
DOCKER_IMAGE := docker$(if $(GIT_BRANCH),:$(GIT_BRANCH))
DOCKER_DOCS_IMAGE := docs-base$(if $(GIT_BRANCH),:$(GIT_BRANCH))
DOCKER_RUN_DOCS := docker run --rm -it $(DOCS_MOUNT) -e AWS_S3_BUCKET -e NOCACHE
# for some docs workarounds (see below in "docs-build" target)
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)
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)
docs-shell: docs-build
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 "$(DOCKER_DOCS_IMAGE)" bash
docs-build:
# ( git remote | grep -v upstream ) || git diff --name-status upstream/release..upstream/docs ./ > ./changed-files
# echo "$(GIT_BRANCH)" > GIT_BRANCH
# echo "$(AWS_S3_BUCKET)" > AWS_S3_BUCKET
# echo "$(GITCOMMIT)" > GITCOMMIT
docker build -t "$(DOCKER_DOCS_IMAGE)" .

View file

@ -1,77 +1,16 @@
# Contributing to the Docker Compose documentation
# The docs have been moved!
The documentation in this directory is part of the [https://docs.docker.com](https://docs.docker.com) website. Docker uses [the Hugo static generator](http://gohugo.io/overview/introduction/) to convert project Markdown files to a static HTML site.
The documentation for Compose has been merged into
[the general documentation repo](https://github.com/docker/docker.github.io).
You don't need to be a Hugo expert to contribute to the compose documentation. If you are familiar with Markdown, you can modify the content in the `docs` files.
The docs for Compose are now here:
https://github.com/docker/docker.github.io/tree/master/compose
If you want to add a new file or change the location of the document in the menu, you do need to know a little more.
Please submit pull requests for unpublished features on the `vnext-compose` branch (https://github.com/docker/docker.github.io/tree/vnext-compose).
## Documentation contributing workflow
If you submit a PR to this codebase that has a docs impact, create a second docs PR on `docker.github.io`. Use the docs PR template provided (coming soon - watch this space).
1. Edit a Markdown file in the tree.
PRs for typos, additional information, etc. for already-published features should be labeled as `okay-to-publish` (we are still settling on a naming convention, will provide a label soon). You can submit these PRs either to `vnext-compose` or directly to `master` on `docker.github.io`
2. Save your changes.
3. Make sure you are in the `docs` subdirectory.
4. Build the documentation.
$ make docs
---> ffcf3f6c4e97
Removing intermediate container a676414185e8
Successfully built ffcf3f6c4e97
docker run --rm -it -e AWS_S3_BUCKET -e NOCACHE -p 8000:8000 -e DOCKERHOST "docs-base:test-tooling" hugo server --port=8000 --baseUrl=192.168.59.103 --bind=0.0.0.0
ERROR: 2015/06/13 MenuEntry's .Url is deprecated and will be removed in Hugo 0.15. Use .URL instead.
0 of 4 drafts rendered
0 future content
12 pages created
0 paginator pages created
0 tags created
0 categories created
in 55 ms
Serving pages from /docs/public
Web Server is available at http://0.0.0.0:8000/
Press Ctrl+C to stop
5. Open the available server in your browser.
The documentation server has the complete menu but only the Docker Compose
documentation resolves. You can't access the other project docs from this
localized build.
## Tips on Hugo metadata and menu positioning
The top of each Docker Compose documentation file contains TOML metadata. The metadata is commented out to prevent it from appearing in GitHub.
<!--[metadata]>
+++
title = "Extending services in Compose"
description = "How to use Docker Compose's extends keyword to share configuration between files and projects"
keywords = ["fig, composition, compose, docker, orchestration, documentation, docs"]
[menu.main]
parent="smn_workw_compose"
weight=2
+++
<![end-metadata]-->
The metadata alone has this structure:
+++
title = "Extending services in Compose"
description = "How to use Docker Compose's extends keyword to share configuration between files and projects"
keywords = ["fig, composition, compose, docker, orchestration, documentation, docs"]
[menu.main]
parent="smn_workw_compose"
weight=2
+++
The `[menu.main]` section refers to navigation defined [in the main Docker menu](https://github.com/docker/docs-base/blob/hugo/config.toml). This metadata says *add a menu item called* Extending services in Compose *to the menu with the* `smn_workdw_compose` *identifier*. If you locate the menu in the configuration, you'll find *Create multi-container applications* is the menu title.
You can move an article in the tree by specifying a new parent. You can shift the location of the item by changing its weight. Higher numbers are heavier and shift the item to the bottom of menu. Low or no numbers shift it up.
## Other key documentation repositories
The `docker/docs-base` repository contains [the Hugo theme and menu configuration](https://github.com/docker/docs-base). If you open the `Dockerfile` you'll see the `make docs` relies on this as a base image for building the Compose documentation.
The `docker/docs.docker.com` repository contains [build system for building the Docker documentation site](https://github.com/docker/docs.docker.com). Fork this repository to build the entire documentation site.
As always, the docs remain open-source and we appreciate your feedback and
pull requests!

View file

@ -1,68 +0,0 @@
<!--[metadata]>
+++
title = "Command-line Completion"
description = "Compose CLI reference"
keywords = ["fig, composition, compose, docker, orchestration, cli, reference"]
[menu.main]
parent="smn_workw_compose"
weight=3
+++
<![end-metadata]-->
# Command-line Completion
Compose comes with [command completion](http://en.wikipedia.org/wiki/Command-line_completion)
for the bash and zsh shell.
## Installing Command Completion
### Bash
Make sure bash completion is installed. If you use a current Linux in a non-minimal installation, bash completion should be available.
On a Mac, install with `brew install bash-completion`
Place the completion script in `/etc/bash_completion.d/` (`/usr/local/etc/bash_completion.d/` on a Mac), using e.g.
curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose --version | awk 'NR==1{print $NF}')/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
Completion will be available upon next login.
### Zsh
Place the completion script in your `/path/to/zsh/completion`, using e.g. `~/.zsh/completion/`
mkdir -p ~/.zsh/completion
curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose --version | awk 'NR==1{print $NF}')/contrib/completion/zsh/_docker-compose > ~/.zsh/completion/_docker-compose
Include the directory in your `$fpath`, e.g. by adding in `~/.zshrc`
fpath=(~/.zsh/completion $fpath)
Make sure `compinit` is loaded or do it by adding in `~/.zshrc`
autoload -Uz compinit && compinit -i
Then reload your shell
exec $SHELL -l
## Available completions
Depending on what you typed on the command line so far, it will complete
- available docker-compose commands
- options that are available for a particular command
- service names that make sense in a given context (e.g. services with running or stopped instances or services based on images vs. services based on Dockerfiles). For `docker-compose scale`, completed service names will automatically have "=" appended.
- arguments for selected options, e.g. `docker-compose kill -s` will complete some signals like SIGHUP and SIGUSR1.
Enjoy working with Compose faster and with less typos!
## Compose documentation
- [User guide](index.md)
- [Installing Compose](install.md)
- [Get started with Django](django.md)
- [Get started with Rails](rails.md)
- [Get started with WordPress](wordpress.md)
- [Command line reference](./reference/index.md)
- [Compose file reference](compose-file.md)

View file

@ -1,451 +0,0 @@
<!--[metadata]>
+++
title = "Compose file reference"
description = "Compose file reference"
keywords = ["fig, composition, compose, docker"]
aliases = ["/compose/yml"]
[menu.main]
parent="smn_compose_ref"
+++
<![end-metadata]-->
# Compose file reference
The compose file is a [YAML](http://yaml.org/) file where all the top level
keys are the name of a service, and the values are the service definition.
The default path for a compose file is `./docker-compose.yml`.
Each service defined in `docker-compose.yml` must specify exactly one of
`image` or `build`. Other keys are optional, and are analogous to their
`docker run` command-line counterparts.
As with `docker run`, options specified in the Dockerfile (e.g., `CMD`,
`EXPOSE`, `VOLUME`, `ENV`) are respected by default - you don't need to
specify them again in `docker-compose.yml`.
### build
Path to a directory containing a Dockerfile. When the value supplied is a
relative path, it is interpreted as relative to the location of the yml file
itself. This directory is also the build context that is sent to the Docker daemon.
Compose will build and tag it with a generated name, and use that image thereafter.
build: /path/to/build/dir
Using `build` together with `image` is not allowed. Attempting to do so results in an error.
### cap_add, cap_drop
Add or drop container capabilities.
See `man 7 capabilities` for a full list.
cap_add:
- ALL
cap_drop:
- NET_ADMIN
- SYS_ADMIN
### command
Override the default command.
command: bundle exec thin -p 3000
### cgroup_parent
Specify an optional parent cgroup for the container.
cgroup_parent: m-executor-abcd
### container_name
Specify a custom container name, rather than a generated default name.
container_name: my-web-container
Because Docker container names must be unique, you cannot scale a service
beyond 1 container if you have specified a custom name. Attempting to do so
results in an error.
### devices
List of device mappings. Uses the same format as the `--device` docker
client create option.
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
### dns
Custom DNS servers. Can be a single value or a list.
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
### dns_search
Custom DNS search domains. Can be a single value or a list.
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
### dockerfile
Alternate Dockerfile.
Compose will use an alternate file to build with.
dockerfile: Dockerfile-alternate
Using `dockerfile` together with `image` is not allowed. Attempting to do so results in an error.
### env_file
Add environment variables from a file. Can be a single value or a list.
If you have specified a Compose file with `docker-compose -f FILE`, paths in
`env_file` are relative to the directory that file is in.
Environment variables specified in `environment` override these values.
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
Compose expects each line in an env file to be in `VAR=VAL` format. Lines
beginning with `#` (i.e. comments) are ignored, as are blank lines.
# Set Rails/Rack environment
RACK_ENV=development
### environment
Add environment variables. You can use either an array or a dictionary. Any
boolean values; true, false, yes no, need to be enclosed in quotes to ensure
they are not converted to True or False by the YML parser.
Environment variables with only a key are resolved to their values on the
machine Compose is running on, which can be helpful for secret or host-specific values.
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
### expose
Expose ports without publishing them to the host machine - they'll only be
accessible to linked services. Only the internal port can be specified.
expose:
- "3000"
- "8000"
### extends
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**:
**common.yml**
webapp:
build: ./webapp
environment:
- DEBUG=false
- SEND_EMAILS=false
**development.yml**
web:
extends:
file: common.yml
service: webapp
ports:
- "8000:8000"
links:
- db
environment:
- DEBUG=true
db:
image: postgres
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).
### external_links
Link to containers started outside this `docker-compose.yml` or even outside
of Compose, especially for containers that provide shared or common services.
`external_links` follow semantics similar to `links` when specifying both the
container name and the link alias (`CONTAINER:ALIAS`).
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
### extra_hosts
Add hostname mappings. Use the same values as the docker client `--add-host` parameter.
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
An entry with the ip address and hostname will be created in `/etc/hosts` inside containers for this service, e.g:
162.242.195.82 somehost
50.31.209.229 otherhost
### image
Tag or partial image ID. Can be local or remote - Compose will attempt to
pull if it doesn't exist locally.
image: ubuntu
image: orchardup/postgresql
image: a4bc65fd
### labels
Add metadata to containers using [Docker labels](http://docs.docker.com/userguide/labels-custom-metadata/). You can use either an array or a dictionary.
It's recommended that you use reverse-DNS notation to prevent your labels from conflicting with those used by other software.
labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
### links
Link to containers in another service. Either specify both the service name and
the link alias (`SERVICE:ALIAS`), or just the service name (which will also be
used for the alias).
links:
- db
- db:database
- redis
An entry with the alias' name will be created in `/etc/hosts` inside containers
for this service, e.g:
172.17.2.186 db
172.17.2.186 database
172.17.2.187 redis
Environment variables will also be created - see the [environment variable
reference](env.md) for details.
### log_driver
Specify a logging driver for the service's containers, as with the ``--log-driver``
option for docker run ([documented here](https://docs.docker.com/reference/logging/overview/)).
The default value is json-file.
log_driver: "json-file"
log_driver: "syslog"
log_driver: "none"
> **Note:** Only the `json-file` driver makes the logs available directly from
> `docker-compose up` and `docker-compose logs`. Using any other driver will not
> print any logs.
### log_opt
Specify logging options with `log_opt` for the logging driver, as with the ``--log-opt`` option for `docker run`.
Logging options are key value pairs. An example of `syslog` options:
log_driver: "syslog"
log_opt:
syslog-address: "tcp://192.168.0.42:123"
### net
Networking mode. Use the same values as the docker client `--net` parameter.
net: "bridge"
net: "none"
net: "container:[name or id]"
net: "host"
### pid
pid: "host"
Sets the PID mode to the host PID mode. This turns on sharing between
container and the host operating system the PID address space. Containers
launched with this flag will be able to access and manipulate other
containers in the bare-metal machine's namespace and vise-versa.
### ports
Expose ports. Either specify both ports (`HOST:CONTAINER`), or just the container
port (a random host port will be chosen).
> **Note:** When mapping ports in the `HOST:CONTAINER` format, you may experience
> erroneous results when using a container port lower than 60, because YAML will
> parse numbers in the format `xx:yy` as sexagesimal (base 60). For this reason,
> we recommend always explicitly specifying your port mappings as strings.
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
### security_opt
Override the default labeling scheme for each container.
security_opt:
- label:user:USER
- label:role:ROLE
### volumes, volume\_driver
Mount paths as volumes, optionally specifying a path on the host machine
(`HOST:CONTAINER`), or an access mode (`HOST:CONTAINER:ro`).
volumes:
- /var/lib/mysql
- ./cache:/tmp/cache
- ~/configs:/etc/configs/:ro
You can mount a relative path on the host, which will expand relative to
the directory of the Compose configuration file being used. Relative paths
should always begin with `.` or `..`.
If you use a volume name (instead of a volume path), you may also specify
a `volume_driver`.
volume_driver: mydriver
> Note: No path expansion will be done if you have also specified a
> `volume_driver`.
See [Docker Volumes](https://docs.docker.com/userguide/dockervolumes/) and
[Volume Plugins](https://docs.docker.com/extend/plugins_volume/) for more
information.
### volumes_from
Mount all of the volumes from another service or container, optionally
specifying read-only access(``ro``) or read-write(``rw``).
volumes_from:
- service_name
- container_name
- service_name:rw
### cpu\_shares, cpuset, domainname, entrypoint, hostname, ipc, mac\_address, mem\_limit, memswap\_limit, privileged, read\_only, restart, stdin\_open, tty, user, working\_dir
Each of these is a single value, analogous to its
[docker run](https://docs.docker.com/reference/run/) counterpart.
cpu_shares: 73
cpuset: 0,1
entrypoint: /code/entrypoint.sh
user: postgresql
working_dir: /code
domainname: foo.com
hostname: foo
ipc: host
mac_address: 02:42:ac:11:65:43
mem_limit: 1000000000
memswap_limit: 2000000000
privileged: true
restart: always
read_only: true
stdin_open: true
tty: true
## Variable substitution
Your configuration options can contain environment variables. Compose uses the
variable values from the shell environment in which `docker-compose` is run. For
example, suppose the shell contains `POSTGRES_VERSION=9.3` and you supply this
configuration:
db:
image: "postgres:${POSTGRES_VERSION}"
When you run `docker-compose up` with this configuration, Compose looks for the
`POSTGRES_VERSION` environment variable in the shell and substitutes its value
in. For this example, Compose resolves the `image` to `postgres:9.3` before
running the configuration.
If an environment variable is not set, Compose substitutes with an empty
string. In the example above, if `POSTGRES_VERSION` is not set, the value for
the `image` option is `postgres:`.
Both `$VARIABLE` and `${VARIABLE}` syntax are supported. Extended shell-style
features, such as `${VARIABLE-default}` and `${VARIABLE/foo/bar}`, are not
supported.
You can use a `$$` (double-dollar sign) when your configuration needs a literal
dollar sign. This also prevents Compose from interpolating a value, so a `$$`
allows you to refer to environment variables that you don't want processed by
Compose.
web:
build: .
command: "$$VAR_NOT_INTERPOLATED_BY_COMPOSE"
If you forget and use a single dollar sign (`$`), Compose interprets the value as an environment variable and will warn you:
The VAR_NOT_INTERPOLATED_BY_COMPOSE is not set. Substituting an empty string.
## Compose documentation
- [User guide](index.md)
- [Installing Compose](install.md)
- [Get started with Django](django.md)
- [Get started with Rails](rails.md)
- [Get started with WordPress](wordpress.md)
- [Command line reference](./reference/index.md)

View file

@ -1,179 +0,0 @@
<!--[metadata]>
+++
title = "Quickstart Guide: Compose and Django"
description = "Getting started with Docker Compose and Django"
keywords = ["documentation, docs, docker, compose, orchestration, containers"]
[menu.main]
parent="smn_workw_compose"
weight=4
+++
<![end-metadata]-->
# Quickstart Guide: Compose and Django
This quick-start guide demonstrates how to use Compose to set up and run a
simple Django/PostgreSQL app. Before starting, you'll need to have
[Compose installed](install.md).
## Define the project components
For this project, you need to create a Dockerfile, a Python dependencies file,
and a `docker-compose.yml` file.
1. Create an empty project directory.
You can name the directory something easy for you to remember. This directory is the context for your application image. The directory should only contain resources to build that image.
2. Create a new file called `Dockerfile` in your project directory.
The Dockerfile defines an application's image content via one or more build
commands that configure that image. Once built, you can run the image in a
container. For more information on `Dockerfiles`, see the [Docker user
guide](https://docs.docker.com/userguide/dockerimages/#building-an-image-from-a-dockerfile)
and the [Dockerfile reference](http://docs.docker.com/reference/builder/).
3. Add the following content to the `Dockerfile`.
FROM python:2.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
This `Dockerfile` starts with a Python 2.7 base image. The base image is
modified by adding a new `code` directory. The base image is further modified
by installing the Python requirements defined in the `requirements.txt` file.
4. Save and close the `Dockerfile`.
5. Create a `requirements.txt` in your project directory.
This file is used by the `RUN pip install -r requirements.txt` command in your `Dockerfile`.
6. Add the required software in the file.
Django
psycopg2
7. Save and close the `requirements.txt` file.
8. Create a file called `docker-compose.yml` in your project directory.
The `docker-compose.yml` file describes the services that make your app. In
this example those services are a web server and database. The compose file
also describes which Docker images these services use, how they link
together, any volumes they might need mounted inside the containers.
Finally, the `docker-compose.yml` file describes which ports these services
expose. See the [`docker-compose.yml` reference](compose-file.md) for more
information on how this file works.
9. Add the following configuration to the file.
db:
image: postgres
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
This file defines two services: The `db` service and the `web` service.
10. Save and close the `docker-compose.yml` file.
## Create a Django project
In this step, you create a Django started project by building the image from the build context defined in the previous procedure.
1. Change to the root of your project directory.
2. Create the Django project using the `docker-compose` command.
$ docker-compose run web django-admin.py startproject composeexample .
This instructs Compose to run `django-admin.py startproject composeeexample`
in a container, using the `web` service's image and configuration. Because
the `web` image doesn't exist yet, Compose builds it from the current
directory, as specified by the `build: .` line in `docker-compose.yml`.
Once the `web` service image is built, Compose runs it and executes the
`django-admin.py startproject` command in the container. This command
instructs Django to create a set of files and directories representing a
Django project.
3. After the `docker-compose` command completes, list the contents of your project.
$ ls -l
drwxr-xr-x 2 root root composeexample
-rw-rw-r-- 1 user user docker-compose.yml
-rw-rw-r-- 1 user user Dockerfile
-rwxr-xr-x 1 root root manage.py
-rw-rw-r-- 1 user user requirements.txt
The files `django-admin` created are owned by root. This happens because
the container runs as the `root` user.
4. Change the ownership of the new files.
sudo chown -R $USER:$USER .
## Connect the database
In this section, you set up the database connection for Django.
1. In your project dirctory, edit the `composeexample/settings.py` file.
2. Replace the `DATABASES = ...` with the following:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'postgres',
'USER': 'postgres',
'HOST': 'db',
'PORT': 5432,
}
}
These settings are determined by the
[postgres](https://registry.hub.docker.com/_/postgres/) Docker image
specified in `docker-compose.yml`.
3. Save and close the file.
4. Run the `docker-compose up` command.
$ docker-compose up
Starting composepractice_db_1...
Starting composepractice_web_1...
Attaching to composepractice_db_1, composepractice_web_1
...
db_1 | PostgreSQL init process complete; ready for start up.
...
db_1 | LOG: database system is ready to accept connections
db_1 | LOG: autovacuum launcher started
..
web_1 | Django version 1.8.4, using settings 'composeexample.settings'
web_1 | Starting development server at http://0.0.0.0:8000/
web_1 | Quit the server with CONTROL-C.
At this point, your Django app should be running at port `8000` on your
Docker host. If you are using a Docker Machine VM, you can use the
`docker-machine ip MACHINE_NAME` to get the IP address.
## More Compose documentation
- [User guide](../index.md)
- [Installing Compose](install.md)
- [Get started with Rails](rails.md)
- [Get started with WordPress](wordpress.md)
- [Command line reference](./reference/index.md)
- [Compose file reference](compose-file.md)

View file

@ -1,45 +0,0 @@
<!--[metadata]>
+++
title = "Compose environment variables reference"
description = "Compose CLI reference"
keywords = ["fig, composition, compose, docker, orchestration, cli, reference"]
[menu.main]
parent="smn_compose_ref"
weight=3
+++
<![end-metadata]-->
# Compose environment variables reference
**Note:** Environment variables are no longer the recommended method for connecting to linked services. Instead, you should use the link name (by default, the name of the linked service) as the hostname to connect to. See the [docker-compose.yml documentation](compose-file.md#links) for details.
Compose uses [Docker links] to expose services' containers to one another. Each linked container injects a set of environment variables, each of which begins with the uppercase name of the container.
To see what environment variables are available to a service, run `docker-compose run SERVICE env`.
<b><i>name</i>\_PORT</b><br>
Full URL, e.g. `DB_PORT=tcp://172.17.0.5:5432`
<b><i>name</i>\_PORT\_<i>num</i>\_<i>protocol</i></b><br>
Full URL, e.g. `DB_PORT_5432_TCP=tcp://172.17.0.5:5432`
<b><i>name</i>\_PORT\_<i>num</i>\_<i>protocol</i>\_ADDR</b><br>
Container's IP address, e.g. `DB_PORT_5432_TCP_ADDR=172.17.0.5`
<b><i>name</i>\_PORT\_<i>num</i>\_<i>protocol</i>\_PORT</b><br>
Exposed port number, e.g. `DB_PORT_5432_TCP_PORT=5432`
<b><i>name</i>\_PORT\_<i>num</i>\_<i>protocol</i>\_PROTO</b><br>
Protocol (tcp or udp), e.g. `DB_PORT_5432_TCP_PROTO=tcp`
<b><i>name</i>\_NAME</b><br>
Fully qualified container name, e.g. `DB_1_NAME=/myapp_web_1/myapp_db_1`
[Docker links]: http://docs.docker.com/userguide/dockerlinks/
## Related Information
- [User guide](index.md)
- [Installing Compose](install.md)
- [Command line reference](./reference/index.md)
- [Compose file reference](compose-file.md)

View file

@ -1,367 +0,0 @@
<!--[metadata]>
+++
title = "Extending services in Compose"
description = "How to use Docker Compose's extends keyword to share configuration between files and projects"
keywords = ["fig, composition, compose, docker, orchestration, documentation, docs"]
[menu.main]
parent="smn_workw_compose"
weight=2
+++
<![end-metadata]-->
## Extending services in Compose
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.
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.
### 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 that `build`, `ports` and `volumes` configuration
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
For full details on how to use `extends`, refer to the [reference](#reference).
### Example use case
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.
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`.
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`&mdash;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&mdash;`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.
### Reference
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.
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
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&mdash;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 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.
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.**
# 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.
# original service
build: .
# local service
image: redis
# result
image: redis
# 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` and `labels`, 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
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
# local service
volumes:
- /local-dir/bar:/bar
- /local-dir/baz/:baz
# result
volumes:
- /original-dir/foo:/foo
- /local-dir/bar:/bar
- /local-dir/baz/:baz
## Compose documentation
- [User guide](/)
- [Installing Compose](install.md)
- [Get started with Django](django.md)
- [Get started with Rails](rails.md)
- [Get started with WordPress](wordpress.md)
- [Command line reference](./reference/index.md)
- [Compose file reference](compose-file.md)

View file

@ -1,216 +0,0 @@
<!--[metadata]>
+++
title = "Overview of Docker Compose"
description = "Introduction and Overview of Compose"
keywords = ["documentation, docs, docker, compose, orchestration, containers"]
[menu.main]
parent="smn_workw_compose"
+++
<![end-metadata]-->
# Overview of Docker Compose
Compose is a tool for defining and running multi-container 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.
Compose is great for development environments, staging servers, and CI. We don't
recommend that you use it in production yet.
Using Compose is basically a three-step process.
1. Define your app's environment with a `Dockerfile` so it can be
reproduced anywhere.
2. Define the services that make up your app in `docker-compose.yml` so
they can be run together in an isolated environment:
3. Lastly, run `docker-compose up` and Compose will start and run your entire app.
A `docker-compose.yml` looks like this:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
links:
- redis
redis:
image: redis
Compose has commands for managing the whole lifecycle of your application:
* Start, stop and rebuild services
* View the status of running services
* Stream the log output of running services
* Run a one-off command on a service
## Compose documentation
- [Installing Compose](install.md)
- [Get started with Django](django.md)
- [Get started with Rails](rails.md)
- [Get started with WordPress](wordpress.md)
- [Command line reference](./reference/index.md)
- [Compose file reference](compose-file.md)
## Quick start
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.
### Installation and set-up
First, [install Docker and Compose](install.md).
Next, you'll want to make a directory for the project:
$ mkdir composetest
$ cd composetest
Inside this directory, create `app.py`, a simple Python web app that uses the Flask
framework and increments a value in Redis. Don't worry if you don't have Redis installed, docker is going to take care of that for you when we [define services](#define-services):
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@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)
Next, define the Python dependencies in a file called `requirements.txt`:
flask
redis
### Create a Docker image
Now, create a Docker image containing all of your app's dependencies. You
specify how to build the image using a file called
[`Dockerfile`](http://docs.docker.com/reference/builder/):
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`
For more information on how to write Dockerfiles, see the [Docker user guide](https://docs.docker.com/userguide/dockerimages/#building-an-image-from-a-dockerfile) and the [Dockerfile reference](http://docs.docker.com/reference/builder/).
You can build the image by running `docker build -t web .`.
### Define services
Next, define a set of services using `docker-compose.yml`:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: redis
This template defines two services, `web` and `redis`. The `web` service:
* Builds from the `Dockerfile` in the current directory.
* Forwards the exposed port 5000 on the container to port 5000 on the host machine.
* Mounts the current 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 [Redis](https://registry.hub.docker.com/_/redis/) image pulled from the Docker Hub registry.
### 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:
$ docker-compose up
Pulling image redis...
Building web...
Starting composetest_redis_1...
Starting composetest_web_1...
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/
web_1 | * Restarting with stat
If you're using [Docker Machine](https://docs.docker.com/machine), then `docker-machine ip MACHINE_VM` will tell you its address and you can open `http://MACHINE_VM_IP:5000` in a browser.
If you're using Docker on Linux natively, then the web app should now be listening on port 5000 on your Docker daemon host. If `http://0.0.0.0:5000` doesn't resolve, you can also try `http://localhost:5000`.
You should get a message in your browser saying:
`Hello World! I have been seen 1 times.`
Refreshing the page will increment the number.
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
see what is currently running:
$ docker-compose up -d
Starting composetest_redis_1...
Starting composetest_web_1...
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------
composetest_redis_1 /usr/local/bin/run Up
composetest_web_1 /bin/sh -c python app.py Up 5000->5000/tcp
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:
$ 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.
If you started Compose with `docker-compose up -d`, you'll probably want to stop
your services once you've finished with them:
$ docker-compose stop
At this point, you have seen the basics of how Compose works.
- 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](./reference/index.md), the
[configuration file](compose-file.md) and [environment variables](env.md).
## Release Notes
To see a detailed list of changes for past and current releases of Docker
Compose, please refer to the [CHANGELOG](https://github.com/docker/compose/blob/master/CHANGELOG.md).
## Getting help
Docker Compose is under active development. If you need help, would like to
contribute, or simply want to talk about the project with like-minded
individuals, we have a number of open channels for communication.
* To report bugs or file feature requests: please use the [issue tracker on Github](https://github.com/docker/compose/issues).
* To talk about the project with people in real time: please join the
`#docker-compose` channel on freenode IRC.
* To contribute code or documentation changes: please submit a [pull request on Github](https://github.com/docker/compose/pulls).
For more information and resources, please visit the [Getting Help project page](https://docs.docker.com/project/get-help/).

View file

@ -1,134 +0,0 @@
<!--[metadata]>
+++
title = "Docker Compose"
description = "How to install Docker Compose"
keywords = ["compose, orchestration, install, installation, docker, documentation"]
[menu.main]
parent="mn_install"
weight=4
+++
<![end-metadata]-->
# Install Docker Compose
You can run Compose on OS X and 64-bit Linux. It is currently not supported on
the Windows operating system. To install Compose, you'll need to install Docker
first.
To install Compose, do the following:
1. Install Docker Engine version 1.7.1 or greater:
* <a href="https://docs.docker.com/installation/mac/" target="_blank">Mac OS X installation</a> (Toolbox installation includes both Engine and Compose)
* <a href="https://docs.docker.com/installation/ubuntulinux/" target="_blank">Ubuntu installation</a>
* <a href="https://docs.docker.com/installation/" target="_blank">other system installations</a>
2. Mac OS X users are done installing. Others should continue to the next step.
3. Go to the <a href="https://github.com/docker/compose/releases" target="_blank">Compose repository release page on GitHub</a>.
4. Follow the instructions from the release page and run the `curl` command,
which the release page specifies, in your terminal.
> Note: If you get a "Permission denied" error, your `/usr/local/bin` directory
probably isn't writable and you'll need to install Compose as the superuser. Run
`sudo -i`, then the two commands below, then `exit`.
The following is an example command illustrating the format:
curl -L https://github.com/docker/compose/releases/download/VERSION_NUM/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
If you have problems installing with `curl`, see
[Alternative Install Options](#alternative-install-options).
5. Apply executable permissions to the binary:
$ chmod +x /usr/local/bin/docker-compose
6. Optionally, install [command completion](completion.md) for the
`bash` and `zsh` shell.
7. Test the installation.
$ docker-compose --version
docker-compose version: 1.5.0rc3
## Alternative install options
### Install using pip
Compose can be installed from [pypi](https://pypi.python.org/pypi/docker-compose)
using `pip`. If you install using `pip` it is highly recommended that you use a
[virtualenv](https://virtualenv.pypa.io/en/latest/) because many operating systems
have python system packages that conflict with docker-compose dependencies. See
the [virtualenv tutorial](http://docs.python-guide.org/en/latest/dev/virtualenvs/)
to get started.
$ pip install docker-compose
### Install as a container
Compose can also be run inside a container, from a small bash script wrapper.
To install compose as a container run:
$ curl -L https://github.com/docker/compose/releases/download/1.5.0rc3/run.sh > /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose
## Master builds
If you're interested in trying out a pre-release build you can download a
binary from https://dl.bintray.com/docker-compose/master/. Pre-release
builds allow you to try out new features before they are released, but may
be less stable.
## Upgrading
If you're upgrading from Compose 1.2 or earlier, you'll need to remove or migrate
your existing containers after upgrading Compose. This is because, as of version
1.3, Compose uses Docker labels to keep track of containers, and so they need to
be recreated with labels added.
If Compose detects containers that were created without labels, it will refuse
to run so that you don't end up with two sets of them. If you want to keep using
your existing containers (for example, because they have data volumes you want
to preserve) you can migrate them with the following command:
$ docker-compose migrate-to-labels
Alternatively, if you're not worried about keeping them, you can remove them.
Compose will just create new ones.
$ docker rm -f -v myapp_web_1 myapp_db_1 ...
## Uninstallation
To uninstall Docker Compose if you installed using `curl`:
$ rm /usr/local/bin/docker-compose
To uninstall Docker Compose if you installed using `pip`:
$ pip uninstall docker-compose
>**Note**: If you get a "Permission denied" error using either of the above
>methods, you probably do not have the proper permissions to remove
>`docker-compose`. To force the removal, prepend `sudo` to either of the above
>commands and run again.
## Where to go next
- [User guide](/)
- [Get started with Django](django.md)
- [Get started with Rails](rails.md)
- [Get started with WordPress](wordpress.md)
- [Command line reference](./reference/index.md)
- [Compose file reference](compose-file.md)

View file

@ -1,92 +0,0 @@
<!--[metadata]>
+++
title = "Networking in Compose"
description = "How Compose sets up networking between containers"
keywords = ["documentation, docs, docker, compose, orchestration, containers, networking"]
[menu.main]
parent="smn_workw_compose"
weight=6
+++
<![end-metadata]-->
# Networking in Compose
> **Note:** Compose's networking support is experimental, and must be explicitly enabled with the `docker-compose --x-networking` flag.
Compose sets up a single default
[network](/engine/reference/commandline/network_create.md) for your app. Each
container for a service joins the default network and is both *reachable* by
other containers on that network, and *discoverable* by them at a hostname
identical to the container name.
> **Note:** Your app's network is given the same name as the "project name", which is based on the name of the directory it lives in. See the [Command line overview](reference/docker-compose.md) for how to override it.
For example, suppose your app is in a directory called `myapp`, and your `docker-compose.yml` looks like this:
web:
build: .
ports:
- "8000:8000"
db:
image: postgres
When you run `docker-compose --x-networking up`, the following happens:
1. A network called `myapp` is created.
2. A container is created using `web`'s configuration. It joins the network
`myapp` under the name `myapp_web_1`.
3. A container is created using `db`'s configuration. It joins the network
`myapp` under the name `myapp_db_1`.
Each container can now look up the hostname `myapp_web_1` or `myapp_db_1` and
get back the appropriate container's IP address. For example, `web`'s
application code could connect to the URL `postgres://myapp_db_1:5432` and start
using the Postgres database.
Because `web` explicitly maps a port, it's also accessible from the outside world via port 8000 on your Docker host's network interface.
> **Note:** in the next release there will be additional aliases for the
> container, including a short name without the project name and container
> index. The full container name will remain as one of the alias for backwards
> compatibility.
## Updating containers
If you make a configuration change to a service and run `docker-compose up` to update it, the old container will be removed and the new one will join the network under a different IP address but the same name. Running containers will be able to look up that name and connect to the new address, but the old address will stop working.
If any containers have connections open to the old container, they will be closed. It is a container's responsibility to detect this condition, look up the name again and reconnect.
## Configure how services are published
By default, containers for each service are published on the network with the
container name. If you want to change the name, or stop containers from being
discoverable at all, you can use the `container_name` option:
web:
build: .
container_name: "my-web-application"
## Links
Docker links are a one-way, single-host communication system. They should now be considered deprecated, and you should update your app to use networking instead. In the majority of cases, this will simply involve removing the `links` sections from your `docker-compose.yml`.
## Specifying the network driver
By default, Compose uses the `bridge` driver when creating the app’s network. The Docker Engine provides one other driver out-of-the-box: `overlay`, which implements secure communication between containers on different hosts (see the next section for how to set up and use the `overlay` driver). Docker also allows you to install [custom network drivers](/engine/extend/plugins_network.md).
You can specify which one to use with the `--x-network-driver` flag:
$ docker-compose --x-networking --x-network-driver=overlay up
## Multi-host networking
(TODO: talk about Swarm and the overlay driver)
## Custom container network modes
Compose allows you to specify a custom network mode for a service with the `net` option - for example, `net: "host"` specifies that its containers should use the same network namespace as the Docker host, and `net: "none"` specifies that they should have no networking capabilities.
If a service specifies the `net` option, its containers will *not* join the app’s network and will not be able to communicate with other services in the app.
If *all* services in an app specify the `net` option, a network will not be created at all.

View file

@ -1,93 +0,0 @@
<!--[metadata]>
+++
title = "Using Compose in production"
description = "Guide to using Docker Compose in production"
keywords = ["documentation, docs, docker, compose, orchestration, containers, production"]
[menu.main]
parent="smn_workw_compose"
weight=1
+++
<![end-metadata]-->
## 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 <a href="https://github.com/docker/compose/blob/master/ROADMAP.md">roadmap</a> for details
on how it's coming along and what still needs to be done.
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
changes may include:
- Removing any volume bindings for application code, so that code stays inside
the container and can't be changed from outside
- Binding to different ports on the host
- Setting environment variables differently (e.g., to decrease the verbosity of
logging, or to enable email sending)
- 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.
> **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 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`.
### Deploying changes
When you make changes to your app code, you'll need to rebuild your image and
recreate your app's containers. To redeploy a service called
`web`, you would use:
$ docker-compose build web
$ docker-compose up --no-deps -d web
This will first rebuild the image for `web` and then stop, destroy, and recreate
*just* the `web` service. The `--no-deps` flag prevents Compose from also
recreating any services which `web` depends on.
### Running Compose on a single server
You can use Compose to deploy an app to a remote Docker host by setting the
`DOCKER_HOST`, `DOCKER_TLS_VERIFY`, and `DOCKER_CERT_PATH` environment variables
appropriately. For tasks like this,
[Docker Machine](https://docs.docker.com/machine) makes managing local and
remote Docker hosts very easy, and is recommended even if you're not deploying
remotely.
Once you've set up your environment variables, all the normal `docker-compose`
commands will work with no further configuration.
### Running Compose on a Swarm cluster
[Docker Swarm](https://docs.docker.com/swarm), a Docker-native clustering
system, exposes the same API as a single Docker host, which means you can use
Compose against a Swarm instance and run your apps across multiple hosts.
Compose/Swarm integration is still in the experimental stage, and Swarm is still
in beta, but if you'd like to explore and experiment, check out the <a
href="https://github.com/docker/compose/blob/master/SWARM.md">integration
guide</a>.
## Compose documentation
- [Installing Compose](install.md)
- [Get started with Django](django.md)
- [Get started with Rails](rails.md)
- [Get started with WordPress](wordpress.md)
- [Command line reference](./reference/index.md)
- [Compose file reference](compose-file.md)

View file

@ -1,142 +0,0 @@
<!--[metadata]>
+++
title = "Quickstart Guide: Compose and Rails"
description = "Getting started with Docker Compose and Rails"
keywords = ["documentation, docs, docker, compose, orchestration, containers"]
[menu.main]
parent="smn_workw_compose"
weight=5
+++
<![end-metadata]-->
## Quickstart Guide: Compose and Rails
This Quickstart guide will show you how to use Compose to set up and run a Rails/PostgreSQL app. Before starting, you'll need to have [Compose installed](install.md).
### Define the project
Start by setting up the three files you'll need to build the app. First, since
your app is going to run inside a Docker container containing all of its
dependencies, you'll need to define exactly what needs to be included in the
container. This is done using a file called `Dockerfile`. To begin with, the
Dockerfile consists of:
FROM ruby:2.2.0
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp
That'll put your application code inside an image that will build a container with Ruby, Bundler and all your dependencies inside it. For more information on how to write Dockerfiles, see the [Docker user guide](https://docs.docker.com/userguide/dockerimages/#building-an-image-from-a-dockerfile) and the [Dockerfile reference](http://docs.docker.com/reference/builder/).
Next, create a bootstrap `Gemfile` which just loads Rails. It'll be overwritten in a moment by `rails new`.
source 'https://rubygems.org'
gem 'rails', '4.2.0'
You'll need an empty `Gemfile.lock` in order to build our `Dockerfile`.
$ touch Gemfile.lock
Finally, `docker-compose.yml` is where the magic happens. This file describes the services that comprise your app (a database and a web app), how to get each one's Docker image (the database just runs on a pre-made PostgreSQL image, and the web app is built from the current directory), and the configuration needed to link them together and expose the web app's port.
db:
image: postgres
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
links:
- db
### Build the project
With those three files in place, you can now generate the Rails skeleton app
using `docker-compose run`:
$ docker-compose run web rails new . --force --database=postgresql --skip-bundle
First, Compose will build the image for the `web` service using the
`Dockerfile`. Then it'll run `rails new` inside a new container, using that
image. Once it's done, you should have generated a fresh app:
$ ls
Dockerfile app docker-compose.yml tmp
Gemfile bin lib vendor
Gemfile.lock config log
README.rdoc config.ru public
Rakefile db test
The files `rails new` created are owned by root. This happens because the
container runs as the `root` user. Change the ownership of the new files.
sudo chown -R $USER:$USER .
Uncomment the line in your new `Gemfile` which loads `therubyracer`, so you've
got a Javascript runtime:
gem 'therubyracer', platforms: :ruby
Now that you've got a new `Gemfile`, you need to build the image again. (This,
and changes to the Dockerfile itself, should be the only times you'll need to
rebuild.)
$ docker-compose build
### Connect the database
The app is now bootable, but you're not quite there yet. By default, Rails
expects a database to be running on `localhost` - so you need to point it at the
`db` container instead. You also need to change the database and username to
align with the defaults set by the `postgres` image.
Replace the contents of `config/database.yml` with the following:
development: &default
adapter: postgresql
encoding: unicode
database: postgres
pool: 5
username: postgres
password:
host: db
test:
<<: *default
database: myapp_test
You can now boot the app with:
$ docker-compose up
If all's well, you should see some PostgreSQL output, and then—after a few
seconds—the familiar refrain:
myapp_web_1 | [2014-01-17 17:16:29] INFO WEBrick 1.3.1
myapp_web_1 | [2014-01-17 17:16:29] INFO ruby 2.2.0 (2014-12-25) [x86_64-linux-gnu]
myapp_web_1 | [2014-01-17 17:16:29] INFO WEBrick::HTTPServer#start: pid=1 port=3000
Finally, you need to create the database. In another terminal, run:
$ docker-compose run web rake db:create
That's it. Your app should now be running on port 3000 on your Docker daemon. If you're using [Docker Machine](https://docs.docker.com/machine), then `docker-machine ip MACHINE_VM` returns the Docker host IP address.
## More Compose documentation
- [User guide](/)
- [Installing Compose](install.md)
- [Get started with Django](django.md)
- [Get started with Rails](rails.md)
- [Get started with WordPress](wordpress.md)
- [Command line reference](./reference/index.md)
- [Compose file reference](compose-file.md)

View file

@ -1,24 +0,0 @@
<!--[metadata]>
+++
title = "build"
description = "build"
keywords = ["fig, composition, compose, docker, orchestration, cli, build"]
[menu.main]
identifier="build.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# build
```
Usage: build [options] [SERVICE...]
Options:
--no-cache Do not use cache when building the image.
--pull Always attempt to pull a newer version of the image.
```
Services are built once and then tagged as `project_service`, e.g.,
`composetest_db`. If you change a service's Dockerfile or the contents of its
build directory, run `docker-compose build` to rebuild it.

View file

@ -1,104 +0,0 @@
<!--[metadata]>
+++
title = "docker-compose"
description = "docker-compose Command Binary"
keywords = ["fig, composition, compose, docker, orchestration, cli, docker-compose"]
[menu.main]
parent = "smn_compose_cli"
weight=-2
+++
<![end-metadata]-->
# docker-compose Command
```
Usage:
docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...]
docker-compose -h|--help
Options:
-f, --file FILE Specify an alternate compose file (default: docker-compose.yml)
-p, --project-name NAME Specify an alternate project name (default: directory name)
--verbose Show more output
-v, --version Print version and exit
Commands:
build Build or rebuild services
help Get help on a command
kill Kill containers
logs View output from containers
pause Pause services
port Print the public port for a port binding
ps List containers
pull Pulls service images
restart Restart services
rm Remove stopped containers
run Run a one-off command
scale Set number of containers for a service
start Start services
stop Stop services
unpause Unpause services
up Create and start containers
migrate-to-labels Recreate containers to add labels
version Show the Docker-Compose version information
```
The Docker Compose binary. You use this command to build and manage multiple
services in Docker containers.
Use the `-f` flag to specify the location of a Compose configuration file. You
can supply multiple `-f` configuration files. When you supply multiple files,
Compose combines them into a single configuration. Compose builds the
configuration in the order you supply the files. Subsequent files override and
add to their successors.
For example, consider this command line:
```
$ docker-compose -f docker-compose.yml -f docker-compose.admin.yml run backup_db`
```
The `docker-compose.yml` file might specify a `webapp` service.
```
webapp:
image: examples/web
ports:
- "8000:8000"
volumes:
- "/data"
```
If the `docker-compose.admin.yml` also specifies this same service, any matching
fields will override the previous file. New values, add to the `webapp` service
configuration.
```
webapp:
build: .
environment:
- DEBUG=1
```
Use a `-f` with `-` (dash) as the filename to read the configuration from
stdin. When stdin is used all paths in the configuration are
relative to the current working directory.
The `-f` flag is optional. If you don't provide this flag on the command line,
Compose traverses the working directory and its subdirectories looking for a
`docker-compose.yml` and a `docker-compose.override.yml` file. You must supply
at least the `docker-compose.yml` file. If both files are present, Compose
combines the two files into a single configuration. The configuration in the
`docker-compose.override.yml` file is applied over and in addition to the values
in the `docker-compose.yml` file.
Each configuration has a project name. If you supply a `-p` flag, you can
specify a project name. If you don't specify the flag, Compose uses the current
directory name.
## Where to go next
* [CLI environment variables](overview.md)
* [Command line reference](index.md)

View file

@ -1,18 +0,0 @@
<!--[metadata]>
+++
title = "help"
description = "help"
keywords = ["fig, composition, compose, docker, orchestration, cli, help"]
[menu.main]
identifier="help.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# help
```
Usage: help COMMAND
```
Displays help and usage instructions for a command.

View file

@ -1,34 +0,0 @@
<!--[metadata]>
+++
title = "Compose CLI reference"
description = "Compose CLI reference"
keywords = ["fig, composition, compose, docker, orchestration, cli, reference"]
[menu.main]
identifier = "smn_compose_cli"
parent = "smn_compose_ref"
+++
<![end-metadata]-->
## Compose CLI reference
The following pages describe the usage information for the [docker-compose](docker-compose.md) subcommands. You can also see this information by running `docker-compose [SUBCOMMAND] --help` from the command line.
* [build](build.md)
* [help](help.md)
* [kill](kill.md)
* [ps](ps.md)
* [restart](restart.md)
* [run](run.md)
* [start](start.md)
* [up](up.md)
* [logs](logs.md)
* [port](port.md)
* [pull](pull.md)
* [rm](rm.md)
* [scale](scale.md)
* [stop](stop.md)
## Where to go next
* [CLI environment variables](overview.md)
* [docker-compose Command](docker-compose.md)

View file

@ -1,24 +0,0 @@
<!--[metadata]>
+++
title = "kill"
description = "Forces running containers to stop."
keywords = ["fig, composition, compose, docker, orchestration, cli, kill"]
[menu.main]
identifier="kill.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# kill
```
Usage: kill [options] [SERVICE...]
Options:
-s SIGNAL SIGNAL to send to the container. Default signal is SIGKILL.
```
Forces running containers to stop by sending a `SIGKILL` signal. Optionally the
signal can be passed, for example:
$ docker-compose kill -s SIGINT

View file

@ -1,21 +0,0 @@
<!--[metadata]>
+++
title = "logs"
description = "Displays log output from services."
keywords = ["fig, composition, compose, docker, orchestration, cli, logs"]
[menu.main]
identifier="logs.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# logs
```
Usage: logs [options] [SERVICE...]
Options:
--no-color Produce monochrome output.
```
Displays log output from services.

View file

@ -1,84 +0,0 @@
<!--[metadata]>
+++
title = "Introduction to the CLI"
description = "Introduction to the CLI"
keywords = ["fig, composition, compose, docker, orchestration, cli, reference"]
[menu.main]
parent = "smn_compose_cli"
weight=-2
+++
<![end-metadata]-->
# Introduction to the CLI
This section describes the subcommands you can use with the `docker-compose` command. You can run subcommand against one or more services. To run against a specific service, you supply the service name from your compose configuration. If you do not specify the service name, the command runs against all the services in your configuration.
## Commands
* [docker-compose Command](docker-compose.md)
* [CLI Reference](index.md)
## Environment Variables
Several environment variables are available for you to configure the Docker Compose command-line behaviour.
Variables starting with `DOCKER_` are the same as those used to configure the
Docker command-line client. If you're using `docker-machine`, then the `eval "$(docker-machine env my-docker-vm)"` command should set them to their correct values. (In this example, `my-docker-vm` is the name of a machine you created.)
### COMPOSE\_PROJECT\_NAME
Sets the project name. This value is prepended along with the service name to the container container on start up. For example, if you project name is `myapp` and it includes two services `db` and `web` then compose starts containers named `myapp_db_1` and `myapp_web_1` respectively.
Setting this is optional. If you do not set this, the `COMPOSE_PROJECT_NAME` defaults to the `basename` of the current working directory.
### COMPOSE\_FILE
Specify the file containing the compose configuration. If not provided, Compose looks for a file named `docker-compose.yml` in the current directory and then each parent directory in succession until a file by that name is found.
### COMPOSE\_API\_VERSION
The Docker API only supports requests from clients which report a specific
version. If you receive a `client and server don't have same version error` using
`docker-compose`, you can workaround this error by setting this environment
variable. Set the version value to match the server version.
Setting this variable is intended as a workaround for situations where you need
to run temporarily with a mismatch between the client and server version. For
example, if you can upgrade the client but need to wait to upgrade the server.
Running with this variable set and a known mismatch does prevent some Docker
features from working properly. The exact features that fail would depend on the
Docker client and server versions. For this reason, running with this variable
set is only intended as a workaround and it is not officially supported.
If you run into problems running with this set, resolve the mismatch through
upgrade and remove this setting to see if your problems resolve before notifying
support.
### DOCKER\_HOST
Sets the URL of the `docker` daemon. As with the Docker client, defaults to `unix:///var/run/docker.sock`.
### DOCKER\_TLS\_VERIFY
When set to anything other than an empty string, enables TLS communication with
the `docker` daemon.
### DOCKER\_CERT\_PATH
Configures the path to the `ca.pem`, `cert.pem`, and `key.pem` files used for TLS verification. Defaults to `~/.docker`.
### COMPOSE\_HTTP\_TIMEOUT
Configures the time (in seconds) a request to the Docker daemon is allowed to hang before Compose considers
it failed. Defaults to 60 seconds.
## Related Information
- [User guide](../index.md)
- [Installing Compose](../install.md)
- [Compose file reference](../compose-file.md)

View file

@ -1,18 +0,0 @@
<!--[metadata]>
+++
title = "pause"
description = "Pauses running containers for a service."
keywords = ["fig, composition, compose, docker, orchestration, cli, pause"]
[menu.main]
identifier="pause.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# pause
```
Usage: pause [SERVICE...]
```
Pauses running containers of a service. They can be unpaused with `docker-compose unpause`.

View file

@ -1,23 +0,0 @@
<!--[metadata]>
+++
title = "port"
description = "Prints the public port for a port binding.s"
keywords = ["fig, composition, compose, docker, orchestration, cli, port"]
[menu.main]
identifier="port.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# port
```
Usage: port [options] SERVICE PRIVATE_PORT
Options:
--protocol=proto tcp or udp [default: tcp]
--index=index index of the container if there are multiple
instances of a service [default: 1]
```
Prints the public port for a port binding.

View file

@ -1,21 +0,0 @@
<!--[metadata]>
+++
title = "ps"
description = "Lists containers."
keywords = ["fig, composition, compose, docker, orchestration, cli, ps"]
[menu.main]
identifier="ps.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# ps
```
Usage: ps [options] [SERVICE...]
Options:
-q Only display IDs
```
Lists containers.

View file

@ -1,21 +0,0 @@
<!--[metadata]>
+++
title = "pull"
description = "Pulls service images."
keywords = ["fig, composition, compose, docker, orchestration, cli, pull"]
[menu.main]
identifier="pull.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# pull
```
Usage: pull [options] [SERVICE...]
Options:
--ignore-pull-failures Pull what it can and ignores images with pull failures.
```
Pulls service images.

View file

@ -1,21 +0,0 @@
<!--[metadata]>
+++
title = "restart"
description = "Restarts Docker Compose services."
keywords = ["fig, composition, compose, docker, orchestration, cli, restart"]
[menu.main]
identifier="restart.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# restart
```
Usage: restart [options] [SERVICE...]
Options:
-t, --timeout TIMEOUT Specify a shutdown timeout in seconds. (default: 10)
```
Restarts services.

View file

@ -1,22 +0,0 @@
<!--[metadata]>
+++
title = "rm"
description = "Removes stopped service containers."
keywords = ["fig, composition, compose, docker, orchestration, cli, rm"]
[menu.main]
identifier="rm.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# rm
```
Usage: rm [options] [SERVICE...]
Options:
-f, --force Don't ask to confirm removal
-v Remove volumes associated with containers
```
Removes stopped service containers.

View file

@ -1,54 +0,0 @@
<!--[metadata]>
+++
title = "run"
description = "Runs a one-off command on a service."
keywords = ["fig, composition, compose, docker, orchestration, cli, run"]
[menu.main]
identifier="run.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# run
```
Usage: run [options] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...]
Options:
-d Detached mode: Run container in the background, print
new container name.
--entrypoint CMD Override the entrypoint of the image.
-e KEY=VAL Set an environment variable (can be used multiple times)
-u, --user="" Run as specified username or uid
--no-deps Don't start linked services.
--rm Remove container after run. Ignored in detached mode.
-p, --publish=[] Publish a container's port(s) to the host
--service-ports Run command with the service's ports enabled and mapped to the host.
-T Disable pseudo-tty allocation. By default `docker-compose run` allocates a TTY.
```
Runs a one-time command against a service. For example, the following command starts the `web` service and runs `bash` as its command.
$ docker-compose run web bash
Commands you use with `run` start in new containers with the same configuration as defined by the service' configuration. This means the container has the same volumes, links, as defined in the configuration file. There two differences though.
First, the command passed by `run` overrides the command defined in the service configuration. For example, if the `web` service configuration is started with `bash`, then `docker-compose run web python app.py` overrides it with `python app.py`.
The second difference is the `docker-compose run` command does not create any of the ports specified in the service configuration. This prevents the port collisions with already open ports. If you *do want* the service's ports created and mapped to the host, specify the `--service-ports` flag:
$ docker-compose run --service-ports web python manage.py shell
Alternatively manual port mapping can be specified. Same as when running Docker's `run` command - using `--publish` or `-p` options:
$ docker-compose run --publish 8080:80 -p 2022:22 -p 127.0.0.1:2021:21 web python manage.py shell
If you start a service configured with links, the `run` command first checks to see if the linked service is running and starts the service if it is stopped. Once all the linked services are running, the `run` executes the command you passed it. So, for example, you could run:
$ docker-compose run db psql -h db -U docker
This would open up an interactive PostgreSQL shell for the linked `db` container.
If you do not want the `run` command to start linked containers, specify the `--no-deps` flag:
$ docker-compose run --no-deps web python manage.py shell

View file

@ -1,21 +0,0 @@
<!--[metadata]>
+++
title = "scale"
description = "Sets the number of containers to run for a service."
keywords = ["fig, composition, compose, docker, orchestration, cli, scale"]
[menu.main]
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# scale
```
Usage: scale [SERVICE=NUM...]
```
Sets the number of containers to run for a service.
Numbers are specified as arguments in the form `service=num`. For example:
$ docker-compose scale web=2 worker=3

View file

@ -1,18 +0,0 @@
<!--[metadata]>
+++
title = "start"
description = "Starts existing containers for a service."
keywords = ["fig, composition, compose, docker, orchestration, cli, start"]
[menu.main]
identifier="start.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# start
```
Usage: start [SERVICE...]
```
Starts existing containers for a service.

View file

@ -1,22 +0,0 @@
<!--[metadata]>
+++
title = "stop"
description = "Stops running containers without removing them. "
keywords = ["fig, composition, compose, docker, orchestration, cli, stop"]
[menu.main]
identifier="stop.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# stop
```
Usage: stop [options] [SERVICE...]
Options:
-t, --timeout TIMEOUT Specify a shutdown timeout in seconds (default: 10).
```
Stops running containers without removing them. They can be started again with
`docker-compose start`.

View file

@ -1,18 +0,0 @@
<!--[metadata]>
+++
title = "unpause"
description = "Unpauses paused containers for a service."
keywords = ["fig, composition, compose, docker, orchestration, cli, unpause"]
[menu.main]
identifier="unpause.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# pause
```
Usage: unpause [SERVICE...]
```
Unpauses paused containers of a service.

View file

@ -1,47 +0,0 @@
<!--[metadata]>
+++
title = "up"
description = "Builds, (re)creates, starts, and attaches to containers for a service."
keywords = ["fig, composition, compose, docker, orchestration, cli, up"]
[menu.main]
identifier="up.compose"
parent = "smn_compose_cli"
+++
<![end-metadata]-->
# up
```
Usage: up [options] [SERVICE...]
Options:
-d Detached mode: Run containers in the background,
print new container names.
--no-color Produce monochrome output.
--no-deps Don't start linked services.
--force-recreate Recreate containers even if their configuration and
image haven't changed. Incompatible with --no-recreate.
--no-recreate If containers already exist, don't recreate them.
Incompatible with --force-recreate.
--no-build Don't build an image, even if it's missing
-t, --timeout TIMEOUT Use this timeout in seconds for container shutdown
when attached or when containers are already
running. (default: 10)
```
Builds, (re)creates, starts, and attaches to containers for a service.
Unless they are already running, this command also starts any linked services.
The `docker-compose up` command aggregates the output of each container. When
the command exits, all containers are stopped. Running `docker-compose up -d`
starts the containers in the background and leaves them running.
If there are existing containers for a service, and the service's configuration
or image was changed after the container's creation, `docker-compose up` picks
up the changes by stopping and recreating the containers (preserving mounted
volumes). To prevent Compose from picking up changes, use the `--no-recreate`
flag.
If you want to force Compose to stop and recreate all containers, use the
`--force-recreate` flag.

View file

@ -1,102 +0,0 @@
<!--[metadata]>
+++
title = "Quickstart Guide: Compose and WordPress"
description = "Getting started with Compose and WordPress"
keywords = ["documentation, docs, docker, compose, orchestration, containers"]
[menu.main]
parent="smn_workw_compose"
weight=6
+++
<![end-metadata]-->
# Quickstart Guide: Compose and WordPress
You can use Compose to easily run WordPress in an isolated environment built
with Docker containers.
## Define the project
First, [Install Compose](install.md) and then download WordPress into the
current directory:
$ curl https://wordpress.org/latest.tar.gz | tar -xvzf -
This will create a directory called `wordpress`. If you wish, you can rename it
to the name of your project.
Next, inside that directory, create a `Dockerfile`, a file that defines what
environment your app is going to run in. For more information on how to write
Dockerfiles, see the
[Docker user guide](https://docs.docker.com/userguide/dockerimages/#building-an-image-from-a-dockerfile) and the
[Dockerfile reference](http://docs.docker.com/reference/builder/). In this case,
your Dockerfile should be:
FROM orchardup/php5
ADD . /code
This tells Docker how to build an image defining a container that contains PHP
and WordPress.
Next you'll create a `docker-compose.yml` file that will start your web service
and a separate MySQL instance:
web:
build: .
command: php -S 0.0.0.0:8000 -t /code
ports:
- "8000:8000"
links:
- db
volumes:
- .:/code
db:
image: orchardup/mysql
environment:
MYSQL_DATABASE: wordpress
A supporting file is needed to get this working. `wp-config.php` is
the standard WordPress config file with a single change to point the database
configuration at the `db` container:
<?php
define('DB_NAME', 'wordpress');
define('DB_USER', 'root');
define('DB_PASSWORD', '');
define('DB_HOST', "db:3306");
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
define('AUTH_KEY', 'put your unique phrase here');
define('SECURE_AUTH_KEY', 'put your unique phrase here');
define('LOGGED_IN_KEY', 'put your unique phrase here');
define('NONCE_KEY', 'put your unique phrase here');
define('AUTH_SALT', 'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT', 'put your unique phrase here');
define('NONCE_SALT', 'put your unique phrase here');
$table_prefix = 'wp_';
define('WPLANG', '');
define('WP_DEBUG', false);
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');
### Build the project
With those four files in place, run `docker-compose up` inside your WordPress
directory and it'll pull and build the needed images, and then start the web and
database containers. If you're using [Docker Machine](https://docs.docker.com/machine), then `docker-machine ip MACHINE_VM` gives you the machine address and you can open `http://MACHINE_VM_IP:8000` in a browser.
## More Compose documentation
- [User guide](/)
- [Installing Compose](install.md)
- [Get started with Django](django.md)
- [Get started with Rails](rails.md)
- [Get started with WordPress](wordpress.md)
- [Command line reference](./reference/index.md)
- [Compose file reference](compose-file.md)

View file

@ -1,183 +1,5 @@
# Experimental: Compose, Swarm and Multi-Host Networking
The [experimental build of Docker](https://github.com/docker/docker/tree/master/experimental) has an entirely new networking system, which enables secure communication between containers on multiple hosts. In combination with Docker Swarm and Docker Compose, you can now run multi-container apps on multi-host clusters with the same tooling and configuration format you use to develop them locally.
Compose now supports multi-host networking as standard. Read more here:
> Note: This functionality is in the experimental stage, and contains some hacks and workarounds which will be removed as it matures.
## Prerequisites
Before you start, you’ll need to install the experimental build of Docker, and the latest versions of Machine and Compose.
- To install the experimental Docker build on a Linux machine, follow the instructions [here](https://github.com/docker/docker/tree/master/experimental#install-docker-experimental).
- To install the experimental Docker build on a Mac, run these commands:
$ curl -L https://experimental.docker.com/builds/Darwin/x86_64/docker-latest > /usr/local/bin/docker
$ chmod +x /usr/local/bin/docker
- To install Machine, follow the instructions [here](http://docs.docker.com/machine/).
- To install Compose, follow the instructions [here](http://docs.docker.com/compose/install/).
You’ll also need a [Docker Hub](https://hub.docker.com/account/signup/) account and a [Digital Ocean](https://www.digitalocean.com/) account.
## Set up a swarm with multi-host networking
Set the `DIGITALOCEAN_ACCESS_TOKEN` environment variable to a valid Digital Ocean API token, which you can generate in the [API panel](https://cloud.digitalocean.com/settings/applications).
DIGITALOCEAN_ACCESS_TOKEN=abc12345
Start a consul server:
docker-machine create -d digitalocean --engine-install-url https://experimental.docker.com consul
docker $(docker-machine config consul) run -d -p 8500:8500 -h consul progrium/consul -server -bootstrap
(In a real world setting you’d set up a distributed consul, but that’s beyond the scope of this guide!)
Create a Swarm token:
SWARM_TOKEN=$(docker run swarm create)
Create a Swarm master:
docker-machine create -d digitalocean --swarm --swarm-master --swarm-discovery=token://$SWARM_TOKEN --engine-install-url="https://experimental.docker.com" --digitalocean-image "ubuntu-14-10-x64" --engine-opt=default-network=overlay:multihost --engine-label=com.docker.network.driver.overlay.bind_interface=eth0 --engine-opt=kv-store=consul:$(docker-machine ip consul):8500 swarm-0
Create a Swarm node:
docker-machine create -d digitalocean --swarm --swarm-discovery=token://$SWARM_TOKEN --engine-install-url="https://experimental.docker.com" --digitalocean-image "ubuntu-14-10-x64" --engine-opt=default-network=overlay:multihost --engine-label=com.docker.network.driver.overlay.bind_interface=eth0 --engine-opt=kv-store=consul:$(docker-machine ip consul):8500 --engine-label com.docker.network.driver.overlay.neighbor_ip=$(docker-machine ip swarm-0) swarm-1
You can create more Swarm nodes if you want - it’s best to give them sensible names (swarm-2, swarm-3, etc).
Finally, point Docker at your swarm:
eval "$(docker-machine env --swarm swarm-0)"
## Run containers and get them communicating
Now that you’ve got a swarm up and running, you can create containers on it just like a single Docker instance:
$ docker run busybox echo hello world
hello world
If you run `docker ps -a`, you can see what node that container was started on by looking at its name (here it’s swarm-3):
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
41f59749737b busybox "echo hello world" 15 seconds ago Exited (0) 13 seconds ago swarm-3/trusting_leakey
As you start more containers, they’ll be placed on different nodes across the cluster, thanks to Swarm’s default “spread” scheduling strategy.
Every container started on this swarm will use the “overlay:multihost” network by default, meaning they can all intercommunicate. Each container gets an IP address on that network, and an `/etc/hosts` file which will be updated on-the-fly with every other container’s IP address and name. That means that if you have a running container named ‘foo’, other containers can access it at the hostname ‘foo’.
Let’s verify that multi-host networking is functioning. Start a long-running container:
$ docker run -d --name long-running busybox top
<container id>
If you start a new container and inspect its /etc/hosts file, you’ll see the long-running container in there:
$ docker run busybox cat /etc/hosts
...
172.21.0.6 long-running
Verify that connectivity works between containers:
$ docker run busybox ping long-running
PING long-running (172.21.0.6): 56 data bytes
64 bytes from 172.21.0.6: seq=0 ttl=64 time=7.975 ms
64 bytes from 172.21.0.6: seq=1 ttl=64 time=1.378 ms
64 bytes from 172.21.0.6: seq=2 ttl=64 time=1.348 ms
^C
--- long-running ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.140/2.099/7.975 ms
## Run a Compose application
Here’s an example of a simple Python + Redis app using multi-host networking on a swarm.
Create a directory for the app:
$ mkdir composetest
$ cd composetest
Inside this directory, create 2 files.
First, create `app.py` - a simple web app that uses the Flask framework and increments a value in Redis:
from flask import Flask
from redis import Redis
import os
app = Flask(__name__)
redis = Redis(host='composetest_redis_1', port=6379)
@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)
Note that we’re connecting to a host called `composetest_redis_1` - this is the name of the Redis container that Compose will start.
Second, create a Dockerfile for the app container:
FROM python:2.7
RUN pip install flask redis
ADD . /code
WORKDIR /code
CMD ["python", "app.py"]
Build the Docker image and push it to the Hub (you’ll need a Hub account). Replace `<username>` with your Docker Hub username:
$ docker build -t <username>/counter .
$ docker push <username>/counter
Next, create a `docker-compose.yml`, which defines the configuration for the web and redis containers. Once again, replace `<username>` with your Hub username:
web:
image: <username>/counter
ports:
- "80:5000"
redis:
image: redis
Now start the app:
$ docker-compose up -d
Pulling web (username/counter:latest)...
swarm-0: Pulling username/counter:latest... : downloaded
swarm-2: Pulling username/counter:latest... : downloaded
swarm-1: Pulling username/counter:latest... : downloaded
swarm-3: Pulling username/counter:latest... : downloaded
swarm-4: Pulling username/counter:latest... : downloaded
Creating composetest_web_1...
Pulling redis (redis:latest)...
swarm-2: Pulling redis:latest... : downloaded
swarm-1: Pulling redis:latest... : downloaded
swarm-3: Pulling redis:latest... : downloaded
swarm-4: Pulling redis:latest... : downloaded
swarm-0: Pulling redis:latest... : downloaded
Creating composetest_redis_1...
Swarm has created containers for both web and redis, and placed them on different nodes, which you can check with `docker ps`:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
92faad2135c9 redis "/entrypoint.sh redi 43 seconds ago Up 42 seconds swarm-2/composetest_redis_1
adb809e5cdac username/counter "/bin/sh -c 'python 55 seconds ago Up 54 seconds 45.67.8.9:80->5000/tcp swarm-1/composetest_web_1
You can also see that the web container has exposed port 80 on its swarm node. If you curl that IP, you’ll get a response from the container:
$ curl http://45.67.8.9
Hello World! I have been seen 1 times.
If you hit it repeatedly, the counter will increment, demonstrating that the web and redis container are communicating:
$ curl http://45.67.8.9
Hello World! I have been seen 2 times.
$ curl http://45.67.8.9
Hello World! I have been seen 3 times.
$ curl http://45.67.8.9
Hello World! I have been seen 4 times.
https://docs.docker.com/compose/networking

View file

@ -20,18 +20,30 @@ release.
As part of this script you'll be asked to:
1. Update the version in `docs/install.md` and `compose/__init__.py`.
1. Update the version in `compose/__init__.py` and `script/run/run.sh`.
If the next release will be an RC, append `rcN`, e.g. `1.4.0rc1`.
If the next release will be an RC, append `-rcN`, e.g. `1.4.0-rc1`.
2. Write release notes in `CHANGES.md`.
Almost every feature enhancement should be mentioned, with the most visible/exciting ones first. Use descriptive sentences and give context where appropriate.
Almost every feature enhancement should be mentioned, with the most
visible/exciting ones first. Use descriptive sentences and give context
where appropriate.
Bug fixes are worth mentioning if it's likely that they've affected lots of people, or if they were regressions in the previous version.
Bug fixes are worth mentioning if it's likely that they've affected lots
of people, or if they were regressions in the previous version.
Improvements to the code are not worth mentioning.
3. Create a new repository on [bintray](https://bintray.com/docker-compose).
The name has to match the name of the branch (e.g. `bump-1.9.0`) and the
type should be "Generic". Other fields can be left blank.
4. Check that the `vnext-compose` branch on
[the docs repo](https://github.com/docker/docker.github.io/) has
documentation for all the new additions in the upcoming release, and create
a PR there for what needs to be amended.
## When a PR is merged into master that we want in the release
@ -55,10 +67,10 @@ Check out the bump branch and run the `build-binaries` script
When prompted build the non-linux binaries and test them.
1. Build the Mac binary in a Mountain Lion VM:
1. Download the osx binary from Bintray. Make sure that the latest Travis
build has finished, otherwise you'll be downloading an old binary.
script/prepare-osx
script/build-osx
https://dl.bintray.com/docker-compose/$BRANCH_NAME/
2. Download the windows binary from AppVeyor
@ -67,28 +79,30 @@ When prompted build the non-linux binaries and test them.
3. Draft a release from the tag on GitHub (the script will open the window for
you)
In the "Tag version" dropdown, select the tag you just pushed.
The tag will only be present on Github when you run the `push-release`
script in step 7, but you can pre-fill it at that point.
4. Paste in installation instructions and release notes. Here's an example - change the Compose version and Docker version as appropriate:
4. Paste in installation instructions and release notes. Here's an example -
change the Compose version and Docker version as appropriate:
Firstly, note that Compose 1.5.0 requires Docker 1.8.0 or later.
If you're a Mac or Windows user, the best way to install Compose and keep it up-to-date is **[Docker for Mac and Windows](https://www.docker.com/products/docker)**.
Secondly, if you're a Mac user, the **[Docker Toolbox](https://www.docker.com/toolbox)** will install Compose 1.5.0 for you, alongside the latest versions of the Docker Engine, Machine and Kitematic.
Note that Compose 1.9.0 requires Docker Engine 1.10.0 or later for version 2 of the Compose File format, and Docker Engine 1.9.1 or later for version 1. Docker for Mac and Windows will automatically install the latest version of Docker Engine for you.
Otherwise, you can use the usual commands to install/upgrade. Either download the binary:
Alternatively, you can use the usual commands to install or upgrade Compose:
curl -L https://github.com/docker/compose/releases/download/1.5.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
```
curl -L https://github.com/docker/compose/releases/download/1.9.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
```
Or install the PyPi package:
pip install -U docker-compose==1.5.0
See the [install docs](https://docs.docker.com/compose/install/) for more install options and instructions.
Here's what's new:
...release notes go here...
5. Attach the binaries and `script/run.sh`
5. Attach the binaries and `script/run/run.sh`
6. Add "Thanks" with a list of contributors. The contributor list can be generated
by running `./script/release/contributors`.
@ -99,6 +113,8 @@ When prompted build the non-linux binaries and test them.
./script/release/push-release
8. Merge the bump PR.
8. Publish the release on GitHub.
9. Check that all the binaries download (following the install instructions) and run.
@ -107,19 +123,7 @@ When prompted build the non-linux binaries and test them.
## If it’s a stable release (not an RC)
1. Merge the bump PR.
2. Make sure `origin/release` is updated locally:
git fetch origin
3. Update the `docs` branch on the upstream repo:
git push git@github.com:docker/compose.git origin/release:docs
4. Let the docs team know that it’s been updated so they can publish it.
5. Close the release’s milestone.
1. Close the release’s milestone.
## If it’s a minor release (1.x.0), rather than a patch release (1.x.y)

View file

@ -1 +1 @@
pyinstaller==3.0
pyinstaller==3.2.1

View file

@ -1,10 +1,16 @@
PyYAML==3.10
docker-py==1.5.0
dockerpty==0.3.4
PyYAML==3.11
backports.ssl-match-hostname==3.5.0.1; python_version < '3'
cached-property==1.2.0
colorama==0.3.7
docker==2.0.2
dockerpty==0.4.1
docopt==0.6.1
enum34==1.0.4
enum34==1.0.4; python_version < '3.4'
functools32==3.2.3.post2; python_version < '3.2'
ipaddress==1.0.16
jsonschema==2.5.1
requests==2.7.0
six==1.7.3
texttable==0.8.2
pypiwin32==219; sys_platform == 'win32'
requests==2.11.1
six==1.10.0
texttable==0.8.4
websocket-client==0.32.0

View file

@ -10,6 +10,6 @@ fi
TAG=$1
VERSION="$(python setup.py --version)"
python setup.py sdist
cp dist/docker-compose-$VERSION.tar.gz dist/docker-compose-release.tar.gz
docker build -t docker/compose:$TAG -f Dockerfile.run .
./script/build/write-git-sha
python setup.py sdist bdist_wheel
docker build --build-arg version=$VERSION -t docker/compose:$TAG -f Dockerfile.run .

View file

@ -7,6 +7,7 @@ set -ex
TAG="docker-compose"
docker build -t "$TAG" . | tail -n 200
docker run \
--rm --entrypoint="script/build-linux-inner" \
--rm --entrypoint="script/build/linux-entrypoint" \
-v $(pwd)/dist:/code/dist \
-v $(pwd)/.git:/code/.git \
"$TAG"

Some files were not shown because too many files have changed in this diff Show more