Skip to content

Commit 0ef488c

Browse files
ericcurtinqwencoder
andcommitted
docs: add deploy command documentation
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
1 parent 55721c4 commit 0ef488c

9 files changed

Lines changed: 292 additions & 3 deletions

File tree

cmd/compose/deploy.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package compose
1818

1919
import (
2020
"context"
21+
"fmt"
2122
"time"
2223

2324
"github.com/docker/cli/cli/command"
@@ -54,6 +55,15 @@ pulled from the registry unless --build is specified.
5455
5556
Use health checks defined in the Compose file to ensure zero-downtime
5657
deployments by passing --wait.`,
58+
PreRunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
59+
if opts.waitTimeout < 0 {
60+
return fmt.Errorf("--wait-timeout must be a non-negative integer")
61+
}
62+
if opts.build && opts.noBuild {
63+
return fmt.Errorf("--build and --no-build are incompatible")
64+
}
65+
return nil
66+
}),
5767
RunE: Adapt(func(ctx context.Context, args []string) error {
5868
return runDeploy(ctx, dockerCli, backendOptions, opts, args)
5969
}),
@@ -86,6 +96,7 @@ func runDeploy(ctx context.Context, dockerCli command.Cli, backendOptions *Backe
8696
Quiet: opts.quiet,
8797
RemoveOrphans: opts.removeOrphans,
8898
Wait: opts.wait,
99+
Services: services,
89100
}
90101

91102
if opts.waitTimeout > 0 {

docs/reference/compose.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Define and run multi-container applications with Docker
1919
| [`config`](compose_config.md) | Parse, resolve and render compose file in canonical format |
2020
| [`cp`](compose_cp.md) | Copy files/folders between a service container and the local filesystem |
2121
| [`create`](compose_create.md) | Creates containers for a service |
22+
| [`deploy`](compose_deploy.md) | Deploy a Compose application to a Docker server |
2223
| [`down`](compose_down.md) | Stop and remove containers, networks |
2324
| [`events`](compose_events.md) | Receive real time events from containers |
2425
| [`exec`](compose_exec.md) | Execute a command in a running container |

docs/reference/compose_deploy.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# docker compose deploy
2+
3+
<!---MARKER_GEN_START-->
4+
Deploy a Compose application to a Docker server.
5+
6+
This command applies the Compose project to the target Docker server,
7+
recreating containers with updated configuration and images. Images are
8+
pulled from the registry unless --build is specified.
9+
10+
Use health checks defined in the Compose file to ensure zero-downtime
11+
deployments by passing --wait.
12+
13+
### Options
14+
15+
| Name | Type | Default | Description |
16+
|:-------------------|:-------|:--------|:--------------------------------------------------------------------------------|
17+
| `--build` | `bool` | | Build images before deploying |
18+
| `--dry-run` | `bool` | | Execute command in dry run mode |
19+
| `--no-build` | `bool` | | Do not build images even if build configuration is defined |
20+
| `--push` | `bool` | | Push images to registry before deploying |
21+
| `-q`, `--quiet` | `bool` | | Suppress pull/push progress output |
22+
| `--remove-orphans` | `bool` | | Remove containers for services not defined in the Compose file |
23+
| `--wait` | `bool` | | Wait for services to be healthy before returning |
24+
| `--wait-timeout` | `int` | `0` | Maximum duration in seconds to wait for services to be healthy (0 = no timeout) |
25+
26+
27+
<!---MARKER_GEN_END-->
28+

docs/reference/docker_compose.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ cname:
1212
- docker compose config
1313
- docker compose cp
1414
- docker compose create
15+
- docker compose deploy
1516
- docker compose down
1617
- docker compose events
1718
- docker compose exec
@@ -48,6 +49,7 @@ clink:
4849
- docker_compose_config.yaml
4950
- docker_compose_cp.yaml
5051
- docker_compose_create.yaml
52+
- docker_compose_deploy.yaml
5153
- docker_compose_down.yaml
5254
- docker_compose_events.yaml
5355
- docker_compose_exec.yaml
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
command: docker compose deploy
2+
short: Deploy a Compose application to a Docker server
3+
long: |-
4+
Deploy a Compose application to a Docker server.
5+
6+
This command applies the Compose project to the target Docker server,
7+
recreating containers with updated configuration and images. Images are
8+
pulled from the registry unless --build is specified.
9+
10+
Use health checks defined in the Compose file to ensure zero-downtime
11+
deployments by passing --wait.
12+
usage: docker compose deploy [OPTIONS] [SERVICE...]
13+
pname: docker compose
14+
plink: docker_compose.yaml
15+
options:
16+
- option: build
17+
value_type: bool
18+
default_value: "false"
19+
description: Build images before deploying
20+
deprecated: false
21+
hidden: false
22+
experimental: false
23+
experimentalcli: false
24+
kubernetes: false
25+
swarm: false
26+
- option: no-build
27+
value_type: bool
28+
default_value: "false"
29+
description: Do not build images even if build configuration is defined
30+
deprecated: false
31+
hidden: false
32+
experimental: false
33+
experimentalcli: false
34+
kubernetes: false
35+
swarm: false
36+
- option: push
37+
value_type: bool
38+
default_value: "false"
39+
description: Push images to registry before deploying
40+
deprecated: false
41+
hidden: false
42+
experimental: false
43+
experimentalcli: false
44+
kubernetes: false
45+
swarm: false
46+
- option: quiet
47+
shorthand: q
48+
value_type: bool
49+
default_value: "false"
50+
description: Suppress pull/push progress output
51+
deprecated: false
52+
hidden: false
53+
experimental: false
54+
experimentalcli: false
55+
kubernetes: false
56+
swarm: false
57+
- option: remove-orphans
58+
value_type: bool
59+
default_value: "false"
60+
description: Remove containers for services not defined in the Compose file
61+
deprecated: false
62+
hidden: false
63+
experimental: false
64+
experimentalcli: false
65+
kubernetes: false
66+
swarm: false
67+
- option: wait
68+
value_type: bool
69+
default_value: "false"
70+
description: Wait for services to be healthy before returning
71+
deprecated: false
72+
hidden: false
73+
experimental: false
74+
experimentalcli: false
75+
kubernetes: false
76+
swarm: false
77+
- option: wait-timeout
78+
value_type: int
79+
default_value: "0"
80+
description: |
81+
Maximum duration in seconds to wait for services to be healthy (0 = no timeout)
82+
deprecated: false
83+
hidden: false
84+
experimental: false
85+
experimentalcli: false
86+
kubernetes: false
87+
swarm: false
88+
inherited_options:
89+
- option: dry-run
90+
value_type: bool
91+
default_value: "false"
92+
description: Execute command in dry run mode
93+
deprecated: false
94+
hidden: false
95+
experimental: false
96+
experimentalcli: false
97+
kubernetes: false
98+
swarm: false
99+
deprecated: false
100+
hidden: false
101+
experimental: false
102+
experimentalcli: false
103+
kubernetes: false
104+
swarm: false
105+

pkg/api/api.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ type DeployOptions struct {
163163
Quiet bool
164164
// RemoveOrphans removes containers for services not defined in the project
165165
RemoveOrphans bool
166+
// Services is the list of services to deploy (defaults to all)
167+
Services []string
166168
// Wait waits for services to be healthy after deploy
167169
Wait bool
168170
// WaitTimeout is the maximum time to wait for services to become healthy

pkg/compose/deploy.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,16 @@ func (s *composeService) Deploy(ctx context.Context, project *types.Project, opt
4141

4242
return s.Up(ctx, project, api.UpOptions{
4343
Create: api.CreateOptions{
44-
Recreate: api.RecreateForce,
45-
RemoveOrphans: options.RemoveOrphans,
46-
QuietPull: options.Quiet,
44+
Services: options.Services,
45+
Recreate: api.RecreateForce,
46+
RecreateDependencies: api.RecreateForce,
47+
RemoveOrphans: options.RemoveOrphans,
48+
Inherit: true,
49+
QuietPull: options.Quiet,
4750
},
4851
Start: api.StartOptions{
52+
Project: project,
53+
Services: options.Services,
4954
Wait: options.Wait,
5055
WaitTimeout: options.WaitTimeout,
5156
},

pkg/e2e/deploy_test.go

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
//go:build !windows
2+
3+
/*
4+
Copyright 2020 Docker Compose CLI authors
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package e2e
20+
21+
import (
22+
"strings"
23+
"testing"
24+
"time"
25+
26+
"gotest.tools/v3/assert"
27+
)
28+
29+
func TestDeploy(t *testing.T) {
30+
c := NewParallelCLI(t)
31+
const projectName = "e2e-deploy"
32+
33+
reset := func() {
34+
c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "-v", "--remove-orphans")
35+
}
36+
reset()
37+
t.Cleanup(reset)
38+
39+
t.Log("Deploy the application")
40+
c.RunDockerComposeCmd(t, "-f", "fixtures/deploy/compose.yaml", "--project-name", projectName, "deploy", "-d")
41+
42+
t.Log("Verify service is running")
43+
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "ps", "--format", "json")
44+
output := res.Stdout()
45+
assert.Assert(t, strings.Contains(output, "running"), "Expected service to be running, got: %s", output)
46+
}
47+
48+
func TestDeployWait(t *testing.T) {
49+
c := NewParallelCLI(t)
50+
const projectName = "e2e-deploy-wait"
51+
52+
reset := func() {
53+
c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "-v", "--remove-orphans")
54+
}
55+
reset()
56+
t.Cleanup(reset)
57+
58+
t.Log("Deploy the application with --wait")
59+
timeout := time.After(30 * time.Second)
60+
done := make(chan bool)
61+
go func() {
62+
res := c.RunDockerComposeCmd(t, "-f", "fixtures/deploy/compose.yaml", "--project-name", projectName, "deploy", "--wait")
63+
assert.Assert(t, strings.Contains(res.Combined(), projectName), "Expected project name in output")
64+
done <- true
65+
}()
66+
67+
select {
68+
case <-timeout:
69+
t.Fatal("deploy --wait did not complete in time")
70+
case <-done:
71+
break
72+
}
73+
74+
t.Log("Verify service is healthy")
75+
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "ps", "--format", "json")
76+
output := res.Stdout()
77+
assert.Assert(t, strings.Contains(output, "running"), "Expected service to be running, got: %s", output)
78+
}
79+
80+
func TestDeployBuild(t *testing.T) {
81+
c := NewParallelCLI(t)
82+
const projectName = "e2e-deploy-build"
83+
84+
reset := func() {
85+
c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "-v", "--remove-orphans")
86+
}
87+
reset()
88+
t.Cleanup(reset)
89+
90+
t.Log("Deploy the application with --build")
91+
c.RunDockerComposeCmd(t, "-f", "fixtures/deploy/compose.yaml", "--project-name", projectName, "deploy", "--build", "-d")
92+
93+
t.Log("Verify service is running")
94+
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "ps", "--format", "json")
95+
output := res.Stdout()
96+
assert.Assert(t, strings.Contains(output, "running"), "Expected service to be running, got: %s", output)
97+
}
98+
99+
func TestDeployRemoveOrphans(t *testing.T) {
100+
c := NewParallelCLI(t)
101+
const projectName = "e2e-deploy-orphans"
102+
103+
reset := func() {
104+
c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "-v", "--remove-orphans")
105+
}
106+
reset()
107+
t.Cleanup(reset)
108+
109+
t.Log("Deploy the application")
110+
c.RunDockerComposeCmd(t, "-f", "fixtures/deploy/compose.yaml", "--project-name", projectName, "deploy", "-d")
111+
112+
t.Log("Verify service is running")
113+
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "ps", "--format", "json")
114+
output := res.Stdout()
115+
assert.Assert(t, strings.Contains(output, "running"), "Expected service to be running, got: %s", output)
116+
117+
t.Log("Deploy with --remove-orphans")
118+
c.RunDockerComposeCmd(t, "-f", "fixtures/deploy/compose.yaml", "--project-name", projectName, "deploy", "--remove-orphans", "-d")
119+
120+
t.Log("Verify service is still running")
121+
res = c.RunDockerComposeCmd(t, "--project-name", projectName, "ps", "--format", "json")
122+
output = res.Stdout()
123+
assert.Assert(t, strings.Contains(output, "running"), "Expected service to be running, got: %s", output)
124+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
services:
2+
web:
3+
image: nginx:alpine
4+
ports:
5+
- "8080:80"
6+
healthcheck:
7+
test: ["CMD", "curl", "-f", "http://localhost/"]
8+
interval: 1s
9+
timeout: 3s
10+
retries: 3
11+
start_period: 2s

0 commit comments

Comments
 (0)