1{
2  "$schema": "http://json-schema.org/draft-04/schema#",
3  "id": "config_schema_v3.1.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
56  "additionalProperties": false,
57
58  "definitions": {
59
60    "service": {
61      "id": "#/definitions/service",
62      "type": "object",
63
64      "properties": {
65        "deploy": {"$ref": "#/definitions/deployment"},
66        "build": {
67          "oneOf": [
68            {"type": "string"},
69            {
70              "type": "object",
71              "properties": {
72                "context": {"type": "string"},
73                "dockerfile": {"type": "string"},
74                "args": {"$ref": "#/definitions/list_or_dict"}
75              },
76              "additionalProperties": false
77            }
78          ]
79        },
80        "cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
81        "cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
82        "cgroup_parent": {"type": "string"},
83        "command": {
84          "oneOf": [
85            {"type": "string"},
86            {"type": "array", "items": {"type": "string"}}
87          ]
88        },
89        "container_name": {"type": "string"},
90        "depends_on": {"$ref": "#/definitions/list_of_strings"},
91        "devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
92        "dns": {"$ref": "#/definitions/string_or_list"},
93        "dns_search": {"$ref": "#/definitions/string_or_list"},
94        "domainname": {"type": "string"},
95        "entrypoint": {
96          "oneOf": [
97            {"type": "string"},
98            {"type": "array", "items": {"type": "string"}}
99          ]
100        },
101        "env_file": {"$ref": "#/definitions/string_or_list"},
102        "environment": {"$ref": "#/definitions/list_or_dict"},
103
104        "expose": {
105          "type": "array",
106          "items": {
107            "type": ["string", "number"],
108            "format": "expose"
109          },
110          "uniqueItems": true
111        },
112
113        "external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
114        "extra_hosts": {"$ref": "#/definitions/list_or_dict"},
115        "healthcheck": {"$ref": "#/definitions/healthcheck"},
116        "hostname": {"type": "string"},
117        "image": {"type": "string"},
118        "ipc": {"type": "string"},
119        "labels": {"$ref": "#/definitions/list_or_dict"},
120        "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
121
122        "logging": {
123            "type": "object",
124
125            "properties": {
126                "driver": {"type": "string"},
127                "options": {
128                  "type": "object",
129                  "patternProperties": {
130                    "^.+$": {"type": ["string", "number", "null"]}
131                  }
132                }
133            },
134            "additionalProperties": false
135        },
136
137        "mac_address": {"type": "string"},
138        "network_mode": {"type": "string"},
139
140        "networks": {
141          "oneOf": [
142            {"$ref": "#/definitions/list_of_strings"},
143            {
144              "type": "object",
145              "patternProperties": {
146                "^[a-zA-Z0-9._-]+$": {
147                  "oneOf": [
148                    {
149                      "type": "object",
150                      "properties": {
151                        "aliases": {"$ref": "#/definitions/list_of_strings"},
152                        "ipv4_address": {"type": "string"},
153                        "ipv6_address": {"type": "string"}
154                      },
155                      "additionalProperties": false
156                    },
157                    {"type": "null"}
158                  ]
159                }
160              },
161              "additionalProperties": false
162            }
163          ]
164        },
165        "pid": {"type": ["string", "null"]},
166
167        "ports": {
168          "type": "array",
169          "items": {
170            "type": ["string", "number"],
171            "format": "ports"
172          },
173          "uniqueItems": true
174        },
175
176        "privileged": {"type": "boolean"},
177        "read_only": {"type": "boolean"},
178        "restart": {"type": "string"},
179        "security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
180        "shm_size": {"type": ["number", "string"]},
181        "secrets": {
182          "type": "array",
183          "items": {
184            "oneOf": [
185              {"type": "string"},
186              {
187                "type": "object",
188                "properties": {
189                  "source": {"type": "string"},
190                  "target": {"type": "string"},
191                  "uid": {"type": "string"},
192                  "gid": {"type": "string"},
193                  "mode": {"type": "number"}
194                }
195              }
196            ]
197          }
198        },
199        "sysctls": {"$ref": "#/definitions/list_or_dict"},
200        "stdin_open": {"type": "boolean"},
201        "stop_grace_period": {"type": "string", "format": "duration"},
202        "stop_signal": {"type": "string"},
203        "tmpfs": {"$ref": "#/definitions/string_or_list"},
204        "tty": {"type": "boolean"},
205        "ulimits": {
206          "type": "object",
207          "patternProperties": {
208            "^[a-z]+$": {
209              "oneOf": [
210                {"type": "integer"},
211                {
212                  "type":"object",
213                  "properties": {
214                    "hard": {"type": "integer"},
215                    "soft": {"type": "integer"}
216                  },
217                  "required": ["soft", "hard"],
218                  "additionalProperties": false
219                }
220              ]
221            }
222          }
223        },
224        "user": {"type": "string"},
225        "userns_mode": {"type": "string"},
226        "volumes": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
227        "working_dir": {"type": "string"}
228      },
229      "additionalProperties": false
230    },
231
232    "healthcheck": {
233      "id": "#/definitions/healthcheck",
234      "type": "object",
235      "additionalProperties": false,
236      "properties": {
237        "disable": {"type": "boolean"},
238        "interval": {"type": "string"},
239        "retries": {"type": "number"},
240        "test": {
241          "oneOf": [
242            {"type": "string"},
243            {"type": "array", "items": {"type": "string"}}
244          ]
245        },
246        "timeout": {"type": "string"}
247      }
248    },
249    "deployment": {
250      "id": "#/definitions/deployment",
251      "type": ["object", "null"],
252      "properties": {
253        "mode": {"type": "string"},
254        "replicas": {"type": "integer"},
255        "labels": {"$ref": "#/definitions/list_or_dict"},
256        "update_config": {
257          "type": "object",
258          "properties": {
259            "parallelism": {"type": "integer"},
260            "delay": {"type": "string", "format": "duration"},
261            "failure_action": {"type": "string"},
262            "monitor": {"type": "string", "format": "duration"},
263            "max_failure_ratio": {"type": "number"}
264          },
265          "additionalProperties": false
266        },
267        "resources": {
268          "type": "object",
269          "properties": {
270            "limits": {"$ref": "#/definitions/resource"},
271            "reservations": {"$ref": "#/definitions/resource"}
272          },
273          "additionalProperties": false
274        },
275        "restart_policy": {
276          "type": "object",
277          "properties": {
278            "condition": {"type": "string"},
279            "delay": {"type": "string", "format": "duration"},
280            "max_attempts": {"type": "integer"},
281            "window": {"type": "string", "format": "duration"}
282          },
283          "additionalProperties": false
284        },
285        "placement": {
286          "type": "object",
287          "properties": {
288            "constraints": {"type": "array", "items": {"type": "string"}}
289          },
290          "additionalProperties": false
291        }
292      },
293      "additionalProperties": false
294    },
295
296    "resource": {
297      "id": "#/definitions/resource",
298      "type": "object",
299      "properties": {
300        "cpus": {"type": "string"},
301        "memory": {"type": "string"}
302      },
303      "additionalProperties": false
304    },
305
306    "network": {
307      "id": "#/definitions/network",
308      "type": ["object", "null"],
309      "properties": {
310        "driver": {"type": "string"},
311        "driver_opts": {
312          "type": "object",
313          "patternProperties": {
314            "^.+$": {"type": ["string", "number"]}
315          }
316        },
317        "ipam": {
318          "type": "object",
319          "properties": {
320            "driver": {"type": "string"},
321            "config": {
322              "type": "array",
323              "items": {
324                "type": "object",
325                "properties": {
326                  "subnet": {"type": "string"}
327                },
328                "additionalProperties": false
329              }
330            }
331          },
332          "additionalProperties": false
333        },
334        "external": {
335          "type": ["boolean", "object"],
336          "properties": {
337            "name": {"type": "string"}
338          },
339          "additionalProperties": false
340        },
341        "internal": {"type": "boolean"},
342        "labels": {"$ref": "#/definitions/list_or_dict"}
343      },
344      "additionalProperties": false
345    },
346
347    "volume": {
348      "id": "#/definitions/volume",
349      "type": ["object", "null"],
350      "properties": {
351        "driver": {"type": "string"},
352        "driver_opts": {
353          "type": "object",
354          "patternProperties": {
355            "^.+$": {"type": ["string", "number"]}
356          }
357        },
358        "external": {
359          "type": ["boolean", "object"],
360          "properties": {
361            "name": {"type": "string"}
362          },
363          "additionalProperties": false
364        },
365        "labels": {"$ref": "#/definitions/list_or_dict"}
366      },
367      "additionalProperties": false
368    },
369
370    "secret": {
371      "id": "#/definitions/secret",
372      "type": "object",
373      "properties": {
374        "file": {"type": "string"},
375        "external": {
376          "type": ["boolean", "object"],
377          "properties": {
378            "name": {"type": "string"}
379          }
380        },
381        "labels": {"$ref": "#/definitions/list_or_dict"}
382      },
383      "additionalProperties": false
384    },
385
386    "string_or_list": {
387      "oneOf": [
388        {"type": "string"},
389        {"$ref": "#/definitions/list_of_strings"}
390      ]
391    },
392
393    "list_of_strings": {
394      "type": "array",
395      "items": {"type": "string"},
396      "uniqueItems": true
397    },
398
399    "list_or_dict": {
400      "oneOf": [
401        {
402          "type": "object",
403          "patternProperties": {
404            ".+": {
405              "type": ["string", "number", "null"]
406            }
407          },
408          "additionalProperties": false
409        },
410        {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
411      ]
412    },
413
414    "constraints": {
415      "service": {
416        "id": "#/definitions/constraints/service",
417        "anyOf": [
418          {"required": ["build"]},
419          {"required": ["image"]}
420        ],
421        "properties": {
422          "build": {
423            "required": ["context"]
424          }
425        }
426      }
427    }
428  }
429}
430