From 99ad13e374434aecaac2d2c1bed5838b7ce384ee Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 6 Dec 2019 14:05:33 +0100 Subject: [PATCH] Remove experimental "deploy" from "dab" files The top-level `docker deploy` command (using the "Docker Application Bundle" (`.dab`) file format was introduced as an experimental feature in Docker 1.13 / 17.03, but superseded by support for Docker Compose files. With no development being done on this feature, and no active use of the file format, support for the DAB file format and the top-level `docker deploy` command (hidden by default in 19.03), is removed in this patch, in favour of `docker stack deploy` using compose files. Signed-off-by: Sebastiaan van Stijn --- cli/command/bundlefile/bundlefile.go | 70 ------ cli/command/bundlefile/bundlefile_test.go | 78 ------- cli/command/commands/commands.go | 1 - cli/command/stack/cmd.go | 12 -- cli/command/stack/deploy.go | 24 --- cli/command/stack/loader/loader.go | 2 +- cli/command/stack/options/opts.go | 1 - cli/command/stack/swarm/deploy_bundlefile.go | 124 ----------- .../stack/swarm/deploy_bundlefile_test.go | 50 ----- .../testdata/bundlefile_with_two_services.dab | 29 --- contrib/completion/bash/docker | 12 +- contrib/completion/zsh/_docker | 1 - docs/reference/commandline/deploy.md | 111 ---------- docs/reference/commandline/stack_deploy.md | 33 +-- .../testdata/stack-deploy-help-swarm.golden | 1 - experimental/README.md | 3 - experimental/docker-stacks-and-bundles.md | 202 ------------------ 17 files changed, 4 insertions(+), 750 deletions(-) delete mode 100644 cli/command/bundlefile/bundlefile.go delete mode 100644 cli/command/bundlefile/bundlefile_test.go delete mode 100644 cli/command/stack/swarm/deploy_bundlefile.go delete mode 100644 cli/command/stack/swarm/deploy_bundlefile_test.go delete mode 100644 cli/command/stack/swarm/testdata/bundlefile_with_two_services.dab delete mode 100644 docs/reference/commandline/deploy.md delete mode 100644 experimental/docker-stacks-and-bundles.md 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" - } - } -} -```