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/list_or_dict"},
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/list_or_dict"},
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"}
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/list_or_dict"}
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/list_or_dict"}
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    "constraints": {
370      "service": {
371        "id": "#/definitions/constraints/service",
372        "anyOf": [
373          {"required": ["build"]},
374          {"required": ["image"]}
375        ],
376        "properties": {
377          "build": {
378            "required": ["context"]
379          }
380        }
381      }
382    }
383  }
384}
385