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