1{
2  "$schema": "http://json-schema.org/draft-04/schema#",
3  "id": "config_schema_v3.7.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    "secrets": {
45      "id": "#/properties/secrets",
46      "type": "object",
47      "patternProperties": {
48        "^[a-zA-Z0-9._-]+$": {
49          "$ref": "#/definitions/secret"
50        }
51      },
52      "additionalProperties": false
53    },
54
55    "configs": {
56      "id": "#/properties/configs",
57      "type": "object",
58      "patternProperties": {
59        "^[a-zA-Z0-9._-]+$": {
60          "$ref": "#/definitions/config"
61        }
62      },
63      "additionalProperties": false
64    }
65  },
66
67  "patternProperties": {"^x-": {}},
68  "additionalProperties": false,
69
70  "definitions": {
71
72    "service": {
73      "id": "#/definitions/service",
74      "type": "object",
75
76      "properties": {
77        "deploy": {"$ref": "#/definitions/deployment"},
78        "build": {
79          "oneOf": [
80            {"type": "string"},
81            {
82              "type": "object",
83              "properties": {
84                "context": {"type": "string"},
85                "dockerfile": {"type": "string"},
86                "args": {"$ref": "#/definitions/list_or_dict"},
87                "labels": {"$ref": "#/definitions/list_or_dict"},
88                "cache_from": {"$ref": "#/definitions/list_of_strings"},
89                "network": {"type": "string"},
90                "target": {"type": "string"},
91                "shm_size": {"type": ["integer", "string"]}
92              },
93              "additionalProperties": false
94            }
95          ]
96        },
97        "cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
98        "cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
99        "cgroup_parent": {"type": "string"},
100        "command": {
101          "oneOf": [
102            {"type": "string"},
103            {"type": "array", "items": {"type": "string"}}
104          ]
105        },
106        "configs": {
107          "type": "array",
108          "items": {
109            "oneOf": [
110              {"type": "string"},
111              {
112                "type": "object",
113                "properties": {
114                  "source": {"type": "string"},
115                  "target": {"type": "string"},
116                  "uid": {"type": "string"},
117                  "gid": {"type": "string"},
118                  "mode": {"type": "number"}
119                }
120              }
121            ]
122          }
123        },
124        "container_name": {"type": "string"},
125        "credential_spec": {"type": "object", "properties": {
126          "file": {"type": "string"},
127          "registry": {"type": "string"}
128        }},
129        "depends_on": {"$ref": "#/definitions/list_of_strings"},
130        "devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
131        "dns": {"$ref": "#/definitions/string_or_list"},
132        "dns_search": {"$ref": "#/definitions/string_or_list"},
133        "domainname": {"type": "string"},
134        "entrypoint": {
135          "oneOf": [
136            {"type": "string"},
137            {"type": "array", "items": {"type": "string"}}
138          ]
139        },
140        "env_file": {"$ref": "#/definitions/string_or_list"},
141        "environment": {"$ref": "#/definitions/list_or_dict"},
142
143        "expose": {
144          "type": "array",
145          "items": {
146            "type": ["string", "number"],
147            "format": "expose"
148          },
149          "uniqueItems": true
150        },
151
152        "external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
153        "extra_hosts": {"$ref": "#/definitions/list_or_dict"},
154        "healthcheck": {"$ref": "#/definitions/healthcheck"},
155        "hostname": {"type": "string"},
156        "image": {"type": "string"},
157	"init": {"type": "boolean"},
158        "ipc": {"type": "string"},
159        "isolation": {"type": "string"},
160        "labels": {"$ref": "#/definitions/list_or_dict"},
161        "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
162
163        "logging": {
164            "type": "object",
165
166            "properties": {
167                "driver": {"type": "string"},
168                "options": {
169                  "type": "object",
170                  "patternProperties": {
171                    "^.+$": {"type": ["string", "number", "null"]}
172                  }
173                }
174            },
175            "additionalProperties": false
176        },
177
178        "mac_address": {"type": "string"},
179        "network_mode": {"type": "string"},
180
181        "networks": {
182          "oneOf": [
183            {"$ref": "#/definitions/list_of_strings"},
184            {
185              "type": "object",
186              "patternProperties": {
187                "^[a-zA-Z0-9._-]+$": {
188                  "oneOf": [
189                    {
190                      "type": "object",
191                      "properties": {
192                        "aliases": {"$ref": "#/definitions/list_of_strings"},
193                        "ipv4_address": {"type": "string"},
194                        "ipv6_address": {"type": "string"}
195                      },
196                      "additionalProperties": false
197                    },
198                    {"type": "null"}
199                  ]
200                }
201              },
202              "additionalProperties": false
203            }
204          ]
205        },
206        "pid": {"type": ["string", "null"]},
207
208        "ports": {
209          "type": "array",
210          "items": {
211            "oneOf": [
212              {"type": "number", "format": "ports"},
213              {"type": "string", "format": "ports"},
214              {
215                "type": "object",
216                "properties": {
217                  "mode": {"type": "string"},
218                  "target": {"type": "integer"},
219                  "published": {"type": "integer"},
220                  "protocol": {"type": "string"}
221                },
222                "additionalProperties": false
223              }
224            ]
225          },
226          "uniqueItems": true
227        },
228
229        "privileged": {"type": "boolean"},
230        "read_only": {"type": "boolean"},
231        "restart": {"type": "string"},
232        "security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
233        "shm_size": {"type": ["number", "string"]},
234        "secrets": {
235          "type": "array",
236          "items": {
237            "oneOf": [
238              {"type": "string"},
239              {
240                "type": "object",
241                "properties": {
242                  "source": {"type": "string"},
243                  "target": {"type": "string"},
244                  "uid": {"type": "string"},
245                  "gid": {"type": "string"},
246                  "mode": {"type": "number"}
247                }
248              }
249            ]
250          }
251        },
252        "sysctls": {"$ref": "#/definitions/list_or_dict"},
253        "stdin_open": {"type": "boolean"},
254        "stop_grace_period": {"type": "string", "format": "duration"},
255        "stop_signal": {"type": "string"},
256        "tmpfs": {"$ref": "#/definitions/string_or_list"},
257        "tty": {"type": "boolean"},
258        "ulimits": {
259          "type": "object",
260          "patternProperties": {
261            "^[a-z]+$": {
262              "oneOf": [
263                {"type": "integer"},
264                {
265                  "type":"object",
266                  "properties": {
267                    "hard": {"type": "integer"},
268                    "soft": {"type": "integer"}
269                  },
270                  "required": ["soft", "hard"],
271                  "additionalProperties": false
272                }
273              ]
274            }
275          }
276        },
277        "user": {"type": "string"},
278        "userns_mode": {"type": "string"},
279        "volumes": {
280          "type": "array",
281          "items": {
282            "oneOf": [
283              {"type": "string"},
284              {
285                "type": "object",
286                "required": ["type"],
287                "properties": {
288                  "type": {"type": "string"},
289                  "source": {"type": "string"},
290                  "target": {"type": "string"},
291                  "read_only": {"type": "boolean"},
292                  "consistency": {"type": "string"},
293                  "bind": {
294                    "type": "object",
295                    "properties": {
296                      "propagation": {"type": "string"}
297                    }
298                  },
299                  "volume": {
300                    "type": "object",
301                    "properties": {
302                      "nocopy": {"type": "boolean"}
303                    }
304                  },
305                  "tmpfs": {
306                    "type": "object",
307                    "properties": {
308                      "size": {
309                        "type": "integer",
310                        "minimum": 0
311                      }
312                    }
313                  }
314                },
315                "additionalProperties": false
316              }
317            ],
318            "uniqueItems": true
319          }
320        },
321        "working_dir": {"type": "string"}
322      },
323      "patternProperties": {"^x-": {}},
324      "additionalProperties": false
325    },
326
327    "healthcheck": {
328      "id": "#/definitions/healthcheck",
329      "type": "object",
330      "additionalProperties": false,
331      "properties": {
332        "disable": {"type": "boolean"},
333        "interval": {"type": "string", "format": "duration"},
334        "retries": {"type": "number"},
335        "test": {
336          "oneOf": [
337            {"type": "string"},
338            {"type": "array", "items": {"type": "string"}}
339          ]
340        },
341        "timeout": {"type": "string", "format": "duration"},
342        "start_period": {"type": "string", "format": "duration"}
343      }
344    },
345    "deployment": {
346      "id": "#/definitions/deployment",
347      "type": ["object", "null"],
348      "properties": {
349        "mode": {"type": "string"},
350        "endpoint_mode": {"type": "string"},
351        "replicas": {"type": "integer"},
352        "labels": {"$ref": "#/definitions/list_or_dict"},
353        "rollback_config": {
354          "type": "object",
355          "properties": {
356            "parallelism": {"type": "integer"},
357            "delay": {"type": "string", "format": "duration"},
358            "failure_action": {"type": "string"},
359            "monitor": {"type": "string", "format": "duration"},
360            "max_failure_ratio": {"type": "number"},
361            "order": {"type": "string", "enum": [
362              "start-first", "stop-first"
363            ]}
364          },
365          "additionalProperties": false
366        },
367        "update_config": {
368          "type": "object",
369          "properties": {
370            "parallelism": {"type": "integer"},
371            "delay": {"type": "string", "format": "duration"},
372            "failure_action": {"type": "string"},
373            "monitor": {"type": "string", "format": "duration"},
374            "max_failure_ratio": {"type": "number"},
375            "order": {"type": "string", "enum": [
376              "start-first", "stop-first"
377            ]}
378          },
379          "additionalProperties": false
380        },
381        "resources": {
382          "type": "object",
383          "properties": {
384            "limits": {
385              "type": "object",
386              "properties": {
387                "cpus": {"type": "string"},
388                "memory": {"type": "string"}
389              },
390              "additionalProperties": false
391            },
392            "reservations": {
393              "type": "object",
394              "properties": {
395                "cpus": {"type": "string"},
396                "memory": {"type": "string"},
397                "generic_resources": {"$ref": "#/definitions/generic_resources"}
398              },
399              "additionalProperties": false
400            }
401          },
402          "additionalProperties": false
403        },
404        "restart_policy": {
405          "type": "object",
406          "properties": {
407            "condition": {"type": "string"},
408            "delay": {"type": "string", "format": "duration"},
409            "max_attempts": {"type": "integer"},
410            "window": {"type": "string", "format": "duration"}
411          },
412          "additionalProperties": false
413        },
414        "placement": {
415          "type": "object",
416          "properties": {
417            "constraints": {"type": "array", "items": {"type": "string"}},
418            "preferences": {
419              "type": "array",
420              "items": {
421                "type": "object",
422                "properties": {
423                  "spread": {"type": "string"}
424                },
425                "additionalProperties": false
426              }
427            }
428          },
429          "additionalProperties": false
430        }
431      },
432      "additionalProperties": false
433    },
434
435    "generic_resources": {
436      "id": "#/definitions/generic_resources",
437      "type": "array",
438      "items": {
439        "type": "object",
440        "properties": {
441          "discrete_resource_spec": {
442            "type": "object",
443            "properties": {
444              "kind": {"type": "string"},
445              "value": {"type": "number"}
446            },
447            "additionalProperties": false
448          }
449        },
450        "additionalProperties": false
451      }
452    },
453
454    "network": {
455      "id": "#/definitions/network",
456      "type": ["object", "null"],
457      "properties": {
458        "name": {"type": "string"},
459        "driver": {"type": "string"},
460        "driver_opts": {
461          "type": "object",
462          "patternProperties": {
463            "^.+$": {"type": ["string", "number"]}
464          }
465        },
466        "ipam": {
467          "type": "object",
468          "properties": {
469            "driver": {"type": "string"},
470            "config": {
471              "type": "array",
472              "items": {
473                "type": "object",
474                "properties": {
475                  "subnet": {"type": "string"}
476                },
477                "additionalProperties": false
478              }
479            }
480          },
481          "additionalProperties": false
482        },
483        "external": {
484          "type": ["boolean", "object"],
485          "properties": {
486            "name": {"type": "string"}
487          },
488          "additionalProperties": false
489        },
490        "internal": {"type": "boolean"},
491        "attachable": {"type": "boolean"},
492        "labels": {"$ref": "#/definitions/list_or_dict"}
493      },
494      "patternProperties": {"^x-": {}},
495      "additionalProperties": false
496    },
497
498    "volume": {
499      "id": "#/definitions/volume",
500      "type": ["object", "null"],
501      "properties": {
502        "name": {"type": "string"},
503        "driver": {"type": "string"},
504        "driver_opts": {
505          "type": "object",
506          "patternProperties": {
507            "^.+$": {"type": ["string", "number"]}
508          }
509        },
510        "external": {
511          "type": ["boolean", "object"],
512          "properties": {
513            "name": {"type": "string"}
514          },
515          "additionalProperties": false
516        },
517        "labels": {"$ref": "#/definitions/list_or_dict"}
518      },
519      "patternProperties": {"^x-": {}},
520      "additionalProperties": false
521    },
522
523    "secret": {
524      "id": "#/definitions/secret",
525      "type": "object",
526      "properties": {
527        "name": {"type": "string"},
528        "file": {"type": "string"},
529        "external": {
530          "type": ["boolean", "object"],
531          "properties": {
532            "name": {"type": "string"}
533          }
534        },
535        "labels": {"$ref": "#/definitions/list_or_dict"}
536      },
537      "patternProperties": {"^x-": {}},
538      "additionalProperties": false
539    },
540
541    "config": {
542      "id": "#/definitions/config",
543      "type": "object",
544      "properties": {
545        "name": {"type": "string"},
546        "file": {"type": "string"},
547        "external": {
548          "type": ["boolean", "object"],
549          "properties": {
550            "name": {"type": "string"}
551          }
552        },
553        "labels": {"$ref": "#/definitions/list_or_dict"}
554      },
555      "patternProperties": {"^x-": {}},
556      "additionalProperties": false
557    },
558
559    "string_or_list": {
560      "oneOf": [
561        {"type": "string"},
562        {"$ref": "#/definitions/list_of_strings"}
563      ]
564    },
565
566    "list_of_strings": {
567      "type": "array",
568      "items": {"type": "string"},
569      "uniqueItems": true
570    },
571
572    "list_or_dict": {
573      "oneOf": [
574        {
575          "type": "object",
576          "patternProperties": {
577            ".+": {
578              "type": ["string", "number", "null"]
579            }
580          },
581          "additionalProperties": false
582        },
583        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
584      ]
585    },
586
587    "constraints": {
588      "service": {
589        "id": "#/definitions/constraints/service",
590        "anyOf": [
591          {"required": ["build"]},
592          {"required": ["image"]}
593        ],
594        "properties": {
595          "build": {
596            "required": ["context"]
597          }
598        }
599      }
600    }
601  }
602}
603