docker-composer 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,76 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, sex characteristics, gender identity and expression,
9
+ level of experience, education, socio-economic status, nationality, personal
10
+ appearance, race, religion, or sexual identity and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at tudvari@tudvari.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72
+
73
+ [homepage]: https://www.contributor-covenant.org
74
+
75
+ For answers to common questions about this code of conduct, see
76
+ https://www.contributor-covenant.org/faq
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Tibor Udvari
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # docker-composer
2
+
3
+ Generate Docker Compose descriptor from a JSON document.
4
+
5
+ ![Node.js CI](https://github.com/tudvari/docker-composer/workflows/Node.js%20CI/badge.svg)
6
+ [![npm version](https://badge.fury.io/js/docker-composer.svg)](https://badge.fury.io/js/docker-composer)
7
+
8
+ ## About the package
9
+
10
+ The reason behind this package is support the Docker Compose descriptor generation from Javascript. You are able to use all Docker Compose keyword to describe your containers and services.
11
+
12
+
13
+ Docker Compose Reference is [HERE](https://docs.docker.com/compose/compose-file/).
14
+
15
+ ### Changes of the Latest Release
16
+
17
+ ## Version 4.0.2 (27.09.2021)
18
+ - Maintenance release, dependency updates
19
+
20
+ You can find all Release Notes [HERE](https://github.com/tudvari/docker-composer/blob/master/ReleaseNotes.md).
21
+
22
+ ## Usage
23
+
24
+ ```javascript
25
+
26
+ const composer = require('docker-composer')
27
+ .
28
+ var generatedYML = composer.generate( inputJSON )
29
+ ```
30
+
31
+ ## Full Example
32
+
33
+ ### Input
34
+
35
+ ```json
36
+ {
37
+ "version" : "3",
38
+ "services" :
39
+ {
40
+ "nginx" : {
41
+ "ports" : [
42
+ "80"
43
+ ],
44
+ "image" : "nginx:latest"
45
+ },
46
+ "http" : {
47
+ "ports" : [
48
+ "443"
49
+ ],
50
+ "image" : "apache:latest"
51
+ }
52
+ }
53
+ }
54
+ ```
55
+ ### Result
56
+ ```yml
57
+ ---
58
+ version: "3"
59
+ services:
60
+ nginx:
61
+ ports:
62
+ - "80"
63
+ image: "nginx:latest"
64
+ http:
65
+ ports:
66
+ - "443"
67
+ image: "nginx:latest"
68
+ ```
69
+
70
+ ### License
71
+
72
+ Copyright (c) 2015 Tibor Udvari. Released under the MIT license. See [LICENSE](https://github.com/tudvari/docker-composer/blob/master/LICENSE) for details.
73
+
74
+
@@ -0,0 +1,102 @@
1
+ # Release Notes
2
+
3
+ ## Version 4.0.2 (27.09.2021)
4
+ - Maintenance release, dependency updates
5
+
6
+ ## Version 4.0.1 (31.03.2021)
7
+ - Maintenance release, dependency updates
8
+
9
+ ## Version 4.0.0 (31.12.2020)
10
+ - Typescript type definitions
11
+
12
+ ## Version 3.1.13 (23.10.2020)
13
+ - Maintenance release, dependency updates
14
+
15
+ ## Version 3.1.12 (17.10.2020)
16
+ - Maintenance release, dependency updates
17
+
18
+ ## Version 3.1.11 (11.10.2020)
19
+ - Maintenance release, dependency updates
20
+
21
+ ## Version 3.1.10 (08.10.2020)
22
+ - Maintenance release, dependency updates
23
+
24
+ ## Version 3.1.9 (30.09.2020)
25
+ - Maintenance release, dependency updates
26
+
27
+ ## Version 3.1.8 (02.04.2020)
28
+ - Dependency update
29
+
30
+ ## Version 3.1.7 (21.03.2020)
31
+ - Vulnerable dependency update
32
+ * More details: https://github.com/advisories/GHSA-7fhm-mqm4-2wp7
33
+
34
+ #### Version 3.1.6 (2019.12.01)
35
+ - Update dependencies
36
+
37
+ #### Version 3.1.5 (2019.11.24)
38
+ - Update dependencies
39
+ - Use nyc instead of istanbul
40
+ - Published package optimalization
41
+
42
+ #### Version 3.1.4 ( 2019.07.11)
43
+ - Update dependencies for security reason
44
+
45
+ #### Version 3.1.3 ( 2019.06.05)
46
+ - Update dependencies
47
+
48
+ ## Version 3.1.2 ( 2019.01.06)
49
+ - Update dependencies
50
+
51
+ ## Version 3.1.1 ( 2018.12.12 )
52
+ - Schema loading fix (thanks for andrepurnomo)
53
+
54
+ ## Version 3.1.0 ( 2018.12.09 )
55
+ - Introduce JSON schema for input validation
56
+ - Version 3 Compose file format support
57
+
58
+ ## Version 3.0.1 (2018.04.15)
59
+ - Remove npm package from dependencies.
60
+
61
+ ## Version 3.0.0 (2018.04.15)
62
+ - Change from callback to Promise for async/await support.
63
+
64
+ ## Version 2.0.2 (2017.12.29)
65
+ - Refresh dependencies.
66
+
67
+ ## Version 2.0.1 (2017.01.03)
68
+ - Code Quality improvements, new eslint ruleset, editorconfig, etc..
69
+
70
+ ## Version 2.0.0 (2016.05.03)
71
+ - Tons of new implemented keywords many thanks to Alex.
72
+
73
+ ## Version 1.0.7 (2016.04.29)
74
+
75
+ - Fixed a bug that was preventing the docker-compose to read array/object variables from the generated YML file
76
+ - New implemented keywords: volumes
77
+
78
+ ## Version 1.0.6 (2015.11.08)
79
+
80
+ - New implemented keywords: cpu_shares
81
+
82
+ ## Version 1.0.5 (2015.10.29)
83
+
84
+ - New implemented keywords: mem_limit, memswap_limit
85
+
86
+ ## Version 1.0.4 (2015.10.21)
87
+
88
+ - Small fixes
89
+
90
+ ## Version 1.0.3 (2015.10.21)
91
+
92
+ - New implemented keywords: dns, dns_search
93
+
94
+ ## Version 1.0.2 (2015.10.20)
95
+
96
+ - Small js fixes
97
+ - New implemented keywords: expose, command
98
+
99
+ ## Version 1.0.0 and Version 1.0.1 (2015.10.14)
100
+
101
+ - First public version released
102
+ - Supported keywords: ports, environment, extra_hosts, image
package/index.d.ts ADDED
@@ -0,0 +1,270 @@
1
+ export type DefinitionsDeployment = {
2
+ mode?: string;
3
+ replicas?: number;
4
+ labels?: Labels;
5
+ update_config?: {
6
+ parallelism?: number;
7
+ delay?: string;
8
+ failure_action?: string;
9
+ monitor?: string;
10
+ max_failure_ratio?: number;
11
+ };
12
+ resources?: {
13
+ limits?: DefinitionsResource;
14
+ reservations?: DefinitionsResource;
15
+ };
16
+ restart_policy?: {
17
+ condition?: string;
18
+ delay?: string;
19
+ max_attempts?: number;
20
+ window?: string;
21
+ };
22
+ placement?: {
23
+ constraints?: string[];
24
+ };
25
+ } & ({
26
+ mode?: string;
27
+ replicas?: number;
28
+ labels?: Labels;
29
+ update_config?: {
30
+ parallelism?: number;
31
+ delay?: string;
32
+ failure_action?: string;
33
+ monitor?: string;
34
+ max_failure_ratio?: number;
35
+ };
36
+ resources?: {
37
+ limits?: DefinitionsResource;
38
+ reservations?: DefinitionsResource;
39
+ };
40
+ restart_policy?: {
41
+ condition?: string;
42
+ delay?: string;
43
+ max_attempts?: number;
44
+ window?: string;
45
+ };
46
+ placement?: {
47
+ constraints?: string[];
48
+ };
49
+ } | null);
50
+ export type Labels =
51
+ | {
52
+ /**
53
+ * This interface was referenced by `undefined`'s JSON-Schema definition
54
+ * via the `patternProperty` ".+".
55
+ */
56
+ [k: string]: string;
57
+ }
58
+ | string[];
59
+ export type ListOrDict =
60
+ | {
61
+ /**
62
+ * This interface was referenced by `undefined`'s JSON-Schema definition
63
+ * via the `patternProperty` ".+".
64
+ */
65
+ [k: string]: string | number | null;
66
+ }
67
+ | string[];
68
+ export type ListOfStrings = string[];
69
+ export type StringOrList = string | ListOfStrings;
70
+ /**
71
+ * This interface was referenced by `PropertiesNetworks`'s JSON-Schema definition
72
+ * via the `patternProperty` "^[a-zA-Z0-9._-]+$".
73
+ */
74
+ export type DefinitionsNetwork = {
75
+ driver?: string;
76
+ driver_opts?: {
77
+ /**
78
+ * This interface was referenced by `undefined`'s JSON-Schema definition
79
+ * via the `patternProperty` "^.+$".
80
+ */
81
+ [k: string]: string | number;
82
+ };
83
+ ipam?: {
84
+ driver?: string;
85
+ config?: {
86
+ subnet?: string;
87
+ }[];
88
+ };
89
+ external?:
90
+ | boolean
91
+ | {
92
+ name?: string;
93
+ };
94
+ internal?: boolean;
95
+ labels?: Labels;
96
+ } & ({
97
+ driver?: string;
98
+ driver_opts?: {
99
+ /**
100
+ * This interface was referenced by `undefined`'s JSON-Schema definition
101
+ * via the `patternProperty` "^.+$".
102
+ */
103
+ [k: string]: string | number;
104
+ };
105
+ ipam?: {
106
+ driver?: string;
107
+ config?: {
108
+ subnet?: string;
109
+ }[];
110
+ };
111
+ external?:
112
+ | boolean
113
+ | {
114
+ name?: string;
115
+ };
116
+ internal?: boolean;
117
+ labels?: Labels;
118
+ } | null);
119
+ /**
120
+ * This interface was referenced by `PropertiesVolumes`'s JSON-Schema definition
121
+ * via the `patternProperty` "^[a-zA-Z0-9._-]+$".
122
+ */
123
+ export type DefinitionsVolume = {
124
+ driver?: string;
125
+ driver_opts?: {
126
+ /**
127
+ * This interface was referenced by `undefined`'s JSON-Schema definition
128
+ * via the `patternProperty` "^.+$".
129
+ */
130
+ [k: string]: string | number;
131
+ };
132
+ external?:
133
+ | boolean
134
+ | {
135
+ name?: string;
136
+ };
137
+ labels?: Labels;
138
+ } & ({
139
+ driver?: string;
140
+ driver_opts?: {
141
+ /**
142
+ * This interface was referenced by `undefined`'s JSON-Schema definition
143
+ * via the `patternProperty` "^.+$".
144
+ */
145
+ [k: string]: string | number;
146
+ };
147
+ external?:
148
+ | boolean
149
+ | {
150
+ name?: string;
151
+ };
152
+ labels?: Labels;
153
+ } | null);
154
+
155
+ export interface ConfigSchemaV30Json {
156
+ version: string;
157
+ services?: PropertiesServices;
158
+ networks?: PropertiesNetworks;
159
+ volumes?: PropertiesVolumes;
160
+ }
161
+ export interface PropertiesServices {
162
+ [k: string]: DefinitionsService;
163
+ }
164
+ /**
165
+ * This interface was referenced by `PropertiesServices`'s JSON-Schema definition
166
+ * via the `patternProperty` "^[a-zA-Z0-9._-]+$".
167
+ */
168
+ export interface DefinitionsService {
169
+ deploy?: DefinitionsDeployment;
170
+ build?:
171
+ | string
172
+ | {
173
+ context?: string;
174
+ dockerfile?: string;
175
+ args?: ListOrDict;
176
+ };
177
+ cap_add?: string[];
178
+ cap_drop?: string[];
179
+ cgroup_parent?: string;
180
+ command?: string | string[];
181
+ container_name?: string;
182
+ depends_on?: ListOfStrings;
183
+ devices?: string[];
184
+ dns?: StringOrList;
185
+ dns_search?: StringOrList;
186
+ domainname?: string;
187
+ entrypoint?: string | string[];
188
+ env_file?: StringOrList;
189
+ environment?: ListOrDict;
190
+ expose?: (string | number)[];
191
+ external_links?: string[];
192
+ extra_hosts?: ListOrDict;
193
+ healthcheck?: DefinitionsHealthcheck;
194
+ hostname?: string;
195
+ image?: string;
196
+ ipc?: string;
197
+ labels?: Labels;
198
+ links?: string[];
199
+ logging?: {
200
+ driver?: string;
201
+ options?: {
202
+ /**
203
+ * This interface was referenced by `undefined`'s JSON-Schema definition
204
+ * via the `patternProperty` "^.+$".
205
+ */
206
+ [k: string]: string | number | null;
207
+ };
208
+ };
209
+ mac_address?: string;
210
+ network_mode?: string;
211
+ networks?:
212
+ | ListOfStrings
213
+ | {
214
+ /**
215
+ * This interface was referenced by `undefined`'s JSON-Schema definition
216
+ * via the `patternProperty` "^[a-zA-Z0-9._-]+$".
217
+ */
218
+ [k: string]: {
219
+ aliases?: ListOfStrings;
220
+ ipv4_address?: string;
221
+ ipv6_address?: string;
222
+ } | null;
223
+ };
224
+ pid?: string | null;
225
+ ports?: (string | number)[];
226
+ privileged?: boolean;
227
+ read_only?: boolean;
228
+ restart?: string;
229
+ security_opt?: string[];
230
+ shm_size?: number | string;
231
+ sysctls?: ListOrDict;
232
+ stdin_open?: boolean;
233
+ stop_grace_period?: string;
234
+ stop_signal?: string;
235
+ tmpfs?: StringOrList;
236
+ tty?: boolean;
237
+ ulimits?: {
238
+ /**
239
+ * This interface was referenced by `undefined`'s JSON-Schema definition
240
+ * via the `patternProperty` "^[a-z]+$".
241
+ */
242
+ [k: string]:
243
+ | number
244
+ | {
245
+ hard: number;
246
+ soft: number;
247
+ };
248
+ };
249
+ user?: string;
250
+ userns_mode?: string;
251
+ volumes?: string[];
252
+ working_dir?: string;
253
+ }
254
+ export interface DefinitionsResource {
255
+ cpus?: string;
256
+ memory?: string;
257
+ }
258
+ export interface DefinitionsHealthcheck {
259
+ disable?: boolean;
260
+ interval?: string;
261
+ retries?: number;
262
+ test?: string | string[];
263
+ timeout?: string;
264
+ }
265
+ export interface PropertiesNetworks {
266
+ [k: string]: DefinitionsNetwork;
267
+ }
268
+ export interface PropertiesVolumes {
269
+ [k: string]: DefinitionsVolume;
270
+ }
package/index.js ADDED
@@ -0,0 +1,18 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const YAML = require('json2yaml')
4
+ const Validator = require('jsonschema').Validator
5
+ const v = new Validator()
6
+
7
+ function generateCompose ( inputJSON ) {
8
+ let schema = JSON.parse(fs.readFileSync(path.resolve(__dirname, './schema.json')))
9
+
10
+ if ( !v.validate(inputJSON, schema).valid )
11
+ throw new Error('Invalid input!')
12
+
13
+ return YAML.stringify( inputJSON )
14
+ }
15
+
16
+ module.exports = {
17
+ generate: generateCompose
18
+ }
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "docker-composer",
3
+ "version": "4.0.2",
4
+ "description": "NodeJS module for generating docker-compose.yml from a json document.",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "./node_modules/mocha/bin/mocha *Test.js",
8
+ "coverage": "nyc npm run test",
9
+ "generate-ts-types": "./node_modules/gulp-cli/bin/gulp.js"
10
+ },
11
+ "keywords": [
12
+ "gulp",
13
+ "docker",
14
+ "compose",
15
+ "docker-compose.yml"
16
+ ],
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/tudvari/docker-composer.git"
20
+ },
21
+ "author": {
22
+ "name": "Tibor Udvari",
23
+ "email": "tudvari@tudvari.com"
24
+ },
25
+ "contributors": [
26
+ {
27
+ "name": "Alex Lamba (@laalex)",
28
+ "email": "alex@codesilk.com",
29
+ "url": "https://github.com/laalex"
30
+ }
31
+ ],
32
+ "license": "MIT",
33
+ "dependencies": {
34
+ "json2yaml": "^1.1.0",
35
+ "jsonschema": "^1.4.0"
36
+ },
37
+ "devDependencies": {
38
+ "ansi-regex": "^5.0.1",
39
+ "atob": ">=2.1.2",
40
+ "eslint": "7.32.0",
41
+ "gulp": "^4.0.2",
42
+ "gulp-cli": "^2.3.0",
43
+ "js-yaml": "^4.0.0",
44
+ "json-schema-to-typescript": "^10.1.4",
45
+ "mixin-deep": ">=2.0.1",
46
+ "mocha": "9.1.2",
47
+ "nyc": "^15.1.0",
48
+ "set-value": "^4.0.1",
49
+ "should": "13.2.3"
50
+ },
51
+ "nyc": {
52
+ "all": true,
53
+ "exclude": [
54
+ "*Test.js"
55
+ ]
56
+ }
57
+ }
package/schema.json ADDED
@@ -0,0 +1,399 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "id": "config_schema_v3.0.json",
4
+ "type": "object",
5
+ "required": ["version"],
6
+
7
+ "properties": {
8
+ "version": {
9
+ "type": "string"
10
+ },
11
+
12
+ "services": {
13
+ "id": "#/properties/services",
14
+ "type": "object",
15
+ "patternProperties": {
16
+ "^[a-zA-Z0-9._-]+$": {
17
+ "$ref": "#/definitions/service"
18
+ }
19
+ },
20
+ "additionalProperties": false
21
+ },
22
+
23
+ "networks": {
24
+ "id": "#/properties/networks",
25
+ "type": "object",
26
+ "patternProperties": {
27
+ "^[a-zA-Z0-9._-]+$": {
28
+ "$ref": "#/definitions/network"
29
+ }
30
+ }
31
+ },
32
+
33
+ "volumes": {
34
+ "id": "#/properties/volumes",
35
+ "type": "object",
36
+ "patternProperties": {
37
+ "^[a-zA-Z0-9._-]+$": {
38
+ "$ref": "#/definitions/volume"
39
+ }
40
+ },
41
+ "additionalProperties": false
42
+ }
43
+ },
44
+
45
+ "additionalProperties": false,
46
+
47
+ "definitions": {
48
+
49
+ "service": {
50
+ "id": "#/definitions/service",
51
+ "type": "object",
52
+
53
+ "properties": {
54
+ "deploy": {"$ref": "#/definitions/deployment"},
55
+ "build": {
56
+ "oneOf": [
57
+ {"type": "string"},
58
+ {
59
+ "type": "object",
60
+ "properties": {
61
+ "context": {"type": "string"},
62
+ "dockerfile": {"type": "string"},
63
+ "args": {"$ref": "#/definitions/list_or_dict"}
64
+ },
65
+ "additionalProperties": false
66
+ }
67
+ ]
68
+ },
69
+ "cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
70
+ "cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
71
+ "cgroup_parent": {"type": "string"},
72
+ "command": {
73
+ "oneOf": [
74
+ {"type": "string"},
75
+ {"type": "array", "items": {"type": "string"}}
76
+ ]
77
+ },
78
+ "container_name": {"type": "string"},
79
+ "depends_on": {"$ref": "#/definitions/list_of_strings"},
80
+ "devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
81
+ "dns": {"$ref": "#/definitions/string_or_list"},
82
+ "dns_search": {"$ref": "#/definitions/string_or_list"},
83
+ "domainname": {"type": "string"},
84
+ "entrypoint": {
85
+ "oneOf": [
86
+ {"type": "string"},
87
+ {"type": "array", "items": {"type": "string"}}
88
+ ]
89
+ },
90
+ "env_file": {"$ref": "#/definitions/string_or_list"},
91
+ "environment": {"$ref": "#/definitions/list_or_dict"},
92
+
93
+ "expose": {
94
+ "type": "array",
95
+ "items": {
96
+ "type": ["string", "number"],
97
+ "format": "expose"
98
+ },
99
+ "uniqueItems": true
100
+ },
101
+
102
+ "external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
103
+ "extra_hosts": {"$ref": "#/definitions/list_or_dict"},
104
+ "healthcheck": {"$ref": "#/definitions/healthcheck"},
105
+ "hostname": {"type": "string"},
106
+ "image": {"type": "string"},
107
+ "ipc": {"type": "string"},
108
+ "labels": {"$ref": "#/definitions/labels"},
109
+ "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
110
+
111
+ "logging": {
112
+ "type": "object",
113
+
114
+ "properties": {
115
+ "driver": {"type": "string"},
116
+ "options": {
117
+ "type": "object",
118
+ "patternProperties": {
119
+ "^.+$": {"type": ["string", "number", "null"]}
120
+ }
121
+ }
122
+ },
123
+ "additionalProperties": false
124
+ },
125
+
126
+ "mac_address": {"type": "string"},
127
+ "network_mode": {"type": "string"},
128
+
129
+ "networks": {
130
+ "oneOf": [
131
+ {"$ref": "#/definitions/list_of_strings"},
132
+ {
133
+ "type": "object",
134
+ "patternProperties": {
135
+ "^[a-zA-Z0-9._-]+$": {
136
+ "oneOf": [
137
+ {
138
+ "type": "object",
139
+ "properties": {
140
+ "aliases": {"$ref": "#/definitions/list_of_strings"},
141
+ "ipv4_address": {"type": "string"},
142
+ "ipv6_address": {"type": "string"}
143
+ },
144
+ "additionalProperties": false
145
+ },
146
+ {"type": "null"}
147
+ ]
148
+ }
149
+ },
150
+ "additionalProperties": false
151
+ }
152
+ ]
153
+ },
154
+ "pid": {"type": ["string", "null"]},
155
+
156
+ "ports": {
157
+ "type": "array",
158
+ "items": {
159
+ "type": ["string", "number"],
160
+ "format": "ports"
161
+ },
162
+ "uniqueItems": true
163
+ },
164
+
165
+ "privileged": {"type": "boolean"},
166
+ "read_only": {"type": "boolean"},
167
+ "restart": {"type": "string"},
168
+ "security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
169
+ "shm_size": {"type": ["number", "string"]},
170
+ "sysctls": {"$ref": "#/definitions/list_or_dict"},
171
+ "stdin_open": {"type": "boolean"},
172
+ "stop_grace_period": {"type": "string", "format": "duration"},
173
+ "stop_signal": {"type": "string"},
174
+ "tmpfs": {"$ref": "#/definitions/string_or_list"},
175
+ "tty": {"type": "boolean"},
176
+ "ulimits": {
177
+ "type": "object",
178
+ "patternProperties": {
179
+ "^[a-z]+$": {
180
+ "oneOf": [
181
+ {"type": "integer"},
182
+ {
183
+ "type":"object",
184
+ "properties": {
185
+ "hard": {"type": "integer"},
186
+ "soft": {"type": "integer"}
187
+ },
188
+ "required": ["soft", "hard"],
189
+ "additionalProperties": false
190
+ }
191
+ ]
192
+ }
193
+ }
194
+ },
195
+ "user": {"type": "string"},
196
+ "userns_mode": {"type": "string"},
197
+ "volumes": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
198
+ "working_dir": {"type": "string"}
199
+ },
200
+ "additionalProperties": false
201
+ },
202
+
203
+ "healthcheck": {
204
+ "id": "#/definitions/healthcheck",
205
+ "type": "object",
206
+ "additionalProperties": false,
207
+ "properties": {
208
+ "disable": {"type": "boolean"},
209
+ "interval": {"type": "string"},
210
+ "retries": {"type": "number"},
211
+ "test": {
212
+ "oneOf": [
213
+ {"type": "string"},
214
+ {"type": "array", "items": {"type": "string"}}
215
+ ]
216
+ },
217
+ "timeout": {"type": "string"}
218
+ }
219
+ },
220
+ "deployment": {
221
+ "id": "#/definitions/deployment",
222
+ "type": ["object", "null"],
223
+ "properties": {
224
+ "mode": {"type": "string"},
225
+ "replicas": {"type": "integer"},
226
+ "labels": {"$ref": "#/definitions/labels"},
227
+ "update_config": {
228
+ "type": "object",
229
+ "properties": {
230
+ "parallelism": {"type": "integer"},
231
+ "delay": {"type": "string", "format": "duration"},
232
+ "failure_action": {"type": "string"},
233
+ "monitor": {"type": "string", "format": "duration"},
234
+ "max_failure_ratio": {"type": "number"}
235
+ },
236
+ "additionalProperties": false
237
+ },
238
+ "resources": {
239
+ "type": "object",
240
+ "properties": {
241
+ "limits": {"$ref": "#/definitions/resource"},
242
+ "reservations": {"$ref": "#/definitions/resource"}
243
+ },
244
+ "additionalProperties": false
245
+ },
246
+ "restart_policy": {
247
+ "type": "object",
248
+ "properties": {
249
+ "condition": {"type": "string"},
250
+ "delay": {"type": "string", "format": "duration"},
251
+ "max_attempts": {"type": "integer"},
252
+ "window": {"type": "string", "format": "duration"}
253
+ },
254
+ "additionalProperties": false
255
+ },
256
+ "placement": {
257
+ "type": "object",
258
+ "properties": {
259
+ "constraints": {"type": "array", "items": {"type": "string"}}
260
+ },
261
+ "additionalProperties": false
262
+ }
263
+ },
264
+ "additionalProperties": false
265
+ },
266
+
267
+ "resource": {
268
+ "id": "#/definitions/resource",
269
+ "type": "object",
270
+ "properties": {
271
+ "cpus": {"type": "string"},
272
+ "memory": {"type": "string"}
273
+ },
274
+ "additionalProperties": false
275
+ },
276
+
277
+ "network": {
278
+ "id": "#/definitions/network",
279
+ "type": ["object", "null"],
280
+ "properties": {
281
+ "driver": {"type": "string"},
282
+ "driver_opts": {
283
+ "type": "object",
284
+ "patternProperties": {
285
+ "^.+$": {"type": ["string", "number"]}
286
+ }
287
+ },
288
+ "ipam": {
289
+ "type": "object",
290
+ "properties": {
291
+ "driver": {"type": "string"},
292
+ "config": {
293
+ "type": "array",
294
+ "items": {
295
+ "type": "object",
296
+ "properties": {
297
+ "subnet": {"type": "string", "format": "subnet_ip_address"}
298
+ },
299
+ "additionalProperties": false
300
+ }
301
+ }
302
+ },
303
+ "additionalProperties": false
304
+ },
305
+ "external": {
306
+ "type": ["boolean", "object"],
307
+ "properties": {
308
+ "name": {"type": "string"}
309
+ },
310
+ "additionalProperties": false
311
+ },
312
+ "internal": {"type": "boolean"},
313
+ "labels": {"$ref": "#/definitions/labels"}
314
+ },
315
+ "additionalProperties": false
316
+ },
317
+
318
+ "volume": {
319
+ "id": "#/definitions/volume",
320
+ "type": ["object", "null"],
321
+ "properties": {
322
+ "driver": {"type": "string"},
323
+ "driver_opts": {
324
+ "type": "object",
325
+ "patternProperties": {
326
+ "^.+$": {"type": ["string", "number"]}
327
+ }
328
+ },
329
+ "external": {
330
+ "type": ["boolean", "object"],
331
+ "properties": {
332
+ "name": {"type": "string"}
333
+ },
334
+ "additionalProperties": false
335
+ },
336
+ "labels": {"$ref": "#/definitions/labels"}
337
+ },
338
+ "additionalProperties": false
339
+ },
340
+
341
+ "string_or_list": {
342
+ "oneOf": [
343
+ {"type": "string"},
344
+ {"$ref": "#/definitions/list_of_strings"}
345
+ ]
346
+ },
347
+
348
+ "list_of_strings": {
349
+ "type": "array",
350
+ "items": {"type": "string"},
351
+ "uniqueItems": true
352
+ },
353
+
354
+ "list_or_dict": {
355
+ "oneOf": [
356
+ {
357
+ "type": "object",
358
+ "patternProperties": {
359
+ ".+": {
360
+ "type": ["string", "number", "null"]
361
+ }
362
+ },
363
+ "additionalProperties": false
364
+ },
365
+ {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
366
+ ]
367
+ },
368
+
369
+ "labels": {
370
+ "oneOf": [
371
+ {
372
+ "type": "object",
373
+ "patternProperties": {
374
+ ".+": {
375
+ "type": "string"
376
+ }
377
+ },
378
+ "additionalProperties": false
379
+ },
380
+ {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
381
+ ]
382
+ },
383
+
384
+ "constraints": {
385
+ "service": {
386
+ "id": "#/definitions/constraints/service",
387
+ "anyOf": [
388
+ {"required": ["build"]},
389
+ {"required": ["image"]}
390
+ ],
391
+ "properties": {
392
+ "build": {
393
+ "required": ["context"]
394
+ }
395
+ }
396
+ }
397
+ }
398
+ }
399
+ }