mirror of
https://github.com/docker/compose.git
synced 2026-02-14 20:49:24 +08:00
Compare commits
337 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b5a4588f9 | ||
|
|
00f72cb553 | ||
|
|
fd7847f2ac | ||
|
|
18a112e88c | ||
|
|
dc01b98aa6 | ||
|
|
312f0d1d61 | ||
|
|
e8caad1903 | ||
|
|
fca454b41f | ||
|
|
77dc9b54f3 | ||
|
|
bceb3c1876 | ||
|
|
a14abb9044 | ||
|
|
0363d9260a | ||
|
|
0e375a8c61 | ||
|
|
b776826d92 | ||
|
|
3b32a264c7 | ||
|
|
e92c5d1392 | ||
|
|
0c1a691fa5 | ||
|
|
f72d5d6099 | ||
|
|
ee70085fba | ||
|
|
90bcf610b3 | ||
|
|
2d25019fe9 | ||
|
|
fb16e49cb2 | ||
|
|
109ce190c4 | ||
|
|
ef03c906b9 | ||
|
|
865a0867a4 | ||
|
|
6ee0376bb6 | ||
|
|
67455e9f33 | ||
|
|
5fdcaa0fe1 | ||
|
|
01afe5265e | ||
|
|
2e4faf80f5 | ||
|
|
e88836ffbd | ||
|
|
b45ca82791 | ||
|
|
d1c36c6e6b | ||
|
|
b304c4e154 | ||
|
|
eca1365d42 | ||
|
|
03f4c0e631 | ||
|
|
2a0e83ad9a | ||
|
|
2df9919ece | ||
|
|
74fc40d895 | ||
|
|
d54a95fed7 | ||
|
|
c1369869f5 | ||
|
|
f5ff40a2f3 | ||
|
|
6347b49f9c | ||
|
|
c072a6f5f5 | ||
|
|
a06d32e7b6 | ||
|
|
28fa309c23 | ||
|
|
4f2c933f78 | ||
|
|
e22c8964b9 | ||
|
|
07c4849cb9 | ||
|
|
e606701d9f | ||
|
|
114e5c6425 | ||
|
|
37dfb5bf26 | ||
|
|
d01ef5887a | ||
|
|
dec608f3cd | ||
|
|
eb0632b1d8 | ||
|
|
1383ab09ec | ||
|
|
5eaafe4237 | ||
|
|
7840a92c40 | ||
|
|
3751c3074b | ||
|
|
2bc6a45c0b | ||
|
|
2268d1e573 | ||
|
|
7b0ed13209 | ||
|
|
d4441efe1e | ||
|
|
58368f69e9 | ||
|
|
bc2b2e52e5 | ||
|
|
7723d11930 | ||
|
|
65fda18821 | ||
|
|
0e7e1b940b | ||
|
|
af6f0ffb9e | ||
|
|
9ef173a3ac | ||
|
|
1fb0c03e8b | ||
|
|
1892be8c70 | ||
|
|
37068a700f | ||
|
|
a4af5e229d | ||
|
|
87da6c1470 | ||
|
|
a99acd940a | ||
|
|
7fb87856aa | ||
|
|
eb933adde0 | ||
|
|
cb688b5fd4 | ||
|
|
8b5b78fbb6 | ||
|
|
d3e49fe360 | ||
|
|
1bca8d5c01 | ||
|
|
76d9cf2711 | ||
|
|
d762f5f473 | ||
|
|
90eda35f3d | ||
|
|
7ce0096f40 | ||
|
|
00eca0af70 | ||
|
|
a10c4c6df5 | ||
|
|
6a37428491 | ||
|
|
449a46a252 | ||
|
|
981cb2024e | ||
|
|
b83edbd039 | ||
|
|
02ad467f89 | ||
|
|
d9e1d419c1 | ||
|
|
a4c324b8e6 | ||
|
|
087fae98b6 | ||
|
|
aafeaa66e2 | ||
|
|
c5317496ac | ||
|
|
67c9ecb4f4 | ||
|
|
72a61c0602 | ||
|
|
0b6133f75b | ||
|
|
b24af42bcc | ||
|
|
cc70851bc8 | ||
|
|
3b85cd2fa9 | ||
|
|
d818bf6f34 | ||
|
|
45a852f438 | ||
|
|
f0bf4fca76 | ||
|
|
cd17c8a950 | ||
|
|
36625ed229 | ||
|
|
a6ffdf6110 | ||
|
|
72260d615d | ||
|
|
fd28ab8d38 | ||
|
|
9ab5d8c44e | ||
|
|
d637cc3ade | ||
|
|
925bc6fbf3 | ||
|
|
16d5354d70 | ||
|
|
7aaea283ca | ||
|
|
6bedc196cc | ||
|
|
a11515e038 | ||
|
|
6c1f06e420 | ||
|
|
88b0d17ff8 | ||
|
|
9e19bc8441 | ||
|
|
bef9c48a1a | ||
|
|
105a7c5b70 | ||
|
|
03f0ed132d | ||
|
|
f7a13aee11 | ||
|
|
bfeb1dc277 | ||
|
|
9ec43973e2 | ||
|
|
0b41df9821 | ||
|
|
643557d534 | ||
|
|
200f47e5be | ||
|
|
e0aaccf430 | ||
|
|
754c06886f | ||
|
|
e492330dd5 | ||
|
|
bbe1b77a67 | ||
|
|
fc4d2dfdd8 | ||
|
|
85ddfde5d6 | ||
|
|
6a0398d786 | ||
|
|
4434cea535 | ||
|
|
62fbf20887 | ||
|
|
3f7d3c2661 | ||
|
|
9cc1613b55 | ||
|
|
c4b47fe911 | ||
|
|
167c6a89b1 | ||
|
|
a84345be8f | ||
|
|
3cfbac6624 | ||
|
|
a3bed265f2 | ||
|
|
ae26426cc8 | ||
|
|
4ea44797f5 | ||
|
|
a99a0b50ef | ||
|
|
af414e9e2c | ||
|
|
89633748d2 | ||
|
|
f648c2949b | ||
|
|
33aa6acefe | ||
|
|
e31b95c16d | ||
|
|
d4f156cc7d | ||
|
|
c0daf8d3b5 | ||
|
|
7bb60d091c | ||
|
|
da1ca578b5 | ||
|
|
267cde91df | ||
|
|
18af72af87 | ||
|
|
e831ea826b | ||
|
|
8d56db5e1d | ||
|
|
1edc64ef93 | ||
|
|
156e54a09e | ||
|
|
762cf9d998 | ||
|
|
f3e543fd6a | ||
|
|
9732608ec2 | ||
|
|
24ff098252 | ||
|
|
593c4263f3 | ||
|
|
313b82e94c | ||
|
|
5e3e2171d4 | ||
|
|
9ac0392baf | ||
|
|
0612b34c68 | ||
|
|
92e0cd4047 | ||
|
|
1a410ffe30 | ||
|
|
282a29e67e | ||
|
|
256ec49974 | ||
|
|
9765f171cd | ||
|
|
b19df5c96c | ||
|
|
7a42ba7eec | ||
|
|
5b043c4d59 | ||
|
|
d93da187f2 | ||
|
|
15f7104cd3 | ||
|
|
eb1c798912 | ||
|
|
78b9404767 | ||
|
|
25be264ed8 | ||
|
|
e6e2f7839f | ||
|
|
7532f76986 | ||
|
|
70ab9f8f33 | ||
|
|
7daa2a5325 | ||
|
|
93bffd9a7f | ||
|
|
9a4e74c70c | ||
|
|
52478f0c6e | ||
|
|
b5f0a4eefa | ||
|
|
e908f41ec8 | ||
|
|
0f5b5ccbd0 | ||
|
|
a2d36b6c6c | ||
|
|
b3ec110612 | ||
|
|
3077234292 | ||
|
|
23585b9e6d | ||
|
|
fdc1738143 | ||
|
|
2336d9fe35 | ||
|
|
bf0ed9a4d4 | ||
|
|
1640f155e9 | ||
|
|
e63cbfba0e | ||
|
|
25576289c8 | ||
|
|
7d6ee74e62 | ||
|
|
c08e07714a | ||
|
|
cf31462398 | ||
|
|
1b71e3efb3 | ||
|
|
4d822676ce | ||
|
|
6fc0b6ff27 | ||
|
|
ab84b6ac5b | ||
|
|
7161778ccf | ||
|
|
1f5bfe8882 | ||
|
|
f79c75ab10 | ||
|
|
e62993a854 | ||
|
|
28251e8be5 | ||
|
|
c7ba7d9de5 | ||
|
|
8b39322365 | ||
|
|
b3615d64e2 | ||
|
|
1a1d1707ed | ||
|
|
fd3e0bbe2b | ||
|
|
d2d4d05264 | ||
|
|
dda0362b6e | ||
|
|
ddc88ec41b | ||
|
|
92c6a65a03 | ||
|
|
00b3caecbb | ||
|
|
17087447e9 | ||
|
|
ec781687fd | ||
|
|
b22dde9f18 | ||
|
|
a31350ede1 | ||
|
|
d744c97f13 | ||
|
|
37647bc600 | ||
|
|
21e5d564af | ||
|
|
390d5cf165 | ||
|
|
7f6e189dbc | ||
|
|
b5ccea7b0e | ||
|
|
47551895f3 | ||
|
|
5e0f1eec16 | ||
|
|
f82e2de57e | ||
|
|
9c7f7bc0fa | ||
|
|
6defe7cac6 | ||
|
|
0482f9276a | ||
|
|
e8a34c8d1e | ||
|
|
9e261c18b3 | ||
|
|
1fd7ca5440 | ||
|
|
139edc403f | ||
|
|
38b3f3b678 | ||
|
|
c5bce8bd42 | ||
|
|
c8a358a455 | ||
|
|
a6701652d2 | ||
|
|
4562b0bf95 | ||
|
|
4801d2b1a4 | ||
|
|
3850a34114 | ||
|
|
664e6f6f23 | ||
|
|
d4f074b32f | ||
|
|
a3b012d89f | ||
|
|
a755c84ea0 | ||
|
|
ef34a38ac0 | ||
|
|
f24d3458c6 | ||
|
|
41e056341b | ||
|
|
a54d488303 | ||
|
|
c0b4dd8606 | ||
|
|
6754c6b68a | ||
|
|
a93f09efac | ||
|
|
bbf3ec1999 | ||
|
|
51bcfa37bd | ||
|
|
982a8ccb88 | ||
|
|
790712fa92 | ||
|
|
97752b23e8 | ||
|
|
69c0a583be | ||
|
|
8bb9a3336d | ||
|
|
634a7d2a7b | ||
|
|
cf12239547 | ||
|
|
a288332fbd | ||
|
|
9d53ed8f63 | ||
|
|
df70735295 | ||
|
|
d8bf175cd4 | ||
|
|
4816f40b90 | ||
|
|
ed5a2e83c7 | ||
|
|
fa8d075d88 | ||
|
|
33c3f4dfad | ||
|
|
aa31387355 | ||
|
|
d47f0f31c2 | ||
|
|
ac8ab8634a | ||
|
|
4721c01702 | ||
|
|
5919fcb4cd | ||
|
|
4671e69a96 | ||
|
|
3a21e1e319 | ||
|
|
b670aefb94 | ||
|
|
d5d9f67547 | ||
|
|
a2899d5ff0 | ||
|
|
220626ec5e | ||
|
|
6c795d60bf | ||
|
|
291e1bd618 | ||
|
|
e94eb056b4 | ||
|
|
c15bf1955a | ||
|
|
0b1c86726e | ||
|
|
82ef998511 | ||
|
|
fb36f7fffd | ||
|
|
3fac506a30 | ||
|
|
eb59b0e265 | ||
|
|
5081ab0507 | ||
|
|
13ef440d6a | ||
|
|
fbf845c5f8 | ||
|
|
5a2b7b83cd | ||
|
|
8c07fa4d25 | ||
|
|
db267d86c1 | ||
|
|
9daf41892f | ||
|
|
2aa88b5c9e | ||
|
|
bb9cf32245 | ||
|
|
7212aaff2e | ||
|
|
69a09624c9 | ||
|
|
f2088bb917 | ||
|
|
dadad01e63 | ||
|
|
1adc9f54d5 | ||
|
|
4cebce3a5c | ||
|
|
bd8e57447a | ||
|
|
4ad87463c5 | ||
|
|
62b3e7409e | ||
|
|
cc912c625d | ||
|
|
cc7e69c02d | ||
|
|
3e12a7cb23 | ||
|
|
0c1979979f | ||
|
|
7e2af3aa81 | ||
|
|
dde7eea212 | ||
|
|
6fae6a41f9 | ||
|
|
dd5ea044bb | ||
|
|
12de97b8d1 | ||
|
|
62b5f78fd9 | ||
|
|
3f526c5c7b | ||
|
|
12916b75a2 | ||
|
|
e3948f6bae | ||
|
|
91a2bdd6de | ||
|
|
ce61e7bf18 |
25
.github/workflows/ci.yml
vendored
25
.github/workflows/ci.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
||||
name: Create matrix
|
||||
id: platforms
|
||||
run: |
|
||||
echo ::set-output name=matrix::$(docker buildx bake binary-cross --print | jq -cr '.target."binary-cross".platforms')
|
||||
echo matrix=$(docker buildx bake binary-cross --print | jq -cr '.target."binary-cross".platforms') >> $GITHUB_OUTPUT
|
||||
-
|
||||
name: Show matrix
|
||||
run: |
|
||||
@@ -123,6 +123,9 @@ jobs:
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=test
|
||||
*.cache-to=type=gha,scope=test
|
||||
-
|
||||
name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
|
||||
e2e:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -134,6 +137,7 @@ jobs:
|
||||
mode:
|
||||
- plugin
|
||||
- standalone
|
||||
- cucumber
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
@@ -157,7 +161,7 @@ jobs:
|
||||
name: Build
|
||||
uses: docker/bake-action@v2
|
||||
with:
|
||||
targets: binary
|
||||
targets: binary-with-coverage
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=binary-linux-amd64
|
||||
*.cache-from=type=gha,scope=binary-e2e-${{ matrix.mode }}
|
||||
@@ -175,10 +179,11 @@ jobs:
|
||||
name: Test plugin mode
|
||||
if: ${{ matrix.mode == 'plugin' }}
|
||||
run: |
|
||||
make e2e-compose
|
||||
-
|
||||
name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
rm -rf ./covdatafiles
|
||||
mkdir ./covdatafiles
|
||||
make e2e-compose GOCOVERDIR=covdatafiles
|
||||
go tool covdata textfmt -i=covdatafiles -o=coverage.out
|
||||
|
||||
-
|
||||
name: Test standalone mode
|
||||
if: ${{ matrix.mode == 'standalone' }}
|
||||
@@ -186,6 +191,14 @@ jobs:
|
||||
rm -f /usr/local/bin/docker-compose
|
||||
cp bin/build/docker-compose /usr/local/bin
|
||||
make e2e-compose-standalone
|
||||
-
|
||||
name: Run cucumber tests
|
||||
if: ${{ matrix.mode == 'cucumber'}}
|
||||
run: |
|
||||
make test-cucumber
|
||||
-
|
||||
name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
|
||||
release:
|
||||
permissions:
|
||||
|
||||
48
.github/workflows/merge.yml
vendored
48
.github/workflows/merge.yml
vendored
@@ -10,11 +10,13 @@ on:
|
||||
- 'v2'
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
env:
|
||||
REPO_SLUG: "docker/compose-bin"
|
||||
|
||||
jobs:
|
||||
e2e:
|
||||
name: Build and test
|
||||
@@ -72,3 +74,47 @@ jobs:
|
||||
run: |
|
||||
make e2e-compose-standalone
|
||||
|
||||
bin-image:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
-
|
||||
name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
${{ env.REPO_SLUG }}
|
||||
tags: |
|
||||
type=ref,event=tag
|
||||
type=edge
|
||||
bake-target: meta-helper
|
||||
-
|
||||
name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERPUBLICBOT_USERNAME }}
|
||||
password: ${{ secrets.DOCKERPUBLICBOT_WRITE_PAT }}
|
||||
-
|
||||
name: Build and push image
|
||||
uses: docker/bake-action@v2
|
||||
with:
|
||||
files: |
|
||||
./docker-bake.hcl
|
||||
${{ steps.meta.outputs.bake-file }}
|
||||
targets: image-cross
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=bin-image
|
||||
*.cache-to=type=gha,scope=bin-image,mode=max
|
||||
*.attest=type=sbom
|
||||
*.attest=type=provenance,mode=max,builder-id=https://github.com/${{ env.GITHUB_REPOSITORY }}/actions/runs/${{ env.GITHUB_RUN_ID }}
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
bin/
|
||||
/.vscode/
|
||||
coverage.out
|
||||
covdatafiles/
|
||||
.DS_Store
|
||||
|
||||
20
Dockerfile
20
Dockerfile
@@ -15,26 +15,31 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ARG GO_VERSION=1.19.4
|
||||
ARG XX_VERSION=1.1.2
|
||||
ARG GOLANGCI_LINT_VERSION=v1.49.0
|
||||
ARG GO_VERSION=1.20.4
|
||||
ARG XX_VERSION=1.2.1
|
||||
ARG GOLANGCI_LINT_VERSION=v1.52.2
|
||||
ARG ADDLICENSE_VERSION=v1.0.0
|
||||
|
||||
ARG BUILD_TAGS="e2e,kube"
|
||||
ARG BUILD_TAGS="e2e"
|
||||
ARG DOCS_FORMATS="md,yaml"
|
||||
ARG LICENSE_FILES=".*\(Dockerfile\|Makefile\|\.go\|\.hcl\|\.sh\)"
|
||||
|
||||
# xx is a helper for cross-compilation
|
||||
FROM --platform=${BUILDPLATFORM} tonistiigi/xx:${XX_VERSION} AS xx
|
||||
|
||||
# osxcross contains the MacOSX cross toolchain for xx
|
||||
FROM crazymax/osxcross:11.3-alpine AS osxcross
|
||||
|
||||
FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint
|
||||
FROM ghcr.io/google/addlicense:${ADDLICENSE_VERSION} AS addlicense
|
||||
|
||||
FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION}-alpine AS base
|
||||
COPY --from=xx / /
|
||||
RUN apk add --no-cache \
|
||||
clang \
|
||||
docker \
|
||||
file \
|
||||
findutils \
|
||||
git \
|
||||
make \
|
||||
protoc \
|
||||
@@ -71,11 +76,14 @@ EOT
|
||||
|
||||
FROM build-base AS build
|
||||
ARG BUILD_TAGS
|
||||
ARG BUILD_FLAGS
|
||||
ARG TARGETPLATFORM
|
||||
RUN xx-go --wrap
|
||||
RUN --mount=type=bind,target=. \
|
||||
--mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
--mount=type=bind,from=osxcross,src=/osxsdk,target=/xx-sdk \
|
||||
xx-go --wrap && \
|
||||
if [ "$(xx-info os)" == "darwin" ]; then export CGO_ENABLED=1; fi && \
|
||||
make build GO_BUILDTAGS="$BUILD_TAGS" DESTDIR=/usr/bin && \
|
||||
xx-verify --static /usr/bin/docker-compose
|
||||
|
||||
@@ -160,6 +168,8 @@ FROM binary-unix AS binary-linux
|
||||
FROM scratch AS binary-windows
|
||||
COPY --link --from=build /usr/bin/docker-compose /docker-compose.exe
|
||||
FROM binary-$TARGETOS AS binary
|
||||
# enable scanning for this stage
|
||||
ARG BUILDKIT_SBOM_SCAN_STAGE=true
|
||||
|
||||
FROM --platform=$BUILDPLATFORM alpine AS releaser
|
||||
WORKDIR /work
|
||||
|
||||
71
MAINTAINERS
71
MAINTAINERS
@@ -1,6 +1,6 @@
|
||||
# Docker maintainers file
|
||||
#
|
||||
# This file describes who runs the docker/compose-cli project and how.
|
||||
# This file describes who runs the docker/compose project and how.
|
||||
# This is a living document - if you see something out of date or missing, speak up!
|
||||
#
|
||||
# It is structured to be consumable by both humans and programs.
|
||||
@@ -22,13 +22,28 @@
|
||||
# subsystem maintainers accountable. If ownership is unclear, they are the de facto owners.
|
||||
|
||||
people = [
|
||||
"rumpl",
|
||||
"gtardif",
|
||||
"glours",
|
||||
"milas",
|
||||
"laurazard",
|
||||
"ndeloof",
|
||||
"chris-crone",
|
||||
"nicksieger",
|
||||
"StefanScherer",
|
||||
"ulyssessouza"
|
||||
]
|
||||
|
||||
[Org."Regular maintainers"]
|
||||
# The Regular maintainers are people who aren't Core maintainers but are around
|
||||
# to help reviewing and fixing bugs, just on a less regular basis than previously.
|
||||
# Most of them were previously Core maintainers of Compose.
|
||||
people = [
|
||||
"aiordache",
|
||||
"chris-crone",
|
||||
"gtardif",
|
||||
"maxcleme",
|
||||
"rumpl",
|
||||
"thaJeztah"
|
||||
]
|
||||
|
||||
[people]
|
||||
|
||||
# A reference list of all people associated with the project.
|
||||
@@ -37,16 +52,46 @@
|
||||
|
||||
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
|
||||
|
||||
[people.aiordache]
|
||||
Name = "Anca Iordache"
|
||||
Email = "anca.iordache@docker.com"
|
||||
GitHub = "aiordache "
|
||||
|
||||
[people.chris-crone]
|
||||
Name = "Christopher Crone"
|
||||
Email = "christopher.crone@docker.com"
|
||||
GitHub = "chris-crone"
|
||||
|
||||
[people.glours]
|
||||
Name = "Guillaume Lours"
|
||||
Email = "guillaume.lours@docker.com"
|
||||
GitHub = "glours"
|
||||
|
||||
[people.gtardif]
|
||||
Name = "Guillaume Tardif"
|
||||
Email = "guillaume.tardif@docker.com"
|
||||
GitHub = "gtardif"
|
||||
|
||||
[people.laurazard]
|
||||
Name = "Laura Brehm"
|
||||
Email = "laura.brehm@docker.com"
|
||||
GitHub = "laurazard"
|
||||
|
||||
[people.maxcleme]
|
||||
Name = "Maxime Clement"
|
||||
Email = "maxime.clement@docker.com"
|
||||
GitHub = "maxcleme"
|
||||
|
||||
[people.milas]
|
||||
Name = "Milas Bowman"
|
||||
Email = "milas.bowman@docker.com"
|
||||
GitHub = "milas"
|
||||
|
||||
[people.nicksieger]
|
||||
Name = "Nick Sieger"
|
||||
Email = "nick.sieger@docker.com"
|
||||
GitHub = "nicksieger"
|
||||
|
||||
[people.ndeloof]
|
||||
Name = "Nicolas Deloof"
|
||||
Email = "nicolas.deloof@docker.com"
|
||||
@@ -57,7 +102,17 @@
|
||||
Email = "djordje.lukic@docker.com"
|
||||
GitHub = "rumpl"
|
||||
|
||||
[people.ulyssessouza]
|
||||
Name = "Ulysses Souza"
|
||||
Email = "<ulysses.souza@docker.com"
|
||||
Github = "ulyssessouza"
|
||||
[people.thaJeztah]
|
||||
Name = "Sebastiaan van Stijn"
|
||||
Email = "sebastiaan.vanstijn@docker.com"
|
||||
GitHub = "thaJeztah "
|
||||
|
||||
[people.StefanScherer]
|
||||
Name = "Stefan Scherer"
|
||||
Email = "stefan.scherer@docker.com"
|
||||
GitHub = "StefanScherer"
|
||||
|
||||
[people.ulyssessouza]
|
||||
Name = "Ulysses Souza"
|
||||
Email = "<ulysses.souza@docker.com"
|
||||
Github = "ulyssessouza"
|
||||
|
||||
25
Makefile
25
Makefile
@@ -15,14 +15,15 @@
|
||||
PKG := github.com/docker/compose/v2
|
||||
VERSION ?= $(shell git describe --match 'v[0-9]*' --dirty='.m' --always --tags)
|
||||
|
||||
GO_LDFLAGS ?= -s -w -X ${PKG}/internal.Version=${VERSION}
|
||||
GO_BUILDTAGS ?= e2e,kube
|
||||
GO_LDFLAGS ?= -w -X ${PKG}/internal.Version=${VERSION}
|
||||
GO_BUILDTAGS ?= e2e
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
DETECTED_OS = Windows
|
||||
else
|
||||
DETECTED_OS = $(shell uname -s)
|
||||
endif
|
||||
|
||||
ifeq ($(DETECTED_OS),Linux)
|
||||
MOBY_DOCKER=/usr/bin/docker
|
||||
endif
|
||||
@@ -33,7 +34,13 @@ ifeq ($(DETECTED_OS),Windows)
|
||||
BINARY_EXT=.exe
|
||||
endif
|
||||
|
||||
TEST_COVERAGE_FLAGS = -race -coverprofile=coverage.out -covermode=atomic
|
||||
TEST_COVERAGE_FLAGS = -coverprofile=coverage.out -covermode=atomic
|
||||
ifneq ($(DETECTED_OS),Windows)
|
||||
# go race detector requires gcc on Windows so not used by default
|
||||
# https://github.com/golang/go/issues/27089
|
||||
TEST_COVERAGE_FLAGS += -race
|
||||
endif
|
||||
BUILD_FLAGS?=
|
||||
TEST_FLAGS?=
|
||||
E2E_TEST?=
|
||||
ifeq ($(E2E_TEST),)
|
||||
@@ -48,12 +55,16 @@ all: build
|
||||
|
||||
.PHONY: build ## Build the compose cli-plugin
|
||||
build:
|
||||
CGO_ENABLED=0 GO111MODULE=on go build -trimpath -tags "$(GO_BUILDTAGS)" -ldflags "$(GO_LDFLAGS)" -o "$(DESTDIR)/docker-compose$(BINARY_EXT)" ./cmd
|
||||
GO111MODULE=on go build $(BUILD_FLAGS) -trimpath -tags "$(GO_BUILDTAGS)" -ldflags "$(GO_LDFLAGS)" -o "$(DESTDIR)/docker-compose$(BINARY_EXT)" ./cmd
|
||||
|
||||
.PHONY: binary
|
||||
binary:
|
||||
$(BUILDX_CMD) bake binary
|
||||
|
||||
.PHONY: binary-with-coverage
|
||||
binary-with-coverage:
|
||||
$(BUILDX_CMD) bake binary-with-coverage
|
||||
|
||||
.PHONY: install
|
||||
install: binary
|
||||
mkdir -p ~/.docker/cli-plugins
|
||||
@@ -61,12 +72,16 @@ install: binary
|
||||
|
||||
.PHONY: e2e-compose
|
||||
e2e-compose: ## Run end to end local tests in plugin mode. Set E2E_TEST=TestName to run a single test
|
||||
go test $(TEST_FLAGS) $(TEST_COVERAGE_FLAGS) -count=1 ./pkg/e2e
|
||||
go test $(TEST_FLAGS) -count=1 ./pkg/e2e
|
||||
|
||||
.PHONY: e2e-compose-standalone
|
||||
e2e-compose-standalone: ## Run End to end local tests in standalone mode. Set E2E_TEST=TestName to run a single test
|
||||
go test $(TEST_FLAGS) -v -count=1 -parallel=1 --tags=standalone ./pkg/e2e
|
||||
|
||||
.PHONY: test-cucumber
|
||||
test-cucumber:
|
||||
go test $(TEST_FLAGS) -v -count=1 -parallel=1 ./e2e
|
||||
|
||||
.PHONY: build-and-e2e-compose
|
||||
build-and-e2e-compose: build e2e-compose ## Compile the compose cli-plugin and run end to end local tests in plugin mode. Set E2E_TEST=TestName to run a single test
|
||||
|
||||
|
||||
37
cmd/compose/alpha.go
Normal file
37
cmd/compose/alpha.go
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
|
||||
Copyright 2020 Docker Compose CLI authors
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compose
|
||||
|
||||
import (
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// alphaCommand groups all experimental subcommands
|
||||
func alphaCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Short: "Experimental commands",
|
||||
Use: "alpha [COMMAND]",
|
||||
Hidden: true,
|
||||
Annotations: map[string]string{
|
||||
"experimentalCLI": "true",
|
||||
},
|
||||
}
|
||||
cmd.AddCommand(
|
||||
watchCommand(p, backend),
|
||||
vizCommand(p, backend),
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/compose-spec/compose-go/loader"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
buildx "github.com/docker/buildx/util/progress"
|
||||
cliopts "github.com/docker/cli/opts"
|
||||
"github.com/docker/compose/v2/pkg/progress"
|
||||
"github.com/docker/compose/v2/pkg/utils"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -38,10 +39,11 @@ type buildOptions struct {
|
||||
composeOptions
|
||||
quiet bool
|
||||
pull bool
|
||||
push bool
|
||||
progress string
|
||||
args []string
|
||||
noCache bool
|
||||
memory string
|
||||
memory cliopts.MemBytes
|
||||
ssh string
|
||||
}
|
||||
|
||||
@@ -57,6 +59,7 @@ func (opts buildOptions) toAPIBuildOptions(services []string) (api.BuildOptions,
|
||||
|
||||
return api.BuildOptions{
|
||||
Pull: opts.pull,
|
||||
Push: opts.push,
|
||||
Progress: opts.progress,
|
||||
Args: types.NewMappingWithEquals(opts.args),
|
||||
NoCache: opts.noCache,
|
||||
@@ -73,7 +76,7 @@ var printerModes = []string{
|
||||
buildx.PrinterModeQuiet,
|
||||
}
|
||||
|
||||
func buildCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
|
||||
func buildCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
opts := buildOptions{
|
||||
ProjectOptions: p,
|
||||
}
|
||||
@@ -81,9 +84,6 @@ func buildCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *
|
||||
Use: "build [OPTIONS] [SERVICE...]",
|
||||
Short: "Build or rebuild services",
|
||||
PreRunE: Adapt(func(ctx context.Context, args []string) error {
|
||||
if opts.memory != "" {
|
||||
fmt.Fprintln(streams.Err(), "WARNING --memory is ignored as not supported in buildkit.")
|
||||
}
|
||||
if opts.quiet {
|
||||
opts.progress = buildx.PrinterModeQuiet
|
||||
devnull, err := os.Open(os.DevNull)
|
||||
@@ -108,6 +108,7 @@ func buildCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *
|
||||
}),
|
||||
ValidArgsFunction: completeServiceNames(p),
|
||||
}
|
||||
cmd.Flags().BoolVar(&opts.push, "push", false, "Push service images.")
|
||||
cmd.Flags().BoolVarP(&opts.quiet, "quiet", "q", false, "Don't print anything to STDOUT")
|
||||
cmd.Flags().BoolVar(&opts.pull, "pull", false, "Always attempt to pull a newer version of the image.")
|
||||
cmd.Flags().StringVar(&opts.progress, "progress", buildx.PrinterModeAuto, fmt.Sprintf(`Set type of progress output (%s)`, strings.Join(printerModes, ", ")))
|
||||
@@ -122,8 +123,7 @@ func buildCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *
|
||||
cmd.Flags().BoolVar(&opts.noCache, "no-cache", false, "Do not use cache when building the image")
|
||||
cmd.Flags().Bool("no-rm", false, "Do not remove intermediate containers after a successful build. DEPRECATED")
|
||||
cmd.Flags().MarkHidden("no-rm") //nolint:errcheck
|
||||
cmd.Flags().StringVarP(&opts.memory, "memory", "m", "", "Set memory limit for the build container. Not supported on buildkit yet.")
|
||||
cmd.Flags().MarkHidden("memory") //nolint:errcheck
|
||||
cmd.Flags().VarP(&opts.memory, "memory", "m", "Set memory limit for the build container. Not supported by BuildKit.")
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -138,5 +138,7 @@ func runBuild(ctx context.Context, backend api.Service, opts buildOptions, servi
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
apiBuildOptions.Memory = int64(opts.memory)
|
||||
return backend.Build(ctx, project, apiBuildOptions)
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
|
||||
"github.com/compose-spec/compose-go/cli"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
composegoutils "github.com/compose-spec/compose-go/utils"
|
||||
@@ -45,6 +47,19 @@ import (
|
||||
"github.com/docker/compose/v2/pkg/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
// ComposeParallelLimit set the limit running concurrent operation on docker engine
|
||||
ComposeParallelLimit = "COMPOSE_PARALLEL_LIMIT"
|
||||
// ComposeProjectName define the project name to be used, instead of guessing from parent directory
|
||||
ComposeProjectName = "COMPOSE_PROJECT_NAME"
|
||||
// ComposeCompatibility try to mimic compose v1 as much as possible
|
||||
ComposeCompatibility = "COMPOSE_COMPATIBILITY"
|
||||
// ComposeRemoveOrphans remove “orphaned" containers, i.e. containers tagged for current project but not declared as service
|
||||
ComposeRemoveOrphans = "COMPOSE_REMOVE_ORPHANS"
|
||||
// ComposeIgnoreOrphans ignore "orphaned" containers
|
||||
ComposeIgnoreOrphans = "COMPOSE_IGNORE_ORPHANS"
|
||||
)
|
||||
|
||||
// Command defines a compose CLI command as a func with args
|
||||
type Command func(context.Context, []string) error
|
||||
|
||||
@@ -97,7 +112,7 @@ type ProjectOptions struct {
|
||||
ConfigPaths []string
|
||||
WorkDir string
|
||||
ProjectDir string
|
||||
EnvFile string
|
||||
EnvFiles []string
|
||||
Compatibility bool
|
||||
}
|
||||
|
||||
@@ -117,7 +132,7 @@ func (o *ProjectOptions) WithProject(fn ProjectFunc) func(cmd *cobra.Command, ar
|
||||
// WithServices creates a cobra run command from a ProjectFunc based on configured project options and selected services
|
||||
func (o *ProjectOptions) WithServices(fn ProjectServicesFunc) func(cmd *cobra.Command, args []string) error {
|
||||
return Adapt(func(ctx context.Context, args []string) error {
|
||||
project, err := o.ToProject(args, cli.WithResolvedPaths(true))
|
||||
project, err := o.ToProject(args, cli.WithResolvedPaths(true), cli.WithDiscardEnvFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -130,7 +145,7 @@ func (o *ProjectOptions) addProjectFlags(f *pflag.FlagSet) {
|
||||
f.StringArrayVar(&o.Profiles, "profile", []string{}, "Specify a profile to enable")
|
||||
f.StringVarP(&o.ProjectName, "project-name", "p", "", "Project name")
|
||||
f.StringArrayVarP(&o.ConfigPaths, "file", "f", []string{}, "Compose configuration files")
|
||||
f.StringVar(&o.EnvFile, "env-file", "", "Specify an alternate environment file.")
|
||||
f.StringArrayVar(&o.EnvFiles, "env-file", nil, "Specify an alternate environment file.")
|
||||
f.StringVar(&o.ProjectDir, "project-directory", "", "Specify an alternate working directory\n(default: the path of the, first specified, Compose file)")
|
||||
f.StringVar(&o.WorkDir, "workdir", "", "DEPRECATED! USE --project-directory INSTEAD.\nSpecify an alternate working directory\n(default: the path of the, first specified, Compose file)")
|
||||
f.BoolVar(&o.Compatibility, "compatibility", false, "Run compose in backward compatibility mode")
|
||||
@@ -141,9 +156,9 @@ func (o *ProjectOptions) projectOrName(services ...string) (*types.Project, stri
|
||||
name := o.ProjectName
|
||||
var project *types.Project
|
||||
if len(o.ConfigPaths) > 0 || o.ProjectName == "" {
|
||||
p, err := o.ToProject(services)
|
||||
p, err := o.ToProject(services, cli.WithDiscardEnvFile)
|
||||
if err != nil {
|
||||
envProjectName := os.Getenv("COMPOSE_PROJECT_NAME")
|
||||
envProjectName := os.Getenv(ComposeProjectName)
|
||||
if envProjectName != "" {
|
||||
return nil, envProjectName, nil
|
||||
}
|
||||
@@ -160,7 +175,7 @@ func (o *ProjectOptions) toProjectName() (string, error) {
|
||||
return o.ProjectName, nil
|
||||
}
|
||||
|
||||
envProjectName := os.Getenv("COMPOSE_PROJECT_NAME")
|
||||
envProjectName := os.Getenv("ComposeProjectName")
|
||||
if envProjectName != "" {
|
||||
return envProjectName, nil
|
||||
}
|
||||
@@ -178,7 +193,7 @@ func (o *ProjectOptions) ToProject(services []string, po ...cli.ProjectOptionsFn
|
||||
return nil, compose.WrapComposeError(err)
|
||||
}
|
||||
|
||||
if o.Compatibility || utils.StringToBool(options.Environment["COMPOSE_COMPATIBILITY"]) {
|
||||
if o.Compatibility || utils.StringToBool(options.Environment[ComposeCompatibility]) {
|
||||
api.Separator = "_"
|
||||
}
|
||||
|
||||
@@ -187,6 +202,15 @@ func (o *ProjectOptions) ToProject(services []string, po ...cli.ProjectOptionsFn
|
||||
return nil, compose.WrapComposeError(err)
|
||||
}
|
||||
|
||||
if project.Name == "" {
|
||||
return nil, errors.New("project name can't be empty. Use `--project-name` to set a valid name")
|
||||
}
|
||||
|
||||
err = project.EnableServices(services...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, s := range project.Services {
|
||||
s.CustomLabels = map[string]string{
|
||||
api.ProjectLabel: project.Name,
|
||||
@@ -196,26 +220,12 @@ func (o *ProjectOptions) ToProject(services []string, po ...cli.ProjectOptionsFn
|
||||
api.ConfigFilesLabel: strings.Join(project.ComposeFiles, ","),
|
||||
api.OneoffLabel: "False", // default, will be overridden by `run` command
|
||||
}
|
||||
if o.EnvFile != "" {
|
||||
s.CustomLabels[api.EnvironmentFileLabel] = o.EnvFile
|
||||
if len(o.EnvFiles) != 0 {
|
||||
s.CustomLabels[api.EnvironmentFileLabel] = strings.Join(o.EnvFiles, ",")
|
||||
}
|
||||
project.Services[i] = s
|
||||
}
|
||||
|
||||
if profiles, ok := options.Environment["COMPOSE_PROFILES"]; ok && len(o.Profiles) == 0 {
|
||||
o.Profiles = append(o.Profiles, strings.Split(profiles, ",")...)
|
||||
}
|
||||
|
||||
if len(services) > 0 {
|
||||
s, err := project.GetServices(services...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
o.Profiles = append(o.Profiles, s.GetProfiles()...)
|
||||
}
|
||||
|
||||
project.ApplyProfiles(o.Profiles)
|
||||
|
||||
project.WithoutUnnecessaryResources()
|
||||
|
||||
err = project.ForServices(services)
|
||||
@@ -227,10 +237,11 @@ func (o *ProjectOptions) toProjectOptions(po ...cli.ProjectOptionsFn) (*cli.Proj
|
||||
append(po,
|
||||
cli.WithWorkingDirectory(o.ProjectDir),
|
||||
cli.WithOsEnv,
|
||||
cli.WithEnvFile(o.EnvFile),
|
||||
cli.WithEnvFiles(o.EnvFiles...),
|
||||
cli.WithDotEnv,
|
||||
cli.WithConfigFileEnv,
|
||||
cli.WithDefaultConfigPath,
|
||||
cli.WithProfiles(o.Profiles),
|
||||
cli.WithName(o.ProjectName))...)
|
||||
}
|
||||
|
||||
@@ -243,7 +254,7 @@ func RunningAsStandalone() bool {
|
||||
}
|
||||
|
||||
// RootCommand returns the compose command with its child commands
|
||||
func RootCommand(streams api.Streams, backend api.Service) *cobra.Command { //nolint:gocyclo
|
||||
func RootCommand(streams command.Cli, backend api.Service) *cobra.Command { //nolint:gocyclo
|
||||
// filter out useless commandConn.CloseWrite warning message that can occur
|
||||
// when using a remote context that is unreachable: "commandConn.CloseWrite: commandconn: failed to wait: signal: killed"
|
||||
// https://github.com/docker/cli/blob/e1f24d3c93df6752d3c27c8d61d18260f141310c/cli/connhelper/commandconn/commandconn.go#L203-L215
|
||||
@@ -261,9 +272,11 @@ func RootCommand(streams api.Streams, backend api.Service) *cobra.Command { //no
|
||||
verbose bool
|
||||
version bool
|
||||
parallel int
|
||||
dryRun bool
|
||||
)
|
||||
c := &cobra.Command{
|
||||
Short: "Docker Compose",
|
||||
Long: "Define and run multi-container applications with Docker.",
|
||||
Use: PluginName,
|
||||
TraverseChildren: true,
|
||||
// By default (no Run/RunE in parent c) for typos in subcommands, cobra displays the help of parent c but exit(0) !
|
||||
@@ -272,7 +285,7 @@ func RootCommand(streams api.Streams, backend api.Service) *cobra.Command { //no
|
||||
return cmd.Help()
|
||||
}
|
||||
if version {
|
||||
return versionCommand().Execute()
|
||||
return versionCommand(streams).Execute()
|
||||
}
|
||||
_ = cmd.Help()
|
||||
return dockercli.StatusError{
|
||||
@@ -305,11 +318,22 @@ func RootCommand(streams api.Streams, backend api.Service) *cobra.Command { //no
|
||||
if verbose {
|
||||
logrus.SetLevel(logrus.TraceLevel)
|
||||
}
|
||||
|
||||
if v, ok := os.LookupEnv("COMPOSE_ANSI"); ok && !cmd.Flags().Changed("ansi") {
|
||||
ansi = v
|
||||
}
|
||||
|
||||
formatter.SetANSIMode(streams, ansi)
|
||||
|
||||
if noColor, ok := os.LookupEnv("NO_COLOR"); ok && noColor != "" {
|
||||
progress.NoColor()
|
||||
formatter.SetANSIMode(streams, formatter.Never)
|
||||
}
|
||||
|
||||
switch ansi {
|
||||
case "never":
|
||||
progress.Mode = progress.ModePlain
|
||||
case "tty":
|
||||
case "always":
|
||||
progress.Mode = progress.ModeTTY
|
||||
}
|
||||
if opts.WorkDir != "" {
|
||||
@@ -319,22 +343,42 @@ func RootCommand(streams api.Streams, backend api.Service) *cobra.Command { //no
|
||||
opts.ProjectDir = opts.WorkDir
|
||||
fmt.Fprint(os.Stderr, aec.Apply("option '--workdir' is DEPRECATED at root level! Please use '--project-directory' instead.\n", aec.RedF))
|
||||
}
|
||||
if opts.EnvFile != "" && !filepath.IsAbs(opts.EnvFile) {
|
||||
opts.EnvFile, err = filepath.Abs(opts.EnvFile)
|
||||
if err != nil {
|
||||
return err
|
||||
for i, file := range opts.EnvFiles {
|
||||
if !filepath.IsAbs(file) {
|
||||
file, err = filepath.Abs(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts.EnvFiles[i] = file
|
||||
}
|
||||
}
|
||||
if v, ok := os.LookupEnv("COMPOSE_PARALLEL_LIMIT"); ok && !cmd.Flags().Changed("parallel") {
|
||||
|
||||
composeCmd := cmd
|
||||
for {
|
||||
if composeCmd.Name() == PluginName {
|
||||
break
|
||||
}
|
||||
if !composeCmd.HasParent() {
|
||||
return fmt.Errorf("error parsing command line, expected %q", PluginName)
|
||||
}
|
||||
composeCmd = composeCmd.Parent()
|
||||
}
|
||||
|
||||
if v, ok := os.LookupEnv(ComposeParallelLimit); ok && !composeCmd.Flags().Changed("parallel") {
|
||||
i, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("COMPOSE_PARALLEL_LIMIT must be an integer (found: %q)", v)
|
||||
return fmt.Errorf("%s must be an integer (found: %q)", ComposeParallelLimit, v)
|
||||
}
|
||||
parallel = i
|
||||
}
|
||||
if parallel > 0 {
|
||||
backend.MaxConcurrency(parallel)
|
||||
}
|
||||
ctx, err := backend.DryRunMode(cmd.Context(), dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.SetContext(ctx)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@@ -348,7 +392,7 @@ func RootCommand(streams api.Streams, backend api.Service) *cobra.Command { //no
|
||||
psCommand(&opts, streams, backend),
|
||||
listCommand(streams, backend),
|
||||
logsCommand(&opts, streams, backend),
|
||||
convertCommand(&opts, streams, backend),
|
||||
configCommand(&opts, streams, backend),
|
||||
killCommand(&opts, backend),
|
||||
runCommand(&opts, streams, backend),
|
||||
removeCommand(&opts, backend),
|
||||
@@ -359,13 +403,15 @@ func RootCommand(streams api.Streams, backend api.Service) *cobra.Command { //no
|
||||
eventsCommand(&opts, streams, backend),
|
||||
portCommand(&opts, streams, backend),
|
||||
imagesCommand(&opts, streams, backend),
|
||||
versionCommand(),
|
||||
buildCommand(&opts, streams, backend),
|
||||
versionCommand(streams),
|
||||
buildCommand(&opts, backend),
|
||||
pushCommand(&opts, backend),
|
||||
pullCommand(&opts, backend),
|
||||
createCommand(&opts, backend),
|
||||
copyCommand(&opts, backend),
|
||||
alphaCommand(&opts, backend),
|
||||
)
|
||||
|
||||
c.Flags().SetInterspersed(false)
|
||||
opts.addProjectFlags(c.Flags())
|
||||
c.RegisterFlagCompletionFunc( //nolint:errcheck
|
||||
@@ -382,6 +428,7 @@ func RootCommand(streams api.Streams, backend api.Service) *cobra.Command { //no
|
||||
c.Flags().StringVar(&ansi, "ansi", "auto", `Control when to print ANSI control characters ("never"|"always"|"auto")`)
|
||||
c.Flags().IntVar(¶llel, "parallel", -1, `Control max parallelism, -1 for unlimited`)
|
||||
c.Flags().BoolVarP(&version, "version", "v", false, "Show the Docker Compose version information")
|
||||
c.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "Execute command in dry run mode")
|
||||
c.Flags().MarkHidden("version") //nolint:errcheck
|
||||
c.Flags().BoolVar(&noAnsi, "no-ansi", false, `Do not print ANSI control characters (DEPRECATED)`)
|
||||
c.Flags().MarkHidden("no-ansi") //nolint:errcheck
|
||||
@@ -400,7 +447,7 @@ func setEnvWithDotEnv(prjOpts *ProjectOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
envFromFile, err := cli.GetEnvFromFile(composegoutils.GetAsEqualsMap(os.Environ()), workingDir, options.EnvFile)
|
||||
envFromFile, err := cli.GetEnvFromFile(composegoutils.GetAsEqualsMap(os.Environ()), workingDir, options.EnvFiles)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -31,8 +31,10 @@ func TestFilterServices(t *testing.T) {
|
||||
Links: []string{"bar"},
|
||||
},
|
||||
{
|
||||
Name: "bar",
|
||||
NetworkMode: types.NetworkModeServicePrefix + "zot",
|
||||
Name: "bar",
|
||||
DependsOn: map[string]types.ServiceDependency{
|
||||
"zot": {},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "zot",
|
||||
|
||||
@@ -32,7 +32,7 @@ import (
|
||||
"github.com/docker/compose/v2/pkg/compose"
|
||||
)
|
||||
|
||||
type convertOptions struct {
|
||||
type configOptions struct {
|
||||
*ProjectOptions
|
||||
Format string
|
||||
Output string
|
||||
@@ -40,6 +40,7 @@ type convertOptions struct {
|
||||
resolveImageDigests bool
|
||||
noInterpolate bool
|
||||
noNormalize bool
|
||||
noResolvePath bool
|
||||
services bool
|
||||
volumes bool
|
||||
profiles bool
|
||||
@@ -48,14 +49,24 @@ type convertOptions struct {
|
||||
noConsistency bool
|
||||
}
|
||||
|
||||
func convertCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
|
||||
opts := convertOptions{
|
||||
func (o *configOptions) ToProject(services []string) (*types.Project, error) {
|
||||
return o.ProjectOptions.ToProject(services,
|
||||
cli.WithInterpolation(!o.noInterpolate),
|
||||
cli.WithResolvedPaths(!o.noResolvePath),
|
||||
cli.WithNormalization(!o.noNormalize),
|
||||
cli.WithConsistency(!o.noConsistency),
|
||||
cli.WithProfiles(o.Profiles),
|
||||
cli.WithDiscardEnvFile)
|
||||
}
|
||||
|
||||
func configCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
|
||||
opts := configOptions{
|
||||
ProjectOptions: p,
|
||||
}
|
||||
cmd := &cobra.Command{
|
||||
Aliases: []string{"config"},
|
||||
Use: "convert [OPTIONS] [SERVICE...]",
|
||||
Short: "Converts the compose file to platform's canonical format",
|
||||
Aliases: []string{"convert"}, // for backward compatibility with Cloud integrations
|
||||
Use: "config [OPTIONS] [SERVICE...]",
|
||||
Short: "Parse, resolve and render compose file in canonical format",
|
||||
PreRunE: Adapt(func(ctx context.Context, args []string) error {
|
||||
if opts.quiet {
|
||||
devnull, err := os.Open(os.DevNull)
|
||||
@@ -86,7 +97,7 @@ func convertCommand(p *ProjectOptions, streams api.Streams, backend api.Service)
|
||||
return runConfigImages(streams, opts, args)
|
||||
}
|
||||
|
||||
return runConvert(ctx, streams, backend, opts, args)
|
||||
return runConfig(ctx, streams, backend, opts, args)
|
||||
}),
|
||||
ValidArgsFunction: completeServiceNames(p),
|
||||
}
|
||||
@@ -96,6 +107,7 @@ func convertCommand(p *ProjectOptions, streams api.Streams, backend api.Service)
|
||||
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only validate the configuration, don't print anything.")
|
||||
flags.BoolVar(&opts.noInterpolate, "no-interpolate", false, "Don't interpolate environment variables.")
|
||||
flags.BoolVar(&opts.noNormalize, "no-normalize", false, "Don't normalize compose model.")
|
||||
flags.BoolVar(&opts.noResolvePath, "no-path-resolution", false, "Don't resolve file paths.")
|
||||
flags.BoolVar(&opts.noConsistency, "no-consistency", false, "Don't check model consistency - warning: may produce invalid Compose output")
|
||||
|
||||
flags.BoolVar(&opts.services, "services", false, "Print the service names, one per line.")
|
||||
@@ -108,19 +120,14 @@ func convertCommand(p *ProjectOptions, streams api.Streams, backend api.Service)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runConvert(ctx context.Context, streams api.Streams, backend api.Service, opts convertOptions, services []string) error {
|
||||
func runConfig(ctx context.Context, streams api.Streams, backend api.Service, opts configOptions, services []string) error {
|
||||
var content []byte
|
||||
project, err := opts.ToProject(services,
|
||||
cli.WithInterpolation(!opts.noInterpolate),
|
||||
cli.WithResolvedPaths(true),
|
||||
cli.WithNormalization(!opts.noNormalize),
|
||||
cli.WithConsistency(!opts.noConsistency),
|
||||
cli.WithDiscardEnvFile)
|
||||
project, err := opts.ToProject(services)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
content, err = backend.Convert(ctx, project, api.ConvertOptions{
|
||||
content, err = backend.Config(ctx, project, api.ConfigOptions{
|
||||
Format: opts.Format,
|
||||
Output: opts.Output,
|
||||
ResolveImageDigests: opts.resolveImageDigests,
|
||||
@@ -144,7 +151,7 @@ func runConvert(ctx context.Context, streams api.Streams, backend api.Service, o
|
||||
return err
|
||||
}
|
||||
|
||||
func runServices(streams api.Streams, opts convertOptions) error {
|
||||
func runServices(streams api.Streams, opts configOptions) error {
|
||||
project, err := opts.ToProject(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -155,7 +162,7 @@ func runServices(streams api.Streams, opts convertOptions) error {
|
||||
})
|
||||
}
|
||||
|
||||
func runVolumes(streams api.Streams, opts convertOptions) error {
|
||||
func runVolumes(streams api.Streams, opts configOptions) error {
|
||||
project, err := opts.ToProject(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -166,16 +173,29 @@ func runVolumes(streams api.Streams, opts convertOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func runHash(streams api.Streams, opts convertOptions) error {
|
||||
func runHash(streams api.Streams, opts configOptions) error {
|
||||
var services []string
|
||||
if opts.hash != "*" {
|
||||
services = append(services, strings.Split(opts.hash, ",")...)
|
||||
}
|
||||
project, err := opts.ToProject(services)
|
||||
project, err := opts.ToProject(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range project.Services {
|
||||
|
||||
if len(services) > 0 {
|
||||
err = project.ForServices(services, types.IgnoreDependencies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
sorted := project.Services
|
||||
sort.Slice(sorted, func(i, j int) bool {
|
||||
return sorted[i].Name < sorted[j].Name
|
||||
})
|
||||
|
||||
for _, s := range sorted {
|
||||
hash, err := compose.ServiceHash(s)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -185,7 +205,7 @@ func runHash(streams api.Streams, opts convertOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func runProfiles(streams api.Streams, opts convertOptions, services []string) error {
|
||||
func runProfiles(streams api.Streams, opts configOptions, services []string) error {
|
||||
set := map[string]struct{}{}
|
||||
project, err := opts.ToProject(services)
|
||||
if err != nil {
|
||||
@@ -207,7 +227,7 @@ func runProfiles(streams api.Streams, opts convertOptions, services []string) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func runConfigImages(streams api.Streams, opts convertOptions, services []string) error {
|
||||
func runConfigImages(streams api.Streams, opts configOptions, services []string) error {
|
||||
project, err := opts.ToProject(services)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -19,6 +19,8 @@ package compose
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
@@ -41,6 +43,7 @@ type createOptions struct {
|
||||
timeChanged bool
|
||||
timeout int
|
||||
quietPull bool
|
||||
scale []string
|
||||
}
|
||||
|
||||
func createCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
@@ -59,7 +62,9 @@ func createCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
return nil
|
||||
}),
|
||||
RunE: p.WithProject(func(ctx context.Context, project *types.Project) error {
|
||||
opts.Apply(project)
|
||||
if err := opts.Apply(project); err != nil {
|
||||
return err
|
||||
}
|
||||
return backend.Create(ctx, project, api.CreateOptions{
|
||||
RemoveOrphans: opts.removeOrphans,
|
||||
IgnoreOrphans: opts.ignoreOrphans,
|
||||
@@ -78,6 +83,8 @@ func createCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
flags.StringVar(&opts.Pull, "pull", "missing", `Pull image before running ("always"|"missing"|"never")`)
|
||||
flags.BoolVar(&opts.forceRecreate, "force-recreate", false, "Recreate containers even if their configuration and image haven't changed.")
|
||||
flags.BoolVar(&opts.noRecreate, "no-recreate", false, "If containers already exist, don't recreate them. Incompatible with --force-recreate.")
|
||||
flags.BoolVar(&opts.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.")
|
||||
flags.StringArrayVar(&opts.scale, "scale", []string{}, "Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.")
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -109,7 +116,7 @@ func (opts createOptions) GetTimeout() *time.Duration {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (opts createOptions) Apply(project *types.Project) {
|
||||
func (opts createOptions) Apply(project *types.Project) error {
|
||||
if opts.pullChanged {
|
||||
for i, service := range project.Services {
|
||||
service.PullPolicy = opts.Pull
|
||||
@@ -134,4 +141,20 @@ func (opts createOptions) Apply(project *types.Project) {
|
||||
project.Services[i] = service
|
||||
}
|
||||
}
|
||||
for _, scale := range opts.scale {
|
||||
split := strings.Split(scale, "=")
|
||||
if len(split) != 2 {
|
||||
return fmt.Errorf("invalid --scale option %q. Should be SERVICE=NUM", scale)
|
||||
}
|
||||
name := split[0]
|
||||
replicas, err := strconv.Atoi(split[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = setServiceScale(project, name, uint64(replicas))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func downCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
ValidArgsFunction: noCompletion(),
|
||||
}
|
||||
flags := downCmd.Flags()
|
||||
removeOrphans := utils.StringToBool(os.Getenv("COMPOSE_REMOVE_ORPHANS"))
|
||||
removeOrphans := utils.StringToBool(os.Getenv(ComposeRemoveOrphans))
|
||||
flags.BoolVar(&opts.removeOrphans, "remove-orphans", removeOrphans, "Remove containers for services not defined in the Compose file.")
|
||||
flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds")
|
||||
flags.BoolVarP(&opts.volumes, "volumes", "v", false, "Remove named volumes declared in the `volumes` section of the Compose file and anonymous volumes attached to containers.")
|
||||
|
||||
@@ -46,7 +46,7 @@ func killCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
removeOrphans := utils.StringToBool(os.Getenv("COMPOSE_REMOVE_ORPHANS"))
|
||||
removeOrphans := utils.StringToBool(os.Getenv(ComposeRemoveOrphans))
|
||||
flags.BoolVar(&opts.removeOrphans, "remove-orphans", removeOrphans, "Remove containers for services not defined in the Compose file.")
|
||||
flags.StringVarP(&opts.signal, "signal", "s", "SIGKILL", "SIGNAL to send to the container.")
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ func logsCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *c
|
||||
flags.BoolVar(&opts.noColor, "no-color", false, "Produce monochrome output.")
|
||||
flags.BoolVar(&opts.noPrefix, "no-log-prefix", false, "Don't print prefix in logs.")
|
||||
flags.BoolVarP(&opts.timestamps, "timestamps", "t", false, "Show timestamps.")
|
||||
flags.StringVar(&opts.tail, "tail", "all", "Number of lines to show from the end of the logs for each container.")
|
||||
flags.StringVarP(&opts.tail, "tail", "n", "all", "Number of lines to show from the end of the logs for each container.")
|
||||
return logsCmd
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
"github.com/docker/compose/v2/pkg/utils"
|
||||
)
|
||||
|
||||
type pullOptions struct {
|
||||
@@ -70,21 +69,6 @@ func pullCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func withSelectedServicesOnly(project *types.Project, services []string) error {
|
||||
enabled, err := project.GetServices(services...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range project.Services {
|
||||
if !utils.StringContains(services, s.Name) {
|
||||
project.DisabledServices = append(project.DisabledServices, s)
|
||||
}
|
||||
}
|
||||
project.Services = enabled
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runPull(ctx context.Context, backend api.Service, opts pullOptions, services []string) error {
|
||||
project, err := opts.ToProject(services)
|
||||
if err != nil {
|
||||
@@ -92,7 +76,7 @@ func runPull(ctx context.Context, backend api.Service, opts pullOptions, service
|
||||
}
|
||||
|
||||
if !opts.includeDeps {
|
||||
err := withSelectedServicesOnly(project, services)
|
||||
err := project.ForServices(services, types.IgnoreDependencies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package compose
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
@@ -58,7 +59,7 @@ func runPush(ctx context.Context, backend api.Service, opts pushOptions, service
|
||||
}
|
||||
|
||||
if !opts.IncludeDeps {
|
||||
err := withSelectedServicesOnly(project, services)
|
||||
err := project.ForServices(services, types.IgnoreDependencies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -64,20 +64,11 @@ func runRemove(ctx context.Context, backend api.Service, opts removeOptions, ser
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.stop {
|
||||
err := backend.Stop(ctx, name, api.StopOptions{
|
||||
Services: services,
|
||||
Project: project,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return backend.Remove(ctx, name, api.RemoveOptions{
|
||||
Services: services,
|
||||
Force: opts.force,
|
||||
Volumes: opts.volumes,
|
||||
Project: project,
|
||||
Stop: opts.stop,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
@@ -28,6 +29,7 @@ import (
|
||||
type restartOptions struct {
|
||||
*ProjectOptions
|
||||
timeout int
|
||||
noDeps bool
|
||||
}
|
||||
|
||||
func restartCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
@@ -44,16 +46,24 @@ func restartCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
}
|
||||
flags := restartCmd.Flags()
|
||||
flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds")
|
||||
flags.BoolVar(&opts.noDeps, "no-deps", false, "Don't restart dependent services.")
|
||||
|
||||
return restartCmd
|
||||
}
|
||||
|
||||
func runRestart(ctx context.Context, backend api.Service, opts restartOptions, services []string) error {
|
||||
project, name, err := opts.projectOrName(services...)
|
||||
project, name, err := opts.projectOrName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.noDeps {
|
||||
err := project.ForServices(services, types.IgnoreDependencies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
timeout := time.Duration(opts.timeout) * time.Second
|
||||
return backend.Restart(ctx, name, api.RestartOptions{
|
||||
Timeout: &timeout,
|
||||
|
||||
@@ -42,6 +42,7 @@ type runOptions struct {
|
||||
Detach bool
|
||||
Remove bool
|
||||
noTty bool
|
||||
tty bool
|
||||
interactive bool
|
||||
user string
|
||||
workdir string
|
||||
@@ -90,12 +91,10 @@ func (opts runOptions) apply(project *types.Project) error {
|
||||
}
|
||||
|
||||
if opts.noDeps {
|
||||
for _, s := range project.Services {
|
||||
if s.Name != opts.Service {
|
||||
project.DisabledServices = append(project.DisabledServices, s)
|
||||
}
|
||||
err := project.ForServices([]string{opts.Service}, types.IgnoreDependencies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
project.Services = types.Services{target}
|
||||
}
|
||||
|
||||
for i, s := range project.Services {
|
||||
@@ -133,15 +132,23 @@ func runCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *co
|
||||
}
|
||||
opts.entrypointCmd = command
|
||||
}
|
||||
if cmd.Flags().Changed("tty") {
|
||||
if cmd.Flags().Changed("no-TTY") {
|
||||
return fmt.Errorf("--tty and --no-TTY can't be used together")
|
||||
} else {
|
||||
opts.noTty = !opts.tty
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}),
|
||||
RunE: Adapt(func(ctx context.Context, args []string) error {
|
||||
project, err := p.ToProject([]string{opts.Service}, cgo.WithResolvedPaths(true))
|
||||
project, err := p.ToProject([]string{opts.Service}, cgo.WithResolvedPaths(true), cgo.WithDiscardEnvFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts.ignoreOrphans = utils.StringToBool(project.Environment["COMPOSE_IGNORE_ORPHANS"])
|
||||
return runRun(ctx, backend, project, opts, createOpts)
|
||||
|
||||
opts.ignoreOrphans = utils.StringToBool(project.Environment[ComposeIgnoreOrphans])
|
||||
return runRun(ctx, backend, project, opts, createOpts, streams)
|
||||
}),
|
||||
ValidArgsFunction: completeServiceNames(p),
|
||||
}
|
||||
@@ -162,9 +169,10 @@ func runCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *co
|
||||
flags.BoolVar(&opts.servicePorts, "service-ports", false, "Run command with the service's ports enabled and mapped to the host.")
|
||||
flags.BoolVar(&opts.quietPull, "quiet-pull", false, "Pull without printing progress information.")
|
||||
flags.BoolVar(&createOpts.Build, "build", false, "Build image before starting container.")
|
||||
flags.BoolVar(&createOpts.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.")
|
||||
|
||||
cmd.Flags().BoolVarP(&opts.interactive, "interactive", "i", true, "Keep STDIN open even if not attached.")
|
||||
cmd.Flags().BoolP("tty", "t", true, "Allocate a pseudo-TTY.")
|
||||
cmd.Flags().BoolVarP(&opts.tty, "tty", "t", true, "Allocate a pseudo-TTY.")
|
||||
cmd.Flags().MarkHidden("tty") //nolint:errcheck
|
||||
|
||||
flags.SetNormalizeFunc(normalizeRunFlags)
|
||||
@@ -182,17 +190,20 @@ func normalizeRunFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||
return pflag.NormalizedName(name)
|
||||
}
|
||||
|
||||
func runRun(ctx context.Context, backend api.Service, project *types.Project, opts runOptions, createOpts createOptions) error {
|
||||
func runRun(ctx context.Context, backend api.Service, project *types.Project, opts runOptions, createOpts createOptions, streams api.Streams) error {
|
||||
err := opts.apply(project)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
createOpts.Apply(project)
|
||||
err = createOpts.Apply(project)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = progress.Run(ctx, func(ctx context.Context) error {
|
||||
return startDependencies(ctx, backend, *project, opts.Service, opts.ignoreOrphans)
|
||||
})
|
||||
}, streams.Err())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ package compose
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/compose/v2/cmd/formatter"
|
||||
|
||||
@@ -43,7 +42,6 @@ type upOptions struct {
|
||||
noDeps bool
|
||||
cascadeStop bool
|
||||
exitCodeFrom string
|
||||
scale []string
|
||||
noColor bool
|
||||
noPrefix bool
|
||||
attachDependencies bool
|
||||
@@ -51,11 +49,12 @@ type upOptions struct {
|
||||
noAttach []string
|
||||
timestamp bool
|
||||
wait bool
|
||||
waitTimeout int
|
||||
}
|
||||
|
||||
func (opts upOptions) apply(project *types.Project, services []string) error {
|
||||
if opts.noDeps {
|
||||
err := withSelectedServicesOnly(project, services)
|
||||
err := project.ForServices(services, types.IgnoreDependencies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -68,22 +67,6 @@ func (opts upOptions) apply(project *types.Project, services []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
for _, scale := range opts.scale {
|
||||
split := strings.Split(scale, "=")
|
||||
if len(split) != 2 {
|
||||
return fmt.Errorf("invalid --scale option %q. Should be SERVICE=NUM", scale)
|
||||
}
|
||||
name := split[0]
|
||||
replicas, err := strconv.Atoi(split[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = setServiceScale(project, name, uint64(replicas))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -95,13 +78,13 @@ func upCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cob
|
||||
Short: "Create and start containers",
|
||||
PreRunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
|
||||
create.pullChanged = cmd.Flags().Changed("pull")
|
||||
create.timeChanged = cmd.Flags().Changed("timeout")
|
||||
create.timeChanged = cmd.Flags().Changed("waitTimeout")
|
||||
return validateFlags(&up, &create)
|
||||
}),
|
||||
RunE: p.WithServices(func(ctx context.Context, project *types.Project, services []string) error {
|
||||
create.ignoreOrphans = utils.StringToBool(project.Environment["COMPOSE_IGNORE_ORPHANS"])
|
||||
create.ignoreOrphans = utils.StringToBool(project.Environment[ComposeIgnoreOrphans])
|
||||
if create.ignoreOrphans && create.removeOrphans {
|
||||
return fmt.Errorf("COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined")
|
||||
return fmt.Errorf("%s and --remove-orphans cannot be combined", ComposeIgnoreOrphans)
|
||||
}
|
||||
return runUp(ctx, streams, backend, create, up, project, services)
|
||||
}),
|
||||
@@ -113,7 +96,7 @@ func upCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cob
|
||||
flags.BoolVar(&create.noBuild, "no-build", false, "Don't build an image, even if it's missing.")
|
||||
flags.StringVar(&create.Pull, "pull", "missing", `Pull image before running ("always"|"missing"|"never")`)
|
||||
flags.BoolVar(&create.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.")
|
||||
flags.StringArrayVar(&up.scale, "scale", []string{}, "Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.")
|
||||
flags.StringArrayVar(&create.scale, "scale", []string{}, "Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.")
|
||||
flags.BoolVar(&up.noColor, "no-color", false, "Produce monochrome output.")
|
||||
flags.BoolVar(&up.noPrefix, "no-log-prefix", false, "Don't print prefix in logs.")
|
||||
flags.BoolVar(&create.forceRecreate, "force-recreate", false, "Recreate containers even if their configuration and image haven't changed.")
|
||||
@@ -131,6 +114,7 @@ func upCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cob
|
||||
flags.StringArrayVar(&up.attach, "attach", []string{}, "Attach to service output.")
|
||||
flags.StringArrayVar(&up.noAttach, "no-attach", []string{}, "Don't attach to specified service.")
|
||||
flags.BoolVar(&up.wait, "wait", false, "Wait for services to be running|healthy. Implies detached mode.")
|
||||
flags.IntVar(&up.waitTimeout, "wait-timeout", 0, "timeout waiting for application to be running|healthy.")
|
||||
|
||||
return upCmd
|
||||
}
|
||||
@@ -165,9 +149,12 @@ func runUp(ctx context.Context, streams api.Streams, backend api.Service, create
|
||||
return fmt.Errorf("no service selected")
|
||||
}
|
||||
|
||||
createOptions.Apply(project)
|
||||
err := createOptions.Apply(project)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := upOptions.apply(project, services)
|
||||
err = upOptions.apply(project, services)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -187,7 +174,7 @@ func runUp(ctx context.Context, streams api.Streams, backend api.Service, create
|
||||
if len(attachTo) == 0 {
|
||||
attachTo = project.ServiceNames()
|
||||
}
|
||||
attachTo = utils.RemoveAll(attachTo, upOptions.noAttach)
|
||||
attachTo = utils.Remove(attachTo, upOptions.noAttach...)
|
||||
|
||||
create := api.CreateOptions{
|
||||
Services: services,
|
||||
@@ -204,6 +191,8 @@ func runUp(ctx context.Context, streams api.Streams, backend api.Service, create
|
||||
return backend.Create(ctx, project, create)
|
||||
}
|
||||
|
||||
timeout := time.Duration(upOptions.waitTimeout) * time.Second
|
||||
|
||||
return backend.Up(ctx, project, api.UpOptions{
|
||||
Create: create,
|
||||
Start: api.StartOptions{
|
||||
@@ -213,6 +202,7 @@ func runUp(ctx context.Context, streams api.Streams, backend api.Service, create
|
||||
ExitCodeFrom: upOptions.exitCodeFrom,
|
||||
CascadeStop: upOptions.cascadeStop,
|
||||
Wait: upOptions.wait,
|
||||
WaitTimeout: timeout,
|
||||
Services: services,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -34,8 +34,8 @@ func TestApplyScaleOpt(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
opt := upOptions{scale: []string{"foo=2"}}
|
||||
err := opt.apply(&p, nil)
|
||||
opt := createOptions{scale: []string{"foo=2"}}
|
||||
err := opt.Apply(&p)
|
||||
assert.NilError(t, err)
|
||||
foo, err := p.GetService("foo")
|
||||
assert.NilError(t, err)
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/compose/v2/cmd/formatter"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@@ -32,14 +33,14 @@ type versionOptions struct {
|
||||
short bool
|
||||
}
|
||||
|
||||
func versionCommand() *cobra.Command {
|
||||
func versionCommand(streams command.Cli) *cobra.Command {
|
||||
opts := versionOptions{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "version [OPTIONS]",
|
||||
Short: "Show the Docker Compose version information",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||
runVersion(opts)
|
||||
runVersion(opts, streams)
|
||||
return nil
|
||||
},
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
@@ -56,14 +57,14 @@ func versionCommand() *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runVersion(opts versionOptions) {
|
||||
func runVersion(opts versionOptions, streams command.Cli) {
|
||||
if opts.short {
|
||||
fmt.Println(strings.TrimPrefix(internal.Version, "v"))
|
||||
fmt.Fprintln(streams.Out(), strings.TrimPrefix(internal.Version, "v"))
|
||||
return
|
||||
}
|
||||
if opts.format == formatter.JSON {
|
||||
fmt.Printf("{\"version\":%q}\n", internal.Version)
|
||||
fmt.Fprintf(streams.Out(), "{\"version\":%q}\n", internal.Version)
|
||||
return
|
||||
}
|
||||
fmt.Println("Docker Compose version", internal.Version)
|
||||
fmt.Fprintln(streams.Out(), "Docker Compose version", internal.Version)
|
||||
}
|
||||
|
||||
96
cmd/compose/viz.go
Normal file
96
cmd/compose/viz.go
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright 2023 Docker Compose CLI authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compose
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type vizOptions struct {
|
||||
*ProjectOptions
|
||||
includeNetworks bool
|
||||
includePorts bool
|
||||
includeImageName bool
|
||||
indentationStr string
|
||||
}
|
||||
|
||||
func vizCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
opts := vizOptions{
|
||||
ProjectOptions: p,
|
||||
}
|
||||
var indentationSize int
|
||||
var useSpaces bool
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "viz [OPTIONS]",
|
||||
Short: "EXPERIMENTAL - Generate a graphviz graph from your compose file",
|
||||
PreRunE: Adapt(func(ctx context.Context, args []string) error {
|
||||
var err error
|
||||
opts.indentationStr, err = preferredIndentationStr(indentationSize, useSpaces)
|
||||
return err
|
||||
}),
|
||||
RunE: Adapt(func(ctx context.Context, args []string) error {
|
||||
return runViz(ctx, backend, &opts)
|
||||
}),
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVar(&opts.includePorts, "ports", false, "Include service's exposed ports in output graph")
|
||||
cmd.Flags().BoolVar(&opts.includeNetworks, "networks", false, "Include service's attached networks in output graph")
|
||||
cmd.Flags().BoolVar(&opts.includeImageName, "image", false, "Include service's image name in output graph")
|
||||
cmd.Flags().IntVar(&indentationSize, "indentation-size", 1, "Number of tabs or spaces to use for indentation")
|
||||
cmd.Flags().BoolVar(&useSpaces, "spaces", false, "If given, space character ' ' will be used to indent,\notherwise tab character '\\t' will be used")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runViz(ctx context.Context, backend api.Service, opts *vizOptions) error {
|
||||
_, _ = fmt.Fprintln(os.Stderr, "viz command is EXPERIMENTAL")
|
||||
project, err := opts.ToProject(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// build graph
|
||||
graphStr, _ := backend.Viz(ctx, project, api.VizOptions{
|
||||
IncludeNetworks: opts.includeNetworks,
|
||||
IncludePorts: opts.includePorts,
|
||||
IncludeImageName: opts.includeImageName,
|
||||
Indentation: opts.indentationStr,
|
||||
})
|
||||
|
||||
fmt.Println(graphStr)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// preferredIndentationStr returns a single string given the indentation preference
|
||||
func preferredIndentationStr(size int, useSpace bool) (string, error) {
|
||||
if size < 0 {
|
||||
return "", fmt.Errorf("invalid indentation size: %d", size)
|
||||
}
|
||||
|
||||
indentationStr := "\t"
|
||||
if useSpace {
|
||||
indentationStr = " "
|
||||
}
|
||||
return strings.Repeat(indentationStr, size), nil
|
||||
}
|
||||
92
cmd/compose/viz_test.go
Normal file
92
cmd/compose/viz_test.go
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright 2020 Docker Compose CLI authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compose
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPreferredIndentationStr(t *testing.T) {
|
||||
type args struct {
|
||||
size int
|
||||
useSpace bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "should return '\\t\\t'",
|
||||
args: args{
|
||||
size: 2,
|
||||
useSpace: false,
|
||||
},
|
||||
want: "\t\t",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "should return ' '",
|
||||
args: args{
|
||||
size: 4,
|
||||
useSpace: true,
|
||||
},
|
||||
want: " ",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "should return ''",
|
||||
args: args{
|
||||
size: 0,
|
||||
useSpace: false,
|
||||
},
|
||||
want: "",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "should return ''",
|
||||
args: args{
|
||||
size: 0,
|
||||
useSpace: true,
|
||||
},
|
||||
want: "",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "should throw error because indentation size < 0",
|
||||
args: args{
|
||||
size: -1,
|
||||
useSpace: false,
|
||||
},
|
||||
want: "",
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := preferredIndentationStr(tt.args.size, tt.args.useSpace)
|
||||
if tt.wantErr && assert.NotNilf(t, err, fmt.Sprintf("preferredIndentationStr(%v, %v)", tt.args.size, tt.args.useSpace)) {
|
||||
return
|
||||
}
|
||||
assert.Equalf(t, tt.want, got, "preferredIndentationStr(%v, %v)", tt.args.size, tt.args.useSpace)
|
||||
})
|
||||
}
|
||||
}
|
||||
61
cmd/compose/watch.go
Normal file
61
cmd/compose/watch.go
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2020 Docker Compose CLI authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compose
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type watchOptions struct {
|
||||
*ProjectOptions
|
||||
quiet bool
|
||||
}
|
||||
|
||||
func watchCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
||||
opts := watchOptions{
|
||||
ProjectOptions: p,
|
||||
}
|
||||
cmd := &cobra.Command{
|
||||
Use: "watch [SERVICE...]",
|
||||
Short: "EXPERIMENTAL - Watch build context for service and rebuild/refresh containers when files are updated",
|
||||
PreRunE: Adapt(func(ctx context.Context, args []string) error {
|
||||
return nil
|
||||
}),
|
||||
RunE: Adapt(func(ctx context.Context, args []string) error {
|
||||
return runWatch(ctx, backend, opts, args)
|
||||
}),
|
||||
ValidArgsFunction: completeServiceNames(p),
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVar(&opts.quiet, "quiet", false, "hide build output")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runWatch(ctx context.Context, backend api.Service, opts watchOptions, services []string) error {
|
||||
fmt.Fprintln(os.Stderr, "watch command is EXPERIMENTAL")
|
||||
project, err := opts.ToProject(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return backend.Watch(ctx, project, services, api.WatchOptions{})
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package formatter
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
)
|
||||
@@ -86,38 +87,34 @@ func makeColorFunc(code string) colorFunc {
|
||||
}
|
||||
|
||||
var nextColor = rainbowColor
|
||||
var rainbow []colorFunc
|
||||
var currentIndex = 0
|
||||
var mutex sync.Mutex
|
||||
|
||||
func rainbowColor() colorFunc {
|
||||
return <-loop
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
result := rainbow[currentIndex]
|
||||
currentIndex = (currentIndex + 1) % len(rainbow)
|
||||
return result
|
||||
}
|
||||
|
||||
var loop = make(chan colorFunc)
|
||||
|
||||
func init() {
|
||||
colors := map[string]colorFunc{}
|
||||
for i, name := range names {
|
||||
colors[name] = makeColorFunc(strconv.Itoa(30 + i))
|
||||
colors["intense_"+name] = makeColorFunc(strconv.Itoa(30+i) + ";1")
|
||||
}
|
||||
|
||||
go func() {
|
||||
i := 0
|
||||
rainbow := []colorFunc{
|
||||
colors["cyan"],
|
||||
colors["yellow"],
|
||||
colors["green"],
|
||||
colors["magenta"],
|
||||
colors["blue"],
|
||||
colors["intense_cyan"],
|
||||
colors["intense_yellow"],
|
||||
colors["intense_green"],
|
||||
colors["intense_magenta"],
|
||||
colors["intense_blue"],
|
||||
}
|
||||
|
||||
for {
|
||||
loop <- rainbow[i]
|
||||
i = (i + 1) % len(rainbow)
|
||||
}
|
||||
}()
|
||||
rainbow = []colorFunc{
|
||||
colors["cyan"],
|
||||
colors["yellow"],
|
||||
colors["green"],
|
||||
colors["magenta"],
|
||||
colors["blue"],
|
||||
colors["intense_cyan"],
|
||||
colors["intense_yellow"],
|
||||
colors["intense_green"],
|
||||
colors["intense_magenta"],
|
||||
colors["intense_blue"],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"go.uber.org/goleak"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
@@ -71,3 +72,7 @@ func TestPrint(t *testing.T) {
|
||||
{"Name":"myName2","Status":"myStatus2"}
|
||||
`)
|
||||
}
|
||||
|
||||
func TestColorsGoroutinesLeak(t *testing.T) {
|
||||
goleak.VerifyNone(t)
|
||||
}
|
||||
|
||||
@@ -13,11 +13,12 @@
|
||||
// limitations under the License.
|
||||
|
||||
variable "GO_VERSION" {
|
||||
default = "1.19.4"
|
||||
# default ARG value set in Dockerfile
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "BUILD_TAGS" {
|
||||
default = "e2e,kube"
|
||||
default = "e2e"
|
||||
}
|
||||
|
||||
variable "DOCS_FORMATS" {
|
||||
@@ -33,6 +34,9 @@ function "bindir" {
|
||||
result = DESTDIR != "" ? DESTDIR : "./bin/${defaultdir}"
|
||||
}
|
||||
|
||||
# Special target: https://github.com/docker/metadata-action#bake-definition
|
||||
target "meta-helper" {}
|
||||
|
||||
target "_common" {
|
||||
args = {
|
||||
GO_VERSION = GO_VERSION
|
||||
@@ -83,6 +87,16 @@ target "test" {
|
||||
output = [bindir("coverage")]
|
||||
}
|
||||
|
||||
target "binary-with-coverage" {
|
||||
inherits = ["_common"]
|
||||
target = "binary"
|
||||
args = {
|
||||
BUILD_FLAGS = "-cover"
|
||||
}
|
||||
output = [bindir("build")]
|
||||
platforms = ["local"]
|
||||
}
|
||||
|
||||
target "binary" {
|
||||
inherits = ["_common"]
|
||||
target = "binary"
|
||||
@@ -124,3 +138,8 @@ target "docs-update" {
|
||||
target = "docs-update"
|
||||
output = ["./docs"]
|
||||
}
|
||||
|
||||
target "image-cross" {
|
||||
inherits = ["meta-helper", "binary-cross"]
|
||||
output = ["type=image"]
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
# docker compose
|
||||
|
||||
<!---MARKER_GEN_START-->
|
||||
Docker Compose
|
||||
Define and run multi-container applications with Docker.
|
||||
|
||||
### Subcommands
|
||||
|
||||
| Name | Description |
|
||||
|:--------------------------------|:------------------------------------------------------------------------|
|
||||
| [`alpha`](compose_alpha.md) | Experimental commands |
|
||||
| [`build`](compose_build.md) | Build or rebuild services |
|
||||
| [`convert`](compose_convert.md) | Converts the compose file to platform's canonical format |
|
||||
| [`config`](compose_config.md) | Parse, resolve and render compose file in canonical format |
|
||||
| [`cp`](compose_cp.md) | Copy files/folders between a service container and the local filesystem |
|
||||
| [`create`](compose_create.md) | Creates containers for a service. |
|
||||
| [`down`](compose_down.md) | Stop and remove containers, networks |
|
||||
@@ -40,7 +41,8 @@ Docker Compose
|
||||
|:-----------------------|:--------------|:--------|:----------------------------------------------------------------------------------------------------|
|
||||
| `--ansi` | `string` | `auto` | Control when to print ANSI control characters ("never"\|"always"\|"auto") |
|
||||
| `--compatibility` | | | Run compose in backward compatibility mode |
|
||||
| `--env-file` | `string` | | Specify an alternate environment file. |
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--env-file` | `stringArray` | | Specify an alternate environment file. |
|
||||
| `-f`, `--file` | `stringArray` | | Compose configuration files |
|
||||
| `--parallel` | `int` | `-1` | Control max parallelism, -1 for unlimited |
|
||||
| `--profile` | `stringArray` | | Specify a profile to enable |
|
||||
@@ -114,12 +116,19 @@ $ docker compose -f ~/sandbox/rails/compose.yaml pull db
|
||||
|
||||
### Use `-p` to specify a project name
|
||||
|
||||
Each configuration has a project name. If you supply a `-p` flag, you can specify a project name. If you don’t
|
||||
specify the flag, Compose uses the current directory name.
|
||||
Project name can also be set by `COMPOSE_PROJECT_NAME` environment variable.
|
||||
|
||||
Many Compose subcommands can be run without a Compose file by passing
|
||||
the project name.
|
||||
Each configuration has a project name. Compose sets the project name using
|
||||
the following mechanisms, in order of precedence:
|
||||
- The `-p` command line flag
|
||||
- The `COMPOSE_PROJECT_NAME` environment variable
|
||||
- The top level `name:` variable from the config file (or the last `name:`
|
||||
from a series of config files specified using `-f`)
|
||||
- The `basename` of the project directory containing the config file (or
|
||||
containing the first config file specified using `-f`)
|
||||
- The `basename` of the current directory if no config file is specified
|
||||
Project names must contain only lowercase letters, decimal digits, dashes,
|
||||
and underscores, and must begin with a lowercase letter or decimal digit. If
|
||||
the `basename` of the project directory or current directory violates this
|
||||
constraint, you must use one of the other mechanisms.
|
||||
|
||||
```console
|
||||
$ docker compose -p my_project ps -a
|
||||
@@ -140,15 +149,70 @@ You can also enable multiple profiles, e.g. with `docker compose --profile front
|
||||
|
||||
Profiles can also be set by `COMPOSE_PROFILES` environment variable.
|
||||
|
||||
### Configuring parallelism
|
||||
|
||||
Use `--parallel` to specify the maximum level of parallelism for concurrent engine calls.
|
||||
Calling `docker compose --parallel 1 pull` will pull the pullable images defined in the Compose file
|
||||
one at a time. This can also be used to control build concurrency.
|
||||
|
||||
Parallelism can also be set by the `COMPOSE_PARALLEL_LIMIT` environment variable.
|
||||
|
||||
### Set up environment variables
|
||||
|
||||
You can set environment variables for various docker compose options, including the `-f`, `-p` and `--profiles` flags.
|
||||
|
||||
Setting the `COMPOSE_FILE` environment variable is equivalent to passing the `-f` flag,
|
||||
`COMPOSE_PROJECT_NAME` environment variable does the same as the `-p` flag,
|
||||
and `COMPOSE_PROFILES` environment variable is equivalent to the `--profiles` flag.
|
||||
`COMPOSE_PROFILES` environment variable is equivalent to the `--profiles` flag
|
||||
and `COMPOSE_PARALLEL_LIMIT` does the same as the `--parallel` flag.
|
||||
|
||||
If flags are explicitly set on the command line, the associated environment variable is ignored.
|
||||
|
||||
Setting the `COMPOSE_IGNORE_ORPHANS` environment variable to `true` will stop docker compose from detecting orphaned
|
||||
containers for the project.
|
||||
|
||||
|
||||
### Use Dry Run mode to test your command
|
||||
|
||||
Use `--dry-run` flag to test a command without changing your application stack state.
|
||||
Dry Run mode shows you all the steps Compose applies when executing a command, for example:
|
||||
```console
|
||||
$ docker compose --dry-run up --build -d
|
||||
[+] Pulling 1/1
|
||||
✔ DRY-RUN MODE - db Pulled 0.9s
|
||||
[+] Running 10/8
|
||||
✔ DRY-RUN MODE - build service backend 0.0s
|
||||
✔ DRY-RUN MODE - ==> ==> writing image dryRun-754a08ddf8bcb1cf22f310f09206dd783d42f7dd 0.0s
|
||||
✔ DRY-RUN MODE - ==> ==> naming to nginx-golang-mysql-backend 0.0s
|
||||
✔ DRY-RUN MODE - Network nginx-golang-mysql_default Created 0.0s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-db-1 Created 0.0s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-backend-1 Created 0.0s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-proxy-1 Created 0.0s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-db-1 Healthy 0.5s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-backend-1 Started 0.0s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-proxy-1 Started Started
|
||||
```
|
||||
From the example above, you can see that the first step is to pull the image defined by `db` service, then build the `backend` service.
|
||||
Next, the containers are created. The `db` service is started, and the `backend` and `proxy` wait until the `db` service is healthy before starting.
|
||||
|
||||
Dry Run mode does not currently work with all commands. In particular, you cannot use Dry Run mode with a command that doesn't change the state of a Compose stack
|
||||
such as `ps`, `ls`, `logs` for example.
|
||||
|
||||
Here the list of commands supporting `--dry-run` flag:
|
||||
* build
|
||||
* cp
|
||||
* create
|
||||
* down
|
||||
* exec
|
||||
* kill
|
||||
* pause
|
||||
* pull
|
||||
* push
|
||||
* remove
|
||||
* restart
|
||||
* run
|
||||
* start
|
||||
* stop
|
||||
* unpause
|
||||
* up
|
||||
|
||||
|
||||
22
docs/reference/compose_alpha.md
Normal file
22
docs/reference/compose_alpha.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# docker compose alpha
|
||||
|
||||
<!---MARKER_GEN_START-->
|
||||
Experimental commands
|
||||
|
||||
### Subcommands
|
||||
|
||||
| Name | Description |
|
||||
|:----------------------------------|:-----------------------------------------------------------------------------------------------------|
|
||||
| [`viz`](compose_alpha_viz.md) | EXPERIMENTAL - Generate a graphviz graph from your compose file |
|
||||
| [`watch`](compose_alpha_watch.md) | EXPERIMENTAL - Watch build context for service and rebuild/refresh containers when files are updated |
|
||||
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------|:-----|:--------|:--------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
8
docs/reference/compose_alpha_dry-run.md
Normal file
8
docs/reference/compose_alpha_dry-run.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# docker compose alpha dry-run
|
||||
|
||||
<!---MARKER_GEN_START-->
|
||||
EXPERIMENTAL - Dry run command allow you to test a command without applying changes
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
19
docs/reference/compose_alpha_viz.md
Normal file
19
docs/reference/compose_alpha_viz.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# docker compose alpha viz
|
||||
|
||||
<!---MARKER_GEN_START-->
|
||||
EXPERIMENTAL - Generate a graphviz graph from your compose file
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:---------------------|:------|:--------|:---------------------------------------------------------------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--image` | | | Include service's image name in output graph |
|
||||
| `--indentation-size` | `int` | `1` | Number of tabs or spaces to use for indentation |
|
||||
| `--networks` | | | Include service's attached networks in output graph |
|
||||
| `--ports` | | | Include service's exposed ports in output graph |
|
||||
| `--spaces` | | | If given, space character ' ' will be used to indent,<br>otherwise tab character '\t' will be used |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
15
docs/reference/compose_alpha_watch.md
Normal file
15
docs/reference/compose_alpha_watch.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# docker compose alpha watch
|
||||
|
||||
<!---MARKER_GEN_START-->
|
||||
EXPERIMENTAL - Watch build context for service and rebuild/refresh containers when files are updated
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------|:-----|:--------|:--------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--quiet` | | | hide build output |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -5,14 +5,17 @@ Build or rebuild services
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------|:--------------|:--------|:------------------------------------------------------------------------------------------------------------|
|
||||
| `--build-arg` | `stringArray` | | Set build-time variables for services. |
|
||||
| `--no-cache` | | | Do not use cache when building the image |
|
||||
| `--progress` | `string` | `auto` | Set type of progress output (auto, tty, plain, quiet) |
|
||||
| `--pull` | | | Always attempt to pull a newer version of the image. |
|
||||
| `-q`, `--quiet` | | | Don't print anything to STDOUT |
|
||||
| `--ssh` | `string` | | Set SSH authentications used when building service images. (use 'default' for using your default SSH Agent) |
|
||||
| Name | Type | Default | Description |
|
||||
|:-----------------|:--------------|:--------|:------------------------------------------------------------------------------------------------------------|
|
||||
| `--build-arg` | `stringArray` | | Set build-time variables for services. |
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `-m`, `--memory` | `bytes` | `0` | Set memory limit for the build container. Not supported by BuildKit. |
|
||||
| `--no-cache` | | | Do not use cache when building the image |
|
||||
| `--progress` | `string` | `auto` | Set type of progress output (auto, tty, plain, quiet) |
|
||||
| `--pull` | | | Always attempt to pull a newer version of the image. |
|
||||
| `--push` | | | Push service images. |
|
||||
| `-q`, `--quiet` | | | Don't print anything to STDOUT |
|
||||
| `--ssh` | `string` | | Set SSH authentications used when building service images. (use 'default' for using your default SSH Agent) |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
# docker compose convert
|
||||
|
||||
<!---MARKER_GEN_START-->
|
||||
Converts the compose file to platform's canonical format
|
||||
Parse, resolve and render compose file in canonical format
|
||||
|
||||
### Aliases
|
||||
|
||||
`docker compose convert`, `docker compose config`
|
||||
`docker compose config`, `docker compose convert`
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:--------------------------|:---------|:--------|:----------------------------------------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--format` | `string` | `yaml` | Format the output. Values: [yaml \| json] |
|
||||
| `--hash` | `string` | | Print the service config hash, one per line. |
|
||||
| `--images` | | | Print the image names, one per line. |
|
||||
| `--no-consistency` | | | Don't check model consistency - warning: may produce invalid Compose output |
|
||||
| `--no-interpolate` | | | Don't interpolate environment variables. |
|
||||
| `--no-normalize` | | | Don't normalize compose model. |
|
||||
| `--no-path-resolution` | | | Don't resolve file paths. |
|
||||
| `-o`, `--output` | `string` | | Save to file (default to stdout) |
|
||||
| `--profiles` | | | Print the profile names, one per line. |
|
||||
| `-q`, `--quiet` | | | Only validate the configuration, don't print anything. |
|
||||
@@ -29,8 +31,6 @@ Converts the compose file to platform's canonical format
|
||||
|
||||
## Description
|
||||
|
||||
`docker compose convert` renders the actual data model to be applied on the target platform. When used with the Docker engine,
|
||||
`docker compose config` renders the actual data model to be applied on the Docker engine.
|
||||
it merges the Compose files set by `-f` flags, resolves variables in the Compose file, and expands short-notation into
|
||||
the canonical format.
|
||||
|
||||
To allow smooth migration from docker-compose, this subcommand declares alias `docker compose config`
|
||||
@@ -8,6 +8,7 @@ Copy files/folders between a service container and the local filesystem
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------------|:------|:--------|:----------------------------------------------------------------------|
|
||||
| `-a`, `--archive` | | | Archive mode (copy all uid/gid information) |
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `-L`, `--follow-link` | | | Always follow symbol link in SRC_PATH |
|
||||
| `--index` | `int` | `0` | Index of the container if there are multiple instances of a service . |
|
||||
|
||||
|
||||
@@ -5,13 +5,16 @@ Creates containers for a service.
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:-------------------|:---------|:----------|:--------------------------------------------------------------------------------------|
|
||||
| `--build` | | | Build images before starting containers. |
|
||||
| `--force-recreate` | | | Recreate containers even if their configuration and image haven't changed. |
|
||||
| `--no-build` | | | Don't build an image, even if it's missing. |
|
||||
| `--no-recreate` | | | If containers already exist, don't recreate them. Incompatible with --force-recreate. |
|
||||
| `--pull` | `string` | `missing` | Pull image before running ("always"\|"missing"\|"never") |
|
||||
| Name | Type | Default | Description |
|
||||
|:-------------------|:--------------|:----------|:----------------------------------------------------------------------------------------------|
|
||||
| `--build` | | | Build images before starting containers. |
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--force-recreate` | | | Recreate containers even if their configuration and image haven't changed. |
|
||||
| `--no-build` | | | Don't build an image, even if it's missing. |
|
||||
| `--no-recreate` | | | If containers already exist, don't recreate them. Incompatible with --force-recreate. |
|
||||
| `--pull` | `string` | `missing` | Pull image before running ("always"\|"missing"\|"never") |
|
||||
| `--remove-orphans` | | | Remove containers for services not defined in the Compose file. |
|
||||
| `--scale` | `stringArray` | | Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present. |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -7,6 +7,7 @@ Stop and remove containers, networks
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:-------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--remove-orphans` | | | Remove containers for services not defined in the Compose file. |
|
||||
| `--rmi` | `string` | | Remove images used by services. "local" remove only images that don't have a custom tag ("local"\|"all") |
|
||||
| `-t`, `--timeout` | `int` | `10` | Specify a shutdown timeout in seconds |
|
||||
|
||||
@@ -5,9 +5,10 @@ Receive real time events from containers.
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:---------|:-----|:--------|:------------------------------------------|
|
||||
| `--json` | | | Output events as a stream of json objects |
|
||||
| Name | Type | Default | Description |
|
||||
|:------------|:-----|:--------|:------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--json` | | | Output events as a stream of json objects |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -8,6 +8,7 @@ Execute a command in a running container.
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------|:--------------|:--------|:----------------------------------------------------------------------------------|
|
||||
| `-d`, `--detach` | | | Detached mode: Run command in the background. |
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `-e`, `--env` | `stringArray` | | Set environment variables |
|
||||
| `--index` | `int` | `1` | index of the container if there are multiple instances of a service [default: 1]. |
|
||||
| `-T`, `--no-TTY` | | | Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY. |
|
||||
|
||||
@@ -7,6 +7,7 @@ List images used by the created containers
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------|:---------|:--------|:--------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--format` | `string` | `table` | Format the output. Values: [table \| json]. |
|
||||
| `-q`, `--quiet` | | | Only display IDs |
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ Force stop service containers.
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:-------------------|:---------|:----------|:----------------------------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--remove-orphans` | | | Remove containers for services not defined in the Compose file. |
|
||||
| `-s`, `--signal` | `string` | `SIGKILL` | SIGNAL to send to the container. |
|
||||
|
||||
|
||||
@@ -7,11 +7,12 @@ View output from containers
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:---------------------|:---------|:--------|:-----------------------------------------------------------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `-f`, `--follow` | | | Follow log output. |
|
||||
| `--no-color` | | | Produce monochrome output. |
|
||||
| `--no-log-prefix` | | | Don't print prefix in logs. |
|
||||
| `--since` | `string` | | Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes) |
|
||||
| `--tail` | `string` | `all` | Number of lines to show from the end of the logs for each container. |
|
||||
| `-n`, `--tail` | `string` | `all` | Number of lines to show from the end of the logs for each container. |
|
||||
| `-t`, `--timestamps` | | | Show timestamps. |
|
||||
| `--until` | `string` | | Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes) |
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ List running compose projects
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------|:---------|:--------|:--------------------------------------------|
|
||||
| `-a`, `--all` | | | Show all stopped Compose projects |
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--filter` | `filter` | | Filter output based on conditions provided. |
|
||||
| `--format` | `string` | `table` | Format the output. Values: [table \| json]. |
|
||||
| `-q`, `--quiet` | | | Only display IDs. |
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
<!---MARKER_GEN_START-->
|
||||
Pause services
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------|:-----|:--------|:--------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ Print the public port for a port binding.
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:-------------|:---------|:--------|:--------------------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--index` | `int` | `1` | index of the container if service has multiple replicas |
|
||||
| `--protocol` | `string` | `tcp` | tcp or udp |
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ List containers
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------------|:--------------|:--------|:--------------------------------------------------------------------------------------------------------------|
|
||||
| `-a`, `--all` | | | Show all stopped containers (including those created by the run command) |
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| [`--filter`](#filter) | `string` | | Filter services by a property (supported filters: status). |
|
||||
| [`--format`](#format) | `string` | `table` | Format the output. Values: [table \| json] |
|
||||
| `-q`, `--quiet` | | | Only display IDs |
|
||||
@@ -20,13 +21,20 @@ List containers
|
||||
## Description
|
||||
|
||||
Lists containers for a Compose project, with current status and exposed ports.
|
||||
By default, both running and stopped containers are shown:
|
||||
|
||||
```console
|
||||
$ docker compose ps
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
example-bar-1 "/docker-entrypoint.…" bar exited (0)
|
||||
example-foo-1 "/docker-entrypoint.…" foo running 0.0.0.0:8080->80/tcp
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
example-foo-1 alpine "/entrypoint.…" foo 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp
|
||||
```
|
||||
|
||||
By default, only running containers are shown. `--all` flag can be used to include stopped containers
|
||||
|
||||
```console
|
||||
$ docker compose ps --all
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
example-foo-1 alpine "/entrypoint.…" foo 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp
|
||||
example-bar-1 alpine "/entrypoint.…" bar 4 seconds ago exited (0)
|
||||
```
|
||||
|
||||
## Examples
|
||||
@@ -89,12 +97,12 @@ to show only containers that are running or only containers that have exited:
|
||||
|
||||
```console
|
||||
$ docker compose ps --status=running
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
example-foo-1 "/docker-entrypoint.…" foo running 0.0.0.0:8080->80/tcp
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
example-foo-1 alpine "/entrypoint.…" foo 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp
|
||||
|
||||
$ docker compose ps --status=exited
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
example-bar-1 "/docker-entrypoint.…" bar exited (0)
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
example-bar-1 alpine "/entrypoint.…" bar 4 seconds ago exited (0)
|
||||
```
|
||||
|
||||
### <a name="filter"></a> Filter containers by status (--filter)
|
||||
@@ -105,12 +113,8 @@ this time using the `--filter` flag:
|
||||
|
||||
```console
|
||||
$ docker compose ps --filter status=running
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
example-foo-1 "/docker-entrypoint.…" foo running 0.0.0.0:8080->80/tcp
|
||||
|
||||
$ docker compose ps --filter status=running
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
example-bar-1 "/docker-entrypoint.…" bar exited (0)
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
example-foo-1 alpine "/entrypoint.…" foo 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp
|
||||
```
|
||||
|
||||
The `docker compose ps` command currently only supports the `--filter status=<status>`
|
||||
|
||||
@@ -7,6 +7,7 @@ Pull service images
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:-------------------------|:-----|:--------|:--------------------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--ignore-buildable` | | | Ignore images that can be built. |
|
||||
| `--ignore-pull-failures` | | | Pull what it can and ignores images with pull failures. |
|
||||
| `--include-deps` | | | Also pull services declared as dependencies. |
|
||||
|
||||
@@ -7,6 +7,7 @@ Push service images
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:-------------------------|:-----|:--------|:-------------------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--ignore-push-failures` | | | Push what it can and ignores images with push failures |
|
||||
| `--include-deps` | | | Also push images of services declared as dependencies |
|
||||
| `-q`, `--quiet` | | | Push without printing progress information |
|
||||
|
||||
@@ -7,6 +7,8 @@ Restart service containers
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------|:------|:--------|:--------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--no-deps` | | | Don't restart dependent services. |
|
||||
| `-t`, `--timeout` | `int` | `10` | Specify a shutdown timeout in seconds |
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ Any data which is not in a volume will be lost.
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------|:-----|:--------|:----------------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `-f`, `--force` | | | Don't ask to confirm removal |
|
||||
| `-s`, `--stop` | | | Stop the containers, if required, before removing |
|
||||
| `-v`, `--volumes` | | | Remove any anonymous volumes attached to containers |
|
||||
|
||||
@@ -9,6 +9,7 @@ Run a one-off command on a service.
|
||||
|:----------------------|:--------------|:--------|:----------------------------------------------------------------------------------|
|
||||
| `--build` | | | Build image before starting container. |
|
||||
| `-d`, `--detach` | | | Run container in background and print container ID |
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--entrypoint` | `string` | | Override the entrypoint of the image |
|
||||
| `-e`, `--env` | `stringArray` | | Set environment variables |
|
||||
| `-i`, `--interactive` | | | Keep STDIN open even if not attached. |
|
||||
@@ -18,6 +19,7 @@ Run a one-off command on a service.
|
||||
| `--no-deps` | | | Don't start linked services. |
|
||||
| `-p`, `--publish` | `stringArray` | | Publish a container's port(s) to the host. |
|
||||
| `--quiet-pull` | | | Pull without printing progress information. |
|
||||
| `--remove-orphans` | | | Remove containers for services not defined in the Compose file. |
|
||||
| `--rm` | | | Automatically remove the container when it exits |
|
||||
| `--service-ports` | | | Run command with the service's ports enabled and mapped to the host. |
|
||||
| `--use-aliases` | | | Use the service's network useAliases in the network(s) the container connects to. |
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
<!---MARKER_GEN_START-->
|
||||
Start services
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------|:-----|:--------|:--------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ Stop services
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------|:------|:--------|:--------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `-t`, `--timeout` | `int` | `10` | Specify a shutdown timeout in seconds |
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
<!---MARKER_GEN_START-->
|
||||
Display the running processes
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------|:-----|:--------|:--------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
<!---MARKER_GEN_START-->
|
||||
Unpause services
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------|:-----|:--------|:--------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ Create and start containers
|
||||
| `--attach-dependencies` | | | Attach to dependent containers. |
|
||||
| `--build` | | | Build images before starting containers. |
|
||||
| `-d`, `--detach` | | | Detached mode: Run containers in the background |
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `--exit-code-from` | `string` | | Return the exit code of the selected service container. Implies --abort-on-container-exit |
|
||||
| `--force-recreate` | | | Recreate containers even if their configuration and image haven't changed. |
|
||||
| `--no-attach` | `stringArray` | | Don't attach to specified service. |
|
||||
@@ -30,6 +31,7 @@ Create and start containers
|
||||
| `-t`, `--timeout` | `int` | `10` | Use this timeout in seconds for container shutdown when attached or when containers are already running. |
|
||||
| `--timestamps` | | | Show timestamps. |
|
||||
| `--wait` | | | Wait for services to be running\|healthy. Implies detached mode. |
|
||||
| `--wait-timeout` | `int` | `0` | timeout waiting for application to be running\|healthy. |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -7,6 +7,7 @@ Show the Docker Compose version information
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:-----------------|:---------|:--------|:---------------------------------------------------------------|
|
||||
| `--dry-run` | | | Execute command in dry run mode |
|
||||
| `-f`, `--format` | `string` | | Format the output. Values: [pretty \| json]. (Default: pretty) |
|
||||
| `--short` | | | Shows only Compose's version number. |
|
||||
|
||||
|
||||
@@ -63,12 +63,19 @@ long: |-
|
||||
|
||||
### Use `-p` to specify a project name
|
||||
|
||||
Each configuration has a project name. If you supply a `-p` flag, you can specify a project name. If you don’t
|
||||
specify the flag, Compose uses the current directory name.
|
||||
Project name can also be set by `COMPOSE_PROJECT_NAME` environment variable.
|
||||
|
||||
Many Compose subcommands can be run without a Compose file by passing
|
||||
the project name.
|
||||
Each configuration has a project name. Compose sets the project name using
|
||||
the following mechanisms, in order of precedence:
|
||||
- The `-p` command line flag
|
||||
- The `COMPOSE_PROJECT_NAME` environment variable
|
||||
- The top level `name:` variable from the config file (or the last `name:`
|
||||
from a series of config files specified using `-f`)
|
||||
- The `basename` of the project directory containing the config file (or
|
||||
containing the first config file specified using `-f`)
|
||||
- The `basename` of the current directory if no config file is specified
|
||||
Project names must contain only lowercase letters, decimal digits, dashes,
|
||||
and underscores, and must begin with a lowercase letter or decimal digit. If
|
||||
the `basename` of the project directory or current directory violates this
|
||||
constraint, you must use one of the other mechanisms.
|
||||
|
||||
```console
|
||||
$ docker compose -p my_project ps -a
|
||||
@@ -89,24 +96,78 @@ long: |-
|
||||
|
||||
Profiles can also be set by `COMPOSE_PROFILES` environment variable.
|
||||
|
||||
### Configuring parallelism
|
||||
|
||||
Use `--parallel` to specify the maximum level of parallelism for concurrent engine calls.
|
||||
Calling `docker compose --parallel 1 pull` will pull the pullable images defined in the Compose file
|
||||
one at a time. This can also be used to control build concurrency.
|
||||
|
||||
Parallelism can also be set by the `COMPOSE_PARALLEL_LIMIT` environment variable.
|
||||
|
||||
### Set up environment variables
|
||||
|
||||
You can set environment variables for various docker compose options, including the `-f`, `-p` and `--profiles` flags.
|
||||
|
||||
Setting the `COMPOSE_FILE` environment variable is equivalent to passing the `-f` flag,
|
||||
`COMPOSE_PROJECT_NAME` environment variable does the same as the `-p` flag,
|
||||
and `COMPOSE_PROFILES` environment variable is equivalent to the `--profiles` flag.
|
||||
`COMPOSE_PROFILES` environment variable is equivalent to the `--profiles` flag
|
||||
and `COMPOSE_PARALLEL_LIMIT` does the same as the `--parallel` flag.
|
||||
|
||||
If flags are explicitly set on the command line, the associated environment variable is ignored.
|
||||
|
||||
Setting the `COMPOSE_IGNORE_ORPHANS` environment variable to `true` will stop docker compose from detecting orphaned
|
||||
containers for the project.
|
||||
|
||||
|
||||
### Use Dry Run mode to test your command
|
||||
|
||||
Use `--dry-run` flag to test a command without changing your application stack state.
|
||||
Dry Run mode shows you all the steps Compose applies when executing a command, for example:
|
||||
```console
|
||||
$ docker compose --dry-run up --build -d
|
||||
[+] Pulling 1/1
|
||||
✔ DRY-RUN MODE - db Pulled 0.9s
|
||||
[+] Running 10/8
|
||||
✔ DRY-RUN MODE - build service backend 0.0s
|
||||
✔ DRY-RUN MODE - ==> ==> writing image dryRun-754a08ddf8bcb1cf22f310f09206dd783d42f7dd 0.0s
|
||||
✔ DRY-RUN MODE - ==> ==> naming to nginx-golang-mysql-backend 0.0s
|
||||
✔ DRY-RUN MODE - Network nginx-golang-mysql_default Created 0.0s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-db-1 Created 0.0s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-backend-1 Created 0.0s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-proxy-1 Created 0.0s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-db-1 Healthy 0.5s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-backend-1 Started 0.0s
|
||||
✔ DRY-RUN MODE - Container nginx-golang-mysql-proxy-1 Started Started
|
||||
```
|
||||
From the example above, you can see that the first step is to pull the image defined by `db` service, then build the `backend` service.
|
||||
Next, the containers are created. The `db` service is started, and the `backend` and `proxy` wait until the `db` service is healthy before starting.
|
||||
|
||||
Dry Run mode does not currently work with all commands. In particular, you cannot use Dry Run mode with a command that doesn't change the state of a Compose stack
|
||||
such as `ps`, `ls`, `logs` for example.
|
||||
|
||||
Here the list of commands supporting `--dry-run` flag:
|
||||
* build
|
||||
* cp
|
||||
* create
|
||||
* down
|
||||
* exec
|
||||
* kill
|
||||
* pause
|
||||
* pull
|
||||
* push
|
||||
* remove
|
||||
* restart
|
||||
* run
|
||||
* start
|
||||
* stop
|
||||
* unpause
|
||||
* up
|
||||
usage: docker compose
|
||||
pname: docker
|
||||
plink: docker.yaml
|
||||
cname:
|
||||
- docker compose build
|
||||
- docker compose convert
|
||||
- docker compose config
|
||||
- docker compose cp
|
||||
- docker compose create
|
||||
- docker compose down
|
||||
@@ -132,7 +193,7 @@ cname:
|
||||
- docker compose version
|
||||
clink:
|
||||
- docker_compose_build.yaml
|
||||
- docker_compose_convert.yaml
|
||||
- docker_compose_config.yaml
|
||||
- docker_compose_cp.yaml
|
||||
- docker_compose_create.yaml
|
||||
- docker_compose_down.yaml
|
||||
@@ -178,8 +239,19 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: env-file
|
||||
value_type: string
|
||||
value_type: stringArray
|
||||
default_value: '[]'
|
||||
description: Specify an alternate environment file.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
|
||||
28
docs/reference/docker_compose_alpha.yaml
Normal file
28
docs/reference/docker_compose_alpha.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
command: docker compose alpha
|
||||
short: Experimental commands
|
||||
long: Experimental commands
|
||||
pname: docker compose
|
||||
plink: docker_compose.yaml
|
||||
cname:
|
||||
- docker compose alpha viz
|
||||
- docker compose alpha watch
|
||||
clink:
|
||||
- docker_compose_alpha_viz.yaml
|
||||
- docker_compose_alpha_watch.yaml
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: true
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
|
||||
14
docs/reference/docker_compose_alpha_dry-run.yaml
Normal file
14
docs/reference/docker_compose_alpha_dry-run.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
command: docker compose alpha dry-run
|
||||
short: |
|
||||
EXPERIMENTAL - Dry run command allow you to test a command without applying changes
|
||||
long: |
|
||||
EXPERIMENTAL - Dry run command allow you to test a command without applying changes
|
||||
usage: docker compose alpha dry-run -- [COMMAND...]
|
||||
pname: docker compose alpha
|
||||
plink: docker_compose_alpha.yaml
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: true
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
|
||||
76
docs/reference/docker_compose_alpha_viz.yaml
Normal file
76
docs/reference/docker_compose_alpha_viz.yaml
Normal file
@@ -0,0 +1,76 @@
|
||||
command: docker compose alpha viz
|
||||
short: EXPERIMENTAL - Generate a graphviz graph from your compose file
|
||||
long: EXPERIMENTAL - Generate a graphviz graph from your compose file
|
||||
usage: docker compose alpha viz [OPTIONS]
|
||||
pname: docker compose alpha
|
||||
plink: docker_compose_alpha.yaml
|
||||
options:
|
||||
- option: image
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Include service's image name in output graph
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: indentation-size
|
||||
value_type: int
|
||||
default_value: "1"
|
||||
description: Number of tabs or spaces to use for indentation
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: networks
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Include service's attached networks in output graph
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: ports
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Include service's exposed ports in output graph
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: spaces
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: |-
|
||||
If given, space character ' ' will be used to indent,
|
||||
otherwise tab character '\t' will be used
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: true
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
|
||||
36
docs/reference/docker_compose_alpha_watch.yaml
Normal file
36
docs/reference/docker_compose_alpha_watch.yaml
Normal file
@@ -0,0 +1,36 @@
|
||||
command: docker compose alpha watch
|
||||
short: |
|
||||
EXPERIMENTAL - Watch build context for service and rebuild/refresh containers when files are updated
|
||||
long: |
|
||||
EXPERIMENTAL - Watch build context for service and rebuild/refresh containers when files are updated
|
||||
usage: docker compose alpha watch [SERVICE...]
|
||||
pname: docker compose alpha
|
||||
plink: docker_compose_alpha.yaml
|
||||
options:
|
||||
- option: quiet
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: hide build output
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: true
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
|
||||
@@ -46,11 +46,12 @@ options:
|
||||
swarm: false
|
||||
- option: memory
|
||||
shorthand: m
|
||||
value_type: string
|
||||
value_type: bytes
|
||||
default_value: "0"
|
||||
description: |
|
||||
Set memory limit for the build container. Not supported on buildkit yet.
|
||||
Set memory limit for the build container. Not supported by BuildKit.
|
||||
deprecated: false
|
||||
hidden: true
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
@@ -106,6 +107,16 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: push
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Push service images.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: quiet
|
||||
shorthand: q
|
||||
value_type: bool
|
||||
@@ -127,6 +138,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
159
docs/reference/docker_compose_config.yaml
Normal file
159
docs/reference/docker_compose_config.yaml
Normal file
@@ -0,0 +1,159 @@
|
||||
command: docker compose config
|
||||
aliases: docker compose config, docker compose convert
|
||||
short: Parse, resolve and render compose file in canonical format
|
||||
long: |-
|
||||
`docker compose config` renders the actual data model to be applied on the Docker engine.
|
||||
it merges the Compose files set by `-f` flags, resolves variables in the Compose file, and expands short-notation into
|
||||
the canonical format.
|
||||
usage: docker compose config [OPTIONS] [SERVICE...]
|
||||
pname: docker compose
|
||||
plink: docker_compose.yaml
|
||||
options:
|
||||
- option: format
|
||||
value_type: string
|
||||
default_value: yaml
|
||||
description: 'Format the output. Values: [yaml | json]'
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: hash
|
||||
value_type: string
|
||||
description: Print the service config hash, one per line.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: images
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Print the image names, one per line.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: no-consistency
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: |
|
||||
Don't check model consistency - warning: may produce invalid Compose output
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: no-interpolate
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Don't interpolate environment variables.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: no-normalize
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Don't normalize compose model.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: no-path-resolution
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Don't resolve file paths.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: output
|
||||
shorthand: o
|
||||
value_type: string
|
||||
description: Save to file (default to stdout)
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: profiles
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Print the profile names, one per line.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: quiet
|
||||
shorthand: q
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Only validate the configuration, don't print anything.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: resolve-image-digests
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Pin image tags to digests.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: services
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Print the service names, one per line.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: volumes
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Print the volume names, one per line.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
|
||||
@@ -50,6 +50,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -57,6 +57,38 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: remove-orphans
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Remove containers for services not defined in the Compose file.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: scale
|
||||
value_type: stringArray
|
||||
default_value: '[]'
|
||||
description: |
|
||||
Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -61,6 +61,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -34,6 +34,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -106,6 +106,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -26,6 +26,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -31,6 +31,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -47,6 +47,7 @@ options:
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: tail
|
||||
shorthand: "n"
|
||||
value_type: string
|
||||
default_value: all
|
||||
description: |
|
||||
@@ -78,6 +79,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -46,6 +46,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -5,6 +5,17 @@ long: |
|
||||
usage: docker compose pause [SERVICE...]
|
||||
pname: docker compose
|
||||
plink: docker_compose.yaml
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -25,6 +25,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -2,13 +2,20 @@ command: docker compose ps
|
||||
short: List containers
|
||||
long: |-
|
||||
Lists containers for a Compose project, with current status and exposed ports.
|
||||
By default, both running and stopped containers are shown:
|
||||
|
||||
```console
|
||||
$ docker compose ps
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
example-bar-1 "/docker-entrypoint.…" bar exited (0)
|
||||
example-foo-1 "/docker-entrypoint.…" foo running 0.0.0.0:8080->80/tcp
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
example-foo-1 alpine "/entrypoint.…" foo 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp
|
||||
```
|
||||
|
||||
By default, only running containers are shown. `--all` flag can be used to include stopped containers
|
||||
|
||||
```console
|
||||
$ docker compose ps --all
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
example-foo-1 alpine "/entrypoint.…" foo 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp
|
||||
example-bar-1 alpine "/entrypoint.…" bar 4 seconds ago exited (0)
|
||||
```
|
||||
usage: docker compose ps [OPTIONS] [SERVICE...]
|
||||
pname: docker compose
|
||||
@@ -80,6 +87,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
examples: |-
|
||||
### Format the output (--format) {#format}
|
||||
|
||||
@@ -139,12 +157,12 @@ examples: |-
|
||||
|
||||
```console
|
||||
$ docker compose ps --status=running
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
example-foo-1 "/docker-entrypoint.…" foo running 0.0.0.0:8080->80/tcp
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
example-foo-1 alpine "/entrypoint.…" foo 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp
|
||||
|
||||
$ docker compose ps --status=exited
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
example-bar-1 "/docker-entrypoint.…" bar exited (0)
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
example-bar-1 alpine "/entrypoint.…" bar 4 seconds ago exited (0)
|
||||
```
|
||||
|
||||
### Filter containers by status (--filter) {#filter}
|
||||
@@ -155,12 +173,8 @@ examples: |-
|
||||
|
||||
```console
|
||||
$ docker compose ps --filter status=running
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
example-foo-1 "/docker-entrypoint.…" foo running 0.0.0.0:8080->80/tcp
|
||||
|
||||
$ docker compose ps --filter status=running
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
example-bar-1 "/docker-entrypoint.…" bar exited (0)
|
||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||
example-foo-1 alpine "/entrypoint.…" foo 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp
|
||||
```
|
||||
|
||||
The `docker compose ps` command currently only supports the `--filter status=<status>`
|
||||
|
||||
@@ -68,6 +68,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
examples: |-
|
||||
suppose you have this `compose.yaml`:
|
||||
|
||||
|
||||
@@ -54,6 +54,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -15,6 +15,16 @@ usage: docker compose restart [OPTIONS] [SERVICE...]
|
||||
pname: docker compose
|
||||
plink: docker_compose.yaml
|
||||
options:
|
||||
- option: no-deps
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Don't restart dependent services.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: timeout
|
||||
shorthand: t
|
||||
value_type: int
|
||||
@@ -26,6 +36,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -64,6 +64,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -172,6 +172,16 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: remove-orphans
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Remove containers for services not defined in the Compose file.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: rm
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
@@ -246,6 +256,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -4,6 +4,17 @@ long: Starts existing containers for a service.
|
||||
usage: docker compose start [SERVICE...]
|
||||
pname: docker compose
|
||||
plink: docker_compose.yaml
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -17,6 +17,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -4,6 +4,17 @@ long: Displays the running processes.
|
||||
usage: docker compose top [SERVICES...]
|
||||
pname: docker compose
|
||||
plink: docker_compose.yaml
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
examples: |-
|
||||
```console
|
||||
$ docker compose top
|
||||
|
||||
@@ -4,6 +4,17 @@ long: Unpauses paused containers of a service.
|
||||
usage: docker compose unpause [SERVICE...]
|
||||
pname: docker compose
|
||||
plink: docker_compose.yaml
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -263,6 +263,27 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: wait-timeout
|
||||
value_type: int
|
||||
default_value: "0"
|
||||
description: timeout waiting for application to be running|healthy.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
@@ -25,6 +25,17 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Execute command in dry run mode
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
deprecated: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
|
||||
21
e2e/cucumber-features/build-contexts.feature
Normal file
21
e2e/cucumber-features/build-contexts.feature
Normal file
@@ -0,0 +1,21 @@
|
||||
Feature: Build Contexts
|
||||
|
||||
Background:
|
||||
Given a compose file
|
||||
"""
|
||||
services:
|
||||
a:
|
||||
build:
|
||||
context: .
|
||||
dockerfile_inline: |
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM alpine:latest
|
||||
COPY --from=dep /etc/hostname /
|
||||
additional_contexts:
|
||||
- dep=docker-image://ubuntu:latest
|
||||
"""
|
||||
|
||||
Scenario: Build w/ build context
|
||||
When I run "compose build"
|
||||
Then the exit code is 0
|
||||
|
||||
27
e2e/cucumber-features/ps.feature
Normal file
27
e2e/cucumber-features/ps.feature
Normal file
@@ -0,0 +1,27 @@
|
||||
Feature: PS
|
||||
|
||||
Background:
|
||||
Given a compose file
|
||||
"""
|
||||
services:
|
||||
build:
|
||||
image: test:latest
|
||||
build:
|
||||
context: ./
|
||||
pull:
|
||||
image: alpine
|
||||
command: top
|
||||
"""
|
||||
And a dockerfile
|
||||
"""
|
||||
FROM golang:1.19-alpine
|
||||
"""
|
||||
|
||||
Scenario: external container from compose image exists
|
||||
When I run "compose build"
|
||||
Then the exit code is 0
|
||||
And I run "docker run --name external-test test:latest ls"
|
||||
Then the exit code is 0
|
||||
And I run "compose ps -a"
|
||||
Then the output does not contain "external-test"
|
||||
|
||||
@@ -12,4 +12,4 @@ Background:
|
||||
Scenario: compose up
|
||||
When I run "compose up -d"
|
||||
Then the output contains "simple-1 Started"
|
||||
And service "simple" is "running"
|
||||
And service "simple" is "Up"
|
||||
|
||||
@@ -17,5 +17,5 @@ Scenario: Start single service
|
||||
Then the output contains "simple-1 Created"
|
||||
And the output contains "another-1 Created"
|
||||
Then I run "compose start another"
|
||||
And service "another" is "running"
|
||||
And service "simple" is "created"
|
||||
And service "another" is "Up"
|
||||
And service "simple" is "Created"
|
||||
|
||||
@@ -11,5 +11,7 @@ Background:
|
||||
|
||||
Scenario: --pull always
|
||||
When I run "compose up --pull=always -d"
|
||||
Then the output contains "simple Pulled"
|
||||
And the output contains "simple Pulled"
|
||||
Then I run "compose up --pull=always -d"
|
||||
And the output contains "simple Pulled"
|
||||
|
||||
|
||||
@@ -20,10 +20,12 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/compose-spec/compose-go/loader"
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/cucumber/godog/colors"
|
||||
"github.com/mattn/go-shellwords"
|
||||
@@ -57,12 +59,14 @@ func TestCucumber(t *testing.T) {
|
||||
|
||||
func setup(s *godog.ScenarioContext) {
|
||||
t := s.TestingT()
|
||||
projectName := loader.NormalizeProjectName(strings.Split(t.Name(), "/")[1])
|
||||
cli := e2e.NewCLI(t, e2e.WithEnv(
|
||||
fmt.Sprintf("COMPOSE_PROJECT_NAME=%s", strings.Split(t.Name(), "/")[1]),
|
||||
fmt.Sprintf("COMPOSE_PROJECT_NAME=%s", projectName),
|
||||
))
|
||||
th := testHelper{
|
||||
T: t,
|
||||
CLI: cli,
|
||||
T: t,
|
||||
CLI: cli,
|
||||
ProjectName: projectName,
|
||||
}
|
||||
|
||||
s.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) {
|
||||
@@ -76,40 +80,51 @@ func setup(s *godog.ScenarioContext) {
|
||||
})
|
||||
|
||||
s.Step(`^a compose file$`, th.setComposeFile)
|
||||
s.Step(`^a dockerfile$`, th.setDockerfile)
|
||||
s.Step(`^I run "compose (.*)"$`, th.runComposeCommand)
|
||||
s.Step(`^I run "docker (.*)"$`, th.runDockerCommand)
|
||||
s.Step(`service "(.*)" is "(.*)"$`, th.serviceIsStatus)
|
||||
s.Step(`output contains "(.*)"$`, th.outputContains)
|
||||
s.Step(`output contains "(.*)"$`, th.outputContains(true))
|
||||
s.Step(`output does not contain "(.*)"$`, th.outputContains(false))
|
||||
s.Step(`exit code is (\d+)$`, th.exitCodeIs)
|
||||
}
|
||||
|
||||
type testHelper struct {
|
||||
T *testing.T
|
||||
ProjectName string
|
||||
ComposeFile string
|
||||
TestDir string
|
||||
CommandOutput string
|
||||
CommandExitCode int
|
||||
CLI *e2e.CLI
|
||||
}
|
||||
|
||||
func (th *testHelper) serviceIsStatus(service, status string) error {
|
||||
serviceContainerName := fmt.Sprintf("%s-%s-1", strings.ToLower(th.ProjectName), service)
|
||||
statusRegex := fmt.Sprintf("%s.*%s", serviceContainerName, status)
|
||||
res := th.CLI.RunDockerComposeCmd(th.T, "ps", "-a")
|
||||
statusRegex := fmt.Sprintf("%s\\s+%s", service, status)
|
||||
r, _ := regexp.Compile(statusRegex)
|
||||
if !r.MatchString(res.Combined()) {
|
||||
return fmt.Errorf("Missing/incorrect ps output:\n%s", res.Combined())
|
||||
return fmt.Errorf("Missing/incorrect ps output:\n%s\nregex:\n%s", res.Combined(), statusRegex)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (th *testHelper) outputContains(substring string) error {
|
||||
if !strings.Contains(th.CommandOutput, substring) {
|
||||
return fmt.Errorf("Missing output substring: %s\noutput: %s", substring, th.CommandOutput)
|
||||
func (th *testHelper) outputContains(expected bool) func(string) error {
|
||||
return func(substring string) error {
|
||||
contains := strings.Contains(th.CommandOutput, substring)
|
||||
if contains && !expected {
|
||||
return fmt.Errorf("Unexpected substring in output: %s\noutput: %s", substring, th.CommandOutput)
|
||||
} else if !contains && expected {
|
||||
return fmt.Errorf("Missing substring in output: %s\noutput: %s", substring, th.CommandOutput)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (th *testHelper) exitCodeIs(exitCode int) error {
|
||||
if exitCode != th.CommandExitCode {
|
||||
return fmt.Errorf("Wrong exit code: %d expected: %d", th.CommandExitCode, exitCode)
|
||||
return fmt.Errorf("Wrong exit code: %d expected: %d || command output: %s", th.CommandExitCode, exitCode, th.CommandOutput)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -123,6 +138,21 @@ func (th *testHelper) runComposeCommand(command string) error {
|
||||
|
||||
cmd := th.CLI.NewDockerComposeCmd(th.T, commandArgs...)
|
||||
cmd.Stdin = strings.NewReader(th.ComposeFile)
|
||||
cmd.Dir = th.TestDir
|
||||
res := icmd.RunCmd(cmd)
|
||||
th.CommandOutput = res.Combined()
|
||||
th.CommandExitCode = res.ExitCode
|
||||
return nil
|
||||
}
|
||||
|
||||
func (th *testHelper) runDockerCommand(command string) error {
|
||||
commandArgs, err := shellwords.Parse(command)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := th.CLI.NewDockerCmd(th.T, commandArgs...)
|
||||
cmd.Dir = th.TestDir
|
||||
res := icmd.RunCmd(cmd)
|
||||
th.CommandOutput = res.Combined()
|
||||
th.CommandExitCode = res.ExitCode
|
||||
@@ -133,3 +163,14 @@ func (th *testHelper) setComposeFile(composeString string) error {
|
||||
th.ComposeFile = composeString
|
||||
return nil
|
||||
}
|
||||
|
||||
func (th *testHelper) setDockerfile(dockerfileString string) error {
|
||||
tempDir := th.T.TempDir()
|
||||
th.TestDir = tempDir
|
||||
|
||||
err := os.WriteFile(filepath.Join(tempDir, "Dockerfile"), []byte(dockerfileString), 0o644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
140
go.mod
140
go.mod
@@ -1,62 +1,82 @@
|
||||
module github.com/docker/compose/v2
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.6
|
||||
github.com/buger/goterm v1.0.4
|
||||
github.com/compose-spec/compose-go v1.8.2
|
||||
github.com/compose-spec/compose-go v1.13.5
|
||||
github.com/containerd/console v1.0.3
|
||||
github.com/containerd/containerd v1.6.14
|
||||
github.com/distribution/distribution/v3 v3.0.0-20221201083218-92d136e113cf
|
||||
github.com/docker/buildx v0.9.1 // when updating, also update the replace rules accordingly
|
||||
github.com/docker/cli v20.10.20+incompatible // replaced; see replace rule for actual version
|
||||
github.com/containerd/containerd v1.6.21
|
||||
github.com/cucumber/godog v0.0.0-00010101000000-000000000000 // replaced; see replace for the actual version used
|
||||
github.com/distribution/distribution/v3 v3.0.0-20230327091844-0c958010ace2
|
||||
github.com/docker/buildx v0.10.4
|
||||
github.com/docker/cli v23.0.6+incompatible
|
||||
github.com/docker/cli-docs-tool v0.5.1
|
||||
github.com/docker/docker v20.10.20+incompatible // replaced; see replace rule for actual version
|
||||
github.com/docker/docker v23.0.6+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-shellwords v1.0.12
|
||||
github.com/moby/buildkit v0.10.4 // replaced; see replace rule for actual version
|
||||
github.com/moby/term v0.0.0-20221128092401-c43b287e0e0f
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/moby/buildkit v0.11.6
|
||||
github.com/moby/term v0.5.0
|
||||
github.com/morikuni/aec v1.0.0
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.1.0-rc2
|
||||
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/theupdateframework/notary v0.7.0
|
||||
go.opentelemetry.io/otel v1.11.2
|
||||
golang.org/x/sync v0.1.0
|
||||
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375
|
||||
go.opentelemetry.io/otel v1.15.1
|
||||
go.uber.org/goleak v1.2.1
|
||||
golang.org/x/sync v0.2.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gotest.tools/v3 v3.4.0
|
||||
k8s.io/client-go v0.24.1 // replaced; see replace for the actual version used
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.15.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.4 // indirect
|
||||
github.com/aws/smithy-go v1.11.2 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bugsnag/bugsnag-go v1.5.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cloudflare/cfssl v1.4.1
|
||||
github.com/containerd/continuity v0.3.0 // indirect
|
||||
github.com/containerd/ttrpc v1.1.0 // indirect
|
||||
github.com/containerd/ttrpc v1.1.1 // indirect
|
||||
github.com/containerd/typeurl v1.0.2 // indirect
|
||||
github.com/cucumber/gherkin-go/v19 v19.0.3 // indirect
|
||||
github.com/cucumber/messages-go/v16 v16.0.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.2 // indirect
|
||||
github.com/fsnotify/fsevents v0.1.1
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/fvbommel/sortorder v1.0.2 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/gofrs/flock v0.8.0 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/gofrs/uuid v4.2.0+incompatible // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
@@ -68,35 +88,48 @@ require (
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-memdb v1.3.2 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/imdario/mergo v0.3.15 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jinzhu/gorm v1.9.11 // indirect
|
||||
github.com/jonboulle/clockwork v0.4.0
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/compress v1.15.9 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/klauspost/compress v1.15.12 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/patternmatcher v0.5.0 // indirect
|
||||
github.com/moby/patternmatcher v0.5.0
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/moby/sys/mountinfo v0.6.2 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/signal v0.7.0 // indirect
|
||||
github.com/moby/sys/symlink v0.2.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/opencontainers/runc v1.1.3 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/opencontainers/runc v1.1.5 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.12.2 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.32.1 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 // indirect
|
||||
github.com/tonistiigi/fsutil v0.0.0-20220930225714-4638ad635be5 // indirect
|
||||
github.com/spf13/afero v1.9.2 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.1 // indirect
|
||||
github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa // indirect
|
||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
||||
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
@@ -114,51 +147,36 @@ require (
|
||||
go.opentelemetry.io/otel/internal/metric v0.27.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v0.27.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.4.1 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.11.2 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.15.1 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.12.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88 // indirect
|
||||
golang.org/x/net v0.4.0 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||
golang.org/x/sys v0.3.0 // indirect
|
||||
golang.org/x/term v0.3.0 // indirect
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
|
||||
golang.org/x/crypto v0.2.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/term v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
|
||||
google.golang.org/grpc v1.47.0 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e // indirect
|
||||
google.golang.org/grpc v1.50.1 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.24.1 // indirect; replaced; see replace for the actual version used
|
||||
k8s.io/apimachinery v0.24.1 // indirect; replaced; see replace for the actual version used
|
||||
k8s.io/client-go v0.24.1 // indirect; replaced; see replace for the actual version used
|
||||
k8s.io/klog/v2 v2.60.1 // indirect
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
|
||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
)
|
||||
|
||||
require github.com/cucumber/godog v0.0.0-00010101000000-000000000000
|
||||
|
||||
require (
|
||||
github.com/bugsnag/bugsnag-go v1.5.0 // indirect
|
||||
github.com/cloudflare/cfssl v1.4.1 // indirect
|
||||
github.com/cucumber/gherkin-go/v19 v19.0.3 // indirect
|
||||
github.com/cucumber/messages-go/v16 v16.0.1 // indirect
|
||||
github.com/gofrs/uuid v4.2.0+incompatible // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-memdb v1.3.2 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/jinzhu/gorm v1.9.11 // indirect
|
||||
github.com/spf13/viper v1.4.0 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
// Override for e2e tests
|
||||
github.com/cucumber/godog => github.com/laurazard/godog v0.0.0-20220922095256-4c4b17abdae7
|
||||
|
||||
github.com/docker/cli => github.com/docker/cli v20.10.3-0.20221013132413-1d6c6e2367e2+incompatible // 22.06 master branch
|
||||
github.com/docker/docker => github.com/docker/docker v20.10.3-0.20221021173910-5aac513617f0+incompatible // 22.06 branch
|
||||
github.com/moby/buildkit => github.com/moby/buildkit v0.10.1-0.20220816171719-55ba9d14360a // same as buildx
|
||||
golang.org/x/oauth2 => golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783
|
||||
|
||||
// For k8s dependencies, we use a replace directive, to prevent them being
|
||||
// upgraded to the version specified in containerd, which is not relevant to the
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/compose/v2/pkg/utils"
|
||||
)
|
||||
|
||||
// Service manages a compose project
|
||||
@@ -52,7 +53,7 @@ type Service interface {
|
||||
// List executes the equivalent to a `docker stack ls`
|
||||
List(ctx context.Context, options ListOptions) ([]Stack, error)
|
||||
// Convert translate compose model into backend's native format
|
||||
Convert(ctx context.Context, project *types.Project, options ConvertOptions) ([]byte, error)
|
||||
Config(ctx context.Context, project *types.Project, options ConfigOptions) ([]byte, error)
|
||||
// Kill executes the equivalent to a `compose kill`
|
||||
Kill(ctx context.Context, projectName string, options KillOptions) error
|
||||
// RunOneOffContainer creates a service oneoff container and starts its dependencies
|
||||
@@ -77,12 +78,35 @@ type Service interface {
|
||||
Images(ctx context.Context, projectName string, options ImagesOptions) ([]ImageSummary, error)
|
||||
// MaxConcurrency defines upper limit for concurrent operations against engine API
|
||||
MaxConcurrency(parallel int)
|
||||
// DryRunMode defines if dry run applies to the command
|
||||
DryRunMode(ctx context.Context, dryRun bool) (context.Context, error)
|
||||
// Watch services' development context and sync/notify/rebuild/restart on changes
|
||||
Watch(ctx context.Context, project *types.Project, services []string, options WatchOptions) error
|
||||
// Viz generates a graphviz graph of the project services
|
||||
Viz(ctx context.Context, project *types.Project, options VizOptions) (string, error)
|
||||
}
|
||||
|
||||
type VizOptions struct {
|
||||
// IncludeNetworks if true, network names a container is attached to should appear in the graph node
|
||||
IncludeNetworks bool
|
||||
// IncludePorts if true, ports a container exposes should appear in the graph node
|
||||
IncludePorts bool
|
||||
// IncludeImageName if true, name of the image used to create a container should appear in the graph node
|
||||
IncludeImageName bool
|
||||
// Indentation string to be used to indent graphviz code, e.g. "\t", " "
|
||||
Indentation string
|
||||
}
|
||||
|
||||
// WatchOptions group options of the Watch API
|
||||
type WatchOptions struct {
|
||||
}
|
||||
|
||||
// BuildOptions group options of the Build API
|
||||
type BuildOptions struct {
|
||||
// Pull always attempt to pull a newer version of the image
|
||||
Pull bool
|
||||
// Push pushes service images
|
||||
Push bool
|
||||
// Progress set type of progress output ("auto", "plain", "tty")
|
||||
Progress string
|
||||
// Args set build-time args
|
||||
@@ -95,6 +119,40 @@ type BuildOptions struct {
|
||||
Services []string
|
||||
// Ssh authentications passed in the command line
|
||||
SSHs []types.SSHKey
|
||||
// Memory limit for the build container
|
||||
Memory int64
|
||||
}
|
||||
|
||||
// Apply mutates project according to build options
|
||||
func (o BuildOptions) Apply(project *types.Project) error {
|
||||
platform := project.Environment["DOCKER_DEFAULT_PLATFORM"]
|
||||
for i, service := range project.Services {
|
||||
if service.Image == "" && service.Build == nil {
|
||||
return fmt.Errorf("invalid service %q. Must specify either image or build", service.Name)
|
||||
}
|
||||
|
||||
if service.Build == nil {
|
||||
continue
|
||||
}
|
||||
service.Image = GetImageNameOrDefault(service, project.Name)
|
||||
if platform != "" {
|
||||
if len(service.Build.Platforms) > 0 && !utils.StringContains(service.Build.Platforms, platform) {
|
||||
return fmt.Errorf("service %q build.platforms does not support value set by DOCKER_DEFAULT_PLATFORM: %s", service.Name, platform)
|
||||
}
|
||||
service.Platform = platform
|
||||
}
|
||||
if service.Platform != "" {
|
||||
if len(service.Build.Platforms) > 0 && !utils.StringContains(service.Build.Platforms, service.Platform) {
|
||||
return fmt.Errorf("service %q build configuration does not support platform: %s", service.Name, service.Platform)
|
||||
}
|
||||
}
|
||||
|
||||
service.Build.Pull = service.Build.Pull || o.Pull
|
||||
service.Build.NoCache = service.Build.NoCache || o.NoCache
|
||||
|
||||
project.Services[i] = service
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateOptions group options of the Create API
|
||||
@@ -130,7 +188,8 @@ type StartOptions struct {
|
||||
// ExitCodeFrom return exit code from specified service
|
||||
ExitCodeFrom string
|
||||
// Wait won't return until containers reached the running|healthy state
|
||||
Wait bool
|
||||
Wait bool
|
||||
WaitTimeout time.Duration
|
||||
// Services passed in the command line to be started
|
||||
Services []string
|
||||
}
|
||||
@@ -175,8 +234,8 @@ type DownOptions struct {
|
||||
Volumes bool
|
||||
}
|
||||
|
||||
// ConvertOptions group options of the Convert API
|
||||
type ConvertOptions struct {
|
||||
// ConfigOptions group options of the Config API
|
||||
type ConfigOptions struct {
|
||||
// Format define the output format used to dump converted application model (json|yaml)
|
||||
Format string
|
||||
// Output defines the path to save the application model
|
||||
@@ -219,8 +278,8 @@ type KillOptions struct {
|
||||
type RemoveOptions struct {
|
||||
// Project is the compose project used to define this app. Might be nil if user ran command just with project name
|
||||
Project *types.Project
|
||||
// DryRun just list removable resources
|
||||
DryRun bool
|
||||
// Stop option passed in the command line
|
||||
Stop bool
|
||||
// Volumes remove anonymous volumes
|
||||
Volumes bool
|
||||
// Force don't ask to confirm removal
|
||||
@@ -458,6 +517,7 @@ type ContainerEvent struct {
|
||||
// This is only suitable for display purposes within Compose, as it's
|
||||
// not guaranteed to be unique across services.
|
||||
Container string
|
||||
ID string
|
||||
Service string
|
||||
Line string
|
||||
// ContainerEventExit only
|
||||
@@ -474,6 +534,8 @@ const (
|
||||
ContainerEventAttach
|
||||
// ContainerEventStopped is a ContainerEvent of type stopped.
|
||||
ContainerEventStopped
|
||||
// ContainerEventRecreated let consumer know container stopped but his being replaced
|
||||
ContainerEventRecreated
|
||||
// ContainerEventExit is a ContainerEvent of type exit. ExitCode is set
|
||||
ContainerEventExit
|
||||
// UserCancel user cancelled compose up, we are stopping containers
|
||||
|
||||
697
pkg/api/dryrunclient.go
Normal file
697
pkg/api/dryrunclient.go
Normal file
@@ -0,0 +1,697 @@
|
||||
/*
|
||||
Copyright 2020 Docker Compose CLI authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/buildx/builder"
|
||||
"github.com/docker/buildx/util/imagetools"
|
||||
"github.com/docker/cli/cli/command"
|
||||
|
||||
"github.com/distribution/distribution/v3/uuid"
|
||||
moby "github.com/docker/docker/api/types"
|
||||
containerType "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
DRYRUN_PREFIX = " DRY-RUN MODE - "
|
||||
)
|
||||
|
||||
var _ client.APIClient = &DryRunClient{}
|
||||
|
||||
type DryRunKey struct{}
|
||||
|
||||
// DryRunClient implements APIClient by delegating to implementation functions. This allows lazy init and per-method overrides
|
||||
type DryRunClient struct {
|
||||
apiClient client.APIClient
|
||||
containers []moby.Container
|
||||
execs sync.Map
|
||||
resolver *imagetools.Resolver
|
||||
}
|
||||
|
||||
type execDetails struct {
|
||||
container string
|
||||
command []string
|
||||
}
|
||||
|
||||
// NewDryRunClient produces a DryRunClient
|
||||
func NewDryRunClient(apiClient client.APIClient, cli *command.DockerCli) (*DryRunClient, error) {
|
||||
b, err := builder.New(cli, builder.WithSkippedValidation())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configFile, err := b.ImageOpt()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DryRunClient{
|
||||
apiClient: apiClient,
|
||||
containers: []moby.Container{},
|
||||
execs: sync.Map{},
|
||||
resolver: imagetools.New(configFile),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getCallingFunction() string {
|
||||
pc, _, _, _ := runtime.Caller(2)
|
||||
fullName := runtime.FuncForPC(pc).Name()
|
||||
return fullName[strings.LastIndex(fullName, ".")+1:]
|
||||
}
|
||||
|
||||
// All methods and functions which need to be overridden for dry run.
|
||||
|
||||
func (d *DryRunClient) ContainerAttach(ctx context.Context, container string, options moby.ContainerAttachOptions) (moby.HijackedResponse, error) {
|
||||
return moby.HijackedResponse{}, errors.New("interactive run is not supported in dry-run mode")
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerCreate(ctx context.Context, config *containerType.Config, hostConfig *containerType.HostConfig,
|
||||
networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (containerType.CreateResponse, error) {
|
||||
d.containers = append(d.containers, moby.Container{
|
||||
ID: containerName,
|
||||
Names: []string{containerName},
|
||||
Labels: config.Labels,
|
||||
HostConfig: struct {
|
||||
NetworkMode string `json:",omitempty"`
|
||||
}{},
|
||||
})
|
||||
return containerType.CreateResponse{ID: containerName}, nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerInspect(ctx context.Context, container string) (moby.ContainerJSON, error) {
|
||||
containerJSON, err := d.apiClient.ContainerInspect(ctx, container)
|
||||
if err != nil {
|
||||
id := "dryRunId"
|
||||
for _, c := range d.containers {
|
||||
if c.ID == container {
|
||||
id = container
|
||||
}
|
||||
}
|
||||
return moby.ContainerJSON{
|
||||
ContainerJSONBase: &moby.ContainerJSONBase{
|
||||
ID: id,
|
||||
Name: container,
|
||||
State: &moby.ContainerState{
|
||||
Status: "running", // needed for --wait option
|
||||
Health: &moby.Health{
|
||||
Status: moby.Healthy, // needed for healthcheck control
|
||||
},
|
||||
},
|
||||
},
|
||||
Mounts: nil,
|
||||
Config: &containerType.Config{},
|
||||
NetworkSettings: &moby.NetworkSettings{},
|
||||
}, nil
|
||||
}
|
||||
return containerJSON, err
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerKill(ctx context.Context, container, signal string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerList(ctx context.Context, options moby.ContainerListOptions) ([]moby.Container, error) {
|
||||
caller := getCallingFunction()
|
||||
switch caller {
|
||||
case "start":
|
||||
return d.containers, nil
|
||||
case "getContainers":
|
||||
if len(d.containers) == 0 {
|
||||
var err error
|
||||
d.containers, err = d.apiClient.ContainerList(ctx, options)
|
||||
return d.containers, err
|
||||
}
|
||||
}
|
||||
return d.apiClient.ContainerList(ctx, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerPause(ctx context.Context, container string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerRemove(ctx context.Context, container string, options moby.ContainerRemoveOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerRename(ctx context.Context, container, newContainerName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerRestart(ctx context.Context, container string, options containerType.StopOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerStart(ctx context.Context, container string, options moby.ContainerStartOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerStop(ctx context.Context, container string, options containerType.StopOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerUnpause(ctx context.Context, container string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, moby.ContainerPathStat, error) {
|
||||
rc := io.NopCloser(strings.NewReader(""))
|
||||
if _, err := d.ContainerStatPath(ctx, container, srcPath); err != nil {
|
||||
return rc, moby.ContainerPathStat{}, fmt.Errorf(" %s Could not find the file %s in container %s", DRYRUN_PREFIX, srcPath, container)
|
||||
}
|
||||
return rc, moby.ContainerPathStat{}, nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options moby.CopyToContainerOptions) error {
|
||||
if _, err := d.ContainerStatPath(ctx, container, path); err != nil {
|
||||
return fmt.Errorf(" %s Could not find the file %s in container %s", DRYRUN_PREFIX, path, container)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImageBuild(ctx context.Context, reader io.Reader, options moby.ImageBuildOptions) (moby.ImageBuildResponse, error) {
|
||||
jsonMessage, err := json.Marshal(&jsonmessage.JSONMessage{
|
||||
Status: fmt.Sprintf("%[1]sSuccessfully built: dryRunID\n%[1]sSuccessfully tagged: %[2]s\n", DRYRUN_PREFIX, options.Tags[0]),
|
||||
Progress: &jsonmessage.JSONProgress{},
|
||||
ID: "",
|
||||
})
|
||||
if err != nil {
|
||||
return moby.ImageBuildResponse{}, err
|
||||
}
|
||||
rc := io.NopCloser(bytes.NewReader(jsonMessage))
|
||||
|
||||
return moby.ImageBuildResponse{
|
||||
Body: rc,
|
||||
OSType: "",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImageInspectWithRaw(ctx context.Context, imageName string) (moby.ImageInspect, []byte, error) {
|
||||
caller := getCallingFunction()
|
||||
switch caller {
|
||||
case "pullServiceImage", "buildContainerVolumes":
|
||||
return moby.ImageInspect{ID: "dryRunId"}, nil, nil
|
||||
default:
|
||||
return d.apiClient.ImageInspectWithRaw(ctx, imageName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImagePull(ctx context.Context, ref string, options moby.ImagePullOptions) (io.ReadCloser, error) {
|
||||
if _, _, err := d.resolver.Resolve(ctx, ref); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rc := io.NopCloser(strings.NewReader(""))
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImagePush(ctx context.Context, ref string, options moby.ImagePushOptions) (io.ReadCloser, error) {
|
||||
if _, _, err := d.resolver.Resolve(ctx, ref); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jsonMessage, err := json.Marshal(&jsonmessage.JSONMessage{
|
||||
Status: "Pushed",
|
||||
Progress: &jsonmessage.JSONProgress{
|
||||
Current: 100,
|
||||
Total: 100,
|
||||
Start: 0,
|
||||
HideCounts: false,
|
||||
Units: "Mb",
|
||||
},
|
||||
ID: ref,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rc := io.NopCloser(bytes.NewReader(jsonMessage))
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImageRemove(ctx context.Context, imageName string, options moby.ImageRemoveOptions) ([]moby.ImageDeleteResponseItem, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NetworkConnect(ctx context.Context, networkName, container string, config *network.EndpointSettings) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NetworkCreate(ctx context.Context, name string, options moby.NetworkCreate) (moby.NetworkCreateResponse, error) {
|
||||
return moby.NetworkCreateResponse{
|
||||
ID: name,
|
||||
Warning: "",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NetworkDisconnect(ctx context.Context, networkName, container string, force bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NetworkRemove(ctx context.Context, networkName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error) {
|
||||
return volume.Volume{
|
||||
ClusterVolume: nil,
|
||||
Driver: options.Driver,
|
||||
Labels: options.Labels,
|
||||
Name: options.Name,
|
||||
Options: options.DriverOpts,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) VolumeRemove(ctx context.Context, volumeID string, force bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerExecCreate(ctx context.Context, container string, config moby.ExecConfig) (moby.IDResponse, error) {
|
||||
id := uuid.Generate().String()
|
||||
d.execs.Store(id, execDetails{
|
||||
container: container,
|
||||
command: config.Cmd,
|
||||
})
|
||||
return moby.IDResponse{
|
||||
ID: id,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerExecStart(ctx context.Context, execID string, config moby.ExecStartCheck) error {
|
||||
v, ok := d.execs.LoadAndDelete(execID)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid exec ID %q", execID)
|
||||
}
|
||||
details := v.(execDetails)
|
||||
fmt.Printf("%sExecuting command %q in %s (detached mode)\n", DRYRUN_PREFIX, details.command, details.container)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Functions delegated to original APIClient (not used by Compose or not modifying the Compose stack
|
||||
|
||||
func (d *DryRunClient) ConfigList(ctx context.Context, options moby.ConfigListOptions) ([]swarm.Config, error) {
|
||||
return d.apiClient.ConfigList(ctx, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ConfigCreate(ctx context.Context, config swarm.ConfigSpec) (moby.ConfigCreateResponse, error) {
|
||||
return d.apiClient.ConfigCreate(ctx, config)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ConfigRemove(ctx context.Context, id string) error {
|
||||
return d.apiClient.ConfigRemove(ctx, id)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ConfigInspectWithRaw(ctx context.Context, name string) (swarm.Config, []byte, error) {
|
||||
return d.apiClient.ConfigInspectWithRaw(ctx, name)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ConfigUpdate(ctx context.Context, id string, version swarm.Version, config swarm.ConfigSpec) error {
|
||||
return d.apiClient.ConfigUpdate(ctx, id, version, config)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerCommit(ctx context.Context, container string, options moby.ContainerCommitOptions) (moby.IDResponse, error) {
|
||||
return d.apiClient.ContainerCommit(ctx, container, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerDiff(ctx context.Context, container string) ([]containerType.ContainerChangeResponseItem, error) {
|
||||
return d.apiClient.ContainerDiff(ctx, container)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerExecAttach(ctx context.Context, execID string, config moby.ExecStartCheck) (moby.HijackedResponse, error) {
|
||||
return moby.HijackedResponse{}, errors.New("interactive exec is not supported in dry-run mode")
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerExecInspect(ctx context.Context, execID string) (moby.ContainerExecInspect, error) {
|
||||
return d.apiClient.ContainerExecInspect(ctx, execID)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerExecResize(ctx context.Context, execID string, options moby.ResizeOptions) error {
|
||||
return d.apiClient.ContainerExecResize(ctx, execID, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerExport(ctx context.Context, container string) (io.ReadCloser, error) {
|
||||
return d.apiClient.ContainerExport(ctx, container)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (moby.ContainerJSON, []byte, error) {
|
||||
return d.apiClient.ContainerInspectWithRaw(ctx, container, getSize)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerLogs(ctx context.Context, container string, options moby.ContainerLogsOptions) (io.ReadCloser, error) {
|
||||
return d.apiClient.ContainerLogs(ctx, container, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerResize(ctx context.Context, container string, options moby.ResizeOptions) error {
|
||||
return d.apiClient.ContainerResize(ctx, container, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerStatPath(ctx context.Context, container, path string) (moby.ContainerPathStat, error) {
|
||||
return d.apiClient.ContainerStatPath(ctx, container, path)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerStats(ctx context.Context, container string, stream bool) (moby.ContainerStats, error) {
|
||||
return d.apiClient.ContainerStats(ctx, container, stream)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerStatsOneShot(ctx context.Context, container string) (moby.ContainerStats, error) {
|
||||
return d.apiClient.ContainerStatsOneShot(ctx, container)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerTop(ctx context.Context, container string, arguments []string) (containerType.ContainerTopOKBody, error) {
|
||||
return d.apiClient.ContainerTop(ctx, container, arguments)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerUpdate(ctx context.Context, container string, updateConfig containerType.UpdateConfig) (containerType.ContainerUpdateOKBody, error) {
|
||||
return d.apiClient.ContainerUpdate(ctx, container, updateConfig)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerWait(ctx context.Context, container string, condition containerType.WaitCondition) (<-chan containerType.WaitResponse, <-chan error) {
|
||||
return d.apiClient.ContainerWait(ctx, container, condition)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (moby.ContainersPruneReport, error) {
|
||||
return d.apiClient.ContainersPrune(ctx, pruneFilters)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) DistributionInspect(ctx context.Context, imageName, encodedRegistryAuth string) (registry.DistributionInspect, error) {
|
||||
return d.apiClient.DistributionInspect(ctx, imageName, encodedRegistryAuth)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) BuildCachePrune(ctx context.Context, opts moby.BuildCachePruneOptions) (*moby.BuildCachePruneReport, error) {
|
||||
return d.apiClient.BuildCachePrune(ctx, opts)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) BuildCancel(ctx context.Context, id string) error {
|
||||
return d.apiClient.BuildCancel(ctx, id)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImageCreate(ctx context.Context, parentReference string, options moby.ImageCreateOptions) (io.ReadCloser, error) {
|
||||
return d.apiClient.ImageCreate(ctx, parentReference, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImageHistory(ctx context.Context, imageName string) ([]image.HistoryResponseItem, error) {
|
||||
return d.apiClient.ImageHistory(ctx, imageName)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImageImport(ctx context.Context, source moby.ImageImportSource, ref string, options moby.ImageImportOptions) (io.ReadCloser, error) {
|
||||
return d.apiClient.ImageImport(ctx, source, ref, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImageList(ctx context.Context, options moby.ImageListOptions) ([]moby.ImageSummary, error) {
|
||||
return d.apiClient.ImageList(ctx, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (moby.ImageLoadResponse, error) {
|
||||
return d.apiClient.ImageLoad(ctx, input, quiet)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImageSearch(ctx context.Context, term string, options moby.ImageSearchOptions) ([]registry.SearchResult, error) {
|
||||
return d.apiClient.ImageSearch(ctx, term, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImageSave(ctx context.Context, images []string) (io.ReadCloser, error) {
|
||||
return d.apiClient.ImageSave(ctx, images)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImageTag(ctx context.Context, imageName, ref string) error {
|
||||
return d.apiClient.ImageTag(ctx, imageName, ref)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImagesPrune(ctx context.Context, pruneFilter filters.Args) (moby.ImagesPruneReport, error) {
|
||||
return d.apiClient.ImagesPrune(ctx, pruneFilter)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) {
|
||||
return d.apiClient.NodeInspectWithRaw(ctx, nodeID)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NodeList(ctx context.Context, options moby.NodeListOptions) ([]swarm.Node, error) {
|
||||
return d.apiClient.NodeList(ctx, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NodeRemove(ctx context.Context, nodeID string, options moby.NodeRemoveOptions) error {
|
||||
return d.apiClient.NodeRemove(ctx, nodeID, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
||||
return d.apiClient.NodeUpdate(ctx, nodeID, version, node)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NetworkInspect(ctx context.Context, networkName string, options moby.NetworkInspectOptions) (moby.NetworkResource, error) {
|
||||
return d.apiClient.NetworkInspect(ctx, networkName, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NetworkInspectWithRaw(ctx context.Context, networkName string, options moby.NetworkInspectOptions) (moby.NetworkResource, []byte, error) {
|
||||
return d.apiClient.NetworkInspectWithRaw(ctx, networkName, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NetworkList(ctx context.Context, options moby.NetworkListOptions) ([]moby.NetworkResource, error) {
|
||||
return d.apiClient.NetworkList(ctx, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NetworksPrune(ctx context.Context, pruneFilter filters.Args) (moby.NetworksPruneReport, error) {
|
||||
return d.apiClient.NetworksPrune(ctx, pruneFilter)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) PluginList(ctx context.Context, filter filters.Args) (moby.PluginsListResponse, error) {
|
||||
return d.apiClient.PluginList(ctx, filter)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) PluginRemove(ctx context.Context, name string, options moby.PluginRemoveOptions) error {
|
||||
return d.apiClient.PluginRemove(ctx, name, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) PluginEnable(ctx context.Context, name string, options moby.PluginEnableOptions) error {
|
||||
return d.apiClient.PluginEnable(ctx, name, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) PluginDisable(ctx context.Context, name string, options moby.PluginDisableOptions) error {
|
||||
return d.apiClient.PluginDisable(ctx, name, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) PluginInstall(ctx context.Context, name string, options moby.PluginInstallOptions) (io.ReadCloser, error) {
|
||||
return d.apiClient.PluginInstall(ctx, name, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) PluginUpgrade(ctx context.Context, name string, options moby.PluginInstallOptions) (io.ReadCloser, error) {
|
||||
return d.apiClient.PluginUpgrade(ctx, name, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) {
|
||||
return d.apiClient.PluginPush(ctx, name, registryAuth)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) PluginSet(ctx context.Context, name string, args []string) error {
|
||||
return d.apiClient.PluginSet(ctx, name, args)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) PluginInspectWithRaw(ctx context.Context, name string) (*moby.Plugin, []byte, error) {
|
||||
return d.apiClient.PluginInspectWithRaw(ctx, name)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) PluginCreate(ctx context.Context, createContext io.Reader, options moby.PluginCreateOptions) error {
|
||||
return d.apiClient.PluginCreate(ctx, createContext, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options moby.ServiceCreateOptions) (moby.ServiceCreateResponse, error) {
|
||||
return d.apiClient.ServiceCreate(ctx, service, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ServiceInspectWithRaw(ctx context.Context, serviceID string, options moby.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||
return d.apiClient.ServiceInspectWithRaw(ctx, serviceID, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ServiceList(ctx context.Context, options moby.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return d.apiClient.ServiceList(ctx, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ServiceRemove(ctx context.Context, serviceID string) error {
|
||||
return d.apiClient.ServiceRemove(ctx, serviceID)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options moby.ServiceUpdateOptions) (moby.ServiceUpdateResponse, error) {
|
||||
return d.apiClient.ServiceUpdate(ctx, serviceID, version, service, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ServiceLogs(ctx context.Context, serviceID string, options moby.ContainerLogsOptions) (io.ReadCloser, error) {
|
||||
return d.apiClient.ServiceLogs(ctx, serviceID, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) TaskLogs(ctx context.Context, taskID string, options moby.ContainerLogsOptions) (io.ReadCloser, error) {
|
||||
return d.apiClient.TaskLogs(ctx, taskID, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) {
|
||||
return d.apiClient.TaskInspectWithRaw(ctx, taskID)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) TaskList(ctx context.Context, options moby.TaskListOptions) ([]swarm.Task, error) {
|
||||
return d.apiClient.TaskList(ctx, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) {
|
||||
return d.apiClient.SwarmInit(ctx, req)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SwarmJoin(ctx context.Context, req swarm.JoinRequest) error {
|
||||
return d.apiClient.SwarmJoin(ctx, req)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SwarmGetUnlockKey(ctx context.Context) (moby.SwarmUnlockKeyResponse, error) {
|
||||
return d.apiClient.SwarmGetUnlockKey(ctx)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error {
|
||||
return d.apiClient.SwarmUnlock(ctx, req)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SwarmLeave(ctx context.Context, force bool) error {
|
||||
return d.apiClient.SwarmLeave(ctx, force)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SwarmInspect(ctx context.Context) (swarm.Swarm, error) {
|
||||
return d.apiClient.SwarmInspect(ctx)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SwarmUpdate(ctx context.Context, version swarm.Version, swarmSpec swarm.Spec, flags swarm.UpdateFlags) error {
|
||||
return d.apiClient.SwarmUpdate(ctx, version, swarmSpec, flags)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SecretList(ctx context.Context, options moby.SecretListOptions) ([]swarm.Secret, error) {
|
||||
return d.apiClient.SecretList(ctx, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (moby.SecretCreateResponse, error) {
|
||||
return d.apiClient.SecretCreate(ctx, secret)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SecretRemove(ctx context.Context, id string) error {
|
||||
return d.apiClient.SecretRemove(ctx, id)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error) {
|
||||
return d.apiClient.SecretInspectWithRaw(ctx, name)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error {
|
||||
return d.apiClient.SecretUpdate(ctx, id, version, secret)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) Events(ctx context.Context, options moby.EventsOptions) (<-chan events.Message, <-chan error) {
|
||||
return d.apiClient.Events(ctx, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) Info(ctx context.Context) (moby.Info, error) {
|
||||
return d.apiClient.Info(ctx)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) RegistryLogin(ctx context.Context, auth moby.AuthConfig) (registry.AuthenticateOKBody, error) {
|
||||
return d.apiClient.RegistryLogin(ctx, auth)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) DiskUsage(ctx context.Context, options moby.DiskUsageOptions) (moby.DiskUsage, error) {
|
||||
return d.apiClient.DiskUsage(ctx, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) Ping(ctx context.Context) (moby.Ping, error) {
|
||||
return d.apiClient.Ping(ctx)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) VolumeInspect(ctx context.Context, volumeID string) (volume.Volume, error) {
|
||||
return d.apiClient.VolumeInspect(ctx, volumeID)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error) {
|
||||
return d.apiClient.VolumeInspectWithRaw(ctx, volumeID)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) VolumeList(ctx context.Context, filter filters.Args) (volume.ListResponse, error) {
|
||||
return d.apiClient.VolumeList(ctx, filter)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) VolumesPrune(ctx context.Context, pruneFilter filters.Args) (moby.VolumesPruneReport, error) {
|
||||
return d.apiClient.VolumesPrune(ctx, pruneFilter)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error {
|
||||
return d.apiClient.VolumeUpdate(ctx, volumeID, version, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ClientVersion() string {
|
||||
return d.apiClient.ClientVersion()
|
||||
}
|
||||
|
||||
func (d *DryRunClient) DaemonHost() string {
|
||||
return d.apiClient.DaemonHost()
|
||||
}
|
||||
|
||||
func (d *DryRunClient) HTTPClient() *http.Client {
|
||||
return d.apiClient.HTTPClient()
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ServerVersion(ctx context.Context) (moby.Version, error) {
|
||||
return d.apiClient.ServerVersion(ctx)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NegotiateAPIVersion(ctx context.Context) {
|
||||
d.apiClient.NegotiateAPIVersion(ctx)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) NegotiateAPIVersionPing(ping moby.Ping) {
|
||||
d.apiClient.NegotiateAPIVersionPing(ping)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error) {
|
||||
return d.apiClient.DialHijack(ctx, url, proto, meta)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) Dialer() func(context.Context) (net.Conn, error) {
|
||||
return d.apiClient.Dialer()
|
||||
}
|
||||
|
||||
func (d *DryRunClient) Close() error {
|
||||
return d.apiClient.Close()
|
||||
}
|
||||
|
||||
func (d *DryRunClient) CheckpointCreate(ctx context.Context, container string, options moby.CheckpointCreateOptions) error {
|
||||
return d.apiClient.CheckpointCreate(ctx, container, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) CheckpointDelete(ctx context.Context, container string, options moby.CheckpointDeleteOptions) error {
|
||||
return d.apiClient.CheckpointDelete(ctx, container, options)
|
||||
}
|
||||
|
||||
func (d *DryRunClient) CheckpointList(ctx context.Context, container string, options moby.CheckpointListOptions) ([]moby.Checkpoint, error) {
|
||||
return d.apiClient.CheckpointList(ctx, container, options)
|
||||
}
|
||||
@@ -55,6 +55,8 @@ const (
|
||||
VersionLabel = "com.docker.compose.version"
|
||||
// ImageBuilderLabel stores the builder (classic or BuildKit) used to produce the image.
|
||||
ImageBuilderLabel = "com.docker.compose.image.builder"
|
||||
// ContainerReplaceLabel is set when container is created to replace another container (recreated)
|
||||
ContainerReplaceLabel = "com.docker.compose.replace"
|
||||
)
|
||||
|
||||
// ComposeVersion is the compose tool version as declared by label VersionLabel
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user