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