Compare commits
86 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f0df35096d | |||
| f485f66943 | |||
| 746c553574 | |||
| 2945ba4f7a | |||
| 032e485e1c | |||
| 88de81ff21 | |||
| 706ca7985b | |||
| e0d47b1c0b | |||
| 54b529feae | |||
| c88e6432ec | |||
| f291a49ba5 | |||
| 78fcd905c6 | |||
| 12e2f94eba | |||
| 00755d7dba | |||
| 8264f5be8d | |||
| 9780f41efe | |||
| 4fbdf3f362 | |||
| 1ff45aac40 | |||
| bb03b9d3c2 | |||
| ed71df1b9f | |||
| ee20fa1ec4 | |||
| ffe40dc6b6 | |||
| 7ab2d19a1e | |||
| 4630fe0075 | |||
| fbbf1be52d | |||
| 3de2cc6efd | |||
| 234036d105 | |||
| 0c442dc179 | |||
| 6b48c78672 | |||
| 370c28948e | |||
| dc017bdda3 | |||
| feb6f439e3 | |||
| 8bc4062fc0 | |||
| 84cc7d87cc | |||
| c1c3d3b3aa | |||
| 048a846146 | |||
| 33dacda24f | |||
| fcc05e5ea1 | |||
| 58061d25f6 | |||
| 55b2abb0ca | |||
| 4c3b87d922 | |||
| e77605c83d | |||
| 0196098721 | |||
| 6ebf765040 | |||
| f508ce9db7 | |||
| 897293c7c7 | |||
| 2c04354315 | |||
| 9c8a91d22b | |||
| ff945151ef | |||
| 4571d90f20 | |||
| 55c4c88966 | |||
| f33a69f6ee | |||
| d3cb89ee53 | |||
| 433014bcfb | |||
| 61cb016851 | |||
| 53c4602909 | |||
| 830d6595e7 | |||
| 13048444cc | |||
| 3e293e6bd1 | |||
| 41b3ea7e47 | |||
| d6eeeb6259 | |||
| 3e157d5293 | |||
| 1fdf84b8e9 | |||
| 376b99c6d6 | |||
| 0de4e6e9a7 | |||
| 3c87f01b18 | |||
| de40c2b172 | |||
| d513e46bfc | |||
| 2b74b90efb | |||
| 05343b36a2 | |||
| f90db254d7 | |||
| 0dcfdde336 | |||
| 03cd1dc50a | |||
| 42811a7eb9 | |||
| be966aa194 | |||
| b22fe0fb14 | |||
| 4eb050071e | |||
| 08c4fdfa7a | |||
| 6aa1b37c8d | |||
| e82920d76d | |||
| 82123939f7 | |||
| 48d30b5b32 | |||
| 5941f4104a | |||
| 18f33b337d | |||
| 9ecc69d17e | |||
| 6f49197cab |
@ -42,6 +42,7 @@ jobs:
|
||||
docker: [{image: 'docker:19.03-git'}]
|
||||
environment:
|
||||
DOCKER_BUILDKIT: 1
|
||||
BUILDX_VERSION: "v0.5.1"
|
||||
parallelism: 3
|
||||
steps:
|
||||
- checkout
|
||||
@ -55,21 +56,14 @@ jobs:
|
||||
- run:
|
||||
name: "Docker info"
|
||||
command: docker info
|
||||
- run:
|
||||
name: "Cross - build image"
|
||||
command: |
|
||||
docker build --progress=plain -f dockerfiles/Dockerfile.cross --tag cli-builder:$CIRCLE_BUILD_NUM .
|
||||
- run:
|
||||
name: "Cross"
|
||||
command: |
|
||||
name=cross-$CIRCLE_BUILD_NUM-$CIRCLE_NODE_INDEX
|
||||
docker run \
|
||||
-e CROSS_GROUP=$CIRCLE_NODE_INDEX \
|
||||
--name $name cli-builder:$CIRCLE_BUILD_NUM \
|
||||
make cross
|
||||
docker cp \
|
||||
$name:/go/src/github.com/docker/cli/build \
|
||||
/work/build
|
||||
- run: apk add make curl
|
||||
- run: mkdir -vp ~/.docker/cli-plugins/
|
||||
- run: curl -fsSL --output ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/${BUILDX_VERSION}/buildx-${BUILDX_VERSION}.linux-amd64
|
||||
- run: chmod a+x ~/.docker/cli-plugins/docker-buildx
|
||||
- run: docker buildx version
|
||||
- run: docker context create buildctx
|
||||
- run: docker buildx create --use buildctx && docker buildx inspect --bootstrap
|
||||
- run: GROUP_INDEX=$CIRCLE_NODE_INDEX GROUP_TOTAL=$CIRCLE_NODE_TOTAL docker buildx bake cross --progress=plain
|
||||
- store_artifacts:
|
||||
path: /work/build
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
.circleci
|
||||
.dockerignore
|
||||
.git
|
||||
.github
|
||||
.gitignore
|
||||
appveyor.yml
|
||||
|
||||
3
.gitignore
vendored
@ -8,8 +8,7 @@
|
||||
Thumbs.db
|
||||
.editorconfig
|
||||
/build/
|
||||
cli/winresources/rsrc_386.syso
|
||||
cli/winresources/rsrc_amd64.syso
|
||||
cli/winresources/rsrc_*.syso
|
||||
/man/man1/
|
||||
/man/man5/
|
||||
/man/man8/
|
||||
|
||||
61
Dockerfile
Normal file
@ -0,0 +1,61 @@
|
||||
#syntax=docker/dockerfile:1.2
|
||||
|
||||
ARG BASE_VARIANT=alpine
|
||||
ARG GO_VERSION=1.13.15
|
||||
|
||||
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} AS gostable
|
||||
FROM --platform=$BUILDPLATFORM golang:1.16-${BASE_VARIANT} AS golatest
|
||||
|
||||
FROM gostable AS go-linux
|
||||
FROM golatest AS go-darwin
|
||||
FROM golatest AS go-windows-amd64
|
||||
FROM golatest AS go-windows-386
|
||||
FROM golatest AS go-windows-arm
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/golang:497feff1-${BASE_VARIANT} AS go-windows-arm64
|
||||
FROM go-windows-${TARGETARCH} AS go-windows
|
||||
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx@sha256:620d36a9d7f1e3b102a5c7e8eff12081ac363828b3a44390f24fa8da2d49383d AS xx
|
||||
|
||||
FROM go-${TARGETOS} AS build-base-alpine
|
||||
COPY --from=xx / /
|
||||
RUN apk add --no-cache clang lld llvm file git
|
||||
WORKDIR /go/src/github.com/docker/cli
|
||||
|
||||
FROM build-base-alpine AS build-alpine
|
||||
ARG TARGETPLATFORM
|
||||
# gcc is installed for libgcc only
|
||||
RUN xx-apk add --no-cache musl-dev gcc
|
||||
|
||||
FROM go-${TARGETOS} AS build-base-buster
|
||||
COPY --from=xx / /
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y clang lld file
|
||||
WORKDIR /go/src/github.com/docker/cli
|
||||
|
||||
FROM build-base-buster AS build-buster
|
||||
ARG TARGETPLATFORM
|
||||
RUN xx-apt install --no-install-recommends -y libc6-dev libgcc-8-dev
|
||||
|
||||
FROM build-${BASE_VARIANT} AS build
|
||||
# GO_LINKMODE defines if static or dynamic binary should be produced
|
||||
ARG GO_LINKMODE=static
|
||||
# GO_BUILDTAGS defines additional build tags
|
||||
ARG GO_BUILDTAGS
|
||||
# GO_STRIP strips debugging symbols if set
|
||||
ARG GO_STRIP
|
||||
# CGO_ENABLED manually sets if cgo is used
|
||||
ARG CGO_ENABLED
|
||||
# VERSION sets the version for the produced binary
|
||||
ARG VERSION
|
||||
RUN --mount=ro --mount=type=cache,target=/root/.cache \
|
||||
--mount=from=dockercore/golang-cross:xx-sdk-extras,target=/xx-sdk,src=/xx-sdk \
|
||||
--mount=type=tmpfs,target=cli/winresources \
|
||||
xx-go --wrap && \
|
||||
# export GOCACHE=$(go env GOCACHE)/$(xx-info)$([ -f /etc/alpine-release ] && echo "alpine") && \
|
||||
TARGET=/out ./scripts/build/binary && \
|
||||
xx-verify $([ "$GO_LINKMODE" = "static" ] && echo "--static") /out/docker
|
||||
|
||||
FROM build-base-${BASE_VARIANT} AS dev
|
||||
COPY . .
|
||||
|
||||
FROM scratch AS binary
|
||||
COPY --from=build /out .
|
||||
17
Makefile
@ -30,8 +30,7 @@ lint: ## run all the lint tools
|
||||
gometalinter --config gometalinter.json ./...
|
||||
|
||||
.PHONY: binary
|
||||
binary: ## build executable for Linux
|
||||
@echo "WARNING: binary creates a Linux executable. Use cross for macOS or Windows."
|
||||
binary:
|
||||
./scripts/build/binary
|
||||
|
||||
.PHONY: plugins
|
||||
@ -39,28 +38,20 @@ plugins: ## build example CLI plugins
|
||||
./scripts/build/plugins
|
||||
|
||||
.PHONY: cross
|
||||
cross: ## build executable for macOS and Windows
|
||||
./scripts/build/cross
|
||||
|
||||
.PHONY: binary-windows
|
||||
binary-windows: ## build executable for Windows
|
||||
./scripts/build/windows
|
||||
cross:
|
||||
./scripts/build/binary
|
||||
|
||||
.PHONY: plugins-windows
|
||||
plugins-windows: ## build example CLI plugins for Windows
|
||||
./scripts/build/plugins-windows
|
||||
|
||||
.PHONY: binary-osx
|
||||
binary-osx: ## build executable for macOS
|
||||
./scripts/build/osx
|
||||
|
||||
.PHONY: plugins-osx
|
||||
plugins-osx: ## build example CLI plugins for macOS
|
||||
./scripts/build/plugins-osx
|
||||
|
||||
.PHONY: dynbinary
|
||||
dynbinary: ## build dynamically linked binary
|
||||
./scripts/build/dynbinary
|
||||
GO_LINKMODE=dynamic ./scripts/build/binary
|
||||
|
||||
vendor: vendor.conf ## check that vendor matches vendor.conf
|
||||
rm -rf vendor
|
||||
|
||||
25
README.md
@ -12,18 +12,31 @@ Development
|
||||
|
||||
`docker/cli` is developed using Docker.
|
||||
|
||||
Build a linux binary:
|
||||
Build CLI from source:
|
||||
|
||||
```
|
||||
$ make -f docker.Makefile binary
|
||||
$ docker buildx bake
|
||||
```
|
||||
|
||||
Build binaries for all supported platforms:
|
||||
|
||||
```
|
||||
$ make -f docker.Makefile cross
|
||||
$ docker buildx bake cross
|
||||
```
|
||||
|
||||
Build for a specific platform:
|
||||
|
||||
```
|
||||
$ docker buildx bake --set binary.platform=linux/arm64
|
||||
```
|
||||
|
||||
Build dynamic binary for glibc or musl:
|
||||
|
||||
```
|
||||
$ USE_GLIBC=1 docker buildx bake dynbinary
|
||||
```
|
||||
|
||||
|
||||
Run all linting:
|
||||
|
||||
```
|
||||
@ -44,12 +57,6 @@ Start an interactive development environment:
|
||||
$ make -f docker.Makefile shell
|
||||
```
|
||||
|
||||
In the development environment you can run many tasks, including build binaries:
|
||||
|
||||
```
|
||||
$ make binary
|
||||
```
|
||||
|
||||
Legal
|
||||
=====
|
||||
*Brought to you courtesy of our legal counsel. For more context,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
exec "golang.org/x/sys/execabs"
|
||||
)
|
||||
|
||||
// Candidate represents a possible plugin candidate, for mocking purposes
|
||||
|
||||
@ -3,7 +3,6 @@ package manager
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
@ -12,6 +11,7 @@ import (
|
||||
"github.com/docker/cli/cli/config"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
exec "golang.org/x/sys/execabs"
|
||||
)
|
||||
|
||||
// ReexecEnvvar is the name of an ennvar which is set to the command
|
||||
|
||||
@ -97,7 +97,8 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
|
||||
}
|
||||
|
||||
if opts.proxy && !c.Config.Tty {
|
||||
sigc := ForwardAllSignals(ctx, dockerCli, opts.container)
|
||||
sigc := notfiyAllSignals()
|
||||
go ForwardAllSignals(ctx, dockerCli, opts.container, sigc)
|
||||
defer signal.StopCatch(sigc)
|
||||
}
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@ type fakeClient struct {
|
||||
containerExportFunc func(string) (io.ReadCloser, error)
|
||||
containerExecResizeFunc func(id string, options types.ResizeOptions) error
|
||||
containerRemoveFunc func(ctx context.Context, container string, options types.ContainerRemoveOptions) error
|
||||
containerKillFunc func(ctx context.Context, container, signal string) error
|
||||
Version string
|
||||
}
|
||||
|
||||
@ -154,3 +155,10 @@ func (f *fakeClient) ContainerExecResize(_ context.Context, id string, options t
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeClient) ContainerKill(ctx context.Context, container, signal string) error {
|
||||
if f.containerKillFunc != nil {
|
||||
return f.containerKillFunc(ctx, container, signal)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -131,7 +131,8 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio
|
||||
return runStartContainerErr(err)
|
||||
}
|
||||
if opts.sigProxy {
|
||||
sigc := ForwardAllSignals(ctx, dockerCli, createResponse.ID)
|
||||
sigc := notfiyAllSignals()
|
||||
go ForwardAllSignals(ctx, dockerCli, createResponse.ID, sigc)
|
||||
defer signal.StopCatch(sigc)
|
||||
}
|
||||
|
||||
|
||||
61
cli/command/container/signals.go
Normal file
@ -0,0 +1,61 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
gosignal "os/signal"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// ForwardAllSignals forwards signals to the container
|
||||
//
|
||||
// The channel you pass in must already be setup to receive any signals you want to forward.
|
||||
func ForwardAllSignals(ctx context.Context, cli command.Cli, cid string, sigc <-chan os.Signal) {
|
||||
var (
|
||||
s os.Signal
|
||||
ok bool
|
||||
)
|
||||
for {
|
||||
select {
|
||||
case s, ok = <-sigc:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
|
||||
if s == signal.SIGCHLD || s == signal.SIGPIPE {
|
||||
continue
|
||||
}
|
||||
|
||||
// In go1.14+, the go runtime issues SIGURG as an interrupt to support pre-emptable system calls on Linux.
|
||||
// Since we can't forward that along we'll check that here.
|
||||
if isRuntimeSig(s) {
|
||||
continue
|
||||
}
|
||||
var sig string
|
||||
for sigStr, sigN := range signal.SignalMap {
|
||||
if sigN == s {
|
||||
sig = sigStr
|
||||
break
|
||||
}
|
||||
}
|
||||
if sig == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := cli.Client().ContainerKill(ctx, cid, sig); err != nil {
|
||||
logrus.Debugf("Error sending signal: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func notfiyAllSignals() chan os.Signal {
|
||||
sigc := make(chan os.Signal, 128)
|
||||
gosignal.Notify(sigc)
|
||||
return sigc
|
||||
}
|
||||
48
cli/command/container/signals_test.go
Normal file
@ -0,0 +1,48 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
)
|
||||
|
||||
func TestForwardSignals(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
called := make(chan struct{})
|
||||
client := &fakeClient{containerKillFunc: func(ctx context.Context, container, signal string) error {
|
||||
close(called)
|
||||
return nil
|
||||
}}
|
||||
|
||||
cli := test.NewFakeCli(client)
|
||||
sigc := make(chan os.Signal)
|
||||
defer close(sigc)
|
||||
|
||||
go ForwardAllSignals(ctx, cli, t.Name(), sigc)
|
||||
|
||||
timer := time.NewTimer(30 * time.Second)
|
||||
defer timer.Stop()
|
||||
|
||||
select {
|
||||
case <-timer.C:
|
||||
t.Fatal("timeout waiting to send signal")
|
||||
case sigc <- signal.SignalMap["TERM"]:
|
||||
}
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
timer.Reset(30 * time.Second)
|
||||
|
||||
select {
|
||||
case <-called:
|
||||
case <-timer.C:
|
||||
t.Fatal("timeout waiting for signal to be processed")
|
||||
}
|
||||
|
||||
}
|
||||
13
cli/command/container/signals_unix.go
Normal file
@ -0,0 +1,13 @@
|
||||
// +build !windows
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func isRuntimeSig(s os.Signal) bool {
|
||||
return s == unix.SIGURG
|
||||
}
|
||||
59
cli/command/container/signals_unix_test.go
Normal file
@ -0,0 +1,59 @@
|
||||
// +build !windows
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"golang.org/x/sys/unix"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestIgnoredSignals(t *testing.T) {
|
||||
ignoredSignals := []syscall.Signal{unix.SIGPIPE, unix.SIGCHLD, unix.SIGURG}
|
||||
|
||||
for _, s := range ignoredSignals {
|
||||
t.Run(unix.SignalName(s), func(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
var called bool
|
||||
client := &fakeClient{containerKillFunc: func(ctx context.Context, container, signal string) error {
|
||||
called = true
|
||||
return nil
|
||||
}}
|
||||
|
||||
cli := test.NewFakeCli(client)
|
||||
sigc := make(chan os.Signal)
|
||||
defer close(sigc)
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
ForwardAllSignals(ctx, cli, t.Name(), sigc)
|
||||
close(done)
|
||||
}()
|
||||
|
||||
timer := time.NewTimer(30 * time.Second)
|
||||
defer timer.Stop()
|
||||
|
||||
select {
|
||||
case <-timer.C:
|
||||
t.Fatal("timeout waiting to send signal")
|
||||
case sigc <- s:
|
||||
case <-done:
|
||||
}
|
||||
|
||||
// cancel the context so ForwardAllSignals will exit after it has processed the signal we sent.
|
||||
// This is how we know the signal was actually processed and are not introducing a flakey test.
|
||||
cancel()
|
||||
<-done
|
||||
|
||||
assert.Assert(t, !called, "kill was called")
|
||||
})
|
||||
}
|
||||
}
|
||||
7
cli/command/container/signals_windows.go
Normal file
@ -0,0 +1,7 @@
|
||||
package container
|
||||
|
||||
import "os"
|
||||
|
||||
func isRuntimeSig(_ os.Signal) bool {
|
||||
return false
|
||||
}
|
||||
@ -74,7 +74,8 @@ func runStart(dockerCli command.Cli, opts *startOptions) error {
|
||||
|
||||
// We always use c.ID instead of container to maintain consistency during `docker start`
|
||||
if !c.Config.Tty {
|
||||
sigc := ForwardAllSignals(ctx, dockerCli, c.ID)
|
||||
sigc := notfiyAllSignals()
|
||||
go ForwardAllSignals(ctx, dockerCli, c.ID, sigc)
|
||||
defer signal.StopCatch(sigc)
|
||||
}
|
||||
|
||||
|
||||
@ -95,32 +95,3 @@ func MonitorTtySize(ctx context.Context, cli command.Cli, id string, isExec bool
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ForwardAllSignals forwards signals to the container
|
||||
func ForwardAllSignals(ctx context.Context, cli command.Cli, cid string) chan os.Signal {
|
||||
sigc := make(chan os.Signal, 128)
|
||||
signal.CatchAll(sigc)
|
||||
go func() {
|
||||
for s := range sigc {
|
||||
if s == signal.SIGCHLD || s == signal.SIGPIPE {
|
||||
continue
|
||||
}
|
||||
var sig string
|
||||
for sigStr, sigN := range signal.SignalMap {
|
||||
if sigN == s {
|
||||
sig = sigStr
|
||||
break
|
||||
}
|
||||
}
|
||||
if sig == "" {
|
||||
fmt.Fprintf(cli.Err(), "Unsupported signal: %v. Discarding.\n", s)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := cli.Client().ContainerKill(ctx, cid, sig); err != nil {
|
||||
logrus.Debugf("Error sending signal: %s", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
return sigc
|
||||
}
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/spf13/cobra"
|
||||
@ -30,20 +26,3 @@ func NewContextCommand(dockerCli command.Cli) *cobra.Command {
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
|
||||
const restrictedNamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$"
|
||||
|
||||
var restrictedNameRegEx = regexp.MustCompile(restrictedNamePattern)
|
||||
|
||||
func validateContextName(name string) error {
|
||||
if name == "" {
|
||||
return errors.New("context name cannot be empty")
|
||||
}
|
||||
if name == "default" {
|
||||
return errors.New(`"default" is a reserved context name`)
|
||||
}
|
||||
if !restrictedNameRegEx.MatchString(name) {
|
||||
return fmt.Errorf("context name %q is invalid, names are validated against regexp %q", name, restrictedNamePattern)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ func createNewContext(o *CreateOptions, stackOrchestrator command.Orchestrator,
|
||||
}
|
||||
|
||||
func checkContextNameForCreation(s store.Reader, name string) error {
|
||||
if err := validateContextName(name); err != nil {
|
||||
if err := store.ValidateContextName(name); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := s.GetMetadata(name); !store.IsErrContextDoesNotExist(err) {
|
||||
|
||||
@ -77,7 +77,7 @@ func writeTo(dockerCli command.Cli, reader io.Reader, dest string) error {
|
||||
|
||||
// RunExport exports a Docker context
|
||||
func RunExport(dockerCli command.Cli, opts *ExportOptions) error {
|
||||
if err := validateContextName(opts.ContextName); err != nil && opts.ContextName != command.DefaultContextName {
|
||||
if err := store.ValidateContextName(opts.ContextName); err != nil && opts.ContextName != command.DefaultContextName {
|
||||
return err
|
||||
}
|
||||
ctxMeta, err := dockerCli.ContextStore().GetMetadata(opts.ContextName)
|
||||
|
||||
@ -68,7 +68,7 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
|
||||
|
||||
// RunUpdate updates a Docker context
|
||||
func RunUpdate(cli command.Cli, o *UpdateOptions) error {
|
||||
if err := validateContextName(o.Name); err != nil {
|
||||
if err := store.ValidateContextName(o.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
s := cli.ContextStore()
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/context/store"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@ -23,7 +24,7 @@ func newUseCommand(dockerCli command.Cli) *cobra.Command {
|
||||
|
||||
// RunUse set the current Docker context
|
||||
func RunUse(dockerCli command.Cli, name string) error {
|
||||
if err := validateContextName(name); err != nil && name != "default" {
|
||||
if err := store.ValidateContextName(name); err != nil && name != "default" {
|
||||
return err
|
||||
}
|
||||
if _, err := dockerCli.ContextStore().GetMetadata(name); err != nil && name != "default" {
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
@ -24,6 +23,7 @@ import (
|
||||
"github.com/docker/docker/pkg/streamformatter"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/pkg/errors"
|
||||
exec "golang.org/x/sys/execabs"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@ -78,7 +78,7 @@ func runBuildBuildKit(dockerCli command.Cli, options buildOptions) error {
|
||||
if options.dockerfileFromStdin() {
|
||||
return errStdinConflict
|
||||
}
|
||||
rc, isArchive, err := build.DetectArchiveReader(os.Stdin)
|
||||
rc, isArchive, err := build.DetectArchiveReader(dockerCli.In())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -98,7 +98,7 @@ func runBuildBuildKit(dockerCli command.Cli, options buildOptions) error {
|
||||
case isLocalDir(options.context):
|
||||
contextDir = options.context
|
||||
if options.dockerfileFromStdin() {
|
||||
dockerfileReader = os.Stdin
|
||||
dockerfileReader = dockerCli.In()
|
||||
} else if options.dockerfileName != "" {
|
||||
dockerfileName = filepath.Base(options.dockerfileName)
|
||||
dockerfileDir = filepath.Dir(options.dockerfileName)
|
||||
|
||||
@ -63,6 +63,9 @@ func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInf
|
||||
indexServer := registry.GetAuthConfigKey(index)
|
||||
isDefaultRegistry := indexServer == ElectAuthServer(context.Background(), cli)
|
||||
authConfig, err := GetDefaultAuthConfig(cli, true, indexServer, isDefaultRegistry)
|
||||
if authConfig == nil {
|
||||
authConfig = &types.AuthConfig{}
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintf(cli.Err(), "Unable to retrieve stored credentials for %s, error: %s.\n", indexServer, err)
|
||||
}
|
||||
|
||||
@ -111,11 +111,12 @@ func runLogin(dockerCli command.Cli, opts loginOptions) error { //nolint: gocycl
|
||||
serverAddress = authServer
|
||||
}
|
||||
|
||||
var err error
|
||||
var authConfig *types.AuthConfig
|
||||
var response registrytypes.AuthenticateOKBody
|
||||
isDefaultRegistry := serverAddress == authServer
|
||||
authConfig, err = command.GetDefaultAuthConfig(dockerCli, opts.user == "" && opts.password == "", serverAddress, isDefaultRegistry)
|
||||
authConfig, err := command.GetDefaultAuthConfig(dockerCli, opts.user == "" && opts.password == "", serverAddress, isDefaultRegistry)
|
||||
if authConfig == nil {
|
||||
authConfig = &types.AuthConfig{}
|
||||
}
|
||||
if err == nil && authConfig.Username != "" && authConfig.Password != "" {
|
||||
response, err = loginWithCredStoreCreds(ctx, dockerCli, authConfig)
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ func updateConfigFromDefaults(defaultUpdateConfig *api.UpdateConfig) *swarm.Upda
|
||||
}
|
||||
|
||||
func (opts updateOptions) updateConfig(flags *pflag.FlagSet) *swarm.UpdateConfig {
|
||||
if !anyChanged(flags, flagUpdateParallelism, flagUpdateDelay, flagUpdateMonitor, flagUpdateFailureAction, flagUpdateMaxFailureRatio) {
|
||||
if !anyChanged(flags, flagUpdateParallelism, flagUpdateDelay, flagUpdateMonitor, flagUpdateFailureAction, flagUpdateMaxFailureRatio, flagUpdateOrder) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ func (opts updateOptions) updateConfig(flags *pflag.FlagSet) *swarm.UpdateConfig
|
||||
}
|
||||
|
||||
func (opts updateOptions) rollbackConfig(flags *pflag.FlagSet) *swarm.UpdateConfig {
|
||||
if !anyChanged(flags, flagRollbackParallelism, flagRollbackDelay, flagRollbackMonitor, flagRollbackFailureAction, flagRollbackMaxFailureRatio) {
|
||||
if !anyChanged(flags, flagRollbackParallelism, flagRollbackDelay, flagRollbackMonitor, flagRollbackFailureAction, flagRollbackMaxFailureRatio, flagRollbackOrder) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -289,6 +289,22 @@ func TestToServiceUpdateRollback(t *testing.T) {
|
||||
assert.Check(t, is.DeepEqual(service.RollbackConfig, expected.RollbackConfig))
|
||||
}
|
||||
|
||||
func TestToServiceUpdateRollbackOrder(t *testing.T) {
|
||||
flags := newCreateCommand(nil).Flags()
|
||||
flags.Set("update-order", "start-first")
|
||||
flags.Set("rollback-order", "start-first")
|
||||
|
||||
o := newServiceOptions()
|
||||
o.mode = "replicated"
|
||||
o.update = updateOptions{order: "start-first"}
|
||||
o.rollback = updateOptions{order: "start-first"}
|
||||
|
||||
service, err := o.ToService(context.Background(), &fakeClient{}, flags)
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(service.UpdateConfig.Order, o.update.order))
|
||||
assert.Check(t, is.Equal(service.RollbackConfig.Order, o.rollback.order))
|
||||
}
|
||||
|
||||
func TestToServiceMaxReplicasGlobalModeConflict(t *testing.T) {
|
||||
opt := serviceOptions{
|
||||
mode: "global",
|
||||
|
||||
@ -99,6 +99,7 @@ func ServiceProgress(ctx context.Context, client client.APIClient, serviceID str
|
||||
convergedAt time.Time
|
||||
monitor = 5 * time.Second
|
||||
rollback bool
|
||||
message *progress.Progress
|
||||
)
|
||||
|
||||
for {
|
||||
@ -140,8 +141,9 @@ func ServiceProgress(ctx context.Context, client client.APIClient, serviceID str
|
||||
return fmt.Errorf("service rollback paused: %s", service.UpdateStatus.Message)
|
||||
case swarm.UpdateStateRollbackCompleted:
|
||||
if !converged {
|
||||
return fmt.Errorf("service rolled back: %s", service.UpdateStatus.Message)
|
||||
message = &progress.Progress{ID: "rollback", Message: service.UpdateStatus.Message}
|
||||
}
|
||||
rollback = true
|
||||
}
|
||||
}
|
||||
if converged && time.Since(convergedAt) >= monitor {
|
||||
@ -149,7 +151,9 @@ func ServiceProgress(ctx context.Context, client client.APIClient, serviceID str
|
||||
ID: "verify",
|
||||
Action: "Service converged",
|
||||
})
|
||||
|
||||
if message != nil {
|
||||
progressOut.WriteProgress(*message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -402,10 +402,7 @@ func printServerWarningsLegacy(dockerCli command.Cli, info types.Info) {
|
||||
if !info.SwapLimit {
|
||||
fmt.Fprintln(dockerCli.Err(), "WARNING: No swap limit support")
|
||||
}
|
||||
if !info.KernelMemory {
|
||||
fmt.Fprintln(dockerCli.Err(), "WARNING: No kernel memory limit support")
|
||||
}
|
||||
if !info.OomKillDisable {
|
||||
if !info.OomKillDisable && info.CgroupVersion != "2" {
|
||||
fmt.Fprintln(dockerCli.Err(), "WARNING: No oom kill disable support")
|
||||
}
|
||||
if !info.CPUCfsQuota {
|
||||
|
||||
@ -248,7 +248,6 @@ func TestPrettyPrintInfo(t *testing.T) {
|
||||
sampleInfoDaemonWarnings.Warnings = []string{
|
||||
"WARNING: No memory limit support",
|
||||
"WARNING: No swap limit support",
|
||||
"WARNING: No kernel memory limit support",
|
||||
"WARNING: No oom kill disable support",
|
||||
"WARNING: No cpu cfs quota support",
|
||||
"WARNING: No cpu cfs period support",
|
||||
|
||||
@ -1 +1 @@
|
||||
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"KernelMemoryTCP":false,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":["WARNING: No memory limit support","WARNING: No swap limit support","WARNING: No kernel memory limit support","WARNING: No oom kill disable support","WARNING: No cpu cfs quota support","WARNING: No cpu cfs period support","WARNING: No cpu shares support","WARNING: No cpuset support","WARNING: IPv4 forwarding is disabled","WARNING: bridge-nf-call-iptables is disabled","WARNING: bridge-nf-call-ip6tables is disabled"],"ClientInfo":{"Debug":true,"Context":"default","Plugins":[],"Warnings":null}}
|
||||
{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"KernelMemoryTCP":false,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":["WARNING: No memory limit support","WARNING: No swap limit support","WARNING: No oom kill disable support","WARNING: No cpu cfs quota support","WARNING: No cpu cfs period support","WARNING: No cpu shares support","WARNING: No cpuset support","WARNING: IPv4 forwarding is disabled","WARNING: bridge-nf-call-iptables is disabled","WARNING: bridge-nf-call-ip6tables is disabled"],"ClientInfo":{"Debug":true,"Context":"default","Plugins":[],"Warnings":null}}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
WARNING: No memory limit support
|
||||
WARNING: No swap limit support
|
||||
WARNING: No kernel memory limit support
|
||||
WARNING: No oom kill disable support
|
||||
WARNING: No cpu cfs quota support
|
||||
WARNING: No cpu cfs period support
|
||||
|
||||
@ -24,17 +24,38 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
initConfigDir sync.Once
|
||||
initConfigDir = new(sync.Once)
|
||||
configDir string
|
||||
homeDir string
|
||||
)
|
||||
|
||||
// resetHomeDir is used in testing to reset the "homeDir" package variable to
|
||||
// force re-lookup of the home directory between tests.
|
||||
func resetHomeDir() {
|
||||
homeDir = ""
|
||||
}
|
||||
|
||||
func getHomeDir() string {
|
||||
if homeDir == "" {
|
||||
homeDir = homedir.Get()
|
||||
}
|
||||
return homeDir
|
||||
}
|
||||
|
||||
// resetConfigDir is used in testing to reset the "configDir" package variable
|
||||
// and its sync.Once to force re-lookup between tests.
|
||||
func resetConfigDir() {
|
||||
configDir = ""
|
||||
initConfigDir = new(sync.Once)
|
||||
}
|
||||
|
||||
func setConfigDir() {
|
||||
if configDir != "" {
|
||||
return
|
||||
}
|
||||
configDir = os.Getenv("DOCKER_CONFIG")
|
||||
if configDir == "" {
|
||||
configDir = filepath.Join(homedir.Get(), configFileDir)
|
||||
configDir = filepath.Join(getHomeDir(), configFileDir)
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,10 +104,15 @@ func LoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) {
|
||||
return &configFile, err
|
||||
}
|
||||
|
||||
// TODO remove this temporary hack, which is used to warn about the deprecated ~/.dockercfg file
|
||||
var printLegacyFileWarning bool
|
||||
|
||||
// Load reads the configuration files in the given directory, and sets up
|
||||
// the auth config information and returns values.
|
||||
// FIXME: use the internal golang config parser
|
||||
func Load(configDir string) (*configfile.ConfigFile, error) {
|
||||
printLegacyFileWarning = false
|
||||
|
||||
if configDir == "" {
|
||||
configDir = Dir()
|
||||
}
|
||||
@ -109,12 +135,9 @@ func Load(configDir string) (*configfile.ConfigFile, error) {
|
||||
}
|
||||
|
||||
// Can't find latest config file so check for the old one
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return configFile, errors.Wrap(err, oldConfigfile)
|
||||
}
|
||||
filename = filepath.Join(home, oldConfigfile)
|
||||
filename = filepath.Join(getHomeDir(), oldConfigfile)
|
||||
if file, err := os.Open(filename); err == nil {
|
||||
printLegacyFileWarning = true
|
||||
defer file.Close()
|
||||
if err := configFile.LegacyLoadFromReader(file); err != nil {
|
||||
return configFile, errors.Wrap(err, filename)
|
||||
@ -130,6 +153,9 @@ func LoadDefaultConfigFile(stderr io.Writer) *configfile.ConfigFile {
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "WARNING: Error loading config file: %v\n", err)
|
||||
}
|
||||
if printLegacyFileWarning {
|
||||
_, _ = fmt.Fprintln(stderr, "WARNING: Support for the legacy ~/.dockercfg configuration file and file-format is deprecated and will be removed in an upcoming release")
|
||||
}
|
||||
if !configFile.ContainsAuth() {
|
||||
configFile.CredentialsStore = credentials.DetectDefaultStore(configFile.CredentialsStore)
|
||||
}
|
||||
|
||||
@ -12,9 +12,11 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/config/credentials"
|
||||
"github.com/docker/cli/cli/config/types"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/env"
|
||||
"gotest.tools/v3/fs"
|
||||
)
|
||||
|
||||
var homeKey = "HOME"
|
||||
@ -115,6 +117,7 @@ password`: "Invalid Auth config file",
|
||||
email`: "Invalid auth configuration file",
|
||||
}
|
||||
|
||||
resetHomeDir()
|
||||
tmpHome, err := ioutil.TempDir("", "config-test")
|
||||
assert.NilError(t, err)
|
||||
defer os.RemoveAll(tmpHome)
|
||||
@ -131,6 +134,7 @@ email`: "Invalid auth configuration file",
|
||||
}
|
||||
|
||||
func TestOldValidAuth(t *testing.T) {
|
||||
resetHomeDir()
|
||||
tmpHome, err := ioutil.TempDir("", "config-test")
|
||||
assert.NilError(t, err)
|
||||
defer os.RemoveAll(tmpHome)
|
||||
@ -165,6 +169,7 @@ func TestOldValidAuth(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestOldJSONInvalid(t *testing.T) {
|
||||
resetHomeDir()
|
||||
tmpHome, err := ioutil.TempDir("", "config-test")
|
||||
assert.NilError(t, err)
|
||||
defer os.RemoveAll(tmpHome)
|
||||
@ -184,6 +189,7 @@ func TestOldJSONInvalid(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestOldJSON(t *testing.T) {
|
||||
resetHomeDir()
|
||||
tmpHome, err := ioutil.TempDir("", "config-test")
|
||||
assert.NilError(t, err)
|
||||
defer os.RemoveAll(tmpHome)
|
||||
@ -219,6 +225,31 @@ func TestOldJSON(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOldJSONFallbackDeprecationWarning(t *testing.T) {
|
||||
js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}`
|
||||
tmpHome := fs.NewDir(t, t.Name(), fs.WithFile(oldConfigfile, js))
|
||||
defer tmpHome.Remove()
|
||||
defer env.PatchAll(t, map[string]string{homeKey: tmpHome.Path(), "DOCKER_CONFIG": ""})()
|
||||
|
||||
// reset the homeDir, configDir, and its sync.Once, to force them being resolved again
|
||||
resetHomeDir()
|
||||
resetConfigDir()
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
configFile := LoadDefaultConfigFile(buffer)
|
||||
expected := configfile.New(tmpHome.Join(configFileDir, ConfigFileName))
|
||||
expected.AuthConfigs = map[string]types.AuthConfig{
|
||||
"https://index.docker.io/v1/": {
|
||||
Username: "joejoe",
|
||||
Password: "hello",
|
||||
Email: "user@example.com",
|
||||
ServerAddress: "https://index.docker.io/v1/",
|
||||
},
|
||||
}
|
||||
assert.Assert(t, strings.Contains(buffer.String(), "WARNING: Support for the legacy ~/.dockercfg configuration file and file-format is deprecated and will be removed in an upcoming release"))
|
||||
assert.Check(t, is.DeepEqual(expected, configFile))
|
||||
}
|
||||
|
||||
func TestNewJSON(t *testing.T) {
|
||||
tmpHome, err := ioutil.TempDir("", "config-test")
|
||||
assert.NilError(t, err)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
exec "golang.org/x/sys/execabs"
|
||||
)
|
||||
|
||||
// DetectDefaultStore return the default credentials store for the platform if
|
||||
|
||||
@ -20,7 +20,6 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -29,6 +28,7 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
exec "golang.org/x/sys/execabs"
|
||||
)
|
||||
|
||||
// New returns net.Conn
|
||||
|
||||
@ -7,19 +7,24 @@ import (
|
||||
"bytes"
|
||||
_ "crypto/sha256" // ensure ids can be computed
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/errdefs"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const restrictedNamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$"
|
||||
|
||||
var restrictedNameRegEx = regexp.MustCompile(restrictedNamePattern)
|
||||
|
||||
// Store provides a context store for easily remembering endpoints configuration
|
||||
type Store interface {
|
||||
Reader
|
||||
@ -184,6 +189,20 @@ func (s *store) GetStorageInfo(contextName string) StorageInfo {
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateContextName checks a context name is valid.
|
||||
func ValidateContextName(name string) error {
|
||||
if name == "" {
|
||||
return errors.New("context name cannot be empty")
|
||||
}
|
||||
if name == "default" {
|
||||
return errors.New(`"default" is a reserved context name`)
|
||||
}
|
||||
if !restrictedNameRegEx.MatchString(name) {
|
||||
return fmt.Errorf("context name %q is invalid, names are validated against regexp %q", name, restrictedNamePattern)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Export exports an existing namespace into an opaque data stream
|
||||
// This stream is actually a tarball containing context metadata and TLS materials, but it does
|
||||
// not map 1:1 the layout of the context store (don't try to restore it manually without calling store.Import)
|
||||
@ -295,6 +314,19 @@ func Import(name string, s Writer, reader io.Reader) error {
|
||||
}
|
||||
}
|
||||
|
||||
func isValidFilePath(p string) error {
|
||||
if p != metaFile && !strings.HasPrefix(p, "tls/") {
|
||||
return errors.New("unexpected context file")
|
||||
}
|
||||
if path.Clean(p) != p {
|
||||
return errors.New("unexpected path format")
|
||||
}
|
||||
if strings.Contains(p, `\`) {
|
||||
return errors.New(`unexpected '\' in path`)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func importTar(name string, s Writer, reader io.Reader) error {
|
||||
tr := tar.NewReader(&LimitedReader{R: reader, N: maxAllowedFileSizeToImport})
|
||||
tlsData := ContextTLSData{
|
||||
@ -309,10 +341,13 @@ func importTar(name string, s Writer, reader io.Reader) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if hdr.Typeflag == tar.TypeDir {
|
||||
if hdr.Typeflag != tar.TypeReg {
|
||||
// skip this entry, only taking files into account
|
||||
continue
|
||||
}
|
||||
if err := isValidFilePath(hdr.Name); err != nil {
|
||||
return errors.Wrap(err, hdr.Name)
|
||||
}
|
||||
if hdr.Name == metaFile {
|
||||
data, err := ioutil.ReadAll(tr)
|
||||
if err != nil {
|
||||
@ -358,10 +393,13 @@ func importZip(name string, s Writer, reader io.Reader) error {
|
||||
var importedMetaFile bool
|
||||
for _, zf := range zr.File {
|
||||
fi := zf.FileInfo()
|
||||
if fi.IsDir() {
|
||||
// skip this entry, only taking files into account
|
||||
if !fi.Mode().IsRegular() {
|
||||
// skip this entry, only taking regular files into account
|
||||
continue
|
||||
}
|
||||
if err := isValidFilePath(zf.Name); err != nil {
|
||||
return errors.Wrap(err, zf.Name)
|
||||
}
|
||||
if zf.Name == metaFile {
|
||||
f, err := zf.Open()
|
||||
if err != nil {
|
||||
@ -408,6 +446,9 @@ func parseMetadata(data []byte, name string) (Metadata, error) {
|
||||
if err := json.Unmarshal(data, &meta); err != nil {
|
||||
return meta, err
|
||||
}
|
||||
if err := ValidateContextName(name); err != nil {
|
||||
return Metadata{}, err
|
||||
}
|
||||
meta.Name = name
|
||||
return meta, nil
|
||||
}
|
||||
|
||||
@ -175,7 +175,7 @@ func TestImportTarInvalid(t *testing.T) {
|
||||
var r io.Reader = source
|
||||
s := New(testDir, testCfg)
|
||||
err = Import("tarInvalid", s, r)
|
||||
assert.ErrorContains(t, err, "invalid context: no metadata found")
|
||||
assert.ErrorContains(t, err, "unexpected context file")
|
||||
}
|
||||
|
||||
func TestImportZip(t *testing.T) {
|
||||
@ -254,5 +254,5 @@ func TestImportZipInvalid(t *testing.T) {
|
||||
var r io.Reader = source
|
||||
s := New(testDir, testCfg)
|
||||
err = Import("zipInvalid", s, r)
|
||||
assert.ErrorContains(t, err, "invalid context: no metadata found")
|
||||
assert.ErrorContains(t, err, "unexpected context file")
|
||||
}
|
||||
|
||||
@ -29,3 +29,32 @@ func TestConfigModification(t *testing.T) {
|
||||
assert.Equal(t, &testEP2{}, cfgCopy.endpointTypes["ep1"]())
|
||||
assert.Equal(t, &testEP3{}, cfgCopy.endpointTypes["ep2"]())
|
||||
}
|
||||
|
||||
func TestValidFilePaths(t *testing.T) {
|
||||
paths := map[string]bool{
|
||||
"tls/_/../../something": false,
|
||||
"tls/../../something": false,
|
||||
"../../something": false,
|
||||
"/tls/absolute/unix/path": false,
|
||||
`C:\tls\absolute\windows\path`: false,
|
||||
"C:/tls/absolute/windows/path": false,
|
||||
"tls/kubernetes/key.pem": true,
|
||||
}
|
||||
for p, expectedValid := range paths {
|
||||
err := isValidFilePath(p)
|
||||
assert.Equal(t, err == nil, expectedValid, "%q should report valid as: %v", p, expectedValid)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateContextName(t *testing.T) {
|
||||
names := map[string]bool{
|
||||
"../../invalid/escape": false,
|
||||
"/invalid/absolute": false,
|
||||
`\invalid\windows`: false,
|
||||
"validname": true,
|
||||
}
|
||||
for n, expectedValid := range names {
|
||||
err := ValidateContextName(n)
|
||||
assert.Equal(t, err == nil, expectedValid, "%q should report valid as: %v", n, expectedValid)
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ These resources are used to provide
|
||||
* An icon
|
||||
* A Windows manifest declaring Windows version support
|
||||
|
||||
The resource object files are generated with go generate.
|
||||
The resource object files are generated when building with scripts/build/binary .
|
||||
The resource source files are located in scripts/winresources.
|
||||
This occurs automatically when you run scripts/build/windows.
|
||||
|
||||
@ -14,5 +14,3 @@ is included.
|
||||
|
||||
*/
|
||||
package winresources
|
||||
|
||||
//go:generate ../../scripts/gen/windows-resources
|
||||
|
||||
@ -17,7 +17,9 @@ import (
|
||||
func TestClientDebugEnabled(t *testing.T) {
|
||||
defer debug.Disable()
|
||||
|
||||
tcmd := newDockerCommand(&command.DockerCli{})
|
||||
cli, err := command.NewDockerCli()
|
||||
assert.NilError(t, err)
|
||||
tcmd := newDockerCommand(cli)
|
||||
tcmd.SetFlag("debug", "true")
|
||||
cmd, _, err := tcmd.HandleGlobalFlags()
|
||||
assert.NilError(t, err)
|
||||
|
||||
@ -935,7 +935,7 @@ __docker_complete_log_options() {
|
||||
# awslogs does not implement the $common_options2.
|
||||
local awslogs_options="$common_options1 awslogs-create-group awslogs-credentials-endpoint awslogs-datetime-format awslogs-group awslogs-multiline-pattern awslogs-region awslogs-stream tag"
|
||||
|
||||
local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries fluentd-sub-second-precision tag"
|
||||
local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async fluentd-buffer-limit fluentd-request-ack fluentd-retry-wait fluentd-max-retries fluentd-sub-second-precision tag"
|
||||
local gcplogs_options="$common_options1 $common_options2 gcp-log-cmd gcp-meta-id gcp-meta-name gcp-meta-zone gcp-project"
|
||||
local gelf_options="$common_options1 $common_options2 gelf-address gelf-compression-level gelf-compression-type gelf-tcp-max-reconnect gelf-tcp-reconnect-delay tag"
|
||||
local journald_options="$common_options1 $common_options2 tag"
|
||||
@ -1955,6 +1955,7 @@ _docker_container_run_and_create() {
|
||||
--pid
|
||||
--pids-limit
|
||||
--publish -p
|
||||
--pull
|
||||
--restart
|
||||
--runtime
|
||||
--security-opt
|
||||
@ -2153,6 +2154,10 @@ _docker_container_run_and_create() {
|
||||
esac
|
||||
return
|
||||
;;
|
||||
--pull)
|
||||
COMPREPLY=( $( compgen -W 'always missing never' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--runtime)
|
||||
__docker_complete_runtimes
|
||||
return
|
||||
@ -2548,6 +2553,7 @@ _docker_daemon() {
|
||||
--ip-forward=false
|
||||
--ip-masq=false
|
||||
--iptables=false
|
||||
--ip6tables
|
||||
--ipv6
|
||||
--live-restore
|
||||
--no-new-privileges
|
||||
@ -3601,7 +3607,7 @@ _docker_service_ls() {
|
||||
return
|
||||
;;
|
||||
mode)
|
||||
COMPREPLY=( $( compgen -W "global replicated" -- "${cur##*=}" ) )
|
||||
COMPREPLY=( $( compgen -W "global global-job replicated replicated-job" -- "${cur##*=}" ) )
|
||||
return
|
||||
;;
|
||||
name)
|
||||
@ -3731,6 +3737,7 @@ _docker_service_update_and_create() {
|
||||
--limit-pids
|
||||
--log-driver
|
||||
--log-opt
|
||||
--max-replicas
|
||||
--replicas
|
||||
--replicas-max-per-node
|
||||
--reserve-cpu
|
||||
@ -3804,7 +3811,7 @@ _docker_service_update_and_create() {
|
||||
return
|
||||
;;
|
||||
--mode)
|
||||
COMPREPLY=( $( compgen -W "global replicated" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "global global-job replicated replicated-job" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
@ -4348,6 +4355,9 @@ _docker_node_ls() {
|
||||
__docker_complete_nodes --cur "${cur##*=}" --id
|
||||
return
|
||||
;;
|
||||
label|node.label)
|
||||
return
|
||||
;;
|
||||
membership)
|
||||
COMPREPLY=( $( compgen -W "accepted pending" -- "${cur##*=}" ) )
|
||||
return
|
||||
@ -4364,7 +4374,7 @@ _docker_node_ls() {
|
||||
|
||||
case "$prev" in
|
||||
--filter|-f)
|
||||
COMPREPLY=( $( compgen -W "id label membership name role" -S = -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "id label membership name node.label role" -S = -- "$cur" ) )
|
||||
__docker_nospace
|
||||
return
|
||||
;;
|
||||
|
||||
@ -1343,7 +1343,7 @@ __docker_node_complete_ls_filters() {
|
||||
;;
|
||||
esac
|
||||
else
|
||||
opts=('id' 'label' 'membership' 'name' 'role')
|
||||
opts=('id' 'label' 'membership' 'name' 'node.label' 'role')
|
||||
_describe -t filter-opts "filter options" opts -qS "=" && ret=0
|
||||
fi
|
||||
|
||||
@ -2544,6 +2544,82 @@ __docker_volume_subcommand() {
|
||||
|
||||
# EO volume
|
||||
|
||||
# BO context
|
||||
|
||||
__docker_complete_contexts() {
|
||||
[[ $PREFIX = -* ]] && return 1
|
||||
integer ret=1
|
||||
declare -a contexts
|
||||
|
||||
contexts=(${(f)${:-"$(_call_program commands docker $docker_options context ls -q)"$'\n'}})
|
||||
|
||||
_describe -t context-list "context" contexts && ret=0
|
||||
return ret
|
||||
}
|
||||
|
||||
__docker_context_commands() {
|
||||
local -a _docker_context_subcommands
|
||||
_docker_context_subcommands=(
|
||||
"create:Create new context"
|
||||
"inspect:Display detailed information on one or more contexts"
|
||||
"list:List available contexts"
|
||||
"rm:Remove one or more contexts"
|
||||
"show:Print the current context"
|
||||
"update:Update a context"
|
||||
"use:Set the default context"
|
||||
)
|
||||
_describe -t docker-context-commands "docker context command" _docker_context_subcommands
|
||||
}
|
||||
|
||||
__docker_context_subcommand() {
|
||||
local -a _command_args opts_help
|
||||
local expl help="--help"
|
||||
integer ret=1
|
||||
|
||||
opts_help=("(: -)--help[Print usage]")
|
||||
|
||||
case "$words[1]" in
|
||||
(create)
|
||||
_arguments $(__docker_arguments) \
|
||||
$opts_help \
|
||||
"($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \
|
||||
"($help)--description=[Description of the context]:description:" \
|
||||
"($help)--docker=[Set the docker endpoint]:docker:" \
|
||||
"($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \
|
||||
"($help)--from=[Create context from a named context]:from:__docker_complete_contexts" \
|
||||
"($help -):name: " && ret=0
|
||||
;;
|
||||
(use)
|
||||
_arguments $(__docker_arguments) \
|
||||
$opts_help \
|
||||
"($help -)1:context:__docker_complete_contexts" && ret=0
|
||||
;;
|
||||
(inspect)
|
||||
_arguments $(__docker_arguments) \
|
||||
$opts_help \
|
||||
"($help -)1:context:__docker_complete_contexts" && ret=0
|
||||
;;
|
||||
(rm)
|
||||
_arguments $(__docker_arguments) \
|
||||
$opts_help \
|
||||
"($help -)1:context:__docker_complete_contexts" && ret=0
|
||||
;;
|
||||
(update)
|
||||
_arguments $(__docker_arguments) \
|
||||
$opts_help \
|
||||
"($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \
|
||||
"($help)--description=[Description of the context]:description:" \
|
||||
"($help)--docker=[Set the docker endpoint]:docker:" \
|
||||
"($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \
|
||||
"($help -):name:" && ret=0
|
||||
;;
|
||||
esac
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
# EO context
|
||||
|
||||
__docker_caching_policy() {
|
||||
oldp=( "$1"(Nmh+1) ) # 1 hour
|
||||
(( $#oldp ))
|
||||
@ -2631,6 +2707,23 @@ __docker_subcommand() {
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(context)
|
||||
local curcontext="$curcontext" state
|
||||
_arguments $(__docker_arguments) \
|
||||
$opts_help \
|
||||
"($help -): :->command" \
|
||||
"($help -)*:: :->option-or-argument" && ret=0
|
||||
|
||||
case $state in
|
||||
(command)
|
||||
__docker_context_commands && ret=0
|
||||
;;
|
||||
(option-or-argument)
|
||||
curcontext=${curcontext%:*:*}:docker-${words[-1]}:
|
||||
__docker_context_subcommand && ret=0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(daemon)
|
||||
_arguments $(__docker_arguments) \
|
||||
$opts_help \
|
||||
|
||||
63
docker-bake.hcl
Normal file
@ -0,0 +1,63 @@
|
||||
variable "VERSION" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "USE_GLIBC" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "STRIP_TARGET" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
group "default" {
|
||||
targets = ["binary"]
|
||||
}
|
||||
|
||||
target "binary" {
|
||||
target = "binary"
|
||||
platforms = ["local"]
|
||||
output = ["build"]
|
||||
args = {
|
||||
BASE_VARIANT = USE_GLIBC != "" ? "buster" : "alpine"
|
||||
VERSION = VERSION
|
||||
GO_STRIP = STRIP_TARGET
|
||||
}
|
||||
}
|
||||
|
||||
target "dynbinary" {
|
||||
inherits = ["binary"]
|
||||
args = {
|
||||
GO_LINKMODE = "dynamic"
|
||||
}
|
||||
}
|
||||
|
||||
variable "GROUP_TOTAL" {
|
||||
default = "1"
|
||||
}
|
||||
|
||||
variable "GROUP_INDEX" {
|
||||
default = "0"
|
||||
}
|
||||
|
||||
function "platforms" {
|
||||
params = []
|
||||
result = ["linux/amd64", "linux/386", "linux/arm64", "linux/arm", "linux/ppc64le", "linux/s390x", "darwin/amd64", "darwin/arm64", "windows/amd64"]
|
||||
}
|
||||
|
||||
function "glen" {
|
||||
params = [platforms, GROUP_TOTAL]
|
||||
result = ceil(length(platforms)/GROUP_TOTAL)
|
||||
}
|
||||
|
||||
target "_all_platforms" {
|
||||
platforms = slice(platforms(), GROUP_INDEX*glen(platforms(), GROUP_TOTAL),min(length(platforms()), (GROUP_INDEX+1)*glen(platforms(), GROUP_TOTAL)))
|
||||
}
|
||||
|
||||
target "cross" {
|
||||
inherits = ["binary", "_all_platforms"]
|
||||
}
|
||||
|
||||
target "dynbinary-cross" {
|
||||
inherits = ["dynbinary", "_all_platforms"]
|
||||
}
|
||||
@ -38,11 +38,6 @@ build_linter_image:
|
||||
# build dockerfile from stdin so that we don't send the build-context; source is bind-mounted in the development environment
|
||||
cat ./dockerfiles/Dockerfile.lint | docker build ${DOCKER_BUILD_ARGS} --build-arg=GO_VERSION -t $(LINTER_IMAGE_NAME) -
|
||||
|
||||
.PHONY: build_cross_image
|
||||
build_cross_image:
|
||||
# build dockerfile from stdin so that we don't send the build-context; source is bind-mounted in the development environment
|
||||
cat ./dockerfiles/Dockerfile.cross | docker build ${DOCKER_BUILD_ARGS} --build-arg=GO_VERSION -t $(CROSS_IMAGE_NAME) -
|
||||
|
||||
.PHONY: build_shell_validate_image
|
||||
build_shell_validate_image:
|
||||
# build dockerfile from stdin so that we don't send the build-context; source is bind-mounted in the development environment
|
||||
@ -80,22 +75,10 @@ test-unit: build_docker_image ## run unit tests (using go test)
|
||||
.PHONY: test ## run unit and e2e tests
|
||||
test: test-unit test-e2e
|
||||
|
||||
.PHONY: cross
|
||||
cross: build_cross_image ## build the CLI for macOS and Windows
|
||||
$(DOCKER_RUN) $(CROSS_IMAGE_NAME) make cross
|
||||
|
||||
.PHONY: binary-windows
|
||||
binary-windows: build_cross_image ## build the CLI for Windows
|
||||
$(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@
|
||||
|
||||
.PHONY: plugins-windows
|
||||
plugins-windows: build_cross_image ## build the example CLI plugins for Windows
|
||||
$(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@
|
||||
|
||||
.PHONY: binary-osx
|
||||
binary-osx: build_cross_image ## build the CLI for macOS
|
||||
$(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@
|
||||
|
||||
.PHONY: plugins-osx
|
||||
plugins-osx: build_cross_image ## build the example CLI plugins for macOS
|
||||
$(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@
|
||||
@ -120,9 +103,6 @@ fmt: ## run gofmt
|
||||
vendor: build_docker_image vendor.conf ## download dependencies (vendor/) listed in vendor.conf
|
||||
$(DOCKER_RUN) -it $(DEV_DOCKER_IMAGE_NAME) make vendor
|
||||
|
||||
dynbinary: build_cross_image ## build the CLI dynamically linked
|
||||
$(DOCKER_RUN) -it $(CROSS_IMAGE_NAME) make dynbinary
|
||||
|
||||
.PHONY: authors
|
||||
authors: ## generate AUTHORS file from git history
|
||||
$(DOCKER_RUN) -it $(DEV_DOCKER_IMAGE_NAME) make authors
|
||||
|
||||
@ -52,6 +52,7 @@ Status | Feature
|
||||
-----------|------------------------------------------------------------------------------------------------------------------------------------|------------|------------
|
||||
Deprecated | [Pulling images from non-compliant image registries](#pulling-images-from-non-compliant-image-registries) | v20.10 | -
|
||||
Deprecated | [Linux containers on Windows (LCOW)](#linux-containers-on-windows-lcow-experimental) | v20.10 | -
|
||||
Deprecated | [BLKIO weight options with cgroups v1](#blkio-weight-options–with-cgroups-v1) | v20.10 | -
|
||||
Deprecated | [Kernel memory limit](#kernel-memory-limit) | v20.10 | -
|
||||
Deprecated | [Classic Swarm and overlay networks using external key/value stores](#classic-swarm-and-overlay-networks-using-cluster-store) | v20.10 | -
|
||||
Deprecated | [Support for the legacy `~/.dockercfg` configuration file for authentication](#support-for-legacy-dockercfg-configuration-files) | v20.10 | -
|
||||
@ -140,6 +141,16 @@ now stopped in favor of running docker natively on Linux in WSL2.
|
||||
Developers who want to run Linux workloads on a Windows host are encouraged to use
|
||||
[Docker Desktop with WSL2](https://docs.docker.com/docker-for-windows/wsl/) instead.
|
||||
|
||||
### BLKIO weight options with cgroups v1
|
||||
|
||||
**Deprecated in Release: v20.10**
|
||||
|
||||
Specifying blkio weight (`docker run --blkio-weight` and `docker run --blkio-weight-device`)
|
||||
is now marked as deprecated when using cgroups v1 because the corresponding features
|
||||
were [removed in Linux kernel v5.0 and up](https://github.com/torvalds/linux/commit/f382fb0bcef4c37dc049e9f6963e3baf204d815c).
|
||||
When using cgroups v2, the `--blkio-weight` options are implemented using
|
||||
[`io.weight](https://github.com/torvalds/linux/blob/v5.0/Documentation/admin-guide/cgroup-v2.rst#io).
|
||||
|
||||
### Kernel memory limit
|
||||
|
||||
**Deprecated in Release: v20.10**
|
||||
|
||||
@ -122,7 +122,7 @@ enabled, and use it to create a volume.
|
||||
To disable a plugin, use the `docker plugin disable` command. To completely
|
||||
remove it, use the `docker plugin remove` command. For other available
|
||||
commands and options, see the
|
||||
[command line reference](../reference/commandline/index.md).
|
||||
[command line reference](https://docs.docker.com/engine/reference/commandline/cli/).
|
||||
|
||||
|
||||
## Developing a plugin
|
||||
|
||||
@ -33,11 +33,11 @@ a `Dockerfile` and a *context*. The build's context is the set of files at a
|
||||
specified location `PATH` or `URL`. The `PATH` is a directory on your local
|
||||
filesystem. The `URL` is a Git repository location.
|
||||
|
||||
A context is processed recursively. So, a `PATH` includes any subdirectories and
|
||||
the `URL` includes the repository and its submodules. This example shows a
|
||||
build command that uses the current directory as context:
|
||||
The build context is processed recursively. So, a `PATH` includes any subdirectories
|
||||
and the `URL` includes the repository and its submodules. This example shows a
|
||||
build command that uses the current directory (`.`) as build context:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker build .
|
||||
|
||||
Sending build context to Docker daemon 6.51 MB
|
||||
@ -52,8 +52,9 @@ Dockerfile.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> Do not use your root directory, `/`, as the `PATH` as it causes the build to
|
||||
> transfer the entire contents of your hard drive to the Docker daemon.
|
||||
> Do not use your root directory, `/`, as the `PATH` for your build context, as
|
||||
> it causes the build to transfer the entire contents of your hard drive to the
|
||||
> Docker daemon.
|
||||
{:.warning}
|
||||
|
||||
To use a file in the build context, the `Dockerfile` refers to the file specified
|
||||
@ -66,32 +67,37 @@ Traditionally, the `Dockerfile` is called `Dockerfile` and located in the root
|
||||
of the context. You use the `-f` flag with `docker build` to point to a Dockerfile
|
||||
anywhere in your file system.
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker build -f /path/to/a/Dockerfile .
|
||||
```
|
||||
|
||||
You can specify a repository and tag at which to save the new image if
|
||||
the build succeeds:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker build -t shykes/myapp .
|
||||
```
|
||||
|
||||
To tag the image into multiple repositories after the build,
|
||||
add multiple `-t` parameters when you run the `build` command:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
|
||||
```
|
||||
|
||||
Before the Docker daemon runs the instructions in the `Dockerfile`, it performs
|
||||
a preliminary validation of the `Dockerfile` and returns an error if the syntax is incorrect:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker build -t test/myapp .
|
||||
|
||||
Sending build context to Docker daemon 2.048 kB
|
||||
Error response from daemon: Unknown instruction: RUNCMD
|
||||
[+] Building 0.3s (2/2) FINISHED
|
||||
=> [internal] load build definition from Dockerfile 0.1s
|
||||
=> => transferring dockerfile: 60B 0.0s
|
||||
=> [internal] load .dockerignore 0.1s
|
||||
=> => transferring context: 2B 0.0s
|
||||
error: failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to create LLB definition:
|
||||
dockerfile parse error line 2: unknown instruction: RUNCMD
|
||||
```
|
||||
|
||||
The Docker daemon runs the instructions in the `Dockerfile` one-by-one,
|
||||
@ -104,38 +110,35 @@ Note that each instruction is run independently, and causes a new image
|
||||
to be created - so `RUN cd /tmp` will not have any effect on the next
|
||||
instructions.
|
||||
|
||||
Whenever possible, Docker will re-use the intermediate images (cache),
|
||||
to accelerate the `docker build` process significantly. This is indicated by
|
||||
the `Using cache` message in the console output.
|
||||
(For more information, see the [`Dockerfile` best practices guide](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/):
|
||||
Whenever possible, Docker uses a build-cache to accelerate the `docker build`
|
||||
process significantly. This is indicated by the `CACHED` message in the console
|
||||
output. (For more information, see the [`Dockerfile` best practices guide](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/):
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker build -t svendowideit/ambassador .
|
||||
|
||||
Sending build context to Docker daemon 15.36 kB
|
||||
Step 1/4 : FROM alpine:3.2
|
||||
---> 31f630c65071
|
||||
Step 2/4 : MAINTAINER SvenDowideit@home.org.au
|
||||
---> Using cache
|
||||
---> 2a1c91448f5f
|
||||
Step 3/4 : RUN apk update && apk add socat && rm -r /var/cache/
|
||||
---> Using cache
|
||||
---> 21ed6e7fbb73
|
||||
Step 4/4 : CMD env | grep _TCP= | (sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat -t 100000000 TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' && echo wait) | sh
|
||||
---> Using cache
|
||||
---> 7ea8aef582cc
|
||||
Successfully built 7ea8aef582cc
|
||||
[+] Building 0.7s (6/6) FINISHED
|
||||
=> [internal] load build definition from Dockerfile 0.1s
|
||||
=> => transferring dockerfile: 286B 0.0s
|
||||
=> [internal] load .dockerignore 0.1s
|
||||
=> => transferring context: 2B 0.0s
|
||||
=> [internal] load metadata for docker.io/library/alpine:3.2 0.4s
|
||||
=> CACHED [1/2] FROM docker.io/library/alpine:3.2@sha256:e9a2035f9d0d7ce 0.0s
|
||||
=> CACHED [2/2] RUN apk add --no-cache socat 0.0s
|
||||
=> exporting to image 0.0s
|
||||
=> => exporting layers 0.0s
|
||||
=> => writing image sha256:1affb80ca37018ac12067fa2af38cc5bcc2a8f09963de 0.0s
|
||||
=> => naming to docker.io/svendowideit/ambassador 0.0s
|
||||
```
|
||||
|
||||
Build cache is only used from images that have a local parent chain. This means
|
||||
that these images were created by previous builds or the whole chain of images
|
||||
was loaded with `docker load`. If you wish to use build cache of a specific
|
||||
image you can specify it with `--cache-from` option. Images specified with
|
||||
`--cache-from` do not need to have a parent chain and may be pulled from other
|
||||
registries.
|
||||
By default, the build cache is based on results from previous builds on the machine
|
||||
on which you are building. The `--cache-from` option also allows you to use a
|
||||
build-cache that's distributed through an image registry refer to the
|
||||
[specifying external cache sources](commandline/build.md#specifying-external-cache-sources)
|
||||
section in the `docker build` command reference.
|
||||
|
||||
When you're done with your build, you're ready to look into [*Pushing a
|
||||
repository to its registry*](https://docs.docker.com/engine/tutorials/dockerrepos/#/contributing-to-docker-hub).
|
||||
When you're done with your build, you're ready to look into [scanning your image with `docker scan`](https://docs.docker.com/engine/scan/),
|
||||
and [pushing your image to Docker Hub](https://docs.docker.com/docker-hub/repos/).
|
||||
|
||||
|
||||
## BuildKit
|
||||
@ -315,6 +318,8 @@ The following parser directives are supported:
|
||||
|
||||
## syntax
|
||||
|
||||
<a name="external-implementation-features"><!-- included for deep-links to old section --></a>
|
||||
|
||||
```dockerfile
|
||||
# syntax=[remote image reference]
|
||||
```
|
||||
@ -322,55 +327,73 @@ The following parser directives are supported:
|
||||
For example:
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile
|
||||
# syntax=docker/dockerfile:1.0
|
||||
# syntax=docker/dockerfile:1
|
||||
# syntax=docker.io/docker/dockerfile:1
|
||||
# syntax=docker/dockerfile:1.0.0-experimental
|
||||
# syntax=example.com/user/repo:tag@sha256:abcdef...
|
||||
```
|
||||
|
||||
This feature is only enabled if the [BuildKit](#buildkit) backend is used.
|
||||
This feature is only available when using the [BuildKit](#buildkit) backend, and
|
||||
is ignored when using the classic builder backend.
|
||||
|
||||
The syntax directive defines the location of the Dockerfile builder that is used for
|
||||
building the current Dockerfile. The BuildKit backend allows to seamlessly use
|
||||
external implementations of builders that are distributed as Docker images and
|
||||
execute inside a container sandbox environment.
|
||||
The syntax directive defines the location of the Dockerfile syntax that is used
|
||||
to build the Dockerfile. The BuildKit backend allows to seamlessly use external
|
||||
implementations that are distributed as Docker images and execute inside a
|
||||
container sandbox environment.
|
||||
|
||||
Custom Dockerfile implementation allows you to:
|
||||
Custom Dockerfile implementations allows you to:
|
||||
|
||||
- Automatically get bugfixes without updating the daemon
|
||||
- Automatically get bugfixes without updating the Docker daemon
|
||||
- Make sure all users are using the same implementation to build your Dockerfile
|
||||
- Use the latest features without updating the daemon
|
||||
- Try out new experimental or third-party features
|
||||
- Use the latest features without updating the Docker daemon
|
||||
- Try out new features or third-party features before they are integrated in the Docker daemon
|
||||
- Use [alternative build definitions, or create your own](https://github.com/moby/buildkit#exploring-llb)
|
||||
|
||||
### Official releases
|
||||
|
||||
Docker distributes official versions of the images that can be used for building
|
||||
Dockerfiles under `docker/dockerfile` repository on Docker Hub. There are two
|
||||
channels where new images are released: stable and experimental.
|
||||
channels where new images are released: `stable` and `labs`.
|
||||
|
||||
Stable channel follows semantic versioning. For example:
|
||||
Stable channel follows [semantic versioning](https://semver.org). For example:
|
||||
|
||||
- `docker/dockerfile:1.0.0` - only allow immutable version `1.0.0`
|
||||
- `docker/dockerfile:1.0` - allow versions `1.0.*`
|
||||
- `docker/dockerfile:1` - allow versions `1.*.*`
|
||||
- `docker/dockerfile:latest` - latest release on stable channel
|
||||
- `docker/dockerfile:1` - kept updated with the latest `1.x.x` minor _and_ patch release
|
||||
- `docker/dockerfile:1.2` - kept updated with the latest `1.2.x` patch release,
|
||||
and stops receiving updates once version `1.3.0` is released.
|
||||
- `docker/dockerfile:1.2.1` - immutable: never updated
|
||||
|
||||
The experimental channel uses incremental versioning with the major and minor
|
||||
component from the stable channel on the time of the release. For example:
|
||||
We recommend using `docker/dockerfile:1`, which always points to the latest stable
|
||||
release of the version 1 syntax, and receives both "minor" and "patch" updates
|
||||
for the version 1 release cycle. BuildKit automatically checks for updates of the
|
||||
syntax when performing a build, making sure you are using the most current version.
|
||||
|
||||
- `docker/dockerfile:1.0.1-experimental` - only allow immutable version `1.0.1-experimental`
|
||||
- `docker/dockerfile:1.0-experimental` - latest experimental releases after `1.0`
|
||||
- `docker/dockerfile:experimental` - latest release on experimental channel
|
||||
If a specific version is used, such as `1.2` or `1.2.1`, the Dockerfile needs to
|
||||
be updated manually to continue receiving bugfixes and new features. Old versions
|
||||
of the Dockerfile remain compatible with the new versions of the builder.
|
||||
|
||||
You should choose a channel that best fits your needs. If you only want
|
||||
bugfixes, you should use `docker/dockerfile:1.0`. If you want to benefit from
|
||||
experimental features, you should use the experimental channel. If you are using
|
||||
the experimental channel, newer releases may not be backwards compatible, so it
|
||||
**labs channel**
|
||||
|
||||
The "labs" channel provides early access to Dockerfile features that are not yet
|
||||
available in the stable channel. Labs channel images are released in conjunction
|
||||
with the stable releases, and follow the same versioning with the `-labs` suffix,
|
||||
for example:
|
||||
|
||||
- `docker/dockerfile:labs` - latest release on labs channel
|
||||
- `docker/dockerfile:1-labs` - same as `dockerfile:1` in the stable channel, with labs features enabled
|
||||
- `docker/dockerfile:1.2-labs` - same as `dockerfile:1.2` in the stable channel, with labs features enabled
|
||||
- `docker/dockerfile:1.2.1-labs` - immutable: never updated. Same as `dockerfile:1.2.1` in the stable channel, with labs features enabled
|
||||
|
||||
Choose a channel that best fits your needs; if you want to benefit from
|
||||
new features, use the labs channel. Images in the labs channel provide a superset
|
||||
of the features in the stable channel; note that `stable` features in the labs
|
||||
channel images follow [semantic versioning](https://semver.org), but "labs"
|
||||
features do not, and newer releases may not be backwards compatible, so it
|
||||
is recommended to use an immutable full version variant.
|
||||
|
||||
For master builds and nightly feature releases refer to the description in
|
||||
[the source repository](https://github.com/moby/buildkit/blob/master/README.md).
|
||||
For documentation on "labs" features, master builds, and nightly feature releases,
|
||||
refer to the description in [the BuildKit source repository on GitHub](https://github.com/moby/buildkit/blob/master/README.md).
|
||||
For a full list of available images, visit the [image repository on Docker Hub](https://hub.docker.com/r/docker/dockerfile),
|
||||
and the [docker/dockerfile-upstream image repository](https://hub.docker.com/r/docker/dockerfile-upstream)
|
||||
for development builds.
|
||||
|
||||
## escape
|
||||
|
||||
@ -413,14 +436,15 @@ RUN dir c:\
|
||||
|
||||
Results in:
|
||||
|
||||
```powershell
|
||||
PS C:\John> docker build -t cmd .
|
||||
```console
|
||||
PS E:\myproject> docker build -t cmd .
|
||||
|
||||
Sending build context to Docker daemon 3.072 kB
|
||||
Step 1/2 : FROM microsoft/nanoserver
|
||||
---> 22738ff49c6d
|
||||
Step 2/2 : COPY testfile.txt c:\RUN dir c:
|
||||
GetFileAttributesEx c:RUN: The system cannot find the file specified.
|
||||
PS C:\John>
|
||||
PS E:\myproject>
|
||||
```
|
||||
|
||||
One solution to the above would be to use `/` as the target of both the `COPY`
|
||||
@ -441,8 +465,9 @@ RUN dir c:\
|
||||
|
||||
Results in:
|
||||
|
||||
```powershell
|
||||
PS C:\John> docker build -t succeeds --no-cache=true .
|
||||
```console
|
||||
PS E:\myproject> docker build -t succeeds --no-cache=true .
|
||||
|
||||
Sending build context to Docker daemon 3.072 kB
|
||||
Step 1/3 : FROM microsoft/nanoserver
|
||||
---> 22738ff49c6d
|
||||
@ -467,7 +492,7 @@ Step 3/3 : RUN dir c:\
|
||||
---> 01c7f3bef04f
|
||||
Removing intermediate container a2c157f842f5
|
||||
Successfully built 01c7f3bef04f
|
||||
PS C:\John>
|
||||
PS E:\myproject>
|
||||
```
|
||||
|
||||
## Environment replacement
|
||||
@ -910,8 +935,8 @@ the most-recently-applied value overrides any previously-set value.
|
||||
To view an image's labels, use the `docker image inspect` command. You can use
|
||||
the `--format` option to show just the labels;
|
||||
|
||||
```bash
|
||||
docker image inspect --format='{{json .Config.Labels}}' myimage
|
||||
```console
|
||||
$ docker image inspect --format='{{json .Config.Labels}}' myimage
|
||||
```
|
||||
```json
|
||||
{
|
||||
@ -938,7 +963,7 @@ easily, for example with `docker inspect`. To set a label corresponding to the
|
||||
`MAINTAINER` field you could use:
|
||||
|
||||
```dockerfile
|
||||
LABEL maintainer="SvenDowideit@home.org.au"
|
||||
LABEL org.opencontainers.image.authors="SvenDowideit@home.org.au"
|
||||
```
|
||||
|
||||
This will then be visible from `docker inspect` with the other labels.
|
||||
@ -980,8 +1005,8 @@ port on the host, so the port will not be the same for TCP and UDP.
|
||||
Regardless of the `EXPOSE` settings, you can override them at runtime by using
|
||||
the `-p` flag. For example
|
||||
|
||||
```bash
|
||||
docker run -p 80:80/tcp -p 80:80/udp ...
|
||||
```console
|
||||
$ docker run -p 80:80/tcp -p 80:80/udp ...
|
||||
```
|
||||
|
||||
To set up port redirection on the host system, see [using the -P flag](run.md#expose-incoming-ports).
|
||||
@ -1397,7 +1422,7 @@ An `ENTRYPOINT` allows you to configure a container that will run as an executab
|
||||
For example, the following starts nginx with its default content, listening
|
||||
on port 80:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker run -i -t --rm -p 80:80 nginx
|
||||
```
|
||||
|
||||
@ -1432,7 +1457,7 @@ CMD ["-c"]
|
||||
|
||||
When you run the container, you can see that `top` is the only process:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker run -it --rm --name test top -H
|
||||
|
||||
top - 08:25:00 up 7:27, 0 users, load average: 0.00, 0.01, 0.05
|
||||
@ -1447,7 +1472,7 @@ KiB Swap: 1441840 total, 0 used, 1441840 free. 1324440 cached Mem
|
||||
|
||||
To examine the result further, you can use `docker exec`:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker exec -it test ps aux
|
||||
|
||||
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
|
||||
@ -1519,7 +1544,7 @@ If you run this image with `docker run -it --rm -p 80:80 --name test apache`,
|
||||
you can then examine the container's processes with `docker exec`, or `docker top`,
|
||||
and then ask the script to stop Apache:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker exec -it test ps aux
|
||||
|
||||
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
|
||||
@ -1579,7 +1604,7 @@ ENTRYPOINT exec top -b
|
||||
|
||||
When you run this image, you'll see the single `PID 1` process:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker run -it --rm --name test top
|
||||
|
||||
Mem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cached
|
||||
@ -1591,7 +1616,7 @@ Load average: 0.08 0.03 0.05 2/98 6
|
||||
|
||||
Which exits cleanly on `docker stop`:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ /usr/bin/time docker stop test
|
||||
|
||||
test
|
||||
@ -1610,7 +1635,7 @@ CMD --ignored-param1
|
||||
|
||||
You can then run it (giving it a name for the next step):
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker run -it --name test top --ignored-param2
|
||||
|
||||
Mem: 1704184K used, 352484K free, 0K shrd, 0K buff, 140621524238337K cached
|
||||
@ -1626,7 +1651,7 @@ You can see from the output of `top` that the specified `ENTRYPOINT` is not `PID
|
||||
If you then run `docker stop test`, the container will not exit cleanly - the
|
||||
`stop` command will be forced to send a `SIGKILL` after the timeout:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker exec -it test ps aux
|
||||
|
||||
PID USER COMMAND
|
||||
@ -1859,9 +1884,10 @@ ARG user
|
||||
USER $user
|
||||
# ...
|
||||
```
|
||||
|
||||
A user builds this file by calling:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker build --build-arg user=what_user .
|
||||
```
|
||||
|
||||
@ -1900,7 +1926,7 @@ RUN echo $CONT_IMG_VER
|
||||
|
||||
Then, assume this image is built with this command:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker build --build-arg CONT_IMG_VER=v2.0.1 .
|
||||
```
|
||||
|
||||
@ -1922,7 +1948,7 @@ RUN echo $CONT_IMG_VER
|
||||
Unlike an `ARG` instruction, `ENV` values are always persisted in the built
|
||||
image. Consider a docker build without the `--build-arg` flag:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker build .
|
||||
```
|
||||
|
||||
@ -1948,10 +1974,11 @@ corresponding `ARG` instruction in the Dockerfile.
|
||||
- `NO_PROXY`
|
||||
- `no_proxy`
|
||||
|
||||
To use these, simply pass them on the command line using the flag:
|
||||
To use these, pass them on the command line using the `--build-arg` flag, for
|
||||
example:
|
||||
|
||||
```bash
|
||||
--build-arg <varname>=<value>
|
||||
```console
|
||||
$ docker build --build-arg HTTPS_PROXY=https://my-proxy.example.com .
|
||||
```
|
||||
|
||||
By default, these pre-defined variables are excluded from the output of
|
||||
@ -2298,8 +2325,9 @@ RUN c:\example\Execute-MyCmdlet -sample 'hello world'
|
||||
|
||||
Resulting in:
|
||||
|
||||
```powershell
|
||||
PS E:\docker\build\shell> docker build -t shell .
|
||||
```console
|
||||
PS E:\myproject> docker build -t shell .
|
||||
|
||||
Sending build context to Docker daemon 4.096 kB
|
||||
Step 1/5 : FROM microsoft/nanoserver
|
||||
---> 22738ff49c6d
|
||||
@ -2314,9 +2342,9 @@ Step 3/5 : RUN New-Item -ItemType Directory C:\Example
|
||||
Directory: C:\
|
||||
|
||||
|
||||
Mode LastWriteTime Length Name
|
||||
---- ------------- ------ ----
|
||||
d----- 10/28/2016 11:26 AM Example
|
||||
Mode LastWriteTime Length Name
|
||||
---- ------------- ------ ----
|
||||
d----- 10/28/2016 11:26 AM Example
|
||||
|
||||
|
||||
---> 3f2fbf1395d9
|
||||
@ -2330,7 +2358,7 @@ hello world
|
||||
---> 8e559e9bf424
|
||||
Removing intermediate container be6d8e63fe75
|
||||
Successfully built 8e559e9bf424
|
||||
PS E:\docker\build\shell>
|
||||
PS E:\myproject>
|
||||
```
|
||||
|
||||
The `SHELL` instruction could also be used to modify the way in which
|
||||
@ -2340,61 +2368,10 @@ environment variable expansion semantics could be modified.
|
||||
The `SHELL` instruction can also be used on Linux should an alternate shell be
|
||||
required such as `zsh`, `csh`, `tcsh` and others.
|
||||
|
||||
## External implementation features
|
||||
|
||||
This feature is only available when using the [BuildKit](#buildkit) backend.
|
||||
|
||||
Docker build supports experimental features like cache mounts, build secrets and
|
||||
ssh forwarding that are enabled by using an external implementation of the
|
||||
builder with a syntax directive. To learn about these features,
|
||||
[refer to the documentation in BuildKit repository](https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md).
|
||||
|
||||
## Dockerfile examples
|
||||
|
||||
Below you can see some examples of Dockerfile syntax.
|
||||
For examples of Dockerfiles, refer to:
|
||||
|
||||
```dockerfile
|
||||
# Nginx
|
||||
#
|
||||
# VERSION 0.0.1
|
||||
|
||||
FROM ubuntu
|
||||
LABEL Description="This image is used to start the foobar executable" Vendor="ACME Products" Version="1.0"
|
||||
RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server
|
||||
```
|
||||
|
||||
```dockerfile
|
||||
# Firefox over VNC
|
||||
#
|
||||
# VERSION 0.3
|
||||
|
||||
FROM ubuntu
|
||||
|
||||
# Install vnc, xvfb in order to create a 'fake' display and firefox
|
||||
RUN apt-get update && apt-get install -y x11vnc xvfb firefox
|
||||
RUN mkdir ~/.vnc
|
||||
# Setup a password
|
||||
RUN x11vnc -storepasswd 1234 ~/.vnc/passwd
|
||||
# Autostart firefox (might not be the best way, but it does the trick)
|
||||
RUN bash -c 'echo "firefox" >> /.bashrc'
|
||||
|
||||
EXPOSE 5900
|
||||
CMD ["x11vnc", "-forever", "-usepw", "-create"]
|
||||
```
|
||||
|
||||
```dockerfile
|
||||
# Multiple images example
|
||||
#
|
||||
# VERSION 0.1
|
||||
|
||||
FROM ubuntu
|
||||
RUN echo foo > bar
|
||||
# Will output something like ===> 907ad6c2736f
|
||||
|
||||
FROM ubuntu
|
||||
RUN echo moo > oink
|
||||
# Will output something like ===> 695d7793cbe4
|
||||
|
||||
# You'll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with
|
||||
# /oink.
|
||||
```
|
||||
- The ["build images" section](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)
|
||||
- The ["get started](https://docs.docker.com/get-started/)
|
||||
- The [language-specific getting started guides](https://docs.docker.com/language/)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Use the Docker command line"
|
||||
description: "Docker's CLI command description and usage"
|
||||
keywords: "Docker, Docker documentation, CLI, command line"
|
||||
keywords: "Docker, Docker documentation, CLI, command line, config.json, CLI configuration file"
|
||||
redirect_from:
|
||||
- /go/experimental/
|
||||
- /engine/reference/commandline/engine/
|
||||
@ -62,30 +62,22 @@ the [installation](https://docs.docker.com/install/) instructions for your opera
|
||||
|
||||
## Environment variables
|
||||
|
||||
For easy reference, the following list of environment variables are supported
|
||||
by the `docker` command line:
|
||||
The following list of environment variables are supported by the `docker` command
|
||||
line:
|
||||
|
||||
* `DOCKER_API_VERSION` The API version to use (e.g. `1.19`)
|
||||
* `DOCKER_CONFIG` The location of your client configuration files.
|
||||
* `DOCKER_HOST` Daemon socket to connect to.
|
||||
* `DOCKER_STACK_ORCHESTRATOR` Configure the default orchestrator to use when using `docker stack` management commands.
|
||||
* `DOCKER_CONTENT_TRUST` When set Docker uses notary to sign and verify images.
|
||||
Equates to `--disable-content-trust=false` for build, create, pull, push, run.
|
||||
* `DOCKER_CONTENT_TRUST_SERVER` The URL of the Notary server to use. This defaults
|
||||
to the same URL as the registry.
|
||||
* `DOCKER_HIDE_LEGACY_COMMANDS` When set, Docker hides "legacy" top-level commands (such as `docker rm`, and
|
||||
`docker pull`) in `docker help` output, and only `Management commands` per object-type (e.g., `docker container`) are
|
||||
printed. This may become the default in a future release, at which point this environment-variable is removed.
|
||||
* `DOCKER_CONTEXT` Specify the context to use (overrides DOCKER_HOST env var and default context set with "docker context use")
|
||||
* `DOCKER_DEFAULT_PLATFORM` Specify the default platform for the commands that take the `--platform` flag.
|
||||
|
||||
#### Shared Environment variables
|
||||
|
||||
These environment variables can be used both with the `docker` command line and
|
||||
`dockerd` command line:
|
||||
|
||||
* `DOCKER_CERT_PATH` The location of your authentication keys.
|
||||
* `DOCKER_TLS_VERIFY` When set Docker uses TLS and verifies the remote.
|
||||
| Variable | Description |
|
||||
|:------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `DOCKER_API_VERSION` | Override the negotiated API version to use for debugging (e.g. `1.19`) |
|
||||
| `DOCKER_CERT_PATH` | Location of your authentication keys. This variable is used both by the `docker` CLI and the [`dockerd` daemon](dockerd.md) |
|
||||
| `DOCKER_CONFIG` | The location of your client configuration files. |
|
||||
| `DOCKER_CONTENT_TRUST_SERVER` | The URL of the Notary server to use. Defaults to the same URL as the registry. |
|
||||
| `DOCKER_CONTENT_TRUST` | When set Docker uses notary to sign and verify images. Equates to `--disable-content-trust=false` for build, create, pull, push, run. |
|
||||
| `DOCKER_CONTEXT` | Name of the `docker context` to use (overrides `DOCKER_HOST` env var and default context set with `docker context use`) |
|
||||
| `DOCKER_DEFAULT_PLATFORM` | Default platform for commands that take the `--platform` flag. |
|
||||
| `DOCKER_HIDE_LEGACY_COMMANDS` | When set, Docker hides "legacy" top-level commands (such as `docker rm`, and `docker pull`) in `docker help` output, and only `Management commands` per object-type (e.g., `docker container`) are printed. This may become the default in a future release, at which point this environment-variable is removed. |
|
||||
| `DOCKER_HOST` | Daemon socket to connect to. |
|
||||
| `DOCKER_STACK_ORCHESTRATOR` | Configure the default orchestrator to use when using `docker stack` management commands. |
|
||||
| `DOCKER_TLS_VERIFY` | When set Docker uses TLS and verifies the remote. This variable is used both by the `docker` CLI and the [`dockerd` daemon](dockerd.md) |
|
||||
|
||||
Because Docker is developed using Go, you can also use any environment
|
||||
variables used by the Go runtime. In particular, you may find these useful:
|
||||
@ -98,7 +90,7 @@ These Go environment variables are case-insensitive. See the
|
||||
[Go specification](http://golang.org/pkg/net/http/) for details on these
|
||||
variables.
|
||||
|
||||
### Configuration files
|
||||
## Configuration files
|
||||
|
||||
By default, the Docker command line stores its configuration files in a
|
||||
directory called `.docker` within your `$HOME` directory.
|
||||
@ -124,7 +116,7 @@ specified, then the `--config` option overrides the `DOCKER_CONFIG` environment
|
||||
variable. The example below overrides the `docker ps` command using a
|
||||
`config.json` file located in the `~/testconfigs/` directory.
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker --config ~/testconfigs/ ps
|
||||
```
|
||||
|
||||
@ -133,79 +125,56 @@ configuration, you can set the `DOCKER_CONFIG` environment variable in your
|
||||
shell (e.g. `~/.profile` or `~/.bashrc`). The example below sets the new
|
||||
directory to be `HOME/newdir/.docker`.
|
||||
|
||||
```bash
|
||||
echo export DOCKER_CONFIG=$HOME/newdir/.docker > ~/.profile
|
||||
```console
|
||||
$ echo export DOCKER_CONFIG=$HOME/newdir/.docker > ~/.profile
|
||||
```
|
||||
|
||||
### `config.json` properties
|
||||
## Docker CLI configuration file (`config.json`) properties
|
||||
|
||||
The `config.json` file stores a JSON encoding of several properties:
|
||||
<a name="configjson-properties"><!-- included for deep-links to old section --></a>
|
||||
|
||||
Use the Docker CLI configuration to customize settings for the `docker` CLI. The
|
||||
configuration file uses JSON formatting, and properties:
|
||||
|
||||
By default, configuration file is stored in `~/.docker/config.json`. Refer to the
|
||||
[change the `.docker` directory](#change-the-docker-directory) section to use a
|
||||
different location.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> The configuration file and other files inside the `~/.docker` configuration
|
||||
> directory may contain sensitive information, such as authentication information
|
||||
> for proxies or, depending on your credential store, credentials for your image
|
||||
> registries. Review your configuration file's content before sharing with others,
|
||||
> and prevent committing the file to version control.
|
||||
|
||||
### Customize the default output format for commands
|
||||
|
||||
These fields allow you to customize the default output format for some commands
|
||||
if no `--format` flag is provided.
|
||||
|
||||
| Property | Description |
|
||||
|:-----------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `configFormat` | Custom default format for `docker config ls` output. Refer to the [**format the output** section in the `docker config ls` documentation](config_ls.md#format-the-output) for a list of supported formatting directives. |
|
||||
| `imagesFormat` | Custom default format for `docker images` / `docker image ls` output. Refer to the [**format the output** section in the `docker images` documentation](images.md#format-the-output) for a list of supported formatting directives. |
|
||||
| `nodesFormat` | Custom default format for `docker node ls` output. Refer to the [**formatting** section in the `docker node ls` documentation](node_ls.md#formatting) for a list of supported formatting directives. |
|
||||
| `pluginsFormat` | Custom default format for `docker plugin ls` output. Refer to the [**formatting** section in the `docker plugin ls` documentation](plugin_ls.md#formatting) for a list of supported formatting directives. |
|
||||
| `psFormat` | Custom default format for `docker ps` / `docker container ps` output. Refer to the [**formatting** section in the `docker ps` documentation](ps.md#formatting) for a list of supported formatting directives. |
|
||||
| `secretFormat` | Custom default format for `docker secret ls` output. Refer to the [**format the output** section in the `docker secret ls` documentation](secret_ls.md#format-the-output) for a list of supported formatting directives. |
|
||||
| `serviceInspectFormat` | Custom default format for `docker service inspect` output. Refer to the [**formatting** section in the `docker service inspect` documentation](service_inspect.md#formatting) for a list of supported formatting directives. |
|
||||
| `servicesFormat` | Custom default format for `docker service ls` output. Refer to the [**formatting** section in the `docker service ls` documentation](service_ls.md#formatting) for a list of supported formatting directives. |
|
||||
| `statsFormat` | Custom default format for `docker stats` output. Refer to the [**formatting** section in the `docker stats` documentation](stats.md#formatting) for a list of supported formatting directives. |
|
||||
|
||||
|
||||
### Custom HTTP headers
|
||||
|
||||
The property `HttpHeaders` specifies a set of headers to include in all messages
|
||||
sent from the Docker client to the daemon. Docker does not try to interpret or
|
||||
understand these header; it simply puts them into the messages. Docker does
|
||||
understand these headers; it simply puts them into the messages. Docker does
|
||||
not allow these headers to change any headers it sets for itself.
|
||||
|
||||
The property `psFormat` specifies the default format for `docker ps` output.
|
||||
When the `--format` flag is not provided with the `docker ps` command,
|
||||
Docker's client uses this property. If this property is not set, the client
|
||||
falls back to the default table format. For a list of supported formatting
|
||||
directives, see the
|
||||
[**Formatting** section in the `docker ps` documentation](ps.md)
|
||||
|
||||
The property `imagesFormat` specifies the default format for `docker images` output.
|
||||
When the `--format` flag is not provided with the `docker images` command,
|
||||
Docker's client uses this property. If this property is not set, the client
|
||||
falls back to the default table format. For a list of supported formatting
|
||||
directives, see the [**Formatting** section in the `docker images` documentation](images.md)
|
||||
|
||||
The property `pluginsFormat` specifies the default format for `docker plugin ls` output.
|
||||
When the `--format` flag is not provided with the `docker plugin ls` command,
|
||||
Docker's client uses this property. If this property is not set, the client
|
||||
falls back to the default table format. For a list of supported formatting
|
||||
directives, see the [**Formatting** section in the `docker plugin ls` documentation](plugin_ls.md)
|
||||
|
||||
The property `servicesFormat` specifies the default format for `docker
|
||||
service ls` output. When the `--format` flag is not provided with the
|
||||
`docker service ls` command, Docker's client uses this property. If this
|
||||
property is not set, the client falls back to the default json format. For a
|
||||
list of supported formatting directives, see the
|
||||
[**Formatting** section in the `docker service ls` documentation](service_ls.md)
|
||||
|
||||
The property `serviceInspectFormat` specifies the default format for `docker
|
||||
service inspect` output. When the `--format` flag is not provided with the
|
||||
`docker service inspect` command, Docker's client uses this property. If this
|
||||
property is not set, the client falls back to the default json format. For a
|
||||
list of supported formatting directives, see the
|
||||
[**Formatting** section in the `docker service inspect` documentation](service_inspect.md)
|
||||
|
||||
The property `statsFormat` specifies the default format for `docker
|
||||
stats` output. When the `--format` flag is not provided with the
|
||||
`docker stats` command, Docker's client uses this property. If this
|
||||
property is not set, the client falls back to the default table
|
||||
format. For a list of supported formatting directives, see
|
||||
[**Formatting** section in the `docker stats` documentation](stats.md)
|
||||
|
||||
The property `secretFormat` specifies the default format for `docker
|
||||
secret ls` output. When the `--format` flag is not provided with the
|
||||
`docker secret ls` command, Docker's client uses this property. If this
|
||||
property is not set, the client falls back to the default table
|
||||
format. For a list of supported formatting directives, see
|
||||
[**Formatting** section in the `docker secret ls` documentation](secret_ls.md)
|
||||
|
||||
|
||||
The property `nodesFormat` specifies the default format for `docker node ls` output.
|
||||
When the `--format` flag is not provided with the `docker node ls` command,
|
||||
Docker's client uses the value of `nodesFormat`. If the value of `nodesFormat` is not set,
|
||||
the client uses the default table format. For a list of supported formatting
|
||||
directives, see the [**Formatting** section in the `docker node ls` documentation](node_ls.md)
|
||||
|
||||
The property `configFormat` specifies the default format for `docker
|
||||
config ls` output. When the `--format` flag is not provided with the
|
||||
`docker config ls` command, Docker's client uses this property. If this
|
||||
property is not set, the client falls back to the default table
|
||||
format. For a list of supported formatting directives, see
|
||||
[**Formatting** section in the `docker config ls` documentation](config_ls.md)
|
||||
### Credential store options
|
||||
|
||||
The property `credsStore` specifies an external binary to serve as the default
|
||||
credential store. When this property is set, `docker login` will attempt to
|
||||
@ -221,11 +190,17 @@ credentials for specific registries. If this property is set, the binary
|
||||
for a specific registry. For more information, see the
|
||||
[**Credential helpers** section in the `docker login` documentation](login.md#credential-helpers)
|
||||
|
||||
|
||||
### Orchestrator options for docker stacks
|
||||
|
||||
The property `stackOrchestrator` specifies the default orchestrator to use when
|
||||
running `docker stack` management commands. Valid values are `"swarm"`,
|
||||
`"kubernetes"`, and `"all"`. This property can be overridden with the
|
||||
`DOCKER_STACK_ORCHESTRATOR` environment variable, or the `--orchestrator` flag.
|
||||
|
||||
|
||||
### Automatic proxy configuration for containers
|
||||
|
||||
The property `proxies` specifies proxy environment variables to be automatically
|
||||
set on containers, and set as `--build-arg` on containers used during `docker build`.
|
||||
A `"default"` set of proxies can be configured, and will be used for any docker
|
||||
@ -233,15 +208,26 @@ daemon that the client connects to, or a configuration per host (docker daemon),
|
||||
for example, "https://docker-daemon1.example.com". The following properties can
|
||||
be set for each environment:
|
||||
|
||||
* `httpProxy` (sets the value of `HTTP_PROXY` and `http_proxy`)
|
||||
* `httpsProxy` (sets the value of `HTTPS_PROXY` and `https_proxy`)
|
||||
* `ftpProxy` (sets the value of `FTP_PROXY` and `ftp_proxy`)
|
||||
* `noProxy` (sets the value of `NO_PROXY` and `no_proxy`)
|
||||
| Property | Description |
|
||||
|:---------------|:--------------------------------------------------------------------------------------------------------|
|
||||
| `httpProxy` | Default value of `HTTP_PROXY` and `http_proxy` for containers, and as `--build-arg` on `docker build` |
|
||||
| `httpsProxy` | Default value of `HTTPS_PROXY` and `https_proxy` for containers, and as `--build-arg` on `docker build` |
|
||||
| `ftpProxy` | Default value of `FTP_PROXY` and `ftp_proxy` for containers, and as `--build-arg` on `docker build` |
|
||||
| `noProxy` | Default value of `NO_PROXY` and `no_proxy` for containers, and as `--build-arg` on `docker build` |
|
||||
|
||||
> **Warning**: Proxy settings may contain sensitive information (for example,
|
||||
> if the proxy requires authentication). Environment variables are stored as
|
||||
> plain text in the container's configuration, and as such can be inspected
|
||||
> through the remote API or committed to an image when using `docker commit`.
|
||||
These settings are used to configure proxy settings for containers only, and not
|
||||
used as proxy settings for the `docker` CLI or the `dockerd` daemon. Refer to the
|
||||
[environment variables](#environment-variables) and [HTTP/HTTPS proxy](https://docs.docker.com/config/daemon/systemd/#httphttps-proxy)
|
||||
sections for configuring proxy settings for the cli and daemon.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> Proxy settings may contain sensitive information (for example, if the proxy
|
||||
> requires authentication). Environment variables are stored as plain text in
|
||||
> the container's configuration, and as such can be inspected through the remote
|
||||
> API or committed to an image when using `docker commit`.
|
||||
|
||||
### Default key-sequence to detach from containers
|
||||
|
||||
Once attached to a container, users detach from it and leave it running using
|
||||
the using `CTRL-p CTRL-q` key sequence. This detach key sequence is customizable
|
||||
@ -261,11 +247,17 @@ Users can override your custom or the default key sequence on a per-container
|
||||
basis. To do this, the user specifies the `--detach-keys` flag with the `docker
|
||||
attach`, `docker exec`, `docker run` or `docker start` command.
|
||||
|
||||
### CLI Plugin options
|
||||
|
||||
The property `plugins` contains settings specific to CLI plugins. The
|
||||
key is the plugin name, while the value is a further map of options,
|
||||
which are specific to that plugin.
|
||||
|
||||
Following is a sample `config.json` file:
|
||||
|
||||
### Sample configuration file
|
||||
|
||||
Following is a sample `config.json` file to illustrate the format used for
|
||||
various fields:
|
||||
|
||||
```json
|
||||
{% raw %}
|
||||
@ -301,14 +293,14 @@ Following is a sample `config.json` file:
|
||||
"proxies": {
|
||||
"default": {
|
||||
"httpProxy": "http://user:pass@example.com:3128",
|
||||
"httpsProxy": "http://user:pass@example.com:3128",
|
||||
"noProxy": "http://user:pass@example.com:3128",
|
||||
"httpsProxy": "https://my-proxy.example.com:3129",
|
||||
"noProxy": "intra.mycorp.example.com",
|
||||
"ftpProxy": "http://user:pass@example.com:3128"
|
||||
},
|
||||
"https://manager1.mycorp.example.com:2377": {
|
||||
"httpProxy": "http://user:pass@example.com:3128",
|
||||
"httpsProxy": "http://user:pass@example.com:3128"
|
||||
},
|
||||
"httpsProxy": "https://my-proxy.example.com:3129"
|
||||
}
|
||||
}
|
||||
}
|
||||
{% endraw %}
|
||||
@ -336,16 +328,18 @@ list of root Certificate Authorities.
|
||||
To list the help on any command just execute the command, followed by the
|
||||
`--help` option.
|
||||
|
||||
$ docker run --help
|
||||
```console
|
||||
$ docker run --help
|
||||
|
||||
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
|
||||
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
|
||||
|
||||
Run a command in a new container
|
||||
Run a command in a new container
|
||||
|
||||
Options:
|
||||
--add-host value Add a custom host-to-IP mapping (host:ip) (default [])
|
||||
-a, --attach value Attach to STDIN, STDOUT or STDERR (default [])
|
||||
...
|
||||
Options:
|
||||
--add-host value Add a custom host-to-IP mapping (host:ip) (default [])
|
||||
-a, --attach value Attach to STDIN, STDOUT or STDERR (default [])
|
||||
<...>
|
||||
```
|
||||
|
||||
### Option types
|
||||
|
||||
@ -366,7 +360,7 @@ container **will** run in "detached" mode, in the background.
|
||||
Options which default to `true` (e.g., `docker build --rm=true`) can only be
|
||||
set to the non-default value by explicitly setting them to `false`:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker build --rm=false .
|
||||
```
|
||||
|
||||
@ -375,7 +369,7 @@ $ docker build --rm=false .
|
||||
You can specify options like `-a=[]` multiple times in a single command line,
|
||||
for example in these commands:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker run -a stdin -a stdout -i -t ubuntu /bin/bash
|
||||
|
||||
$ docker run -a stdin -a stdout -a stderr ubuntu /bin/ls
|
||||
@ -384,7 +378,7 @@ $ docker run -a stdin -a stdout -a stderr ubuntu /bin/ls
|
||||
Sometimes, multiple options can call for a more complex value string as for
|
||||
`-v`:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ docker run -v /host:/container example/mysql
|
||||
```
|
||||
|
||||
|
||||
35
docs/reference/commandline/config.md
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
title: "config"
|
||||
description: "The config command description and usage"
|
||||
keywords: "config"
|
||||
---
|
||||
|
||||
# config
|
||||
|
||||
```markdown
|
||||
Usage: docker config COMMAND
|
||||
|
||||
Manage Docker configs
|
||||
|
||||
Options:
|
||||
--help Print usage
|
||||
|
||||
Commands:
|
||||
create Create a config from a file or STDIN
|
||||
inspect Display detailed information on one or more configs
|
||||
ls List configs
|
||||
rm Remove one or more configs
|
||||
|
||||
Run 'docker config COMMAND --help' for more information on a command.
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
Manage configs.
|
||||
|
||||
## Related commands
|
||||
|
||||
* [config create](config_create.md)
|
||||
* [config inspect](config_inspect.md)
|
||||
* [config list](config_ls.md)
|
||||
* [config rm](config_rm.md)
|
||||
99
docs/reference/commandline/config_create.md
Normal file
@ -0,0 +1,99 @@
|
||||
---
|
||||
title: "config create"
|
||||
description: "The config create command description and usage"
|
||||
keywords: ["config, create"]
|
||||
---
|
||||
|
||||
# config create
|
||||
|
||||
```Markdown
|
||||
Usage: docker config create [OPTIONS] CONFIG [file|-]
|
||||
|
||||
Create a config from a file or STDIN as content
|
||||
|
||||
Options:
|
||||
-l, --label list Config labels
|
||||
--template-driver string Template driver
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
Creates a config using standard input or from a file for the config content.
|
||||
|
||||
For detailed information about using configs, refer to [store configuration data using Docker Configs](https://docs.docker.com/engine/swarm/configs/).
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> This is a cluster management command, and must be executed on a swarm
|
||||
> manager node. To learn about managers and workers, refer to the
|
||||
> [Swarm mode section](https://docs.docker.com/engine/swarm/) in the
|
||||
> documentation.
|
||||
|
||||
## Examples
|
||||
|
||||
### Create a config
|
||||
|
||||
```bash
|
||||
$ printf <config> | docker config create my_config -
|
||||
|
||||
onakdyv307se2tl7nl20anokv
|
||||
|
||||
$ docker config ls
|
||||
|
||||
ID NAME CREATED UPDATED
|
||||
onakdyv307se2tl7nl20anokv my_config 6 seconds ago 6 seconds ago
|
||||
```
|
||||
|
||||
### Create a config with a file
|
||||
|
||||
```bash
|
||||
$ docker config create my_config ./config.json
|
||||
|
||||
dg426haahpi5ezmkkj5kyl3sn
|
||||
|
||||
$ docker config ls
|
||||
|
||||
ID NAME CREATED UPDATED
|
||||
dg426haahpi5ezmkkj5kyl3sn my_config 7 seconds ago 7 seconds ago
|
||||
```
|
||||
|
||||
### Create a config with labels
|
||||
|
||||
```bash
|
||||
$ docker config create \
|
||||
--label env=dev \
|
||||
--label rev=20170324 \
|
||||
my_config ./config.json
|
||||
|
||||
eo7jnzguqgtpdah3cm5srfb97
|
||||
```
|
||||
|
||||
```bash
|
||||
$ docker config inspect my_config
|
||||
|
||||
[
|
||||
{
|
||||
"ID": "eo7jnzguqgtpdah3cm5srfb97",
|
||||
"Version": {
|
||||
"Index": 17
|
||||
},
|
||||
"CreatedAt": "2017-03-24T08:15:09.735271783Z",
|
||||
"UpdatedAt": "2017-03-24T08:15:09.735271783Z",
|
||||
"Spec": {
|
||||
"Name": "my_config",
|
||||
"Labels": {
|
||||
"env": "dev",
|
||||
"rev": "20170324"
|
||||
},
|
||||
"Data": "aGVsbG8K"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
## Related commands
|
||||
|
||||
* [config inspect](config_inspect.md)
|
||||
* [config ls](config_ls.md)
|
||||
* [config rm](config_rm.md)
|
||||
97
docs/reference/commandline/config_inspect.md
Normal file
@ -0,0 +1,97 @@
|
||||
---
|
||||
title: "config inspect"
|
||||
description: "The config inspect command description and usage"
|
||||
keywords: ["config, inspect"]
|
||||
---
|
||||
|
||||
# config inspect
|
||||
|
||||
```Markdown
|
||||
Usage: docker config inspect [OPTIONS] CONFIG [CONFIG...]
|
||||
|
||||
Display detailed information on one or more configs
|
||||
|
||||
Options:
|
||||
-f, --format string Format the output using the given Go template
|
||||
--help Print usage
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
Inspects the specified config.
|
||||
|
||||
By default, this renders all results in a JSON array. If a format is specified,
|
||||
the given template will be executed for each result.
|
||||
|
||||
Go's [text/template](http://golang.org/pkg/text/template/) package
|
||||
describes all the details of the format.
|
||||
|
||||
For detailed information about using configs, refer to [store configuration data using Docker Configs](https://docs.docker.com/engine/swarm/configs/).
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> This is a cluster management command, and must be executed on a swarm
|
||||
> manager node. To learn about managers and workers, refer to the
|
||||
> [Swarm mode section](https://docs.docker.com/engine/swarm/) in the
|
||||
> documentation.
|
||||
|
||||
## Examples
|
||||
|
||||
### Inspect a config by name or ID
|
||||
|
||||
You can inspect a config, either by its *name*, or *ID*
|
||||
|
||||
For example, given the following config:
|
||||
|
||||
```bash
|
||||
$ docker config ls
|
||||
|
||||
ID NAME CREATED UPDATED
|
||||
eo7jnzguqgtpdah3cm5srfb97 my_config 3 minutes ago 3 minutes ago
|
||||
```
|
||||
|
||||
```bash
|
||||
$ docker config inspect config.json
|
||||
```
|
||||
|
||||
The output is in JSON format, for example:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"ID": "eo7jnzguqgtpdah3cm5srfb97",
|
||||
"Version": {
|
||||
"Index": 17
|
||||
},
|
||||
"CreatedAt": "2017-03-24T08:15:09.735271783Z",
|
||||
"UpdatedAt": "2017-03-24T08:15:09.735271783Z",
|
||||
"Spec": {
|
||||
"Name": "my_config",
|
||||
"Labels": {
|
||||
"env": "dev",
|
||||
"rev": "20170324"
|
||||
},
|
||||
"Data": "aGVsbG8K"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Formatting
|
||||
|
||||
You can use the --format option to obtain specific information about a
|
||||
config. The following example command outputs the creation time of the
|
||||
config.
|
||||
|
||||
```bash
|
||||
$ docker config inspect --format='{{.CreatedAt}}' eo7jnzguqgtpdah3cm5srfb97
|
||||
|
||||
2017-03-24 08:15:09.735271783 +0000 UTC
|
||||
```
|
||||
|
||||
|
||||
## Related commands
|
||||
|
||||
* [config create](config_create.md)
|
||||
* [config ls](config_ls.md)
|
||||
* [config rm](config_rm.md)
|
||||
155
docs/reference/commandline/config_ls.md
Normal file
@ -0,0 +1,155 @@
|
||||
---
|
||||
title: "config ls"
|
||||
description: "The config ls command description and usage"
|
||||
keywords: ["config, ls"]
|
||||
---
|
||||
|
||||
# config ls
|
||||
|
||||
```Markdown
|
||||
Usage: docker config ls [OPTIONS]
|
||||
|
||||
List configs
|
||||
|
||||
Aliases:
|
||||
ls, list
|
||||
|
||||
Options:
|
||||
-f, --filter filter Filter output based on conditions provided
|
||||
--format string Pretty-print configs using a Go template
|
||||
--help Print usage
|
||||
-q, --quiet Only display IDs
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
Run this command on a manager node to list the configs in the swarm.
|
||||
|
||||
For detailed information about using configs, refer to [store configuration data using Docker Configs](https://docs.docker.com/engine/swarm/configs/).
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> This is a cluster management command, and must be executed on a swarm
|
||||
> manager node. To learn about managers and workers, refer to the
|
||||
> [Swarm mode section](https://docs.docker.com/engine/swarm/) in the
|
||||
> documentation.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
$ docker config ls
|
||||
|
||||
ID NAME CREATED UPDATED
|
||||
6697bflskwj1998km1gnnjr38 q5s5570vtvnimefos1fyeo2u2 6 weeks ago 6 weeks ago
|
||||
9u9hk4br2ej0wgngkga6rp4hq my_config 5 weeks ago 5 weeks ago
|
||||
mem02h8n73mybpgqjf0kfi1n0 test_config 3 seconds ago 3 seconds ago
|
||||
```
|
||||
|
||||
### Filtering
|
||||
|
||||
The filtering flag (`-f` or `--filter`) format is a `key=value` pair. If there is more
|
||||
than one filter, then pass multiple flags (e.g., `--filter "foo=bar" --filter "bif=baz"`)
|
||||
|
||||
The currently supported filters are:
|
||||
|
||||
- [id](#id) (config's ID)
|
||||
- [label](#label) (`label=<key>` or `label=<key>=<value>`)
|
||||
- [name](#name) (config's name)
|
||||
|
||||
#### id
|
||||
|
||||
The `id` filter matches all or prefix of a config's id.
|
||||
|
||||
```bash
|
||||
$ docker config ls -f "id=6697bflskwj1998km1gnnjr38"
|
||||
|
||||
ID NAME CREATED UPDATED
|
||||
6697bflskwj1998km1gnnjr38 q5s5570vtvnimefos1fyeo2u2 6 weeks ago 6 weeks ago
|
||||
```
|
||||
|
||||
#### label
|
||||
|
||||
The `label` filter matches configs based on the presence of a `label` alone or
|
||||
a `label` and a value.
|
||||
|
||||
The following filter matches all configs with a `project` label regardless of
|
||||
its value:
|
||||
|
||||
```bash
|
||||
$ docker config ls --filter label=project
|
||||
|
||||
ID NAME CREATED UPDATED
|
||||
mem02h8n73mybpgqjf0kfi1n0 test_config About an hour ago About an hour ago
|
||||
```
|
||||
|
||||
The following filter matches only services with the `project` label with the
|
||||
`project-a` value.
|
||||
|
||||
```bash
|
||||
$ docker service ls --filter label=project=test
|
||||
|
||||
ID NAME CREATED UPDATED
|
||||
mem02h8n73mybpgqjf0kfi1n0 test_config About an hour ago About an hour ago
|
||||
```
|
||||
|
||||
#### name
|
||||
|
||||
The `name` filter matches on all or prefix of a config's name.
|
||||
|
||||
The following filter matches config with a name containing a prefix of `test`.
|
||||
|
||||
```bash
|
||||
$ docker config ls --filter name=test_config
|
||||
|
||||
ID NAME CREATED UPDATED
|
||||
mem02h8n73mybpgqjf0kfi1n0 test_config About an hour ago About an hour ago
|
||||
```
|
||||
|
||||
### Format the output
|
||||
|
||||
The formatting option (`--format`) pretty prints configs output
|
||||
using a Go template.
|
||||
|
||||
Valid placeholders for the Go template are listed below:
|
||||
|
||||
| Placeholder | Description |
|
||||
| ------------ | ------------------------------------------------------------------------------------ |
|
||||
| `.ID` | Config ID |
|
||||
| `.Name` | Config name |
|
||||
| `.CreatedAt` | Time when the config was created |
|
||||
| `.UpdatedAt` | Time when the config was updated |
|
||||
| `.Labels` | All labels assigned to the config |
|
||||
| `.Label` | Value of a specific label for this config. For example `{{.Label "my-label"}}` |
|
||||
|
||||
When using the `--format` option, the `config ls` command will either
|
||||
output the data exactly as the template declares or, when using the
|
||||
`table` directive, will include column headers as well.
|
||||
|
||||
The following example uses a template without headers and outputs the
|
||||
`ID` and `Name` entries separated by a colon (`:`) for all images:
|
||||
|
||||
```bash
|
||||
$ docker config ls --format "{{.ID}}: {{.Name}}"
|
||||
|
||||
77af4d6b9913: config-1
|
||||
b6fa739cedf5: config-2
|
||||
78a85c484f71: config-3
|
||||
```
|
||||
|
||||
To list all configs with their name and created date in a table format you
|
||||
can use:
|
||||
|
||||
```bash
|
||||
$ docker config ls --format "table {{.ID}}\t{{.Name}}\t{{.CreatedAt}}"
|
||||
|
||||
ID NAME CREATED
|
||||
77af4d6b9913 config-1 5 minutes ago
|
||||
b6fa739cedf5 config-2 3 hours ago
|
||||
78a85c484f71 config-3 10 days ago
|
||||
```
|
||||
|
||||
## Related commands
|
||||
|
||||
* [config create](config_create.md)
|
||||
* [config inspect](config_inspect.md)
|
||||
* [config rm](config_rm.md)
|
||||
53
docs/reference/commandline/config_rm.md
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
title: "config rm"
|
||||
description: "The config rm command description and usage"
|
||||
keywords: ["config, rm"]
|
||||
---
|
||||
|
||||
# config rm
|
||||
|
||||
```Markdown
|
||||
Usage: docker config rm CONFIG [CONFIG...]
|
||||
|
||||
Remove one or more configs
|
||||
|
||||
Aliases:
|
||||
rm, remove
|
||||
|
||||
Options:
|
||||
--help Print usage
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
Removes the specified configs from the swarm.
|
||||
|
||||
For detailed information about using configs, refer to [store configuration data using Docker Configs](https://docs.docker.com/engine/swarm/configs/).
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> This is a cluster management command, and must be executed on a swarm
|
||||
> manager node. To learn about managers and workers, refer to the
|
||||
> [Swarm mode section](https://docs.docker.com/engine/swarm/) in the
|
||||
> documentation.
|
||||
|
||||
## Examples
|
||||
|
||||
This example removes a config:
|
||||
|
||||
```bash
|
||||
$ docker config rm my_config
|
||||
sapth4csdo5b6wz2p5uimh5xg
|
||||
```
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> Unlike `docker rm`, this command does not ask for confirmation before removing
|
||||
> a config.
|
||||
|
||||
|
||||
## Related commands
|
||||
|
||||
* [config create](config_create.md)
|
||||
* [config inspect](config_inspect.md)
|
||||
* [config ls](config_ls.md)
|
||||
@ -1203,8 +1203,8 @@ command line or Docker's Engine API are allowed or denied by the plugin.
|
||||
If you have multiple plugins installed, each plugin, in order, must
|
||||
allow the request for it to complete.
|
||||
|
||||
For information about how to create an authorization plugin, see [authorization
|
||||
plugin](../../extend/plugins_authorization.md) section in the Docker extend section of this documentation.
|
||||
For information about how to create an authorization plugin, refer to the
|
||||
[authorization plugin](../../extend/plugins_authorization.md) section.
|
||||
|
||||
|
||||
### Daemon user namespace options
|
||||
@ -1232,10 +1232,16 @@ Docker supports softlinks for the Docker data directory (`/var/lib/docker`) and
|
||||
for `/var/lib/docker/tmp`. The `DOCKER_TMPDIR` and the data directory can be
|
||||
set like this:
|
||||
|
||||
DOCKER_TMPDIR=/mnt/disk2/tmp /usr/local/bin/dockerd -D -g /var/lib/docker -H unix:// > /var/lib/docker-machine/docker.log 2>&1
|
||||
# or
|
||||
export DOCKER_TMPDIR=/mnt/disk2/tmp
|
||||
/usr/local/bin/dockerd -D -g /var/lib/docker -H unix:// > /var/lib/docker-machine/docker.log 2>&1
|
||||
```console
|
||||
$ DOCKER_TMPDIR=/mnt/disk2/tmp /usr/local/bin/dockerd -D -g /var/lib/docker -H unix:// > /var/lib/docker-machine/docker.log 2>&1
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```console
|
||||
$ export DOCKER_TMPDIR=/mnt/disk2/tmp
|
||||
$ /usr/local/bin/dockerd -D -g /var/lib/docker -H unix:// > /var/lib/docker-machine/docker.log 2>&1
|
||||
````
|
||||
|
||||
#### Default cgroup parent
|
||||
|
||||
@ -1400,6 +1406,10 @@ This is a full example of the allowed configuration options on Linux:
|
||||
"log-driver": "json-file",
|
||||
"log-level": "",
|
||||
"log-opts": {
|
||||
"cache-disabled": "false",
|
||||
"cache-max-file": "5",
|
||||
"cache-max-size": "20m",
|
||||
"cache-compress": "true",
|
||||
"env": "os,customer",
|
||||
"labels": "somelabel",
|
||||
"max-file": "5",
|
||||
@ -1560,7 +1570,9 @@ previously configured cluster configurations.
|
||||
|
||||
### Run multiple daemons
|
||||
|
||||
> **Note:** Running multiple daemons on a single host is considered as "experimental". The user should be aware of
|
||||
> **Note:**
|
||||
>
|
||||
> Running multiple daemons on a single host is considered as "experimental". The user should be aware of
|
||||
> unsolved problems. This solution may not work properly in some cases. Solutions are currently under development
|
||||
> and will be delivered in the near future.
|
||||
|
||||
@ -1612,7 +1624,7 @@ The `--tls*` options enable use of specific certificates for individual daemons.
|
||||
|
||||
Example script for a separate “bootstrap” instance of the Docker daemon without network:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ sudo dockerd \
|
||||
-H unix:///var/run/docker-bootstrap.sock \
|
||||
-p /var/run/docker-bootstrap.pid \
|
||||
|
||||
@ -60,6 +60,7 @@ The currently supported filters are:
|
||||
|
||||
* [id](#id)
|
||||
* [label](#label)
|
||||
* [node.label](#nodelabel)
|
||||
* [membership](#membership)
|
||||
* [name](#name)
|
||||
* [role](#role)
|
||||
@ -77,7 +78,10 @@ ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
|
||||
|
||||
#### label
|
||||
|
||||
The `label` filter matches nodes based on engine labels and on the presence of a `label` alone or a `label` and a value. Node labels are currently not used for filtering.
|
||||
The `label` filter matches nodes based on engine labels and on the presence of a
|
||||
`label` alone or a `label` and a value. Engine labels are configured in
|
||||
the [daemon configuration](dockerd.md#daemon-configuration-file). To filter on
|
||||
Swarm `node` labels, use [`node.label` instead](#nodelabel).
|
||||
|
||||
The following filter matches nodes with the `foo` label regardless of its value.
|
||||
|
||||
@ -88,6 +92,42 @@ ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
|
||||
1bcef6utixb0l0ca7gxuivsj0 swarm-worker2 Ready Active
|
||||
```
|
||||
|
||||
#### node.label
|
||||
|
||||
The `node.label` filter matches nodes based on node labels and on the presence
|
||||
of a `node.label` alone or a `node.label` and a value.
|
||||
|
||||
The following filter updates nodes to have a `region` node label:
|
||||
|
||||
```console
|
||||
$ docker node update --label-add region=region-a swarm-test-01
|
||||
$ docker node update --label-add region=region-a swarm-test-02
|
||||
$ docker node update --label-add region=region-b swarm-test-03
|
||||
$ docker node update --label-add region=region-b swarm-test-04
|
||||
```
|
||||
|
||||
Show all nodes that have a `region` node label set:
|
||||
|
||||
```console
|
||||
$ docker node ls --filter node.label=region
|
||||
|
||||
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
|
||||
yg550ettvsjn6g6t840iaiwgb * swarm-test-01 Ready Active Leader 20.10.2
|
||||
2lm9w9kbepgvkzkkeyku40e65 swarm-test-02 Ready Active Reachable 20.10.2
|
||||
hc0pu7ntc7s4uvj4pv7z7pz15 swarm-test-03 Ready Active Reachable 20.10.2
|
||||
n41b2cijmhifxxvz56vwrs12q swarm-test-04 Ready Active 20.10.2
|
||||
```
|
||||
|
||||
Show all nodes that have a `region` node label, with value `region-a`:
|
||||
|
||||
```console
|
||||
$ docker node ls --filter node.label=region=region-a
|
||||
|
||||
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
|
||||
yg550ettvsjn6g6t840iaiwgb * swarm-test-01 Ready Active Leader 20.10.2
|
||||
2lm9w9kbepgvkzkkeyku40e65 swarm-test-02 Ready Active Reachable 20.10.2
|
||||
```
|
||||
|
||||
#### membership
|
||||
|
||||
The `membership` filter matches nodes based on the presence of a `membership` and a value
|
||||
|
||||
@ -160,7 +160,7 @@ Digest can also be used in the `FROM` of a Dockerfile, for example:
|
||||
|
||||
```dockerfile
|
||||
FROM ubuntu@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2
|
||||
LABEL maintainer="some maintainer <maintainer@example.com>"
|
||||
LABEL org.opencontainers.image.authors="some maintainer <maintainer@example.com>"
|
||||
```
|
||||
|
||||
> **Note**
|
||||
|
||||
@ -76,7 +76,7 @@ listed.
|
||||
|
||||
### Push all tags of an image
|
||||
|
||||
Use the `-a` (or `--all-tags`) option to push To push all tags of a local image.
|
||||
Use the `-a` (or `--all-tags`) option to push all tags of a local image.
|
||||
|
||||
The following example creates multiple tags for an image, and pushes all those
|
||||
tags to Docker Hub.
|
||||
|
||||
@ -58,13 +58,33 @@ The main process inside the container referenced under the link `redis` will rec
|
||||
|
||||
### Remove all stopped containers
|
||||
|
||||
```bash
|
||||
$ docker rm $(docker ps -a -q)
|
||||
Use the [`docker container prune`](container_prune.md) command to remove all
|
||||
stopped containers, or refer to the [`docker system prune`](system_prune.md)
|
||||
command to remove unused containers in addition to other Docker resources, such
|
||||
as (unused) images and networks.
|
||||
|
||||
Alternatively, you can use the `docker ps` with the `-q` / `--quiet` option to
|
||||
generate a list of container IDs to remove, and use that list as argument for
|
||||
the `docker rm` command.
|
||||
|
||||
Combining commands can be more flexible, but is less portable as it depends
|
||||
on features provided by the shell, and the exact syntax may differ depending on
|
||||
what shell is used. To use this approach on Windows, consider using PowerShell
|
||||
or Bash.
|
||||
|
||||
The example below uses `docker ps -q` to print the IDs of all containers that
|
||||
have exited (`--filter status=exited`), and removes those containers with
|
||||
the `docker rm` command:
|
||||
|
||||
```console
|
||||
$ docker rm $(docker ps --filter status=exited -q)
|
||||
```
|
||||
|
||||
This command deletes all stopped containers. The command
|
||||
`docker ps -a -q` above returns all existing container IDs and passes them to
|
||||
the `rm` command which deletes them. Running containers are not deleted.
|
||||
Or, using the `xargs` Linux utility;
|
||||
|
||||
```console
|
||||
$ docker ps --filter status=exited -q | xargs docker rm
|
||||
```
|
||||
|
||||
### Remove a container and its volumes
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ ID NAME MODE REPLICAS IMAGE
|
||||
c8wgl7q4ndfd frontend replicated 5/5 nginx:alpine
|
||||
dmu1ept4cxcf redis replicated 3/3 redis:3.0.6
|
||||
iwe3278osahj mongo global 7/7 mongo:3.3
|
||||
hh08h9uu8uwr job replicated-job 1/1 (3/5 completed) nginx:latest
|
||||
hh08h9uu8uwr job replicated-job 1/1 (3/5 completed) nginx:latest
|
||||
```
|
||||
|
||||
The `REPLICAS` column shows both the *actual* and *desired* number of tasks for
|
||||
|
||||
@ -19,7 +19,9 @@ Options:
|
||||
## Description
|
||||
|
||||
The main process inside the container will receive `SIGTERM`, and after a grace
|
||||
period, `SIGKILL`.
|
||||
period, `SIGKILL`. The first signal can be changed with the `STOPSIGNAL`
|
||||
instruction in the container's Dockerfile, or the `--stop-signal` option to
|
||||
`docker run`.
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
---
|
||||
description: "Configure containers at runtime"
|
||||
keywords: "docker, run, configure, runtime"
|
||||
redirect_from:
|
||||
- /reference/run/
|
||||
---
|
||||
|
||||
<!-- This file is maintained within the docker/cli GitHub
|
||||
@ -585,7 +587,7 @@ $ docker inspect -f "{{ .State.StartedAt }}" my-container
|
||||
|
||||
Combining `--restart` (restart policy) with the `--rm` (clean up) flag results
|
||||
in an error. On container restart, attached clients are disconnected. See the
|
||||
examples on using the [`--rm` (clean up)](#clean-up-rm) flag later in this page.
|
||||
examples on using the [`--rm` (clean up)](#clean-up---rm) flag later in this page.
|
||||
|
||||
### Examples
|
||||
|
||||
@ -1738,7 +1740,7 @@ volume mounted on the host).
|
||||
|
||||
The `container-dest` must always be an absolute path such as `/src/docs`.
|
||||
The `host-src` can either be an absolute path or a `name` value. If you
|
||||
supply an absolute path for the `host-dir`, Docker bind-mounts to the path
|
||||
supply an absolute path for the `host-src`, Docker bind-mounts to the path
|
||||
you specify. If you supply a `name`, Docker creates a named volume by that `name`.
|
||||
|
||||
A `name` value must start with an alphanumeric character,
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/golden"
|
||||
"gotest.tools/v3/icmd"
|
||||
)
|
||||
@ -19,3 +22,73 @@ func TestContextList(t *testing.T) {
|
||||
})
|
||||
golden.Assert(t, result.Stdout(), "context-ls.golden")
|
||||
}
|
||||
|
||||
func TestContextImportNoTLS(t *testing.T) {
|
||||
d, _ := ioutil.TempDir("", "")
|
||||
defer func() {
|
||||
os.RemoveAll(d)
|
||||
}()
|
||||
cmd := icmd.Command("docker", "context", "import", "remote", "./testdata/test-dockerconfig.tar")
|
||||
cmd.Env = append(cmd.Env,
|
||||
"DOCKER_CONFIG="+d,
|
||||
)
|
||||
icmd.RunCmd(cmd).Assert(t, icmd.Success)
|
||||
|
||||
cmd = icmd.Command("docker", "context", "ls")
|
||||
cmd.Env = append(cmd.Env,
|
||||
"DOCKER_CONFIG="+d,
|
||||
"KUBECONFIG=./testdata/test-kubeconfig", // Allows reuse of context-ls.golden
|
||||
)
|
||||
result := icmd.RunCmd(cmd).Assert(t, icmd.Success)
|
||||
golden.Assert(t, result.Stdout(), "context-ls.golden")
|
||||
}
|
||||
|
||||
func TestContextImportTLS(t *testing.T) {
|
||||
d, _ := ioutil.TempDir("", "")
|
||||
defer func() {
|
||||
os.RemoveAll(d)
|
||||
}()
|
||||
cmd := icmd.Command("docker", "context", "import", "test", "./testdata/test-dockerconfig-tls.tar")
|
||||
cmd.Env = append(cmd.Env,
|
||||
"DOCKER_CONFIG="+d,
|
||||
)
|
||||
icmd.RunCmd(cmd).Assert(t, icmd.Success)
|
||||
|
||||
cmd = icmd.Command("docker", "context", "ls")
|
||||
cmd.Env = append(cmd.Env,
|
||||
"DOCKER_CONFIG="+d,
|
||||
)
|
||||
result := icmd.RunCmd(cmd).Assert(t, icmd.Success)
|
||||
golden.Assert(t, result.Stdout(), "context-ls-tls.golden")
|
||||
|
||||
b, err := ioutil.ReadFile(d + "/contexts/tls/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08/kubernetes/key.pem")
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, string(b), `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEArQk77K5sgrQYY6HiQ1y7AC+67HrRB36oEvR+Fq60RsFcc3cZ
|
||||
xAvMkRSBPjQyskjdYY7kfykGHhfJxGKopb3cDJx3eDBxjgAniwnnOMmHVWbf8Eik
|
||||
o0sNxkgzQPGq83nL3QvVxm3xgqe4nlTdR/Swoq6Pv0oaVYvPPMnaZIF89SJ/wlNT
|
||||
myCs6Uq00dICi20II+M2Nw9b+EVEK4ENl+SlrsK7iuoBIh/H0ZghxOthO9J/HeBb
|
||||
hmM4wcs1OonhPDYKHEaChYA7/Q3/8OBp3bAdlQJ1ziyP3ROAKHL2NwwkGZ8o8HP8
|
||||
u0ex/NAb8w5J5WNePqYQd/sqfisfNpA5VIKcEQIDAQABAoIBABLo4W2aGi2mdMve
|
||||
kxV9esoobSsOuO0ywDdiFK1x5i2dT/cmWuB70Z1BOmaL2cZ2BAt3TC1BVHPRcbFO
|
||||
ftOuDfAq4Tt3P9Ge3rNpH6WrEGka1voxVhyqRRUYKtG8F0yIUOkVNAV9WllG7vwO
|
||||
ligY63y7yuXCuWID51/jR0SYiglXz6G4gcJKFXtugXXiLUIg08GVWkwOsrACC+hR
|
||||
mhcHly1926VhN5+ozjNU/GZ1LaTuK6erBZakH5bqlN97s5rrk0ZRwk/JtnkoRRdI
|
||||
cq0918Za2vqGDHZ3MqLttL52YfDXPIEJPwlFdvC/+sXK2NhUB/xY4yuliU3sY0sf
|
||||
XsIvIWECgYEAwD8AnZI0hnGv8hc6zJppHFRwhrtLZ+09SJwPv5Y4wxuuk5dzNkpf
|
||||
xCNo5hjSVYA1MMmWG8p/sEXo2IyCT8sWDNCn9kieTXihxRxbj88Y2qA5O4N46Zy4
|
||||
kPngjkP5PPDMkwaQQgUr9LvlWS7P6OJkH18ZN8s3QhMaKcHu9FFT44UCgYEA5mte
|
||||
mMSDf9hUK3IK+yrGX62qc2H+ecXN3Zf3nehyiz+dX4ZXhBwBkwJ/mHvuAZPfoFUN
|
||||
Xg6cdyWFJg9ynm45JXnDjmYPGmFLn0mP3Mje/+SbbW2fdFWHJW/maqj4uUqqgQd+
|
||||
pGNzKXq34MzDrpsqIJ7AHu3LYVMOoLAVqC7LXh0CgYEAnLF9ZfFqQH7fgvouIeBl
|
||||
dgLZKOf2AUJcJheVunnN0DF67K+P55tdTTfzY0CuB6SVNivI3uQBiYKh1AdKm5ET
|
||||
auSTUmlEJi8B4/BGLQQG5QOdQoXZgsgLo5cX0b1To7k9dUTvRfCDMFoKCNPgAJiu
|
||||
NOfFXTWU15VMSObaRmcXciUCgYEA5e1cXwsxwUAodZX+eTXs8ArHHQ47Nl55GFeN
|
||||
wufybRuUuX7AE9cyhvUmSA3aqX5a144noaTo40fwftNJZ+jLY6cGyjDzfzp5kMCC
|
||||
KynSxPzlUCPkytyR2Hy6K9LjJ1rnm4vUBswqXcjUdiE+Xxz8w8JGKlbV7Q9JeHVd
|
||||
lw7i5s0CgYAn9T9ySI3xCbrUa/XV/ZY2hopUdH5CDPeTd2eH+L+lctkD9nlzLrpj
|
||||
qij+jaEUweymNx0uttgv02J3DYcIIvVq3RNAwORy5Mp9KasHmjbW2xq+HAq5yFOO
|
||||
1ma82F5zeUl+bKqjMRCY8IVZ349VxRZtb2RVVEKyVswb7HmKp6gGbA==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
`)
|
||||
}
|
||||
|
||||
3
e2e/context/testdata/context-ls-notls.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
|
||||
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm
|
||||
remote my remote cluster ssh://someserver https://someserver (default) kubernetes
|
||||
3
e2e/context/testdata/context-ls-tls.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
|
||||
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm
|
||||
test unix:///var/run/docker.sock https://kubernetes.docker.internal:6443 (default) swarm
|
||||
BIN
e2e/context/testdata/test-dockerconfig-tls.tar
vendored
Normal file
BIN
e2e/context/testdata/test-dockerconfig.tar
vendored
Normal file
@ -39,12 +39,5 @@ Checkpoint and restore support for Containers.
|
||||
Metrics (Prometheus) output for basic container, image, and daemon operations.
|
||||
|
||||
* [External graphdriver plugins](../docs/extend/plugins_graphdriver.md)
|
||||
* [Ipvlan Network Drivers](vlan-networks.md)
|
||||
* [Checkpoint & Restore](checkpoint-restore.md)
|
||||
* [Docker build with --squash argument](../docs/reference/commandline/build.md#squash-an-images-layers---squash-experimental)
|
||||
|
||||
## How to comment on an experimental feature
|
||||
|
||||
Each feature's documentation includes a list of proposal pull requests or PRs associated with the feature. If you want to comment on or suggest a change to a feature, please add it to the existing feature PR.
|
||||
|
||||
Issues or problems with a feature? Inquire for help on the `#docker` IRC channel or on the [Docker Google group](https://groups.google.com/forum/#!forum/docker-user).
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 108 KiB |
@ -1,632 +0,0 @@
|
||||
# Ipvlan Network Driver
|
||||
|
||||
### Getting Started
|
||||
|
||||
The Ipvlan driver is currently in experimental mode in order to incubate Docker
|
||||
users use cases and vet the implementation to ensure a hardened, production ready
|
||||
driver in a future release. Libnetwork now gives users total control over both
|
||||
IPv4 and IPv6 addressing. The VLAN driver builds on top of that in giving
|
||||
operators complete control of layer 2 VLAN tagging and even Ipvlan L3 routing
|
||||
for users interested in underlay network integration. For overlay deployments
|
||||
that abstract away physical constraints see the
|
||||
[multi-host overlay](https://docs.docker.com/network/network-tutorial-overlay/)
|
||||
driver.
|
||||
|
||||
Ipvlan is a new twist on the tried and true network virtualization technique.
|
||||
The Linux implementations are extremely lightweight because rather than using
|
||||
the traditional Linux bridge for isolation, they are simply associated to a Linux
|
||||
Ethernet interface or sub-interface to enforce separation between networks and
|
||||
connectivity to the physical network.
|
||||
|
||||
Ipvlan offers a number of unique features and plenty of room for further
|
||||
innovations with the various modes. Two high level advantages of these approaches
|
||||
are, the positive performance implications of bypassing the Linux bridge and the
|
||||
simplicity of having fewer moving parts. Removing the bridge that traditionally
|
||||
resides in between the Docker host NIC and container interface leaves a simple
|
||||
setup consisting of container interfaces, attached directly to the Docker host
|
||||
interface. This result is easy access for external facing services as there is
|
||||
no need for port mappings in these scenarios.
|
||||
|
||||
### Pre-Requisites
|
||||
|
||||
- The examples on this page are all single host and require using Docker
|
||||
experimental features to be enabled.
|
||||
- All of the examples can be performed on a single host running Docker. Any
|
||||
example using a sub-interface like `eth0.10` can be replaced with `eth0` or
|
||||
any other valid parent interface on the Docker host. Sub-interfaces with a `.`
|
||||
are created on the fly. `-o parent` interfaces can also be left out of the
|
||||
`docker network create` all together and the driver will create a `dummy`
|
||||
interface that will enable local host connectivity to perform the examples.
|
||||
- Kernel requirements:
|
||||
- To check your current kernel version, use `uname -r`
|
||||
- Ipvlan Linux kernel v4.2+ (support for earlier kernels exists but is buggy)
|
||||
|
||||
### Ipvlan L2 Mode Example Usage
|
||||
|
||||
An example of the ipvlan `L2` mode topology is shown in the following image.
|
||||
The driver is specified with `-d driver_name` option. In this case `-d ipvlan`.
|
||||
|
||||

|
||||
|
||||
The parent interface in the next example `-o parent=eth0` is configured as follows:
|
||||
|
||||
```bash
|
||||
$ ip addr show eth0
|
||||
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
|
||||
inet 192.168.1.250/24 brd 192.168.1.255 scope global eth0
|
||||
```
|
||||
|
||||
Use the network from the host's interface as the `--subnet` in the
|
||||
`docker network create`. The container will be attached to the same network as
|
||||
the host interface as set via the `-o parent=` option.
|
||||
|
||||
Create the ipvlan network and run a container attaching to it:
|
||||
|
||||
```bash
|
||||
# Ipvlan (-o ipvlan_mode= Defaults to L2 mode if not specified)
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.1.0/24 \
|
||||
--gateway=192.168.1.1 \
|
||||
-o ipvlan_mode=l2 \
|
||||
-o parent=eth0 db_net
|
||||
|
||||
# Start a container on the db_net network
|
||||
$ docker run --net=db_net -it --rm alpine /bin/sh
|
||||
|
||||
# NOTE: the containers can NOT ping the underlying host interfaces as
|
||||
# they are intentionally filtered by Linux for additional isolation.
|
||||
```
|
||||
|
||||
The default mode for Ipvlan is `l2`. If `-o ipvlan_mode=` are left unspecified,
|
||||
the default mode will be used. Similarly, if the `--gateway` is left empty, the
|
||||
first usable address on the network will be set as the gateway. For example, if
|
||||
the subnet provided in the network create is `--subnet=192.168.1.0/24` then the
|
||||
gateway the container receives is `192.168.1.1`.
|
||||
|
||||
To help understand how this mode interacts with other hosts, the following
|
||||
figure shows the same layer 2 segment between two Docker hosts that applies to
|
||||
and Ipvlan L2 mode.
|
||||
|
||||

|
||||
|
||||
The following will create the exact same network as the network `db_net` created
|
||||
prior, with the driver defaults for `--gateway=192.168.1.1` and `-o ipvlan_mode=l2`.
|
||||
|
||||
```bash
|
||||
# Ipvlan (-o ipvlan_mode= Defaults to L2 mode if not specified)
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.1.0/24 \
|
||||
-o parent=eth0 db_net_ipv
|
||||
|
||||
# Start a container with an explicit name in daemon mode
|
||||
$ docker run --net=db_net_ipv --name=ipv1 -itd alpine /bin/sh
|
||||
|
||||
# Start a second container and ping using the container name
|
||||
# to see the docker included name resolution functionality
|
||||
$ docker run --net=db_net_ipv --name=ipv2 -it --rm alpine /bin/sh
|
||||
$ ping -c 4 ipv1
|
||||
|
||||
# NOTE: the containers can NOT ping the underlying host interfaces as
|
||||
# they are intentionally filtered by Linux for additional isolation.
|
||||
```
|
||||
|
||||
The drivers also support the `--internal` flag that will completely isolate
|
||||
containers on a network from any communications external to that network. Since
|
||||
network isolation is tightly coupled to the network's parent interface the result
|
||||
of leaving the `-o parent=` option off of a `docker network create` is the exact
|
||||
same as the `--internal` option. If the parent interface is not specified or the
|
||||
`--internal` flag is used, a netlink type `dummy` parent interface is created
|
||||
for the user and used as the parent interface effectively isolating the network
|
||||
completely.
|
||||
|
||||
The following two `docker network create` examples result in identical networks
|
||||
that you can attach container to:
|
||||
|
||||
```bash
|
||||
# Empty '-o parent=' creates an isolated network
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.10.0/24 isolated1
|
||||
|
||||
# Explicit '--internal' flag is the same:
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.11.0/24 --internal isolated2
|
||||
|
||||
# Even the '--subnet=' can be left empty and the default
|
||||
# IPAM subnet of 172.18.0.0/16 will be assigned
|
||||
$ docker network create -d ipvlan isolated3
|
||||
|
||||
$ docker run --net=isolated1 --name=cid1 -it --rm alpine /bin/sh
|
||||
$ docker run --net=isolated2 --name=cid2 -it --rm alpine /bin/sh
|
||||
$ docker run --net=isolated3 --name=cid3 -it --rm alpine /bin/sh
|
||||
|
||||
# To attach to any use `docker exec` and start a shell
|
||||
$ docker exec -it cid1 /bin/sh
|
||||
$ docker exec -it cid2 /bin/sh
|
||||
$ docker exec -it cid3 /bin/sh
|
||||
```
|
||||
|
||||
### Ipvlan 802.1q Trunk L2 Mode Example Usage
|
||||
|
||||
Architecturally, Ipvlan L2 mode trunking is the same as Macvlan with regard to
|
||||
gateways and L2 path isolation. There are nuances that can be advantageous for
|
||||
CAM table pressure in ToR switches, one MAC per port and MAC exhaustion on a
|
||||
host's parent NIC to name a few. The 802.1q trunk scenario looks the same. Both
|
||||
modes adhere to tagging standards and have seamless integration with the physical
|
||||
network for underlay integration and hardware vendor plugin integrations.
|
||||
|
||||
Hosts on the same VLAN are typically on the same subnet and almost always are
|
||||
grouped together based on their security policy. In most scenarios, a multi-tier
|
||||
application is tiered into different subnets because the security profile of each
|
||||
process requires some form of isolation. For example, hosting your credit card
|
||||
processing on the same virtual network as the frontend webserver would be a
|
||||
regulatory compliance issue, along with circumventing the long standing best
|
||||
practice of layered defense in depth architectures. VLANs or the equivocal VNI
|
||||
(Virtual Network Identifier) when using the Overlay driver, are the first step
|
||||
in isolating tenant traffic.
|
||||
|
||||

|
||||
|
||||
The Linux sub-interface tagged with a vlan can either already exist or will be
|
||||
created when you call a `docker network create`. `docker network rm` will delete
|
||||
the sub-interface. Parent interfaces such as `eth0` are not deleted, only
|
||||
sub-interfaces with a netlink parent index > 0.
|
||||
|
||||
For the driver to add/delete the vlan sub-interfaces the format needs to be
|
||||
`interface_name.vlan_tag`. Other sub-interface naming can be used as the
|
||||
specified parent, but the link will not be deleted automatically when
|
||||
`docker network rm` is invoked.
|
||||
|
||||
The option to use either existing parent vlan sub-interfaces or let Docker manage
|
||||
them enables the user to either completely manage the Linux interfaces and
|
||||
networking or let Docker create and delete the Vlan parent sub-interfaces
|
||||
(netlink `ip link`) with no effort from the user.
|
||||
|
||||
For example: use `eth0.10` to denote a sub-interface of `eth0` tagged with the
|
||||
vlan id of `10`. The equivalent `ip link` command would be
|
||||
`ip link add link eth0 name eth0.10 type vlan id 10`.
|
||||
|
||||
The example creates the vlan tagged networks and then start two containers to
|
||||
test connectivity between containers. Different Vlans cannot ping one another
|
||||
without a router routing between the two networks. The default namespace is not
|
||||
reachable per ipvlan design in order to isolate container namespaces from the
|
||||
underlying host.
|
||||
|
||||
**Vlan ID 20**
|
||||
|
||||
In the first network tagged and isolated by the Docker host, `eth0.20` is the
|
||||
parent interface tagged with vlan id `20` specified with `-o parent=eth0.20`.
|
||||
Other naming formats can be used, but the links need to be added and deleted
|
||||
manually using `ip link` or Linux configuration files. As long as the `-o parent`
|
||||
exists anything can be used if compliant with Linux netlink.
|
||||
|
||||
```bash
|
||||
# now add networks and hosts as you would normally by attaching to the master (sub)interface that is tagged
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.20.0/24 \
|
||||
--gateway=192.168.20.1 \
|
||||
-o parent=eth0.20 ipvlan20
|
||||
|
||||
# in two separate terminals, start a Docker container and the containers can now ping one another.
|
||||
$ docker run --net=ipvlan20 -it --name ivlan_test1 --rm alpine /bin/sh
|
||||
$ docker run --net=ipvlan20 -it --name ivlan_test2 --rm alpine /bin/sh
|
||||
```
|
||||
|
||||
**Vlan ID 30**
|
||||
|
||||
In the second network, tagged and isolated by the Docker host, `eth0.30` is the
|
||||
parent interface tagged with vlan id `30` specified with `-o parent=eth0.30`. The
|
||||
`ipvlan_mode=` defaults to l2 mode `ipvlan_mode=l2`. It can also be explicitly
|
||||
set with the same result as shown in the next example.
|
||||
|
||||
```bash
|
||||
# now add networks and hosts as you would normally by attaching to the master (sub)interface that is tagged.
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.30.0/24 \
|
||||
--gateway=192.168.30.1 \
|
||||
-o parent=eth0.30 \
|
||||
-o ipvlan_mode=l2 ipvlan30
|
||||
|
||||
# in two separate terminals, start a Docker container and the containers can now ping one another.
|
||||
$ docker run --net=ipvlan30 -it --name ivlan_test3 --rm alpine /bin/sh
|
||||
$ docker run --net=ipvlan30 -it --name ivlan_test4 --rm alpine /bin/sh
|
||||
```
|
||||
|
||||
The gateway is set inside of the container as the default gateway. That gateway
|
||||
would typically be an external router on the network.
|
||||
|
||||
```bash
|
||||
$$ ip route
|
||||
default via 192.168.30.1 dev eth0
|
||||
192.168.30.0/24 dev eth0 src 192.168.30.2
|
||||
```
|
||||
|
||||
Example: Multi-Subnet Ipvlan L2 Mode starting two containers on the same subnet
|
||||
and pinging one another. In order for the `192.168.114.0/24` to reach
|
||||
`192.168.116.0/24` it requires an external router in L2 mode. L3 mode can route
|
||||
between subnets that share a common `-o parent=`.
|
||||
|
||||
Secondary addresses on network routers are common as an address space becomes
|
||||
exhausted to add another secondary to an L3 vlan interface or commonly referred
|
||||
to as a "switched virtual interface" (SVI).
|
||||
|
||||
```bash
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.114.0/24 --subnet=192.168.116.0/24 \
|
||||
--gateway=192.168.114.254 --gateway=192.168.116.254 \
|
||||
-o parent=eth0.114 \
|
||||
-o ipvlan_mode=l2 ipvlan114
|
||||
|
||||
$ docker run --net=ipvlan114 --ip=192.168.114.10 -it --rm alpine /bin/sh
|
||||
$ docker run --net=ipvlan114 --ip=192.168.114.11 -it --rm alpine /bin/sh
|
||||
```
|
||||
|
||||
A key takeaway is, operators have the ability to map their physical network into
|
||||
their virtual network for integrating containers into their environment with no
|
||||
operational overhauls required. NetOps simply drops an 802.1q trunk into the
|
||||
Docker host. That virtual link would be the `-o parent=` passed in the network
|
||||
creation. For untagged (non-VLAN) links, it is as simple as `-o parent=eth0` or
|
||||
for 802.1q trunks with VLAN IDs each network gets mapped to the corresponding
|
||||
VLAN/Subnet from the network.
|
||||
|
||||
An example being, NetOps provides VLAN ID and the associated subnets for VLANs
|
||||
being passed on the Ethernet link to the Docker host server. Those values are
|
||||
simply plugged into the `docker network create` commands when provisioning the
|
||||
Docker networks. These are persistent configurations that are applied every time
|
||||
the Docker engine starts which alleviates having to manage often complex
|
||||
configuration files. The network interfaces can also be managed manually by
|
||||
being pre-created and docker networking will never modify them, simply use them
|
||||
as parent interfaces. Example mappings from NetOps to Docker network commands
|
||||
are as follows:
|
||||
|
||||
- VLAN: 10, Subnet: 172.16.80.0/24, Gateway: 172.16.80.1
|
||||
- `--subnet=172.16.80.0/24 --gateway=172.16.80.1 -o parent=eth0.10`
|
||||
- VLAN: 20, IP subnet: 172.16.50.0/22, Gateway: 172.16.50.1
|
||||
- `--subnet=172.16.50.0/22 --gateway=172.16.50.1 -o parent=eth0.20 `
|
||||
- VLAN: 30, Subnet: 10.1.100.0/16, Gateway: 10.1.100.1
|
||||
- `--subnet=10.1.100.0/16 --gateway=10.1.100.1 -o parent=eth0.30`
|
||||
|
||||
### IPVlan L3 Mode Example
|
||||
|
||||
IPVlan will require routes to be distributed to each endpoint. The driver only
|
||||
builds the Ipvlan L3 mode port and attaches the container to the interface. Route
|
||||
distribution throughout a cluster is beyond the initial implementation of this
|
||||
single host scoped driver. In L3 mode, the Docker host is very similar to a
|
||||
router starting new networks in the container. They are on networks that the
|
||||
upstream network will not know about without route distribution. For those
|
||||
curious how Ipvlan L3 will fit into container networking see the following
|
||||
examples.
|
||||
|
||||

|
||||
|
||||
Ipvlan L3 mode drops all broadcast and multicast traffic. This reason alone
|
||||
makes Ipvlan L3 mode a prime candidate for those looking for massive scale and
|
||||
predictable network integrations. It is predictable and in turn will lead to
|
||||
greater uptimes because there is no bridging involved. Bridging loops have been
|
||||
responsible for high profile outages that can be hard to pinpoint depending on
|
||||
the size of the failure domain. This is due to the cascading nature of BPDUs
|
||||
(Bridge Port Data Units) that are flooded throughout a broadcast domain (VLAN)
|
||||
to find and block topology loops. Eliminating bridging domains, or at the least,
|
||||
keeping them isolated to a pair of ToRs (top of rack switches) will reduce hard
|
||||
to troubleshoot bridging instabilities. Ipvlan L2 modes is well suited for
|
||||
isolated VLANs only trunked into a pair of ToRs that can provide a loop-free
|
||||
non-blocking fabric. The next step further is to route at the edge via Ipvlan L3
|
||||
mode that reduces a failure domain to a local host only.
|
||||
|
||||
- L3 mode needs to be on a separate subnet as the default namespace since it
|
||||
requires a netlink route in the default namespace pointing to the Ipvlan parent
|
||||
interface.
|
||||
- The parent interface used in this example is `eth0` and it is on the subnet
|
||||
`192.168.1.0/24`. Notice the `docker network` is **not** on the same subnet
|
||||
as `eth0`.
|
||||
- Unlike ipvlan l2 modes, different subnets/networks can ping one another as
|
||||
long as they share the same parent interface `-o parent=`.
|
||||
|
||||
```bash
|
||||
$$ ip a show eth0
|
||||
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
|
||||
link/ether 00:50:56:39:45:2e brd ff:ff:ff:ff:ff:ff
|
||||
inet 192.168.1.250/24 brd 192.168.1.255 scope global eth0
|
||||
```
|
||||
|
||||
- A traditional gateway doesn't mean much to an L3 mode Ipvlan interface since
|
||||
there is no broadcast traffic allowed. Because of that, the container default
|
||||
gateway simply points to the containers `eth0` device. See below for CLI output
|
||||
of `ip route` or `ip -6 route` from inside an L3 container for details.
|
||||
|
||||
The mode ` -o ipvlan_mode=l3` must be explicitly specified since the default
|
||||
ipvlan mode is `l2`.
|
||||
|
||||
The following example does not specify a parent interface. The network drivers
|
||||
will create a dummy type link for the user rather than rejecting the network
|
||||
creation and isolating containers from only communicating with one another.
|
||||
|
||||
```bash
|
||||
# Create the Ipvlan L3 network
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.214.0/24 \
|
||||
--subnet=10.1.214.0/24 \
|
||||
-o ipvlan_mode=l3 ipnet210
|
||||
|
||||
# Test 192.168.214.0/24 connectivity
|
||||
$ docker run --net=ipnet210 --ip=192.168.214.10 -itd alpine /bin/sh
|
||||
$ docker run --net=ipnet210 --ip=10.1.214.10 -itd alpine /bin/sh
|
||||
|
||||
# Test L3 connectivity from 10.1.214.0/24 to 192.168.212.0/24
|
||||
$ docker run --net=ipnet210 --ip=192.168.214.9 -it --rm alpine ping -c 2 10.1.214.10
|
||||
|
||||
# Test L3 connectivity from 192.168.212.0/24 to 10.1.214.0/24
|
||||
$ docker run --net=ipnet210 --ip=10.1.214.9 -it --rm alpine ping -c 2 192.168.214.10
|
||||
|
||||
```
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Notice that there is no `--gateway=` option in the network create. The field
|
||||
> is ignored if one is specified `l3` mode. Take a look at the container routing
|
||||
> table from inside of the container:
|
||||
>
|
||||
> ```bash
|
||||
> # Inside an L3 mode container
|
||||
> $$ ip route
|
||||
> default dev eth0
|
||||
> 192.168.214.0/24 dev eth0 src 192.168.214.10
|
||||
> ```
|
||||
|
||||
In order to ping the containers from a remote Docker host or the container be
|
||||
able to ping a remote host, the remote host or the physical network in between
|
||||
need to have a route pointing to the host IP address of the container's Docker
|
||||
host eth interface. More on this as we evolve the Ipvlan `L3` story.
|
||||
|
||||
### Dual Stack IPv4 IPv6 Ipvlan L2 Mode
|
||||
|
||||
- Not only does Libnetwork give you complete control over IPv4 addressing, but
|
||||
it also gives you total control over IPv6 addressing as well as feature parity
|
||||
between the two address families.
|
||||
|
||||
- The next example will start with IPv6 only. Start two containers on the same
|
||||
VLAN `139` and ping one another. Since the IPv4 subnet is not specified, the
|
||||
default IPAM will provision a default IPv4 subnet. That subnet is isolated
|
||||
unless the upstream network is explicitly routing it on VLAN `139`.
|
||||
|
||||
```bash
|
||||
# Create a v6 network
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=2001:db8:abc2::/64 --gateway=2001:db8:abc2::22 \
|
||||
-o parent=eth0.139 v6ipvlan139
|
||||
|
||||
# Start a container on the network
|
||||
$ docker run --net=v6ipvlan139 -it --rm alpine /bin/sh
|
||||
```
|
||||
|
||||
View the container eth0 interface and v6 routing table:
|
||||
|
||||
```bash
|
||||
# Inside the IPv6 container
|
||||
$$ ip a show eth0
|
||||
75: eth0@if55: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
|
||||
link/ether 00:50:56:2b:29:40 brd ff:ff:ff:ff:ff:ff
|
||||
inet 172.18.0.2/16 scope global eth0
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 2001:db8:abc4::250:56ff:fe2b:2940/64 scope link
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 2001:db8:abc2::1/64 scope link nodad
|
||||
valid_lft forever preferred_lft forever
|
||||
|
||||
$$ ip -6 route
|
||||
2001:db8:abc4::/64 dev eth0 proto kernel metric 256
|
||||
2001:db8:abc2::/64 dev eth0 proto kernel metric 256
|
||||
default via 2001:db8:abc2::22 dev eth0 metric 1024
|
||||
```
|
||||
|
||||
Start a second container and ping the first container's v6 address.
|
||||
|
||||
```bash
|
||||
# Test L2 connectivity over IPv6
|
||||
$ docker run --net=v6ipvlan139 -it --rm alpine /bin/sh
|
||||
|
||||
# Inside the second IPv6 container
|
||||
$$ ip a show eth0
|
||||
75: eth0@if55: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
|
||||
link/ether 00:50:56:2b:29:40 brd ff:ff:ff:ff:ff:ff
|
||||
inet 172.18.0.3/16 scope global eth0
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 2001:db8:abc4::250:56ff:fe2b:2940/64 scope link tentative dadfailed
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 2001:db8:abc2::2/64 scope link nodad
|
||||
valid_lft forever preferred_lft forever
|
||||
|
||||
$$ ping6 2001:db8:abc2::1
|
||||
PING 2001:db8:abc2::1 (2001:db8:abc2::1): 56 data bytes
|
||||
64 bytes from 2001:db8:abc2::1%eth0: icmp_seq=0 ttl=64 time=0.044 ms
|
||||
64 bytes from 2001:db8:abc2::1%eth0: icmp_seq=1 ttl=64 time=0.058 ms
|
||||
|
||||
2 packets transmitted, 2 packets received, 0% packet loss
|
||||
round-trip min/avg/max/stddev = 0.044/0.051/0.058/0.000 ms
|
||||
```
|
||||
|
||||
The next example with setup a dual stack IPv4/IPv6 network with an example
|
||||
VLAN ID of `140`.
|
||||
|
||||
Next create a network with two IPv4 subnets and one IPv6 subnets, all of which
|
||||
have explicit gateways:
|
||||
|
||||
```bash
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.140.0/24 --subnet=192.168.142.0/24 \
|
||||
--gateway=192.168.140.1 --gateway=192.168.142.1 \
|
||||
--subnet=2001:db8:abc9::/64 --gateway=2001:db8:abc9::22 \
|
||||
-o parent=eth0.140 \
|
||||
-o ipvlan_mode=l2 ipvlan140
|
||||
```
|
||||
|
||||
Start a container and view eth0 and both v4 & v6 routing tables:
|
||||
|
||||
```bash
|
||||
$ docker run --net=ipvlan140 --ip6=2001:db8:abc2::51 -it --rm alpine /bin/sh
|
||||
|
||||
$ ip a show eth0
|
||||
78: eth0@if77: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
|
||||
link/ether 00:50:56:2b:29:40 brd ff:ff:ff:ff:ff:ff
|
||||
inet 192.168.140.2/24 scope global eth0
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 2001:db8:abc4::250:56ff:fe2b:2940/64 scope link
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 2001:db8:abc9::1/64 scope link nodad
|
||||
valid_lft forever preferred_lft forever
|
||||
|
||||
$$ ip route
|
||||
default via 192.168.140.1 dev eth0
|
||||
192.168.140.0/24 dev eth0 proto kernel scope link src 192.168.140.2
|
||||
|
||||
$$ ip -6 route
|
||||
2001:db8:abc4::/64 dev eth0 proto kernel metric 256
|
||||
2001:db8:abc9::/64 dev eth0 proto kernel metric 256
|
||||
default via 2001:db8:abc9::22 dev eth0 metric 1024
|
||||
```
|
||||
|
||||
Start a second container with a specific `--ip4` address and ping the first host
|
||||
using IPv4 packets:
|
||||
|
||||
```bash
|
||||
$ docker run --net=ipvlan140 --ip=192.168.140.10 -it --rm alpine /bin/sh
|
||||
```
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Different subnets on the same parent interface in Ipvlan `L2` mode cannot ping
|
||||
> one another. That requires a router to proxy-arp the requests with a secondary
|
||||
> subnet. However, Ipvlan `L3` will route the unicast traffic between disparate
|
||||
> subnets as long as they share the same `-o parent` parent link.
|
||||
|
||||
### Dual Stack IPv4 IPv6 Ipvlan L3 Mode
|
||||
|
||||
**Example:** IpVlan L3 Mode Dual Stack IPv4/IPv6, Multi-Subnet w/ 802.1q Vlan Tag:118
|
||||
|
||||
As in all of the examples, a tagged VLAN interface does not have to be used. The
|
||||
sub-interfaces can be swapped with `eth0`, `eth1`, `bond0` or any other valid
|
||||
interface on the host other then the `lo` loopback.
|
||||
|
||||
The primary difference you will see is that L3 mode does not create a default
|
||||
route with a next-hop but rather sets a default route pointing to `dev eth` only
|
||||
since ARP/Broadcasts/Multicast are all filtered by Linux as per the design. Since
|
||||
the parent interface is essentially acting as a router, the parent interface IP
|
||||
and subnet needs to be different from the container networks. That is the opposite
|
||||
of bridge and L2 modes, which need to be on the same subnet (broadcast domain)
|
||||
in order to forward broadcast and multicast packets.
|
||||
|
||||
```bash
|
||||
# Create an IPv6+IPv4 Dual Stack Ipvlan L3 network
|
||||
# Gateways for both v4 and v6 are set to a dev e.g. 'default dev eth0'
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.110.0/24 \
|
||||
--subnet=192.168.112.0/24 \
|
||||
--subnet=2001:db8:abc6::/64 \
|
||||
-o parent=eth0 \
|
||||
-o ipvlan_mode=l3 ipnet110
|
||||
|
||||
|
||||
# Start a few of containers on the network (ipnet110)
|
||||
# in separate terminals and check connectivity
|
||||
$ docker run --net=ipnet110 -it --rm alpine /bin/sh
|
||||
# Start a second container specifying the v6 address
|
||||
$ docker run --net=ipnet110 --ip6=2001:db8:abc6::10 -it --rm alpine /bin/sh
|
||||
# Start a third specifying the IPv4 address
|
||||
$ docker run --net=ipnet110 --ip=192.168.112.30 -it --rm alpine /bin/sh
|
||||
# Start a 4th specifying both the IPv4 and IPv6 addresses
|
||||
$ docker run --net=ipnet110 --ip6=2001:db8:abc6::50 --ip=192.168.112.50 -it --rm alpine /bin/sh
|
||||
```
|
||||
|
||||
Interface and routing table outputs are as follows:
|
||||
|
||||
```bash
|
||||
$$ ip a show eth0
|
||||
63: eth0@if59: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
|
||||
link/ether 00:50:56:2b:29:40 brd ff:ff:ff:ff:ff:ff
|
||||
inet 192.168.112.2/24 scope global eth0
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 2001:db8:abc4::250:56ff:fe2b:2940/64 scope link
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 2001:db8:abc6::10/64 scope link nodad
|
||||
valid_lft forever preferred_lft forever
|
||||
|
||||
# Note the default route is simply the eth device because ARPs are filtered.
|
||||
$$ ip route
|
||||
default dev eth0 scope link
|
||||
192.168.112.0/24 dev eth0 proto kernel scope link src 192.168.112.2
|
||||
|
||||
$$ ip -6 route
|
||||
2001:db8:abc4::/64 dev eth0 proto kernel metric 256
|
||||
2001:db8:abc6::/64 dev eth0 proto kernel metric 256
|
||||
default dev eth0 metric 1024
|
||||
```
|
||||
|
||||
> *Note*
|
||||
>
|
||||
> There may be a bug when specifying `--ip6=` addresses when you delete a
|
||||
> container with a specified v6 address and then start a new container with the
|
||||
> same v6 address it throws the following like the address isn't properly being
|
||||
> released to the v6 pool. It will fail to unmount the container and be left dead.
|
||||
|
||||
```console
|
||||
docker: Error response from daemon: Address already in use.
|
||||
```
|
||||
|
||||
### Manually Creating 802.1q Links
|
||||
|
||||
**Vlan ID 40**
|
||||
|
||||
If a user does not want the driver to create the vlan sub-interface it simply
|
||||
needs to exist prior to the `docker network create`. If you have sub-interface
|
||||
naming that is not `interface.vlan_id` it is honored in the `-o parent=` option
|
||||
again as long as the interface exists and is up.
|
||||
|
||||
Links, when manually created, can be named anything as long as they exist when
|
||||
the network is created. Manually created links do not get deleted regardless of
|
||||
the name when the network is deleted with `docker network rm`.
|
||||
|
||||
```bash
|
||||
# create a new sub-interface tied to dot1q vlan 40
|
||||
$ ip link add link eth0 name eth0.40 type vlan id 40
|
||||
|
||||
# enable the new sub-interface
|
||||
$ ip link set eth0.40 up
|
||||
|
||||
# now add networks and hosts as you would normally by attaching to the master (sub)interface that is tagged
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.40.0/24 \
|
||||
--gateway=192.168.40.1 \
|
||||
-o parent=eth0.40 ipvlan40
|
||||
|
||||
# in two separate terminals, start a Docker container and the containers can now ping one another.
|
||||
$ docker run --net=ipvlan40 -it --name ivlan_test5 --rm alpine /bin/sh
|
||||
$ docker run --net=ipvlan40 -it --name ivlan_test6 --rm alpine /bin/sh
|
||||
```
|
||||
|
||||
**Example:** Vlan sub-interface manually created with any name:
|
||||
|
||||
```bash
|
||||
# create a new sub interface tied to dot1q vlan 40
|
||||
$ ip link add link eth0 name foo type vlan id 40
|
||||
|
||||
# enable the new sub-interface
|
||||
$ ip link set foo up
|
||||
|
||||
# now add networks and hosts as you would normally by attaching to the master (sub)interface that is tagged
|
||||
$ docker network create -d ipvlan \
|
||||
--subnet=192.168.40.0/24 --gateway=192.168.40.1 \
|
||||
-o parent=foo ipvlan40
|
||||
|
||||
# in two separate terminals, start a Docker container and the containers can now ping one another.
|
||||
$ docker run --net=ipvlan40 -it --name ivlan_test5 --rm alpine /bin/sh
|
||||
$ docker run --net=ipvlan40 -it --name ivlan_test6 --rm alpine /bin/sh
|
||||
```
|
||||
|
||||
Manually created links can be cleaned up with:
|
||||
|
||||
```bash
|
||||
$ ip link del foo
|
||||
```
|
||||
|
||||
As with all of the Libnetwork drivers, they can be mixed and matched, even as
|
||||
far as running 3rd party ecosystem drivers in parallel for maximum flexibility
|
||||
to the Docker user.
|
||||
@ -438,8 +438,12 @@ A Dockerfile is similar to a Makefile.
|
||||
* `NO_PROXY`
|
||||
* `no_proxy`
|
||||
|
||||
To use these, simply pass them on the command line using the `--build-arg
|
||||
<varname>=<value>` flag.
|
||||
To use these, pass them on the command line using `--build-arg` flag, for
|
||||
example:
|
||||
|
||||
```
|
||||
$ docker build --build-arg HTTPS_PROXY=https://my-proxy.example.com .
|
||||
```
|
||||
|
||||
**ONBUILD**
|
||||
-- `ONBUILD [INSTRUCTION]`
|
||||
|
||||
@ -504,13 +504,13 @@ and foreground Docker containers.
|
||||
**--network**=*type*
|
||||
Set the Network mode for the container. Supported values are:
|
||||
|
||||
| Value | Description |
|
||||
|:----------------------------|:-----------------------------------------------------------------------------------------|
|
||||
| **none** | No networking in the container. |
|
||||
| **bridge** | Connect the container to the default Docker bridge via veth interfaces. |
|
||||
| **host** | Use the host's network stack inside the container. |
|
||||
| **container:**_name_|_id_ | Use the network stack of another container, specified via its _name_ or _id_. |
|
||||
| _network-name_|_network-id_ | Connects the container to a user created network (using `docker network create` command) |
|
||||
| Value | Description |
|
||||
|:-----------------------------|:-----------------------------------------------------------------------------------------|
|
||||
| **none** | No networking in the container. |
|
||||
| **bridge** | Connect the container to the default Docker bridge via veth interfaces. |
|
||||
| **host** | Use the host's network stack inside the container. |
|
||||
| **container:**_name_\|_id_ | Use the network stack of another container, specified via its _name_ or _id_. |
|
||||
| _network-name_\|_network-id_ | Connects the container to a user created network (using `docker network create` command) |
|
||||
|
||||
Default is **bridge**.
|
||||
|
||||
|
||||
@ -18,5 +18,5 @@ for FILE in *.md; do
|
||||
continue
|
||||
fi
|
||||
mkdir -p "./man${num}"
|
||||
md2man -in "$FILE" -out "./man${num}/${name}"
|
||||
go-md2man -in "$FILE" -out "./man${num}/${name}"
|
||||
done
|
||||
|
||||
@ -111,7 +111,7 @@ pull the above image by digest, run the following command:
|
||||
Digest can also be used in the `FROM` of a Dockerfile, for example:
|
||||
|
||||
FROM ubuntu@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2
|
||||
LABEL maintainer="some maintainer <maintainer@example.com>"
|
||||
LABEL org.opencontainers.image.authors="some maintainer <maintainer@example.com>"
|
||||
|
||||
> **Note**: Using this feature "pins" an image to a specific version in time.
|
||||
> Docker will therefore not pull updated versions of an image, which may include
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
TARGET=${TARGET:-"build"}
|
||||
|
||||
PLATFORM=${PLATFORM:-}
|
||||
VERSION=${VERSION:-"unknown-version"}
|
||||
VERSION=${VERSION:-$(git describe --match 'v[0-9]*' --dirty='.m' --always --tags | sed 's/^v//' 2>/dev/null || echo "unknown-version" )}
|
||||
GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)}
|
||||
BUILDTIME=${BUILDTIME:-$(date -u +"%Y-%m-%dT%H:%M:%SZ")}
|
||||
|
||||
@ -20,15 +22,15 @@ export LDFLAGS="\
|
||||
${LDFLAGS:-} \
|
||||
"
|
||||
|
||||
GOOS="${GOOS:-$(go env GOHOSTOS)}"
|
||||
GOARCH="${GOARCH:-$(go env GOHOSTARCH)}"
|
||||
GOOS="$(go env GOOS)"
|
||||
GOARCH="$(go env GOARCH)"
|
||||
if [ "${GOARCH}" = "arm" ]; then
|
||||
GOARM="${GOARM:-$(go env GOHOSTARM)}"
|
||||
GOARM="$(go env GOARM)"
|
||||
fi
|
||||
|
||||
TARGET="build/docker-$GOOS-$GOARCH"
|
||||
TARGET="$TARGET/docker-${GOOS}-${GOARCH}"
|
||||
if [ "${GOARCH}" = "arm" ] && [ -n "${GOARM}" ]; then
|
||||
TARGET="${TARGET}-v${GOARM}"
|
||||
TARGET="${TARGET}-v${GOARM}"
|
||||
fi
|
||||
|
||||
if [ "${GOOS}" = "windows" ]; then
|
||||
|
||||
@ -1,14 +1,80 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
#
|
||||
# Build a static binary for the host OS/ARCH
|
||||
#
|
||||
|
||||
set -eu -o pipefail
|
||||
set -eu
|
||||
|
||||
source ./scripts/build/.variables
|
||||
: "${CGO_ENABLED=}"
|
||||
: "${GO_LINKMODE=static}"
|
||||
: "${GO_BUILDMODE=}"
|
||||
: "${GO_BUILDTAGS=}"
|
||||
: "${GO_STRIP=}"
|
||||
|
||||
echo "Building statically linked $TARGET"
|
||||
export CGO_ENABLED=0
|
||||
go build -o "${TARGET}" --ldflags "${LDFLAGS}" "${SOURCE}"
|
||||
. ./scripts/build/.variables
|
||||
|
||||
ln -sf "$(basename "${TARGET}")" build/docker
|
||||
if [ -z "$CGO_ENABLED" ]; then
|
||||
case "$(go env GOOS)" in
|
||||
linux)
|
||||
case "$(go env GOARCH)" in
|
||||
amd64|arm64|arm|s390x)
|
||||
CGO_ENABLED=1
|
||||
;;
|
||||
*)
|
||||
CGO_ENABLED=0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
darwin|windows)
|
||||
CGO_ENABLED=1
|
||||
;;
|
||||
*)
|
||||
CGO_ENABLED=0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
export CGO_ENABLED
|
||||
if [ "$CGO_ENABLED" = "1" ] && [ "$(go env GOOS)" != "windows" ]; then
|
||||
case "$(go env GOARCH)" in
|
||||
mips*|ppc64)
|
||||
# pie build mode is not supported on mips architectures
|
||||
;;
|
||||
*)
|
||||
GO_BUILDMODE="-buildmode=pie"
|
||||
;;
|
||||
esac
|
||||
GO_BUILDTAGS="$GO_BUILDTAGS pkcs11"
|
||||
fi
|
||||
|
||||
if [ "$CGO_ENABLED" = "1" ] && [ "$GO_LINKMODE" = "static" ] && [ "$(go env GOOS)" = "linux" ]; then
|
||||
LDFLAGS="$LDFLAGS -extldflags -static"
|
||||
fi
|
||||
|
||||
if [ -n "$GO_STRIP" ]; then
|
||||
LDFLAGS="$LDFLAGS -s -w"
|
||||
fi
|
||||
|
||||
if [ "$(go env GOOS)" = "windows" ]; then
|
||||
# Generate a Windows file version of the form major,minor,patch,build
|
||||
VERSION_QUAD=$(printf "%s" "$VERSION" | sed -re 's/^([0-9.]*).*$/\1/' | tr . , | sed -re 's/^[0-9]+$/\0,0/' | sed -re 's/^[0-9]+,[0-9]+$/\0,0/' | sed -re 's/^[0-9]+,[0-9]+,[0-9]+$/\0,0/')
|
||||
|
||||
set --
|
||||
[ -n "$VERSION" ] && set -- "$@" -D "DOCKER_VERSION=\"$VERSION\""
|
||||
[ -n "$VERSION_QUAD" ] && set -- "$@" -D "DOCKER_VERSION_QUAD=$VERSION_QUAD"
|
||||
[ -n "$GITCOMMIT" ] && set -- "$@" -D "DOCKER_COMMIT=\"$GITCOMMIT\""
|
||||
|
||||
windres=$($(go env CC) --print-prog-name=windres)
|
||||
|
||||
target="$(dirname "$0")/../../cli/winresources/rsrc_$(go env GOARCH).syso"
|
||||
mkdir -p "$(dirname "${target}")"
|
||||
"$windres" -i "$(dirname "$0")/../winresources/docker.rc" -o "$target" "$@"
|
||||
echo "package winresources" > "$(dirname "${target}")/stub_windows.go"
|
||||
fi
|
||||
|
||||
echo "Building $GO_LINKMODE $(basename "${TARGET}")"
|
||||
|
||||
export GO111MODULE=auto
|
||||
|
||||
go build -o "${TARGET}" -tags "${GO_BUILDTAGS}" --ldflags "${LDFLAGS}" ${GO_BUILDMODE} "${SOURCE}"
|
||||
|
||||
ln -sf "$(basename "${TARGET}")" "$(dirname "${TARGET}")/docker"
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build a binary for all supported platforms
|
||||
#
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
BUILDDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
export SHELL=bash
|
||||
|
||||
jobs=(
|
||||
"$BUILDDIR/windows" \
|
||||
"$BUILDDIR/osx" \
|
||||
"GOOS=linux GOARCH=amd64 $BUILDDIR/binary" \
|
||||
"GOOS=linux GOARCH=arm $BUILDDIR/binary" \
|
||||
"GOOS=linux GOARCH=ppc64le $BUILDDIR/binary" \
|
||||
"GOOS=linux GOARCH=s390x $BUILDDIR/binary" \
|
||||
)
|
||||
|
||||
# Outside of circleCI run all at once. On circleCI run two at a time because
|
||||
# each container has access to two cores.
|
||||
group=${CROSS_GROUP-"all"}
|
||||
|
||||
if [ "$group" = "all" ]; then
|
||||
|
||||
echo "Building binaries for all platforms"
|
||||
parallel ::: "${jobs[@]}"
|
||||
exit 0
|
||||
|
||||
fi
|
||||
|
||||
declare -i start="$group*2"
|
||||
parallel ::: "${jobs[@]:$start:2}"
|
||||
@ -1,24 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build a dynamically linked binary for the host OS/ARCH
|
||||
#
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
source ./scripts/build/.variables
|
||||
|
||||
echo "Building dynamically linked $TARGET"
|
||||
export CGO_ENABLED=1
|
||||
case "$(go env GOARCH)" in
|
||||
mips*|ppc64)
|
||||
# pie build mode is not supported on mips architectures
|
||||
GO_BUILDMODE=""
|
||||
;;
|
||||
*)
|
||||
GO_BUILDMODE="-buildmode=pie"
|
||||
;;
|
||||
esac
|
||||
|
||||
go build -o "${TARGET}" -tags pkcs11 --ldflags "${LDFLAGS}" ${GO_BUILDMODE} "${SOURCE}"
|
||||
|
||||
ln -sf "$(basename "${TARGET}")" build/docker
|
||||
@ -1,22 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build an osx binary from linux
|
||||
#
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
source ./scripts/build/.variables
|
||||
|
||||
export CGO_ENABLED=1
|
||||
export GOOS=darwin
|
||||
export GOARCH=amd64
|
||||
export CC=o64-clang
|
||||
export CXX=o64-clang++
|
||||
export LDFLAGS="$LDFLAGS -linkmode external -s"
|
||||
export LDFLAGS_STATIC_DOCKER='-extld='${CC}
|
||||
|
||||
# Override TARGET
|
||||
TARGET="build/docker-$GOOS-$GOARCH"
|
||||
|
||||
echo "Building $TARGET"
|
||||
go build -o "${TARGET}" -tags pkcs11 --ldflags "${LDFLAGS}" "${SOURCE}"
|
||||
@ -1,23 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build a windows binary from linux
|
||||
#
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
source ./scripts/build/.variables
|
||||
|
||||
export CC=x86_64-w64-mingw32-gcc
|
||||
export CGO_ENABLED=1
|
||||
export GOOS=windows
|
||||
export GOARCH=amd64
|
||||
|
||||
# Override TARGET
|
||||
TARGET="build/docker-$GOOS-$GOARCH.exe"
|
||||
|
||||
echo "Generating windows resources"
|
||||
go generate ./cli/winresources
|
||||
|
||||
echo "Building $TARGET"
|
||||
# TODO: -tags pkcs11
|
||||
go build -o "${TARGET}" --ldflags "${LDFLAGS}" "${SOURCE}"
|
||||
@ -4,9 +4,9 @@ set -eu -o pipefail
|
||||
|
||||
mkdir -p ./man/man1
|
||||
|
||||
if ! command -v md2man &> /dev/null; then
|
||||
if ! command -v go-md2man &> /dev/null; then
|
||||
# yay, go install creates a binary named "v2" ¯\_(ツ)_/¯
|
||||
go build -o "/go/bin/md2man" ./vendor/github.com/cpuguy83/go-md2man/v2
|
||||
go build -o "/go/bin/go-md2man" ./vendor/github.com/cpuguy83/go-md2man/v2
|
||||
fi
|
||||
|
||||
# Generate man pages from cobra commands
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Compile the Windows resources into the sources
|
||||
#
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
# shellcheck source=/go/src/github.com/docker/cli/scripts/build/.variables
|
||||
source "$SCRIPTDIR"/../build/.variables
|
||||
|
||||
RESOURCES=$SCRIPTDIR/../winresources
|
||||
|
||||
TEMPDIR=$(mktemp -d)
|
||||
trap 'rm -rf $TEMPDIR' EXIT
|
||||
|
||||
if [ "$(go env GOHOSTOS)" = "windows" ]; then
|
||||
WINDRES=windres
|
||||
else
|
||||
# Cross compiling
|
||||
WINDRES=x86_64-w64-mingw32-windres
|
||||
fi
|
||||
|
||||
# Generate a Windows file version of the form major,minor,patch,build (with any part optional)
|
||||
VERSION_QUAD=$(printf "%s" "$VERSION" | sed -re 's/^([0-9.]*).*$/\1/' | tr . ,)
|
||||
|
||||
# Pass version and commit information into the resource compiler
|
||||
defs=
|
||||
[ -n "$VERSION" ] && defs+=( "-D DOCKER_VERSION=\"$VERSION\"")
|
||||
[ -n "$VERSION_QUAD" ] && defs+=( "-D DOCKER_VERSION_QUAD=$VERSION_QUAD")
|
||||
[ -n "$GITCOMMIT" ] && defs+=( "-D DOCKER_COMMIT=\"$GITCOMMIT\"")
|
||||
|
||||
makeres() {
|
||||
# shellcheck disable=SC2086
|
||||
"$WINDRES" \
|
||||
-i "$RESOURCES/$1" \
|
||||
-o "$3" \
|
||||
-F "$2" \
|
||||
--use-temp-file \
|
||||
-I "$TEMPDIR" \
|
||||
${defs[*]}
|
||||
}
|
||||
|
||||
makeres docker.rc pe-x86-64 rsrc_amd64.syso
|
||||
makeres docker.rc pe-i386 rsrc_386.syso
|
||||
@ -1,5 +1,4 @@
|
||||
cloud.google.com/go ceeb313ad77b789a7fa5287b36a1d127b69b7093 # v0.44.3
|
||||
github.com/agl/ed25519 5312a61534124124185d41f09206b9fef1d88403
|
||||
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
|
||||
github.com/beorn7/perks 37c8de3658fcb183f997c4e13e8337516ab753e6 # v1.0.1
|
||||
github.com/cespare/xxhash/v2 d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1
|
||||
@ -14,8 +13,8 @@ github.com/creack/pty 2a38352e8b4d7ab6c336eef107e4
|
||||
github.com/davecgh/go-spew 8991bc29aa16c548c550c7ff78260e27b9ab7c73 # v1.1.1
|
||||
github.com/docker/compose-on-kubernetes 78e6a00beda64ac8ccb9fec787e601fe2ce0d5bb # v0.5.0-alpha1
|
||||
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
|
||||
github.com/docker/docker f0014860c1b3345e1fcc7ed81c491298de2633fb # v20.10.1
|
||||
github.com/docker/docker-credential-helpers 54f0238b6bf101fc3ad3b34114cb5520beb562f5 # v0.6.3
|
||||
github.com/docker/docker 46229ca1d815cfd4b50eb377ac75ad8300e13a85
|
||||
github.com/docker/docker-credential-helpers 38bea2ce277ad0c9d2a6230692b0606ca5286526
|
||||
github.com/docker/go d30aec9fd63c35133f8f79c3412ad91a3b08be06 # Contains a customized version of canonical/json and is used by Notary. The package is periodically rebased on current Go versions.
|
||||
github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
|
||||
github.com/docker/go-events e31b211e4f1cd09aa76fe4ac244571fab96ae47f
|
||||
@ -68,7 +67,7 @@ github.com/shurcooL/sanitized_anchor_name 7bfe4c7ecddb3666a94b053b422c
|
||||
github.com/sirupsen/logrus 6699a89a232f3db797f2e280639854bbc4b89725 # v1.7.0
|
||||
github.com/spf13/cobra 86f8bfd7fef868a174e1b606783bd7f5c82ddf8f # v1.1.1
|
||||
github.com/spf13/pflag 2e9d26c8c37aae03e3f9d4e90b7116f5accb7cab # v1.0.5
|
||||
github.com/theupdateframework/notary d6e1431feb32348e0650bf7551ac5cffd01d857b # v0.6.1
|
||||
github.com/theupdateframework/notary bf96a202a09a312ae005cd312fc06ff4d2c166ce # v0.7.0-21-gbf96a202
|
||||
github.com/tonistiigi/fsutil 0834f99b7b85462efb69b4f571a4fa3ca7da5ac9
|
||||
github.com/tonistiigi/go-rosetta f79598599c5d34ea253b56a1d7c89bc6a96de7db
|
||||
github.com/tonistiigi/units 6950e57a87eaf136bbe44ef2ec8e75b9e3569de2
|
||||
@ -80,7 +79,7 @@ golang.org/x/crypto c1f2f97bffc9c53fc40a1a28a5b4
|
||||
golang.org/x/net ab34263943818b32f575efc978a3d24e80b04bd7
|
||||
golang.org/x/oauth2 bf48bf16ab8d622ce64ec6ce98d2c98f916b6303
|
||||
golang.org/x/sync cd5d95a43a6e21273425c7ae415d3df9ea832eeb
|
||||
golang.org/x/sys eeed37f84f13f52d35e095e8023ba65671ff86a1
|
||||
golang.org/x/sys b64e53b001e413bd5067f36d4e439eded3827374
|
||||
golang.org/x/term f5c789dd3221ff39d752ac54467d762de7cfbec6
|
||||
golang.org/x/text 23ae387dee1f90d29a23c0e87ee0b46038fbed0e # v0.3.3
|
||||
golang.org/x/time 555d28b269f0569763d25dbe1a237ae74c6bcc82
|
||||
|
||||
27
vendor/github.com/agl/ed25519/LICENSE
generated
vendored
@ -1,27 +0,0 @@
|
||||
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||