diff --git a/cli/command/bundlefile/bundlefile.go b/cli/command/bundlefile/bundlefile.go deleted file mode 100644 index 07e2c8b081..0000000000 --- a/cli/command/bundlefile/bundlefile.go +++ /dev/null @@ -1,70 +0,0 @@ -package bundlefile - -import ( - "encoding/json" - "io" - - "github.com/pkg/errors" -) - -// Bundlefile stores the contents of a bundlefile -type Bundlefile struct { - Version string - Services map[string]Service -} - -// Service is a service from a bundlefile -type Service struct { - Image string - Command []string `json:",omitempty"` - Args []string `json:",omitempty"` - Env []string `json:",omitempty"` - Labels map[string]string `json:",omitempty"` - Ports []Port `json:",omitempty"` - WorkingDir *string `json:",omitempty"` - User *string `json:",omitempty"` - Networks []string `json:",omitempty"` -} - -// Port is a port as defined in a bundlefile -type Port struct { - Protocol string - Port uint32 -} - -// LoadFile loads a bundlefile from a path to the file -func LoadFile(reader io.Reader) (*Bundlefile, error) { - bundlefile := &Bundlefile{} - - decoder := json.NewDecoder(reader) - if err := decoder.Decode(bundlefile); err != nil { - switch jsonErr := err.(type) { - case *json.SyntaxError: - return nil, errors.Errorf( - "JSON syntax error at byte %v: %s", - jsonErr.Offset, - jsonErr.Error()) - case *json.UnmarshalTypeError: - return nil, errors.Errorf( - "Unexpected type at byte %v. Expected %s but received %s.", - jsonErr.Offset, - jsonErr.Type, - jsonErr.Value) - } - return nil, err - } - - return bundlefile, nil -} - -// Print writes the contents of the bundlefile to the output writer -// as human readable json -func Print(out io.Writer, bundle *Bundlefile) error { - bytes, err := json.MarshalIndent(*bundle, "", " ") - if err != nil { - return err - } - - _, err = out.Write(bytes) - return err -} diff --git a/cli/command/bundlefile/bundlefile_test.go b/cli/command/bundlefile/bundlefile_test.go deleted file mode 100644 index cbaa341cd7..0000000000 --- a/cli/command/bundlefile/bundlefile_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package bundlefile - -import ( - "bytes" - "strings" - "testing" - - "gotest.tools/assert" - is "gotest.tools/assert/cmp" -) - -func TestLoadFileV01Success(t *testing.T) { - reader := strings.NewReader(`{ - "Version": "0.1", - "Services": { - "redis": { - "Image": "redis@sha256:4b24131101fa0117bcaa18ac37055fffd9176aa1a240392bb8ea85e0be50f2ce", - "Networks": ["default"] - }, - "web": { - "Image": "dockercloud/hello-world@sha256:fe79a2cfbd17eefc344fb8419420808df95a1e22d93b7f621a7399fd1e9dca1d", - "Networks": ["default"], - "User": "web" - } - } - }`) - - bundle, err := LoadFile(reader) - assert.NilError(t, err) - assert.Check(t, is.Equal("0.1", bundle.Version)) - assert.Check(t, is.Len(bundle.Services, 2)) -} - -func TestLoadFileSyntaxError(t *testing.T) { - reader := strings.NewReader(`{ - "Version": "0.1", - "Services": unquoted string - }`) - - _, err := LoadFile(reader) - assert.Error(t, err, "JSON syntax error at byte 37: invalid character 'u' looking for beginning of value") -} - -func TestLoadFileTypeError(t *testing.T) { - reader := strings.NewReader(`{ - "Version": "0.1", - "Services": { - "web": { - "Image": "redis", - "Networks": "none" - } - } - }`) - - _, err := LoadFile(reader) - assert.Error(t, err, "Unexpected type at byte 94. Expected []string but received string.") -} - -func TestPrint(t *testing.T) { - var buffer bytes.Buffer - bundle := &Bundlefile{ - Version: "0.1", - Services: map[string]Service{ - "web": { - Image: "image", - Command: []string{"echo", "something"}, - }, - }, - } - assert.Check(t, Print(&buffer, bundle)) - output := buffer.String() - assert.Check(t, is.Contains(output, "\"Image\": \"image\"")) - assert.Check(t, is.Contains(output, - `"Command": [ - "echo", - "something" - ]`)) -} diff --git a/cli/command/commands/commands.go b/cli/command/commands/commands.go index c72b386d2e..8cb5edd655 100644 --- a/cli/command/commands/commands.go +++ b/cli/command/commands/commands.go @@ -90,7 +90,6 @@ func AddCommands(cmd *cobra.Command, dockerCli command.Cli) { context.NewContextCommand(dockerCli), // legacy commands may be hidden - hide(stack.NewTopLevelDeployCommand(dockerCli)), hide(system.NewEventsCommand(dockerCli)), hide(system.NewInfoCommand(dockerCli)), hide(system.NewInspectCommand(dockerCli)), diff --git a/cli/command/stack/cmd.go b/cli/command/stack/cmd.go index 080732f56b..f4ded77169 100644 --- a/cli/command/stack/cmd.go +++ b/cli/command/stack/cmd.go @@ -73,18 +73,6 @@ func NewStackCommand(dockerCli command.Cli) *cobra.Command { return cmd } -// NewTopLevelDeployCommand returns a command for `docker deploy` -func NewTopLevelDeployCommand(dockerCli command.Cli) *cobra.Command { - cmd := newDeployCommand(dockerCli, nil) - // Remove the aliases at the top level - cmd.Aliases = []string{} - cmd.Annotations = map[string]string{ - "experimental": "", - "version": "1.25", - } - return cmd -} - func getOrchestrator(dockerCli command.Cli, cmd *cobra.Command) (command.Orchestrator, error) { var orchestratorFlag string if o, err := cmd.Flags().GetString("orchestrator"); err == nil { diff --git a/cli/command/stack/deploy.go b/cli/command/stack/deploy.go index 8007572747..8dd31f4193 100644 --- a/cli/command/stack/deploy.go +++ b/cli/command/stack/deploy.go @@ -1,8 +1,6 @@ package stack import ( - "context" - "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/stack/kubernetes" @@ -10,7 +8,6 @@ import ( "github.com/docker/cli/cli/command/stack/options" "github.com/docker/cli/cli/command/stack/swarm" composetypes "github.com/docker/cli/cli/compose/types" - "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -28,24 +25,6 @@ func newDeployCommand(dockerCli command.Cli, common *commonOptions) *cobra.Comma if err := validateStackName(opts.Namespace); err != nil { return err } - - commonOrchestrator := command.OrchestratorSwarm // default for top-level deploy command - if common != nil { - commonOrchestrator = common.orchestrator - } - - switch { - case opts.Bundlefile == "" && len(opts.Composefiles) == 0: - return errors.Errorf("Please specify either a bundle file (with --bundle-file) or a Compose file (with --compose-file).") - case opts.Bundlefile != "" && len(opts.Composefiles) != 0: - return errors.Errorf("You cannot specify both a bundle file and a Compose file.") - case opts.Bundlefile != "": - if commonOrchestrator != command.OrchestratorSwarm { - return errors.Errorf("bundle files are not supported on another orchestrator than swarm.") - } - return swarm.DeployBundle(context.Background(), dockerCli, opts) - } - config, err := loader.LoadComposefile(dockerCli, opts) if err != nil { return err @@ -55,9 +34,6 @@ func newDeployCommand(dockerCli command.Cli, common *commonOptions) *cobra.Comma } flags := cmd.Flags() - flags.StringVar(&opts.Bundlefile, "bundle-file", "", "Path to a Distributed Application Bundle file") - flags.SetAnnotation("bundle-file", "experimental", nil) - flags.SetAnnotation("bundle-file", "swarm", nil) flags.StringSliceVarP(&opts.Composefiles, "compose-file", "c", []string{}, `Path to a Compose file, or "-" to read from stdin`) flags.SetAnnotation("compose-file", "version", []string{"1.25"}) flags.BoolVar(&opts.SendRegistryAuth, "with-registry-auth", false, "Send registry authentication details to Swarm agents") diff --git a/cli/command/stack/loader/loader.go b/cli/command/stack/loader/loader.go index b479094512..c4333965fa 100644 --- a/cli/command/stack/loader/loader.go +++ b/cli/command/stack/loader/loader.go @@ -72,7 +72,7 @@ func getConfigDetails(composefiles []string, stdin io.Reader) (composetypes.Conf var details composetypes.ConfigDetails if len(composefiles) == 0 { - return details, errors.New("no composefile(s)") + return details, errors.New("Please specify a Compose file (with --compose-file)") } if composefiles[0] == "-" && len(composefiles) == 1 { diff --git a/cli/command/stack/options/opts.go b/cli/command/stack/options/opts.go index afcecd9961..fb45dc4558 100644 --- a/cli/command/stack/options/opts.go +++ b/cli/command/stack/options/opts.go @@ -4,7 +4,6 @@ import "github.com/docker/cli/opts" // Deploy holds docker stack deploy options type Deploy struct { - Bundlefile string Composefiles []string Namespace string ResolveImage string diff --git a/cli/command/stack/swarm/deploy_bundlefile.go b/cli/command/stack/swarm/deploy_bundlefile.go deleted file mode 100644 index 8db6f66b0e..0000000000 --- a/cli/command/stack/swarm/deploy_bundlefile.go +++ /dev/null @@ -1,124 +0,0 @@ -package swarm - -import ( - "context" - "fmt" - "io" - "os" - - "github.com/docker/cli/cli/command" - "github.com/docker/cli/cli/command/bundlefile" - "github.com/docker/cli/cli/command/stack/options" - "github.com/docker/cli/cli/compose/convert" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/swarm" - "github.com/pkg/errors" -) - -// DeployBundle deploy a bundlefile (dab) on a swarm. -func DeployBundle(ctx context.Context, dockerCli command.Cli, opts options.Deploy) error { - bundle, err := loadBundlefile(dockerCli.Err(), opts.Namespace, opts.Bundlefile) - if err != nil { - return err - } - - if err := checkDaemonIsSwarmManager(ctx, dockerCli); err != nil { - return err - } - - namespace := convert.NewNamespace(opts.Namespace) - - if opts.Prune { - services := map[string]struct{}{} - for service := range bundle.Services { - services[service] = struct{}{} - } - pruneServices(ctx, dockerCli, namespace, services) - } - - networks := make(map[string]types.NetworkCreate) - for _, service := range bundle.Services { - for _, networkName := range service.Networks { - networks[namespace.Scope(networkName)] = types.NetworkCreate{ - Labels: convert.AddStackLabel(namespace, nil), - } - } - } - - services := make(map[string]swarm.ServiceSpec) - for internalName, service := range bundle.Services { - name := namespace.Scope(internalName) - - var ports []swarm.PortConfig - for _, portSpec := range service.Ports { - ports = append(ports, swarm.PortConfig{ - Protocol: swarm.PortConfigProtocol(portSpec.Protocol), - TargetPort: portSpec.Port, - }) - } - - nets := []swarm.NetworkAttachmentConfig{} - for _, networkName := range service.Networks { - nets = append(nets, swarm.NetworkAttachmentConfig{ - Target: namespace.Scope(networkName), - Aliases: []string{internalName}, - }) - } - - serviceSpec := swarm.ServiceSpec{ - Annotations: swarm.Annotations{ - Name: name, - Labels: convert.AddStackLabel(namespace, service.Labels), - }, - TaskTemplate: swarm.TaskSpec{ - ContainerSpec: &swarm.ContainerSpec{ - Image: service.Image, - Command: service.Command, - Args: service.Args, - Env: service.Env, - // Service Labels will not be copied to Containers - // automatically during the deployment so we apply - // it here. - Labels: convert.AddStackLabel(namespace, nil), - }, - }, - EndpointSpec: &swarm.EndpointSpec{ - Ports: ports, - }, - Networks: nets, - } - - services[internalName] = serviceSpec - } - - if err := createNetworks(ctx, dockerCli, namespace, networks); err != nil { - return err - } - return deployServices(ctx, dockerCli, services, namespace, opts.SendRegistryAuth, opts.ResolveImage) -} - -func loadBundlefile(stderr io.Writer, namespace string, path string) (*bundlefile.Bundlefile, error) { - defaultPath := fmt.Sprintf("%s.dab", namespace) - - if path == "" { - path = defaultPath - } - if _, err := os.Stat(path); err != nil { - return nil, errors.Errorf( - "Bundle %s not found. Specify the path with --file", - path) - } - - fmt.Fprintf(stderr, "Loading bundle from %s\n", path) - reader, err := os.Open(path) - if err != nil { - return nil, err - } - defer reader.Close() - - bundle, err := bundlefile.LoadFile(reader) - if err != nil { - return nil, errors.Errorf("Error reading %s: %v\n", path, err) - } - return bundle, err -} diff --git a/cli/command/stack/swarm/deploy_bundlefile_test.go b/cli/command/stack/swarm/deploy_bundlefile_test.go deleted file mode 100644 index 485271cbc9..0000000000 --- a/cli/command/stack/swarm/deploy_bundlefile_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package swarm - -import ( - "bytes" - "path/filepath" - "testing" - - "gotest.tools/assert" - is "gotest.tools/assert/cmp" -) - -func TestLoadBundlefileErrors(t *testing.T) { - testCases := []struct { - namespace string - path string - expectedError string - }{ - { - namespace: "namespace_foo", - expectedError: "Bundle namespace_foo.dab not found", - }, - { - namespace: "namespace_foo", - path: "invalid_path", - expectedError: "Bundle invalid_path not found", - }, - // FIXME: this test never working, testdata file is missing from repo - //{ - // namespace: "namespace_foo", - // path: string(golden.Get(t, "bundlefile_with_invalid_syntax")), - // expectedError: "Error reading", - //}, - } - - for _, tc := range testCases { - _, err := loadBundlefile(&bytes.Buffer{}, tc.namespace, tc.path) - assert.ErrorContains(t, err, tc.expectedError) - } -} - -func TestLoadBundlefile(t *testing.T) { - buf := new(bytes.Buffer) - - namespace := "" - path := filepath.Join("testdata", "bundlefile_with_two_services.dab") - bundleFile, err := loadBundlefile(buf, namespace, path) - - assert.NilError(t, err) - assert.Check(t, is.Equal(len(bundleFile.Services), 2)) -} diff --git a/cli/command/stack/swarm/testdata/bundlefile_with_two_services.dab b/cli/command/stack/swarm/testdata/bundlefile_with_two_services.dab deleted file mode 100644 index ced8180dc0..0000000000 --- a/cli/command/stack/swarm/testdata/bundlefile_with_two_services.dab +++ /dev/null @@ -1,29 +0,0 @@ -{ - "Services": { - "visualizer": { - "Image": "busybox@sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f", - "Networks": [ - "webnet" - ], - "Ports": [ - { - "Port": 8080, - "Protocol": "tcp" - } - ] - }, - "web": { - "Image": "busybox@sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f", - "Networks": [ - "webnet" - ], - "Ports": [ - { - "Port": 80, - "Protocol": "tcp" - } - ] - } - }, - "Version": "0.1" -} diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index a1f8246a2c..c44d6b3eb1 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -2695,10 +2695,6 @@ _docker_daemon() { esac } -_docker_deploy() { - __docker_server_is_experimental && _docker_stack_deploy -} - _docker_diff() { _docker_container_diff } @@ -4878,10 +4874,6 @@ _docker_stack_deploy() { __docker_complete_stack_orchestrator_options && return case "$prev" in - --bundle-file) - _filedir dab - return - ;; --compose-file|-c) _filedir yml return @@ -4895,13 +4887,12 @@ _docker_stack_deploy() { case "$cur" in -*) local options="--compose-file -c --help --orchestrator" - __docker_server_is_experimental && __docker_stack_orchestrator_is swarm && options+=" --bundle-file" __docker_stack_orchestrator_is kubernetes && options+=" --kubeconfig --namespace" __docker_stack_orchestrator_is swarm && options+=" --prune --resolve-image --with-registry-auth" COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) ;; *) - local counter=$(__docker_pos_first_nonflag '--bundle-file|--compose-file|-c|--kubeconfig|--namespace|--orchestrator|--resolve-image') + local counter=$(__docker_pos_first_nonflag '--compose-file|-c|--kubeconfig|--namespace|--orchestrator|--resolve-image') if [ "$cword" -eq "$counter" ]; then __docker_complete_stacks fi @@ -5531,7 +5522,6 @@ _docker() { local experimental_server_commands=( checkpoint - deploy ) local commands=(${management_commands[*]} ${top_level_commands[*]}) diff --git a/contrib/completion/zsh/_docker b/contrib/completion/zsh/_docker index 512bfbc83f..79e11e3bde 100644 --- a/contrib/completion/zsh/_docker +++ b/contrib/completion/zsh/_docker @@ -2216,7 +2216,6 @@ __docker_stack_subcommand() { (deploy|up) _arguments $(__docker_arguments) \ $opts_help \ - "($help)--bundle-file=[Path to a Distributed Application Bundle file]:dab:_files -g \"*.dab\"" \ "($help -c --compose-file)"{-c=,--compose-file=}"[Path to a Compose file, or '-' to read from stdin]:compose file:_files -g \"*.(yml|yaml)\"" \ "($help)--with-registry-auth[Send registry authentication details to Swarm agents]" \ "($help -):stack:__docker_complete_stacks" && ret=0 diff --git a/docs/reference/commandline/deploy.md b/docs/reference/commandline/deploy.md deleted file mode 100644 index e31a3858c6..0000000000 --- a/docs/reference/commandline/deploy.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: "deploy" -description: "The deploy command description and usage" -keywords: "stack, deploy" -advisory: "experimental" ---- - - - -# deploy (experimental) - -An alias for `stack deploy`. - -```markdown -Usage: docker deploy [OPTIONS] STACK - -Deploy a new stack or update an existing stack - -Aliases: - deploy, up - -Options: - --bundle-file string Path to a Distributed Application Bundle file - --compose-file string Path to a Compose file, or "-" to read from stdin - --help Print usage - --prune Prune services that are no longer referenced - --with-registry-auth Send registry authentication details to Swarm agents -``` - -## Description - -Create and update a stack from a `compose` or a `dab` file on the swarm. This command -has to be run targeting a manager node. - -## Examples - -### Compose file - -The `deploy` command supports compose file version `3.0` and above. - -```bash -$ docker stack deploy --compose-file docker-compose.yml vossibility - -Ignoring unsupported options: links - -Creating network vossibility_vossibility -Creating network vossibility_default -Creating service vossibility_nsqd -Creating service vossibility_logstash -Creating service vossibility_elasticsearch -Creating service vossibility_kibana -Creating service vossibility_ghollector -Creating service vossibility_lookupd -``` - -You can verify that the services were correctly created - -```bash -$ docker service ls - -ID NAME MODE REPLICAS IMAGE -29bv0vnlm903 vossibility_lookupd replicated 1/1 nsqio/nsq@sha256:eeba05599f31eba418e96e71e0984c3dc96963ceb66924dd37a47bf7ce18a662 -4awt47624qwh vossibility_nsqd replicated 1/1 nsqio/nsq@sha256:eeba05599f31eba418e96e71e0984c3dc96963ceb66924dd37a47bf7ce18a662 -4tjx9biia6fs vossibility_elasticsearch replicated 1/1 elasticsearch@sha256:12ac7c6af55d001f71800b83ba91a04f716e58d82e748fa6e5a7359eed2301aa -7563uuzr9eys vossibility_kibana replicated 1/1 kibana@sha256:6995a2d25709a62694a937b8a529ff36da92ebee74bafd7bf00e6caf6db2eb03 -9gc5m4met4he vossibility_logstash replicated 1/1 logstash@sha256:2dc8bddd1bb4a5a34e8ebaf73749f6413c101b2edef6617f2f7713926d2141fe -axqh55ipl40h vossibility_vossibility-collector replicated 1/1 icecrime/vossibility-collector@sha256:f03f2977203ba6253988c18d04061c5ec7aab46bca9dfd89a9a1fa4500989fba -``` - -### DAB file - -```bash -$ docker stack deploy --bundle-file vossibility-stack.dab vossibility - -Loading bundle from vossibility-stack.dab -Creating service vossibility_elasticsearch -Creating service vossibility_kibana -Creating service vossibility_logstash -Creating service vossibility_lookupd -Creating service vossibility_nsqd -Creating service vossibility_vossibility-collector -``` - -You can verify that the services were correctly created: - -```bash -$ docker service ls - -ID NAME MODE REPLICAS IMAGE -29bv0vnlm903 vossibility_lookupd replicated 1/1 nsqio/nsq@sha256:eeba05599f31eba418e96e71e0984c3dc96963ceb66924dd37a47bf7ce18a662 -4awt47624qwh vossibility_nsqd replicated 1/1 nsqio/nsq@sha256:eeba05599f31eba418e96e71e0984c3dc96963ceb66924dd37a47bf7ce18a662 -4tjx9biia6fs vossibility_elasticsearch replicated 1/1 elasticsearch@sha256:12ac7c6af55d001f71800b83ba91a04f716e58d82e748fa6e5a7359eed2301aa -7563uuzr9eys vossibility_kibana replicated 1/1 kibana@sha256:6995a2d25709a62694a937b8a529ff36da92ebee74bafd7bf00e6caf6db2eb03 -9gc5m4met4he vossibility_logstash replicated 1/1 logstash@sha256:2dc8bddd1bb4a5a34e8ebaf73749f6413c101b2edef6617f2f7713926d2141fe -axqh55ipl40h vossibility_vossibility-collector replicated 1/1 icecrime/vossibility-collector@sha256:f03f2977203ba6253988c18d04061c5ec7aab46bca9dfd89a9a1fa4500989fba -``` - -## Related commands - -* [stack deploy](stack_deploy.md) -* [stack ls](stack_ls.md) -* [stack ps](stack_ps.md) -* [stack rm](stack_rm.md) -* [stack services](stack_services.md) diff --git a/docs/reference/commandline/stack_deploy.md b/docs/reference/commandline/stack_deploy.md index 9542973aeb..334d5cfb5a 100644 --- a/docs/reference/commandline/stack_deploy.md +++ b/docs/reference/commandline/stack_deploy.md @@ -24,7 +24,6 @@ Aliases: deploy, up Options: - --bundle-file string Path to a Distributed Application Bundle file -c, --compose-file strings Path to a Compose file, or "-" to read from stdin --help Print usage --kubeconfig string Kubernetes config file @@ -38,8 +37,8 @@ Options: ## Description -Create and update a stack from a `compose` or a `dab` file on the swarm. This command -has to be run targeting a manager node. +Create and update a stack from a `compose` file on the swarm. This command has to +be run targeting a manager node. ## Examples @@ -112,34 +111,6 @@ ID NAME MODE REPLICAS IMAGE axqh55ipl40h vossibility_vossibility-collector replicated 1/1 icecrime/vossibility-collector@sha256:f03f2977203ba6253988c18d04061c5ec7aab46bca9dfd89a9a1fa4500989fba ``` -### DAB file - -```bash -$ docker stack deploy --bundle-file vossibility-stack.dab vossibility - -Loading bundle from vossibility-stack.dab -Creating service vossibility_elasticsearch -Creating service vossibility_kibana -Creating service vossibility_logstash -Creating service vossibility_lookupd -Creating service vossibility_nsqd -Creating service vossibility_vossibility-collector -``` - -You can verify that the services were correctly created: - -```bash -$ docker service ls - -ID NAME MODE REPLICAS IMAGE -29bv0vnlm903 vossibility_lookupd replicated 1/1 nsqio/nsq@sha256:eeba05599f31eba418e96e71e0984c3dc96963ceb66924dd37a47bf7ce18a662 -4awt47624qwh vossibility_nsqd replicated 1/1 nsqio/nsq@sha256:eeba05599f31eba418e96e71e0984c3dc96963ceb66924dd37a47bf7ce18a662 -4tjx9biia6fs vossibility_elasticsearch replicated 1/1 elasticsearch@sha256:12ac7c6af55d001f71800b83ba91a04f716e58d82e748fa6e5a7359eed2301aa -7563uuzr9eys vossibility_kibana replicated 1/1 kibana@sha256:6995a2d25709a62694a937b8a529ff36da92ebee74bafd7bf00e6caf6db2eb03 -9gc5m4met4he vossibility_logstash replicated 1/1 logstash@sha256:2dc8bddd1bb4a5a34e8ebaf73749f6413c101b2edef6617f2f7713926d2141fe -axqh55ipl40h vossibility_vossibility-collector replicated 1/1 icecrime/vossibility-collector@sha256:f03f2977203ba6253988c18d04061c5ec7aab46bca9dfd89a9a1fa4500989fba -``` - ## Related commands * [stack ls](stack_ls.md) diff --git a/e2e/stack/testdata/stack-deploy-help-swarm.golden b/e2e/stack/testdata/stack-deploy-help-swarm.golden index 5532dc0152..19ee3676d0 100644 --- a/e2e/stack/testdata/stack-deploy-help-swarm.golden +++ b/e2e/stack/testdata/stack-deploy-help-swarm.golden @@ -7,7 +7,6 @@ Aliases: deploy, up Options: - --bundle-file string Path to a Distributed Application Bundle file -c, --compose-file strings Path to a Compose file, or "-" to read from stdin --orchestrator string Orchestrator to use (swarm|kubernetes|all) diff --git a/experimental/README.md b/experimental/README.md index 63e676e3f7..4995483ce5 100644 --- a/experimental/README.md +++ b/experimental/README.md @@ -38,11 +38,8 @@ Option to squash image layers to the base image after successful builds. Checkpoint and restore support for Containers. Metrics (Prometheus) output for basic container, image, and daemon operations. - * The top-level [docker deploy](../docs/reference/commandline/deploy.md) command. The - `docker stack deploy` command is **not** experimental. * [External graphdriver plugins](../docs/extend/plugins_graphdriver.md) * [Ipvlan Network Drivers](vlan-networks.md) - * [Distributed Application Bundles](docker-stacks-and-bundles.md) * [Checkpoint & Restore](checkpoint-restore.md) * [Docker build with --squash argument](../docs/reference/commandline/build.md#squash-an-images-layers---squash-experimental-only) diff --git a/experimental/docker-stacks-and-bundles.md b/experimental/docker-stacks-and-bundles.md deleted file mode 100644 index 1271af67e0..0000000000 --- a/experimental/docker-stacks-and-bundles.md +++ /dev/null @@ -1,202 +0,0 @@ -# Docker Stacks and Distributed Application Bundles - -## Overview - -Docker Stacks and Distributed Application Bundles are experimental features -introduced in Docker 1.12 and Docker Compose 1.8, alongside the concept of -swarm mode, and Nodes and Services in the Engine API. - -A Dockerfile can be built into an image, and containers can be created from -that image. Similarly, a docker-compose.yml can be built into a **distributed -application bundle**, and **stacks** can be created from that bundle. In that -sense, the bundle is a multi-services distributable image format. - -As of Docker 1.12 and Compose 1.8, the features are experimental. Neither -Docker Engine nor the Docker Registry supports distribution of bundles. - -## Producing a bundle - -The easiest way to produce a bundle is to generate it using `docker-compose` -from an existing `docker-compose.yml`. Of course, that's just *one* possible way -to proceed, in the same way that `docker build` isn't the only way to produce a -Docker image. - -From `docker-compose`: - -```bash -$ docker-compose bundle -WARNING: Unsupported key 'network_mode' in services.nsqd - ignoring -WARNING: Unsupported key 'links' in services.nsqd - ignoring -WARNING: Unsupported key 'volumes' in services.nsqd - ignoring -[...] -Wrote bundle to vossibility-stack.dab -``` - -## Creating a stack from a bundle - -A stack is created using the `docker deploy` command: - -```bash -$ docker deploy --help -Usage: docker deploy [OPTIONS] STACK - -Deploy a new stack or update an existing stack - -Aliases: - deploy, up - -Options: - --bundle-file string Path to a Distributed Application Bundle file - -c, --compose-file string Path to a Compose file - --help Print usage - --with-registry-auth Send registry authentication details to Swarm agents - -``` - -Let's deploy the stack created before: - -```bash -$ docker deploy --bundle-file vossibility-stack.dab vossibility-stack -Loading bundle from vossibility-stack.dab -Creating service vossibility-stack_elasticsearch -Creating service vossibility-stack_kibana -Creating service vossibility-stack_logstash -Creating service vossibility-stack_lookupd -Creating service vossibility-stack_nsqd -Creating service vossibility-stack_vossibility-collector -``` - -We can verify that services were correctly created: - -```bash -$ docker service ls -ID NAME MODE REPLICAS IMAGE -29bv0vnlm903 vossibility-stack_lookupd replicated 1/1 nsqio/nsq@sha256:eeba05599f31eba418e96e71e0984c3dc96963ceb66924dd37a47bf7ce18a662 -4awt47624qwh vossibility-stack_nsqd replicated 1/1 nsqio/nsq@sha256:eeba05599f31eba418e96e71e0984c3dc96963ceb66924dd37a47bf7ce18a662 -4tjx9biia6fs vossibility-stack_elasticsearch replicated 1/1 elasticsearch@sha256:12ac7c6af55d001f71800b83ba91a04f716e58d82e748fa6e5a7359eed2301aa -7563uuzr9eys vossibility-stack_kibana replicated 1/1 kibana@sha256:6995a2d25709a62694a937b8a529ff36da92ebee74bafd7bf00e6caf6db2eb03 -9gc5m4met4he vossibility-stack_logstash replicated 1/1 logstash@sha256:2dc8bddd1bb4a5a34e8ebaf73749f6413c101b2edef6617f2f7713926d2141fe -axqh55ipl40h vossibility-stack_vossibility-collector replicated 1/1 icecrime/vossibility-collector@sha256:f03f2977203ba6253988c18d04061c5ec7aab46bca9dfd89a9a1fa4500989fba -``` - -## Managing stacks - -Stacks are managed using the `docker stack` command: - -```bash -# docker stack --help - -Usage: docker stack COMMAND - -Manage Docker stacks - -Options: - --help Print usage - -Commands: - deploy Deploy a new stack or update an existing stack - ls List stacks - ps List the tasks in the stack - rm Remove the stack - services List the services in the stack - -Run 'docker stack COMMAND --help' for more information on a command. -``` - -## Bundle file format - -Distributed application bundles are described in a JSON format. When bundles -are persisted as files, the file extension is `.dab` (Docker 1.12RC2 tools use -`.dsb` for the file extension—this will be updated in the next release client). - -A bundle has two top-level fields: `version` and `services`. The version used -by Docker 1.12 and later tools is `0.1`. - -`services` in the bundle are the services that comprise the app. They -correspond to the new `Service` object introduced in the 1.12 Docker Engine API. - -A service has the following fields: - -
-
- Image (required) string -
-
- The image that the service will run. Docker images should be referenced - with full content hash to fully specify the deployment artifact for the - service. Example: - postgres@sha256:f76245b04ddbcebab5bb6c28e76947f49222c99fec4aadb0bb - 1c24821a 9e83ef -
-
- Command []string -
-
- Command to run in service containers. -
-
- Args []string -
-
- Arguments passed to the service containers. -
-
- Env []string -
-
- Environment variables. -
-
- Labels map[string]string -
-
- Labels used for setting meta data on services. -
-
- Ports []Port -
-
- Service ports (composed of Port (int) and - Protocol (string). A service description can - only specify the container port to be exposed. These ports can be - mapped on runtime hosts at the operator's discretion. -
-
- WorkingDir string -
-
- Working directory inside the service containers. -
-
- User string -
-
- Username or UID (format: <name|uid>[:<group|gid>]). -
-
- Networks []string -
-
- Networks that the service containers should be connected to. An entity - deploying a bundle should create networks as needed. -
-
- -The following is an example of bundlefile with two services: - -```json -{ - "Version": "0.1", - "Services": { - "redis": { - "Image": "redis@sha256:4b24131101fa0117bcaa18ac37055fffd9176aa1a240392bb8ea85e0be50f2ce", - "Networks": ["default"] - }, - "web": { - "Image": "dockercloud/hello-world@sha256:fe79a2cfbd17eefc344fb8419420808df95a1e22d93b7f621a7399fd1e9dca1d", - "Networks": ["default"], - "User": "web" - } - } -} -```