背景说明

官方网段: https://github.com/compose-spec/compose-spec/blob/master/spec.md

语法中的指令又被称为模板指令

网络地址

https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json

相关文件

compose-spec.json

文件内容

  1. {
  2. "$schema": "http://json-schema.org/draft/2019-09/schema#",
  3. "id": "compose_spec.json",
  4. "type": "object",
  5. "title": "Compose Specification",
  6. "description": "The Compose file is a YAML file defining a multi-containers based application.",
  7. "properties": {
  8. "version": {
  9. "type": "string",
  10. "description": "declared for backward compatibility, ignored."
  11. },
  12. "name": {
  13. "type": "string",
  14. "description": "define the Compose project name, until user defines one explicitly."
  15. },
  16. "services": {
  17. "id": "#/properties/services",
  18. "type": "object",
  19. "patternProperties": {
  20. "^[a-zA-Z0-9._-]+$": {
  21. "$ref": "#/definitions/service"
  22. }
  23. },
  24. "additionalProperties": false
  25. },
  26. "networks": {
  27. "id": "#/properties/networks",
  28. "type": "object",
  29. "patternProperties": {
  30. "^[a-zA-Z0-9._-]+$": {
  31. "$ref": "#/definitions/network"
  32. }
  33. }
  34. },
  35. "volumes": {
  36. "id": "#/properties/volumes",
  37. "type": "object",
  38. "patternProperties": {
  39. "^[a-zA-Z0-9._-]+$": {
  40. "$ref": "#/definitions/volume"
  41. }
  42. },
  43. "additionalProperties": false
  44. },
  45. "secrets": {
  46. "id": "#/properties/secrets",
  47. "type": "object",
  48. "patternProperties": {
  49. "^[a-zA-Z0-9._-]+$": {
  50. "$ref": "#/definitions/secret"
  51. }
  52. },
  53. "additionalProperties": false
  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. "patternProperties": {"^x-": {}},
  67. "additionalProperties": false,
  68. "definitions": {
  69. "service": {
  70. "id": "#/definitions/service",
  71. "type": "object",
  72. "properties": {
  73. "deploy": {"$ref": "#/definitions/deployment"},
  74. "build": {
  75. "oneOf": [
  76. {"type": "string"},
  77. {
  78. "type": "object",
  79. "properties": {
  80. "context": {"type": "string"},
  81. "dockerfile": {"type": "string"},
  82. "args": {"$ref": "#/definitions/list_or_dict"},
  83. "ssh": {"$ref": "#/definitions/list_or_dict"},
  84. "labels": {"$ref": "#/definitions/list_or_dict"},
  85. "cache_from": {"type": "array", "items": {"type": "string"}},
  86. "cache_to": {"type": "array", "items": {"type": "string"}},
  87. "network": {"type": "string"},
  88. "target": {"type": "string"},
  89. "shm_size": {"type": ["integer", "string"]},
  90. "extra_hosts": {"$ref": "#/definitions/list_or_dict"},
  91. "isolation": {"type": "string"},
  92. "secrets": {"$ref": "#/definitions/service_config_or_secret"}
  93. },
  94. "additionalProperties": false,
  95. "patternProperties": {"^x-": {}}
  96. }
  97. ]
  98. },
  99. "blkio_config": {
  100. "type": "object",
  101. "properties": {
  102. "device_read_bps": {
  103. "type": "array",
  104. "items": {"$ref": "#/definitions/blkio_limit"}
  105. },
  106. "device_read_iops": {
  107. "type": "array",
  108. "items": {"$ref": "#/definitions/blkio_limit"}
  109. },
  110. "device_write_bps": {
  111. "type": "array",
  112. "items": {"$ref": "#/definitions/blkio_limit"}
  113. },
  114. "device_write_iops": {
  115. "type": "array",
  116. "items": {"$ref": "#/definitions/blkio_limit"}
  117. },
  118. "weight": {"type": "integer"},
  119. "weight_device": {
  120. "type": "array",
  121. "items": {"$ref": "#/definitions/blkio_weight"}
  122. }
  123. },
  124. "additionalProperties": false
  125. },
  126. "cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
  127. "cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
  128. "cgroup_parent": {"type": "string"},
  129. "command": {
  130. "oneOf": [
  131. {"type": "string"},
  132. {"type": "array", "items": {"type": "string"}}
  133. ]
  134. },
  135. "configs": {"$ref": "#/definitions/service_config_or_secret"},
  136. "container_name": {"type": "string"},
  137. "cpu_count": {"type": "integer", "minimum": 0},
  138. "cpu_percent": {"type": "integer", "minimum": 0, "maximum": 100},
  139. "cpu_shares": {"type": ["number", "string"]},
  140. "cpu_quota": {"type": ["number", "string"]},
  141. "cpu_period": {"type": ["number", "string"]},
  142. "cpu_rt_period": {"type": ["number", "string"]},
  143. "cpu_rt_runtime": {"type": ["number", "string"]},
  144. "cpus": {"type": ["number", "string"]},
  145. "cpuset": {"type": "string"},
  146. "credential_spec": {
  147. "type": "object",
  148. "properties": {
  149. "config": {"type": "string"},
  150. "file": {"type": "string"},
  151. "registry": {"type": "string"}
  152. },
  153. "additionalProperties": false,
  154. "patternProperties": {"^x-": {}}
  155. },
  156. "depends_on": {
  157. "oneOf": [
  158. {"$ref": "#/definitions/list_of_strings"},
  159. {
  160. "type": "object",
  161. "additionalProperties": false,
  162. "patternProperties": {
  163. "^[a-zA-Z0-9._-]+$": {
  164. "type": "object",
  165. "additionalProperties": false,
  166. "properties": {
  167. "condition": {
  168. "type": "string",
  169. "enum": ["service_started", "service_healthy", "service_completed_successfully"]
  170. }
  171. },
  172. "required": ["condition"]
  173. }
  174. }
  175. }
  176. ]
  177. },
  178. "device_cgroup_rules": {"$ref": "#/definitions/list_of_strings"},
  179. "devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
  180. "dns": {"$ref": "#/definitions/string_or_list"},
  181. "dns_opt": {"type": "array","items": {"type": "string"}, "uniqueItems": true},
  182. "dns_search": {"$ref": "#/definitions/string_or_list"},
  183. "domainname": {"type": "string"},
  184. "entrypoint": {
  185. "oneOf": [
  186. {"type": "string"},
  187. {"type": "array", "items": {"type": "string"}}
  188. ]
  189. },
  190. "env_file": {"$ref": "#/definitions/string_or_list"},
  191. "environment": {"$ref": "#/definitions/list_or_dict"},
  192. "expose": {
  193. "type": "array",
  194. "items": {
  195. "type": ["string", "number"],
  196. "format": "expose"
  197. },
  198. "uniqueItems": true
  199. },
  200. "extends": {
  201. "oneOf": [
  202. {"type": "string"},
  203. {
  204. "type": "object",
  205. "properties": {
  206. "service": {"type": "string"},
  207. "file": {"type": "string"}
  208. },
  209. "required": ["service"],
  210. "additionalProperties": false
  211. }
  212. ]
  213. },
  214. "external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
  215. "extra_hosts": {"$ref": "#/definitions/list_or_dict"},
  216. "group_add": {
  217. "type": "array",
  218. "items": {
  219. "type": ["string", "number"]
  220. },
  221. "uniqueItems": true
  222. },
  223. "healthcheck": {"$ref": "#/definitions/healthcheck"},
  224. "hostname": {"type": "string"},
  225. "image": {"type": "string"},
  226. "init": {"type": "boolean"},
  227. "ipc": {"type": "string"},
  228. "isolation": {"type": "string"},
  229. "labels": {"$ref": "#/definitions/list_or_dict"},
  230. "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
  231. "logging": {
  232. "type": "object",
  233. "properties": {
  234. "driver": {"type": "string"},
  235. "options": {
  236. "type": "object",
  237. "patternProperties": {
  238. "^.+$": {"type": ["string", "number", "null"]}
  239. }
  240. }
  241. },
  242. "additionalProperties": false,
  243. "patternProperties": {"^x-": {}}
  244. },
  245. "mac_address": {"type": "string"},
  246. "mem_limit": {"type": ["number", "string"]},
  247. "mem_reservation": {"type": ["string", "integer"]},
  248. "mem_swappiness": {"type": "integer"},
  249. "memswap_limit": {"type": ["number", "string"]},
  250. "network_mode": {"type": "string"},
  251. "networks": {
  252. "oneOf": [
  253. {"$ref": "#/definitions/list_of_strings"},
  254. {
  255. "type": "object",
  256. "patternProperties": {
  257. "^[a-zA-Z0-9._-]+$": {
  258. "oneOf": [
  259. {
  260. "type": "object",
  261. "properties": {
  262. "aliases": {"$ref": "#/definitions/list_of_strings"},
  263. "ipv4_address": {"type": "string"},
  264. "ipv6_address": {"type": "string"},
  265. "link_local_ips": {"$ref": "#/definitions/list_of_strings"},
  266. "priority": {"type": "number"}
  267. },
  268. "additionalProperties": false,
  269. "patternProperties": {"^x-": {}}
  270. },
  271. {"type": "null"}
  272. ]
  273. }
  274. },
  275. "additionalProperties": false
  276. }
  277. ]
  278. },
  279. "oom_kill_disable": {"type": "boolean"},
  280. "oom_score_adj": {"type": "integer", "minimum": -1000, "maximum": 1000},
  281. "pid": {"type": ["string", "null"]},
  282. "pids_limit": {"type": ["number", "string"]},
  283. "platform": {"type": "string"},
  284. "ports": {
  285. "type": "array",
  286. "items": {
  287. "oneOf": [
  288. {"type": "number", "format": "ports"},
  289. {"type": "string", "format": "ports"},
  290. {
  291. "type": "object",
  292. "properties": {
  293. "mode": {"type": "string"},
  294. "host_ip": {"type": "string"},
  295. "target": {"type": "integer"},
  296. "published": {"type": ["string", "integer"]},
  297. "protocol": {"type": "string"}
  298. },
  299. "additionalProperties": false,
  300. "patternProperties": {"^x-": {}}
  301. }
  302. ]
  303. },
  304. "uniqueItems": true
  305. },
  306. "privileged": {"type": "boolean"},
  307. "profiles": {"$ref": "#/definitions/list_of_strings"},
  308. "pull_policy": {"type": "string", "enum": [
  309. "always", "never", "if_not_present", "build", "missing"
  310. ]},
  311. "read_only": {"type": "boolean"},
  312. "restart": {"type": "string"},
  313. "runtime": {
  314. "type": "string"
  315. },
  316. "scale": {
  317. "type": "integer"
  318. },
  319. "security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
  320. "shm_size": {"type": ["number", "string"]},
  321. "secrets": {"$ref": "#/definitions/service_config_or_secret"},
  322. "sysctls": {"$ref": "#/definitions/list_or_dict"},
  323. "stdin_open": {"type": "boolean"},
  324. "stop_grace_period": {"type": "string", "format": "duration"},
  325. "stop_signal": {"type": "string"},
  326. "storage_opt": {"type": "object"},
  327. "tmpfs": {"$ref": "#/definitions/string_or_list"},
  328. "tty": {"type": "boolean"},
  329. "ulimits": {
  330. "type": "object",
  331. "patternProperties": {
  332. "^[a-z]+$": {
  333. "oneOf": [
  334. {"type": "integer"},
  335. {
  336. "type": "object",
  337. "properties": {
  338. "hard": {"type": "integer"},
  339. "soft": {"type": "integer"}
  340. },
  341. "required": ["soft", "hard"],
  342. "additionalProperties": false,
  343. "patternProperties": {"^x-": {}}
  344. }
  345. ]
  346. }
  347. }
  348. },
  349. "user": {"type": "string"},
  350. "userns_mode": {"type": "string"},
  351. "volumes": {
  352. "type": "array",
  353. "items": {
  354. "oneOf": [
  355. {"type": "string"},
  356. {
  357. "type": "object",
  358. "required": ["type"],
  359. "properties": {
  360. "type": {"type": "string"},
  361. "source": {"type": "string"},
  362. "target": {"type": "string"},
  363. "read_only": {"type": "boolean"},
  364. "consistency": {"type": "string"},
  365. "bind": {
  366. "type": "object",
  367. "properties": {
  368. "propagation": {"type": "string"},
  369. "create_host_path": {"type": "boolean"},
  370. "selinux": {"type": "string", "enum": ["z", "Z"]}
  371. },
  372. "additionalProperties": false,
  373. "patternProperties": {"^x-": {}}
  374. },
  375. "volume": {
  376. "type": "object",
  377. "properties": {
  378. "nocopy": {"type": "boolean"}
  379. },
  380. "additionalProperties": false,
  381. "patternProperties": {"^x-": {}}
  382. },
  383. "tmpfs": {
  384. "type": "object",
  385. "properties": {
  386. "size": {
  387. "oneOf": [
  388. {"type": "integer", "minimum": 0},
  389. {"type": "string"}
  390. ]
  391. }
  392. },
  393. "additionalProperties": false,
  394. "patternProperties": {"^x-": {}}
  395. }
  396. },
  397. "additionalProperties": false,
  398. "patternProperties": {"^x-": {}}
  399. }
  400. ]
  401. },
  402. "uniqueItems": true
  403. },
  404. "volumes_from": {
  405. "type": "array",
  406. "items": {"type": "string"},
  407. "uniqueItems": true
  408. },
  409. "working_dir": {"type": "string"}
  410. },
  411. "patternProperties": {"^x-": {}},
  412. "additionalProperties": false
  413. },
  414. "healthcheck": {
  415. "id": "#/definitions/healthcheck",
  416. "type": "object",
  417. "properties": {
  418. "disable": {"type": "boolean"},
  419. "interval": {"type": "string", "format": "duration"},
  420. "retries": {"type": "number"},
  421. "test": {
  422. "oneOf": [
  423. {"type": "string"},
  424. {"type": "array", "items": {"type": "string"}}
  425. ]
  426. },
  427. "timeout": {"type": "string", "format": "duration"},
  428. "start_period": {"type": "string", "format": "duration"}
  429. },
  430. "additionalProperties": false,
  431. "patternProperties": {"^x-": {}}
  432. },
  433. "deployment": {
  434. "id": "#/definitions/deployment",
  435. "type": ["object", "null"],
  436. "properties": {
  437. "mode": {"type": "string"},
  438. "endpoint_mode": {"type": "string"},
  439. "replicas": {"type": "integer"},
  440. "labels": {"$ref": "#/definitions/list_or_dict"},
  441. "rollback_config": {
  442. "type": "object",
  443. "properties": {
  444. "parallelism": {"type": "integer"},
  445. "delay": {"type": "string", "format": "duration"},
  446. "failure_action": {"type": "string"},
  447. "monitor": {"type": "string", "format": "duration"},
  448. "max_failure_ratio": {"type": "number"},
  449. "order": {"type": "string", "enum": [
  450. "start-first", "stop-first"
  451. ]}
  452. },
  453. "additionalProperties": false,
  454. "patternProperties": {"^x-": {}}
  455. },
  456. "update_config": {
  457. "type": "object",
  458. "properties": {
  459. "parallelism": {"type": "integer"},
  460. "delay": {"type": "string", "format": "duration"},
  461. "failure_action": {"type": "string"},
  462. "monitor": {"type": "string", "format": "duration"},
  463. "max_failure_ratio": {"type": "number"},
  464. "order": {"type": "string", "enum": [
  465. "start-first", "stop-first"
  466. ]}
  467. },
  468. "additionalProperties": false,
  469. "patternProperties": {"^x-": {}}
  470. },
  471. "resources": {
  472. "type": "object",
  473. "properties": {
  474. "limits": {
  475. "type": "object",
  476. "properties": {
  477. "cpus": {"type": ["number", "string"]},
  478. "memory": {"type": "string"},
  479. "pids": {"type": "integer"}
  480. },
  481. "additionalProperties": false,
  482. "patternProperties": {"^x-": {}}
  483. },
  484. "reservations": {
  485. "type": "object",
  486. "properties": {
  487. "cpus": {"type": ["number", "string"]},
  488. "memory": {"type": "string"},
  489. "generic_resources": {"$ref": "#/definitions/generic_resources"},
  490. "devices": {"$ref": "#/definitions/devices"}
  491. },
  492. "additionalProperties": false,
  493. "patternProperties": {"^x-": {}}
  494. }
  495. },
  496. "additionalProperties": false,
  497. "patternProperties": {"^x-": {}}
  498. },
  499. "restart_policy": {
  500. "type": "object",
  501. "properties": {
  502. "condition": {"type": "string"},
  503. "delay": {"type": "string", "format": "duration"},
  504. "max_attempts": {"type": "integer"},
  505. "window": {"type": "string", "format": "duration"}
  506. },
  507. "additionalProperties": false,
  508. "patternProperties": {"^x-": {}}
  509. },
  510. "placement": {
  511. "type": "object",
  512. "properties": {
  513. "constraints": {"type": "array", "items": {"type": "string"}},
  514. "preferences": {
  515. "type": "array",
  516. "items": {
  517. "type": "object",
  518. "properties": {
  519. "spread": {"type": "string"}
  520. },
  521. "additionalProperties": false,
  522. "patternProperties": {"^x-": {}}
  523. }
  524. },
  525. "max_replicas_per_node": {"type": "integer"}
  526. },
  527. "additionalProperties": false,
  528. "patternProperties": {"^x-": {}}
  529. }
  530. },
  531. "additionalProperties": false,
  532. "patternProperties": {"^x-": {}}
  533. },
  534. "generic_resources": {
  535. "id": "#/definitions/generic_resources",
  536. "type": "array",
  537. "items": {
  538. "type": "object",
  539. "properties": {
  540. "discrete_resource_spec": {
  541. "type": "object",
  542. "properties": {
  543. "kind": {"type": "string"},
  544. "value": {"type": "number"}
  545. },
  546. "additionalProperties": false,
  547. "patternProperties": {"^x-": {}}
  548. }
  549. },
  550. "additionalProperties": false,
  551. "patternProperties": {"^x-": {}}
  552. }
  553. },
  554. "devices": {
  555. "id": "#/definitions/devices",
  556. "type": "array",
  557. "items": {
  558. "type": "object",
  559. "properties": {
  560. "capabilities": {"$ref": "#/definitions/list_of_strings"},
  561. "count": {"type": ["string", "integer"]},
  562. "device_ids": {"$ref": "#/definitions/list_of_strings"},
  563. "driver":{"type": "string"},
  564. "options":{"$ref": "#/definitions/list_or_dict"}
  565. },
  566. "additionalProperties": false,
  567. "patternProperties": {"^x-": {}}
  568. }
  569. },
  570. "network": {
  571. "id": "#/definitions/network",
  572. "type": ["object", "null"],
  573. "properties": {
  574. "name": {"type": "string"},
  575. "driver": {"type": "string"},
  576. "driver_opts": {
  577. "type": "object",
  578. "patternProperties": {
  579. "^.+$": {"type": ["string", "number"]}
  580. }
  581. },
  582. "ipam": {
  583. "type": "object",
  584. "properties": {
  585. "driver": {"type": "string"},
  586. "config": {
  587. "type": "array",
  588. "items": {
  589. "type": "object",
  590. "properties": {
  591. "subnet": {"type": "string", "format": "subnet_ip_address"},
  592. "ip_range": {"type": "string"},
  593. "gateway": {"type": "string"},
  594. "aux_addresses": {
  595. "type": "object",
  596. "additionalProperties": false,
  597. "patternProperties": {"^.+$": {"type": "string"}}
  598. }
  599. },
  600. "additionalProperties": false,
  601. "patternProperties": {"^x-": {}}
  602. }
  603. },
  604. "options": {
  605. "type": "object",
  606. "additionalProperties": false,
  607. "patternProperties": {"^.+$": {"type": "string"}}
  608. }
  609. },
  610. "additionalProperties": false,
  611. "patternProperties": {"^x-": {}}
  612. },
  613. "external": {
  614. "type": ["boolean", "object"],
  615. "properties": {
  616. "name": {
  617. "deprecated": true,
  618. "type": "string"
  619. }
  620. },
  621. "additionalProperties": false,
  622. "patternProperties": {"^x-": {}}
  623. },
  624. "internal": {"type": "boolean"},
  625. "enable_ipv6": {"type": "boolean"},
  626. "attachable": {"type": "boolean"},
  627. "labels": {"$ref": "#/definitions/list_or_dict"}
  628. },
  629. "additionalProperties": false,
  630. "patternProperties": {"^x-": {}}
  631. },
  632. "volume": {
  633. "id": "#/definitions/volume",
  634. "type": ["object", "null"],
  635. "properties": {
  636. "name": {"type": "string"},
  637. "driver": {"type": "string"},
  638. "driver_opts": {
  639. "type": "object",
  640. "patternProperties": {
  641. "^.+$": {"type": ["string", "number"]}
  642. }
  643. },
  644. "external": {
  645. "type": ["boolean", "object"],
  646. "properties": {
  647. "name": {
  648. "deprecated": true,
  649. "type": "string"
  650. }
  651. },
  652. "additionalProperties": false,
  653. "patternProperties": {"^x-": {}}
  654. },
  655. "labels": {"$ref": "#/definitions/list_or_dict"}
  656. },
  657. "additionalProperties": false,
  658. "patternProperties": {"^x-": {}}
  659. },
  660. "secret": {
  661. "id": "#/definitions/secret",
  662. "type": "object",
  663. "properties": {
  664. "name": {"type": "string"},
  665. "file": {"type": "string"},
  666. "external": {
  667. "type": ["boolean", "object"],
  668. "properties": {
  669. "name": {"type": "string"}
  670. }
  671. },
  672. "labels": {"$ref": "#/definitions/list_or_dict"},
  673. "driver": {"type": "string"},
  674. "driver_opts": {
  675. "type": "object",
  676. "patternProperties": {
  677. "^.+$": {"type": ["string", "number"]}
  678. }
  679. },
  680. "template_driver": {"type": "string"}
  681. },
  682. "additionalProperties": false,
  683. "patternProperties": {"^x-": {}}
  684. },
  685. "config": {
  686. "id": "#/definitions/config",
  687. "type": "object",
  688. "properties": {
  689. "name": {"type": "string"},
  690. "file": {"type": "string"},
  691. "external": {
  692. "type": ["boolean", "object"],
  693. "properties": {
  694. "name": {
  695. "deprecated": true,
  696. "type": "string"
  697. }
  698. }
  699. },
  700. "labels": {"$ref": "#/definitions/list_or_dict"},
  701. "template_driver": {"type": "string"}
  702. },
  703. "additionalProperties": false,
  704. "patternProperties": {"^x-": {}}
  705. },
  706. "string_or_list": {
  707. "oneOf": [
  708. {"type": "string"},
  709. {"$ref": "#/definitions/list_of_strings"}
  710. ]
  711. },
  712. "list_of_strings": {
  713. "type": "array",
  714. "items": {"type": "string"},
  715. "uniqueItems": true
  716. },
  717. "list_or_dict": {
  718. "oneOf": [
  719. {
  720. "type": "object",
  721. "patternProperties": {
  722. ".+": {
  723. "type": ["string", "number", "boolean", "null"]
  724. }
  725. },
  726. "additionalProperties": false
  727. },
  728. {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
  729. ]
  730. },
  731. "blkio_limit": {
  732. "type": "object",
  733. "properties": {
  734. "path": {"type": "string"},
  735. "rate": {"type": ["integer", "string"]}
  736. },
  737. "additionalProperties": false
  738. },
  739. "blkio_weight": {
  740. "type": "object",
  741. "properties": {
  742. "path": {"type": "string"},
  743. "weight": {"type": "integer"}
  744. },
  745. "additionalProperties": false
  746. },
  747. "service_config_or_secret": {
  748. "type": "array",
  749. "items": {
  750. "oneOf": [
  751. {"type": "string"},
  752. {
  753. "type": "object",
  754. "properties": {
  755. "source": {"type": "string"},
  756. "target": {"type": "string"},
  757. "uid": {"type": "string"},
  758. "gid": {"type": "string"},
  759. "mode": {"type": "number"}
  760. },
  761. "additionalProperties": false,
  762. "patternProperties": {"^x-": {}}
  763. }
  764. ]
  765. }
  766. },
  767. "constraints": {
  768. "service": {
  769. "id": "#/definitions/constraints/service",
  770. "anyOf": [
  771. {"required": ["build"]},
  772. {"required": ["image"]}
  773. ],
  774. "properties": {
  775. "build": {
  776. "required": ["context"]
  777. }
  778. }
  779. }
  780. }
  781. }
  782. }