github.com/AliyunContainerService/cli@v0.0.0-20181009023821-814ced4b30d0/cli/compose/loader/full-struct_test.go (about) 1 package loader 2 3 import ( 4 "fmt" 5 "path/filepath" 6 "time" 7 8 "github.com/docker/cli/cli/compose/types" 9 ) 10 11 func fullExampleConfig(workingDir, homeDir string) *types.Config { 12 return &types.Config{ 13 Version: "3.7", 14 Services: services(workingDir, homeDir), 15 Networks: networks(), 16 Volumes: volumes(), 17 Configs: configs(workingDir), 18 Secrets: secrets(workingDir), 19 Extras: map[string]interface{}{ 20 "x-foo": "bar", 21 "x-bar": "baz", 22 "x-nested": map[string]interface{}{ 23 "foo": "bar", 24 "bar": "baz", 25 }, 26 }, 27 } 28 } 29 30 func services(workingDir, homeDir string) []types.ServiceConfig { 31 return []types.ServiceConfig{ 32 { 33 Name: "foo", 34 35 Build: types.BuildConfig{ 36 Context: "./dir", 37 Dockerfile: "Dockerfile", 38 Args: map[string]*string{"foo": strPtr("bar")}, 39 Target: "foo", 40 Network: "foo", 41 CacheFrom: []string{"foo", "bar"}, 42 Labels: map[string]string{"FOO": "BAR"}, 43 }, 44 CapAdd: []string{"ALL"}, 45 CapDrop: []string{"NET_ADMIN", "SYS_ADMIN"}, 46 CgroupParent: "m-executor-abcd", 47 Command: []string{"bundle", "exec", "thin", "-p", "3000"}, 48 Configs: []types.ServiceConfigObjConfig{ 49 { 50 Source: "config1", 51 }, 52 { 53 Source: "config2", 54 Target: "/my_config", 55 UID: "103", 56 GID: "103", 57 Mode: uint32Ptr(0440), 58 }, 59 }, 60 ContainerName: "my-web-container", 61 DependsOn: []string{"db", "redis"}, 62 Deploy: types.DeployConfig{ 63 Mode: "replicated", 64 Replicas: uint64Ptr(6), 65 Labels: map[string]string{"FOO": "BAR"}, 66 RollbackConfig: &types.UpdateConfig{ 67 Parallelism: uint64Ptr(3), 68 Delay: types.Duration(10 * time.Second), 69 FailureAction: "continue", 70 Monitor: types.Duration(60 * time.Second), 71 MaxFailureRatio: 0.3, 72 Order: "start-first", 73 }, 74 UpdateConfig: &types.UpdateConfig{ 75 Parallelism: uint64Ptr(3), 76 Delay: types.Duration(10 * time.Second), 77 FailureAction: "continue", 78 Monitor: types.Duration(60 * time.Second), 79 MaxFailureRatio: 0.3, 80 Order: "start-first", 81 }, 82 Resources: types.Resources{ 83 Limits: &types.Resource{ 84 NanoCPUs: "0.001", 85 MemoryBytes: 50 * 1024 * 1024, 86 }, 87 Reservations: &types.Resource{ 88 NanoCPUs: "0.0001", 89 MemoryBytes: 20 * 1024 * 1024, 90 GenericResources: []types.GenericResource{ 91 { 92 DiscreteResourceSpec: &types.DiscreteGenericResource{ 93 Kind: "gpu", 94 Value: 2, 95 }, 96 }, 97 { 98 DiscreteResourceSpec: &types.DiscreteGenericResource{ 99 Kind: "ssd", 100 Value: 1, 101 }, 102 }, 103 }, 104 }, 105 }, 106 RestartPolicy: &types.RestartPolicy{ 107 Condition: "on-failure", 108 Delay: durationPtr(5 * time.Second), 109 MaxAttempts: uint64Ptr(3), 110 Window: durationPtr(2 * time.Minute), 111 }, 112 Placement: types.Placement{ 113 Constraints: []string{"node=foo"}, 114 Preferences: []types.PlacementPreferences{ 115 { 116 Spread: "node.labels.az", 117 }, 118 }, 119 }, 120 EndpointMode: "dnsrr", 121 }, 122 Devices: []string{"/dev/ttyUSB0:/dev/ttyUSB0"}, 123 DNS: []string{"8.8.8.8", "9.9.9.9"}, 124 DNSSearch: []string{"dc1.example.com", "dc2.example.com"}, 125 DomainName: "foo.com", 126 Entrypoint: []string{"/code/entrypoint.sh", "-p", "3000"}, 127 Environment: map[string]*string{ 128 "FOO": strPtr("foo_from_env_file"), 129 "BAR": strPtr("bar_from_env_file_2"), 130 "BAZ": strPtr("baz_from_service_def"), 131 "QUX": strPtr("qux_from_environment"), 132 }, 133 EnvFile: []string{ 134 "./example1.env", 135 "./example2.env", 136 }, 137 Expose: []string{"3000", "8000"}, 138 ExternalLinks: []string{ 139 "redis_1", 140 "project_db_1:mysql", 141 "project_db_1:postgresql", 142 }, 143 ExtraHosts: []string{ 144 "somehost:162.242.195.82", 145 "otherhost:50.31.209.229", 146 }, 147 Extras: map[string]interface{}{ 148 "x-bar": "baz", 149 "x-foo": "bar", 150 }, 151 HealthCheck: &types.HealthCheckConfig{ 152 Test: types.HealthCheckTest([]string{"CMD-SHELL", "echo \"hello world\""}), 153 Interval: durationPtr(10 * time.Second), 154 Timeout: durationPtr(1 * time.Second), 155 Retries: uint64Ptr(5), 156 StartPeriod: durationPtr(15 * time.Second), 157 }, 158 Hostname: "foo", 159 Image: "redis", 160 Ipc: "host", 161 Labels: map[string]string{ 162 "com.example.description": "Accounting webapp", 163 "com.example.number": "42", 164 "com.example.empty-label": "", 165 }, 166 Links: []string{ 167 "db", 168 "db:database", 169 "redis", 170 }, 171 Logging: &types.LoggingConfig{ 172 Driver: "syslog", 173 Options: map[string]string{ 174 "syslog-address": "tcp://192.168.0.42:123", 175 }, 176 }, 177 MacAddress: "02:42:ac:11:65:43", 178 NetworkMode: "container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b", 179 Networks: map[string]*types.ServiceNetworkConfig{ 180 "some-network": { 181 Aliases: []string{"alias1", "alias3"}, 182 Ipv4Address: "", 183 Ipv6Address: "", 184 }, 185 "other-network": { 186 Ipv4Address: "172.16.238.10", 187 Ipv6Address: "2001:3984:3989::10", 188 }, 189 "other-other-network": nil, 190 }, 191 Pid: "host", 192 Ports: []types.ServicePortConfig{ 193 //"3000", 194 { 195 Mode: "ingress", 196 Target: 3000, 197 Protocol: "tcp", 198 }, 199 { 200 Mode: "ingress", 201 Target: 3001, 202 Protocol: "tcp", 203 }, 204 { 205 Mode: "ingress", 206 Target: 3002, 207 Protocol: "tcp", 208 }, 209 { 210 Mode: "ingress", 211 Target: 3003, 212 Protocol: "tcp", 213 }, 214 { 215 Mode: "ingress", 216 Target: 3004, 217 Protocol: "tcp", 218 }, 219 { 220 Mode: "ingress", 221 Target: 3005, 222 Protocol: "tcp", 223 }, 224 //"8000:8000", 225 { 226 Mode: "ingress", 227 Target: 8000, 228 Published: 8000, 229 Protocol: "tcp", 230 }, 231 //"9090-9091:8080-8081", 232 { 233 Mode: "ingress", 234 Target: 8080, 235 Published: 9090, 236 Protocol: "tcp", 237 }, 238 { 239 Mode: "ingress", 240 Target: 8081, 241 Published: 9091, 242 Protocol: "tcp", 243 }, 244 //"49100:22", 245 { 246 Mode: "ingress", 247 Target: 22, 248 Published: 49100, 249 Protocol: "tcp", 250 }, 251 //"127.0.0.1:8001:8001", 252 { 253 Mode: "ingress", 254 Target: 8001, 255 Published: 8001, 256 Protocol: "tcp", 257 }, 258 //"127.0.0.1:5000-5010:5000-5010", 259 { 260 Mode: "ingress", 261 Target: 5000, 262 Published: 5000, 263 Protocol: "tcp", 264 }, 265 { 266 Mode: "ingress", 267 Target: 5001, 268 Published: 5001, 269 Protocol: "tcp", 270 }, 271 { 272 Mode: "ingress", 273 Target: 5002, 274 Published: 5002, 275 Protocol: "tcp", 276 }, 277 { 278 Mode: "ingress", 279 Target: 5003, 280 Published: 5003, 281 Protocol: "tcp", 282 }, 283 { 284 Mode: "ingress", 285 Target: 5004, 286 Published: 5004, 287 Protocol: "tcp", 288 }, 289 { 290 Mode: "ingress", 291 Target: 5005, 292 Published: 5005, 293 Protocol: "tcp", 294 }, 295 { 296 Mode: "ingress", 297 Target: 5006, 298 Published: 5006, 299 Protocol: "tcp", 300 }, 301 { 302 Mode: "ingress", 303 Target: 5007, 304 Published: 5007, 305 Protocol: "tcp", 306 }, 307 { 308 Mode: "ingress", 309 Target: 5008, 310 Published: 5008, 311 Protocol: "tcp", 312 }, 313 { 314 Mode: "ingress", 315 Target: 5009, 316 Published: 5009, 317 Protocol: "tcp", 318 }, 319 { 320 Mode: "ingress", 321 Target: 5010, 322 Published: 5010, 323 Protocol: "tcp", 324 }, 325 }, 326 Privileged: true, 327 ReadOnly: true, 328 Restart: "always", 329 Secrets: []types.ServiceSecretConfig{ 330 { 331 Source: "secret1", 332 }, 333 { 334 Source: "secret2", 335 Target: "my_secret", 336 UID: "103", 337 GID: "103", 338 Mode: uint32Ptr(0440), 339 }, 340 }, 341 SecurityOpt: []string{ 342 "label=level:s0:c100,c200", 343 "label=type:svirt_apache_t", 344 }, 345 StdinOpen: true, 346 StopSignal: "SIGUSR1", 347 StopGracePeriod: durationPtr(20 * time.Second), 348 Tmpfs: []string{"/run", "/tmp"}, 349 Tty: true, 350 Ulimits: map[string]*types.UlimitsConfig{ 351 "nproc": { 352 Single: 65535, 353 }, 354 "nofile": { 355 Soft: 20000, 356 Hard: 40000, 357 }, 358 }, 359 User: "someone", 360 Volumes: []types.ServiceVolumeConfig{ 361 {Target: "/var/lib/mysql", Type: "volume"}, 362 {Source: "/opt/data", Target: "/var/lib/mysql", Type: "bind"}, 363 {Source: workingDir, Target: "/code", Type: "bind"}, 364 {Source: filepath.Join(workingDir, "static"), Target: "/var/www/html", Type: "bind"}, 365 {Source: homeDir + "/configs", Target: "/etc/configs/", Type: "bind", ReadOnly: true}, 366 {Source: "datavolume", Target: "/var/lib/mysql", Type: "volume"}, 367 {Source: filepath.Join(workingDir, "opt"), Target: "/opt", Consistency: "cached", Type: "bind"}, 368 {Target: "/opt", Type: "tmpfs", Tmpfs: &types.ServiceVolumeTmpfs{ 369 Size: int64(10000), 370 }}, 371 }, 372 WorkingDir: "/code", 373 }, 374 } 375 } 376 377 func networks() map[string]types.NetworkConfig { 378 return map[string]types.NetworkConfig{ 379 "some-network": {}, 380 381 "other-network": { 382 Driver: "overlay", 383 DriverOpts: map[string]string{ 384 "foo": "bar", 385 "baz": "1", 386 }, 387 Ipam: types.IPAMConfig{ 388 Driver: "overlay", 389 Config: []*types.IPAMPool{ 390 {Subnet: "172.16.238.0/24"}, 391 {Subnet: "2001:3984:3989::/64"}, 392 }, 393 }, 394 Labels: map[string]string{ 395 "foo": "bar", 396 }, 397 }, 398 399 "external-network": { 400 Name: "external-network", 401 External: types.External{External: true}, 402 }, 403 404 "other-external-network": { 405 Name: "my-cool-network", 406 External: types.External{External: true}, 407 Extras: map[string]interface{}{ 408 "x-bar": "baz", 409 "x-foo": "bar", 410 }, 411 }, 412 } 413 } 414 415 func volumes() map[string]types.VolumeConfig { 416 return map[string]types.VolumeConfig{ 417 "some-volume": {}, 418 "other-volume": { 419 Driver: "flocker", 420 DriverOpts: map[string]string{ 421 "foo": "bar", 422 "baz": "1", 423 }, 424 Labels: map[string]string{ 425 "foo": "bar", 426 }, 427 }, 428 "another-volume": { 429 Name: "user_specified_name", 430 Driver: "vsphere", 431 DriverOpts: map[string]string{ 432 "foo": "bar", 433 "baz": "1", 434 }, 435 }, 436 "external-volume": { 437 Name: "external-volume", 438 External: types.External{External: true}, 439 }, 440 "other-external-volume": { 441 Name: "my-cool-volume", 442 External: types.External{External: true}, 443 }, 444 "external-volume3": { 445 Name: "this-is-volume3", 446 External: types.External{External: true}, 447 Extras: map[string]interface{}{ 448 "x-bar": "baz", 449 "x-foo": "bar", 450 }, 451 }, 452 } 453 } 454 455 func configs(workingDir string) map[string]types.ConfigObjConfig { 456 return map[string]types.ConfigObjConfig{ 457 "config1": { 458 File: filepath.Join(workingDir, "config_data"), 459 Labels: map[string]string{ 460 "foo": "bar", 461 }, 462 }, 463 "config2": { 464 Name: "my_config", 465 External: types.External{External: true}, 466 }, 467 "config3": { 468 Name: "config3", 469 External: types.External{External: true}, 470 }, 471 "config4": { 472 Name: "foo", 473 File: workingDir, 474 Extras: map[string]interface{}{ 475 "x-bar": "baz", 476 "x-foo": "bar", 477 }, 478 }, 479 } 480 } 481 482 func secrets(workingDir string) map[string]types.SecretConfig { 483 return map[string]types.SecretConfig{ 484 "secret1": { 485 File: filepath.Join(workingDir, "secret_data"), 486 Labels: map[string]string{ 487 "foo": "bar", 488 }, 489 }, 490 "secret2": { 491 Name: "my_secret", 492 External: types.External{External: true}, 493 }, 494 "secret3": { 495 Name: "secret3", 496 External: types.External{External: true}, 497 }, 498 "secret4": { 499 Name: "bar", 500 File: workingDir, 501 Extras: map[string]interface{}{ 502 "x-bar": "baz", 503 "x-foo": "bar", 504 }, 505 }, 506 } 507 } 508 509 func fullExampleYAML(workingDir string) string { 510 return fmt.Sprintf(`version: "3.7" 511 services: 512 foo: 513 build: 514 context: ./dir 515 dockerfile: Dockerfile 516 args: 517 foo: bar 518 labels: 519 FOO: BAR 520 cache_from: 521 - foo 522 - bar 523 network: foo 524 target: foo 525 cap_add: 526 - ALL 527 cap_drop: 528 - NET_ADMIN 529 - SYS_ADMIN 530 cgroup_parent: m-executor-abcd 531 command: 532 - bundle 533 - exec 534 - thin 535 - -p 536 - "3000" 537 configs: 538 - source: config1 539 - source: config2 540 target: /my_config 541 uid: "103" 542 gid: "103" 543 mode: 288 544 container_name: my-web-container 545 depends_on: 546 - db 547 - redis 548 deploy: 549 mode: replicated 550 replicas: 6 551 labels: 552 FOO: BAR 553 update_config: 554 parallelism: 3 555 delay: 10s 556 failure_action: continue 557 monitor: 1m0s 558 max_failure_ratio: 0.3 559 order: start-first 560 rollback_config: 561 parallelism: 3 562 delay: 10s 563 failure_action: continue 564 monitor: 1m0s 565 max_failure_ratio: 0.3 566 order: start-first 567 resources: 568 limits: 569 cpus: "0.001" 570 memory: "52428800" 571 reservations: 572 cpus: "0.0001" 573 memory: "20971520" 574 generic_resources: 575 - discrete_resource_spec: 576 kind: gpu 577 value: 2 578 - discrete_resource_spec: 579 kind: ssd 580 value: 1 581 restart_policy: 582 condition: on-failure 583 delay: 5s 584 max_attempts: 3 585 window: 2m0s 586 placement: 587 constraints: 588 - node=foo 589 preferences: 590 - spread: node.labels.az 591 endpoint_mode: dnsrr 592 devices: 593 - /dev/ttyUSB0:/dev/ttyUSB0 594 dns: 595 - 8.8.8.8 596 - 9.9.9.9 597 dns_search: 598 - dc1.example.com 599 - dc2.example.com 600 domainname: foo.com 601 entrypoint: 602 - /code/entrypoint.sh 603 - -p 604 - "3000" 605 environment: 606 BAR: bar_from_env_file_2 607 BAZ: baz_from_service_def 608 FOO: foo_from_env_file 609 QUX: qux_from_environment 610 env_file: 611 - ./example1.env 612 - ./example2.env 613 expose: 614 - "3000" 615 - "8000" 616 external_links: 617 - redis_1 618 - project_db_1:mysql 619 - project_db_1:postgresql 620 extra_hosts: 621 - somehost:162.242.195.82 622 - otherhost:50.31.209.229 623 hostname: foo 624 healthcheck: 625 test: 626 - CMD-SHELL 627 - echo "hello world" 628 timeout: 1s 629 interval: 10s 630 retries: 5 631 start_period: 15s 632 image: redis 633 ipc: host 634 labels: 635 com.example.description: Accounting webapp 636 com.example.empty-label: "" 637 com.example.number: "42" 638 links: 639 - db 640 - db:database 641 - redis 642 logging: 643 driver: syslog 644 options: 645 syslog-address: tcp://192.168.0.42:123 646 mac_address: 02:42:ac:11:65:43 647 network_mode: container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b 648 networks: 649 other-network: 650 ipv4_address: 172.16.238.10 651 ipv6_address: 2001:3984:3989::10 652 other-other-network: null 653 some-network: 654 aliases: 655 - alias1 656 - alias3 657 pid: host 658 ports: 659 - mode: ingress 660 target: 3000 661 protocol: tcp 662 - mode: ingress 663 target: 3001 664 protocol: tcp 665 - mode: ingress 666 target: 3002 667 protocol: tcp 668 - mode: ingress 669 target: 3003 670 protocol: tcp 671 - mode: ingress 672 target: 3004 673 protocol: tcp 674 - mode: ingress 675 target: 3005 676 protocol: tcp 677 - mode: ingress 678 target: 8000 679 published: 8000 680 protocol: tcp 681 - mode: ingress 682 target: 8080 683 published: 9090 684 protocol: tcp 685 - mode: ingress 686 target: 8081 687 published: 9091 688 protocol: tcp 689 - mode: ingress 690 target: 22 691 published: 49100 692 protocol: tcp 693 - mode: ingress 694 target: 8001 695 published: 8001 696 protocol: tcp 697 - mode: ingress 698 target: 5000 699 published: 5000 700 protocol: tcp 701 - mode: ingress 702 target: 5001 703 published: 5001 704 protocol: tcp 705 - mode: ingress 706 target: 5002 707 published: 5002 708 protocol: tcp 709 - mode: ingress 710 target: 5003 711 published: 5003 712 protocol: tcp 713 - mode: ingress 714 target: 5004 715 published: 5004 716 protocol: tcp 717 - mode: ingress 718 target: 5005 719 published: 5005 720 protocol: tcp 721 - mode: ingress 722 target: 5006 723 published: 5006 724 protocol: tcp 725 - mode: ingress 726 target: 5007 727 published: 5007 728 protocol: tcp 729 - mode: ingress 730 target: 5008 731 published: 5008 732 protocol: tcp 733 - mode: ingress 734 target: 5009 735 published: 5009 736 protocol: tcp 737 - mode: ingress 738 target: 5010 739 published: 5010 740 protocol: tcp 741 privileged: true 742 read_only: true 743 restart: always 744 secrets: 745 - source: secret1 746 - source: secret2 747 target: my_secret 748 uid: "103" 749 gid: "103" 750 mode: 288 751 security_opt: 752 - label=level:s0:c100,c200 753 - label=type:svirt_apache_t 754 stdin_open: true 755 stop_grace_period: 20s 756 stop_signal: SIGUSR1 757 tmpfs: 758 - /run 759 - /tmp 760 tty: true 761 ulimits: 762 nofile: 763 soft: 20000 764 hard: 40000 765 nproc: 65535 766 user: someone 767 volumes: 768 - type: volume 769 target: /var/lib/mysql 770 - type: bind 771 source: /opt/data 772 target: /var/lib/mysql 773 - type: bind 774 source: /foo 775 target: /code 776 - type: bind 777 source: %s 778 target: /var/www/html 779 - type: bind 780 source: /bar/configs 781 target: /etc/configs/ 782 read_only: true 783 - type: volume 784 source: datavolume 785 target: /var/lib/mysql 786 - type: bind 787 source: %s 788 target: /opt 789 consistency: cached 790 - type: tmpfs 791 target: /opt 792 tmpfs: 793 size: 10000 794 working_dir: /code 795 x-bar: baz 796 x-foo: bar 797 networks: 798 external-network: 799 name: external-network 800 external: true 801 other-external-network: 802 name: my-cool-network 803 external: true 804 x-bar: baz 805 x-foo: bar 806 other-network: 807 driver: overlay 808 driver_opts: 809 baz: "1" 810 foo: bar 811 ipam: 812 driver: overlay 813 config: 814 - subnet: 172.16.238.0/24 815 - subnet: 2001:3984:3989::/64 816 labels: 817 foo: bar 818 some-network: {} 819 volumes: 820 another-volume: 821 name: user_specified_name 822 driver: vsphere 823 driver_opts: 824 baz: "1" 825 foo: bar 826 external-volume: 827 name: external-volume 828 external: true 829 external-volume3: 830 name: this-is-volume3 831 external: true 832 x-bar: baz 833 x-foo: bar 834 other-external-volume: 835 name: my-cool-volume 836 external: true 837 other-volume: 838 driver: flocker 839 driver_opts: 840 baz: "1" 841 foo: bar 842 labels: 843 foo: bar 844 some-volume: {} 845 secrets: 846 secret1: 847 file: %s/secret_data 848 labels: 849 foo: bar 850 secret2: 851 name: my_secret 852 external: true 853 secret3: 854 name: secret3 855 external: true 856 secret4: 857 name: bar 858 file: %s 859 x-bar: baz 860 x-foo: bar 861 configs: 862 config1: 863 file: %s/config_data 864 labels: 865 foo: bar 866 config2: 867 name: my_config 868 external: true 869 config3: 870 name: config3 871 external: true 872 config4: 873 name: foo 874 file: %s 875 x-bar: baz 876 x-foo: bar 877 x-bar: baz 878 x-foo: bar 879 x-nested: 880 bar: baz 881 foo: bar 882 `, 883 filepath.Join(workingDir, "static"), 884 filepath.Join(workingDir, "opt"), 885 workingDir, 886 workingDir, 887 workingDir, 888 workingDir) 889 } 890 891 func fullExampleJSON(workingDir string) string { 892 return fmt.Sprintf(`{ 893 "configs": { 894 "config1": { 895 "file": "%s/config_data", 896 "external": false, 897 "labels": { 898 "foo": "bar" 899 } 900 }, 901 "config2": { 902 "name": "my_config", 903 "external": true 904 }, 905 "config3": { 906 "name": "config3", 907 "external": true 908 }, 909 "config4": { 910 "name": "foo", 911 "file": "%s", 912 "external": false 913 } 914 }, 915 "networks": { 916 "external-network": { 917 "name": "external-network", 918 "ipam": {}, 919 "external": true 920 }, 921 "other-external-network": { 922 "name": "my-cool-network", 923 "ipam": {}, 924 "external": true 925 }, 926 "other-network": { 927 "driver": "overlay", 928 "driver_opts": { 929 "baz": "1", 930 "foo": "bar" 931 }, 932 "ipam": { 933 "driver": "overlay", 934 "config": [ 935 { 936 "subnet": "172.16.238.0/24" 937 }, 938 { 939 "subnet": "2001:3984:3989::/64" 940 } 941 ] 942 }, 943 "external": false, 944 "labels": { 945 "foo": "bar" 946 } 947 }, 948 "some-network": { 949 "ipam": {}, 950 "external": false 951 } 952 }, 953 "secrets": { 954 "secret1": { 955 "file": "%s/secret_data", 956 "external": false, 957 "labels": { 958 "foo": "bar" 959 } 960 }, 961 "secret2": { 962 "name": "my_secret", 963 "external": true 964 }, 965 "secret3": { 966 "name": "secret3", 967 "external": true 968 }, 969 "secret4": { 970 "name": "bar", 971 "file": "%s", 972 "external": false 973 } 974 }, 975 "services": { 976 "foo": { 977 "build": { 978 "context": "./dir", 979 "dockerfile": "Dockerfile", 980 "args": { 981 "foo": "bar" 982 }, 983 "labels": { 984 "FOO": "BAR" 985 }, 986 "cache_from": [ 987 "foo", 988 "bar" 989 ], 990 "network": "foo", 991 "target": "foo" 992 }, 993 "cap_add": [ 994 "ALL" 995 ], 996 "cap_drop": [ 997 "NET_ADMIN", 998 "SYS_ADMIN" 999 ], 1000 "cgroup_parent": "m-executor-abcd", 1001 "command": [ 1002 "bundle", 1003 "exec", 1004 "thin", 1005 "-p", 1006 "3000" 1007 ], 1008 "configs": [ 1009 { 1010 "source": "config1" 1011 }, 1012 { 1013 "source": "config2", 1014 "target": "/my_config", 1015 "uid": "103", 1016 "gid": "103", 1017 "mode": 288 1018 } 1019 ], 1020 "container_name": "my-web-container", 1021 "credential_spec": {}, 1022 "depends_on": [ 1023 "db", 1024 "redis" 1025 ], 1026 "deploy": { 1027 "mode": "replicated", 1028 "replicas": 6, 1029 "labels": { 1030 "FOO": "BAR" 1031 }, 1032 "update_config": { 1033 "parallelism": 3, 1034 "delay": "10s", 1035 "failure_action": "continue", 1036 "monitor": "1m0s", 1037 "max_failure_ratio": 0.3, 1038 "order": "start-first" 1039 }, 1040 "rollback_config": { 1041 "parallelism": 3, 1042 "delay": "10s", 1043 "failure_action": "continue", 1044 "monitor": "1m0s", 1045 "max_failure_ratio": 0.3, 1046 "order": "start-first" 1047 }, 1048 "resources": { 1049 "limits": { 1050 "cpus": "0.001", 1051 "memory": "52428800" 1052 }, 1053 "reservations": { 1054 "cpus": "0.0001", 1055 "memory": "20971520", 1056 "generic_resources": [ 1057 { 1058 "discrete_resource_spec": { 1059 "kind": "gpu", 1060 "value": 2 1061 } 1062 }, 1063 { 1064 "discrete_resource_spec": { 1065 "kind": "ssd", 1066 "value": 1 1067 } 1068 } 1069 ] 1070 } 1071 }, 1072 "restart_policy": { 1073 "condition": "on-failure", 1074 "delay": "5s", 1075 "max_attempts": 3, 1076 "window": "2m0s" 1077 }, 1078 "placement": { 1079 "constraints": [ 1080 "node=foo" 1081 ], 1082 "preferences": [ 1083 { 1084 "spread": "node.labels.az" 1085 } 1086 ] 1087 }, 1088 "endpoint_mode": "dnsrr" 1089 }, 1090 "devices": [ 1091 "/dev/ttyUSB0:/dev/ttyUSB0" 1092 ], 1093 "dns": [ 1094 "8.8.8.8", 1095 "9.9.9.9" 1096 ], 1097 "dns_search": [ 1098 "dc1.example.com", 1099 "dc2.example.com" 1100 ], 1101 "domainname": "foo.com", 1102 "entrypoint": [ 1103 "/code/entrypoint.sh", 1104 "-p", 1105 "3000" 1106 ], 1107 "environment": { 1108 "BAR": "bar_from_env_file_2", 1109 "BAZ": "baz_from_service_def", 1110 "FOO": "foo_from_env_file", 1111 "QUX": "qux_from_environment" 1112 }, 1113 "env_file": [ 1114 "./example1.env", 1115 "./example2.env" 1116 ], 1117 "expose": [ 1118 "3000", 1119 "8000" 1120 ], 1121 "external_links": [ 1122 "redis_1", 1123 "project_db_1:mysql", 1124 "project_db_1:postgresql" 1125 ], 1126 "extra_hosts": [ 1127 "somehost:162.242.195.82", 1128 "otherhost:50.31.209.229" 1129 ], 1130 "hostname": "foo", 1131 "healthcheck": { 1132 "test": [ 1133 "CMD-SHELL", 1134 "echo \"hello world\"" 1135 ], 1136 "timeout": "1s", 1137 "interval": "10s", 1138 "retries": 5, 1139 "start_period": "15s" 1140 }, 1141 "image": "redis", 1142 "ipc": "host", 1143 "labels": { 1144 "com.example.description": "Accounting webapp", 1145 "com.example.empty-label": "", 1146 "com.example.number": "42" 1147 }, 1148 "links": [ 1149 "db", 1150 "db:database", 1151 "redis" 1152 ], 1153 "logging": { 1154 "driver": "syslog", 1155 "options": { 1156 "syslog-address": "tcp://192.168.0.42:123" 1157 } 1158 }, 1159 "mac_address": "02:42:ac:11:65:43", 1160 "network_mode": "container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b", 1161 "networks": { 1162 "other-network": { 1163 "ipv4_address": "172.16.238.10", 1164 "ipv6_address": "2001:3984:3989::10" 1165 }, 1166 "other-other-network": null, 1167 "some-network": { 1168 "aliases": [ 1169 "alias1", 1170 "alias3" 1171 ] 1172 } 1173 }, 1174 "pid": "host", 1175 "ports": [ 1176 { 1177 "mode": "ingress", 1178 "target": 3000, 1179 "protocol": "tcp" 1180 }, 1181 { 1182 "mode": "ingress", 1183 "target": 3001, 1184 "protocol": "tcp" 1185 }, 1186 { 1187 "mode": "ingress", 1188 "target": 3002, 1189 "protocol": "tcp" 1190 }, 1191 { 1192 "mode": "ingress", 1193 "target": 3003, 1194 "protocol": "tcp" 1195 }, 1196 { 1197 "mode": "ingress", 1198 "target": 3004, 1199 "protocol": "tcp" 1200 }, 1201 { 1202 "mode": "ingress", 1203 "target": 3005, 1204 "protocol": "tcp" 1205 }, 1206 { 1207 "mode": "ingress", 1208 "target": 8000, 1209 "published": 8000, 1210 "protocol": "tcp" 1211 }, 1212 { 1213 "mode": "ingress", 1214 "target": 8080, 1215 "published": 9090, 1216 "protocol": "tcp" 1217 }, 1218 { 1219 "mode": "ingress", 1220 "target": 8081, 1221 "published": 9091, 1222 "protocol": "tcp" 1223 }, 1224 { 1225 "mode": "ingress", 1226 "target": 22, 1227 "published": 49100, 1228 "protocol": "tcp" 1229 }, 1230 { 1231 "mode": "ingress", 1232 "target": 8001, 1233 "published": 8001, 1234 "protocol": "tcp" 1235 }, 1236 { 1237 "mode": "ingress", 1238 "target": 5000, 1239 "published": 5000, 1240 "protocol": "tcp" 1241 }, 1242 { 1243 "mode": "ingress", 1244 "target": 5001, 1245 "published": 5001, 1246 "protocol": "tcp" 1247 }, 1248 { 1249 "mode": "ingress", 1250 "target": 5002, 1251 "published": 5002, 1252 "protocol": "tcp" 1253 }, 1254 { 1255 "mode": "ingress", 1256 "target": 5003, 1257 "published": 5003, 1258 "protocol": "tcp" 1259 }, 1260 { 1261 "mode": "ingress", 1262 "target": 5004, 1263 "published": 5004, 1264 "protocol": "tcp" 1265 }, 1266 { 1267 "mode": "ingress", 1268 "target": 5005, 1269 "published": 5005, 1270 "protocol": "tcp" 1271 }, 1272 { 1273 "mode": "ingress", 1274 "target": 5006, 1275 "published": 5006, 1276 "protocol": "tcp" 1277 }, 1278 { 1279 "mode": "ingress", 1280 "target": 5007, 1281 "published": 5007, 1282 "protocol": "tcp" 1283 }, 1284 { 1285 "mode": "ingress", 1286 "target": 5008, 1287 "published": 5008, 1288 "protocol": "tcp" 1289 }, 1290 { 1291 "mode": "ingress", 1292 "target": 5009, 1293 "published": 5009, 1294 "protocol": "tcp" 1295 }, 1296 { 1297 "mode": "ingress", 1298 "target": 5010, 1299 "published": 5010, 1300 "protocol": "tcp" 1301 } 1302 ], 1303 "privileged": true, 1304 "read_only": true, 1305 "restart": "always", 1306 "secrets": [ 1307 { 1308 "source": "secret1" 1309 }, 1310 { 1311 "source": "secret2", 1312 "target": "my_secret", 1313 "uid": "103", 1314 "gid": "103", 1315 "mode": 288 1316 } 1317 ], 1318 "security_opt": [ 1319 "label=level:s0:c100,c200", 1320 "label=type:svirt_apache_t" 1321 ], 1322 "stdin_open": true, 1323 "stop_grace_period": "20s", 1324 "stop_signal": "SIGUSR1", 1325 "tmpfs": [ 1326 "/run", 1327 "/tmp" 1328 ], 1329 "tty": true, 1330 "ulimits": { 1331 "nofile": { 1332 "soft": 20000, 1333 "hard": 40000 1334 }, 1335 "nproc": 65535 1336 }, 1337 "user": "someone", 1338 "volumes": [ 1339 { 1340 "type": "volume", 1341 "target": "/var/lib/mysql" 1342 }, 1343 { 1344 "type": "bind", 1345 "source": "/opt/data", 1346 "target": "/var/lib/mysql" 1347 }, 1348 { 1349 "type": "bind", 1350 "source": "/foo", 1351 "target": "/code" 1352 }, 1353 { 1354 "type": "bind", 1355 "source": "%s", 1356 "target": "/var/www/html" 1357 }, 1358 { 1359 "type": "bind", 1360 "source": "/bar/configs", 1361 "target": "/etc/configs/", 1362 "read_only": true 1363 }, 1364 { 1365 "type": "volume", 1366 "source": "datavolume", 1367 "target": "/var/lib/mysql" 1368 }, 1369 { 1370 "type": "bind", 1371 "source": "%s", 1372 "target": "/opt", 1373 "consistency": "cached" 1374 }, 1375 { 1376 "type": "tmpfs", 1377 "target": "/opt", 1378 "tmpfs": { 1379 "size": 10000 1380 } 1381 } 1382 ], 1383 "working_dir": "/code" 1384 } 1385 }, 1386 "version": "3.7", 1387 "volumes": { 1388 "another-volume": { 1389 "name": "user_specified_name", 1390 "driver": "vsphere", 1391 "driver_opts": { 1392 "baz": "1", 1393 "foo": "bar" 1394 }, 1395 "external": false 1396 }, 1397 "external-volume": { 1398 "name": "external-volume", 1399 "external": true 1400 }, 1401 "external-volume3": { 1402 "name": "this-is-volume3", 1403 "external": true 1404 }, 1405 "other-external-volume": { 1406 "name": "my-cool-volume", 1407 "external": true 1408 }, 1409 "other-volume": { 1410 "driver": "flocker", 1411 "driver_opts": { 1412 "baz": "1", 1413 "foo": "bar" 1414 }, 1415 "external": false, 1416 "labels": { 1417 "foo": "bar" 1418 } 1419 }, 1420 "some-volume": { 1421 "external": false 1422 } 1423 }, 1424 "x-bar": "baz", 1425 "x-foo": "bar", 1426 "x-nested": { 1427 "bar": "baz", 1428 "foo": "bar" 1429 } 1430 }`, 1431 workingDir, 1432 workingDir, 1433 workingDir, 1434 workingDir, 1435 filepath.Join(workingDir, "static"), 1436 filepath.Join(workingDir, "opt")) 1437 }