diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..37abdef44 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +bundles +.gopath diff --git a/.gitignore b/.gitignore index 4f8f09c77..2a86e41ca 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ Vagrantfile docs/AWS_S3_BUCKET docs/GIT_BRANCH docs/VERSION +docs/GITCOMMIT diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a7d3c2e1..e55cb0c75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # Changelog +## 1.1.0 (2014-07-03) + +#### Notable features since 1.0.1 ++ Add `.dockerignore` support ++ Pause containers during `docker commit` ++ Add `--tail` to `docker logs` + +#### Builder ++ Allow a tar file as context for `docker build` +* Fix issue with white-spaces and multi-lines in `Dockerfiles` + +#### Runtime +* Overall performance improvements +* Allow `/` as source of `docker run -v` +* Fix port allocation +* Fix bug in `docker save` +* Add links information to `docker inspect` + +#### Client +* Improve command line parsing for `docker commit` + +#### Remote API +* Improve status code for the `start` and `stop` endpoints + ## 1.0.1 (2014-06-19) #### Notable features since 1.0.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cb5c80651..d07b972eb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,7 @@ feels wrong or incomplete. When reporting [issues](https://github.com/dotcloud/docker/issues) on GitHub please include your host OS (Ubuntu 12.04, Fedora 19, etc), the output of `uname -a` and the output of `docker version` along with -the output of `docker info`. Please include the steps required to reproduce +the output of `docker -D info`. Please include the steps required to reproduce the problem if possible and applicable. This information will help us review and fix your issue faster. @@ -17,7 +17,7 @@ This information will help us review and fix your issue faster. For instructions on setting up your development environment, please see our dedicated [dev environment setup -docs](http://docs.docker.io/en/latest/contributing/devenvironment/). +docs](http://docs.docker.com/contributing/devenvironment/). ## Contribution guidelines @@ -190,7 +190,7 @@ There are several exceptions to the signing requirement. Currently these are: * Your patch fixes Markdown formatting or syntax errors in the documentation contained in the `docs` directory. -If you have any questions, please refer to the FAQ in the [docs](http://docs.docker.io) +If you have any questions, please refer to the FAQ in the [docs](http://docs.docker.com) ### How can I become a maintainer? diff --git a/MAINTAINERS b/MAINTAINERS index 059ff79f0..2947eb355 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6,3 +6,4 @@ Michael Crosby (@crosbymichael) AUTHORS: Tianon Gravi (@tianon) Dockerfile: Tianon Gravi (@tianon) Makefile: Tianon Gravi (@tianon) +.dockerignore: Tianon Gravi (@tianon) diff --git a/Makefile b/Makefile index a8e4dc5ca..2d07b39c3 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ BINDDIR := bundles DOCSPORT := 8000 GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null) +GITCOMMIT := $(shell git rev-parse --short HEAD 2>/dev/null) DOCKER_IMAGE := docker$(if $(GIT_BRANCH),:$(GIT_BRANCH)) DOCKER_DOCS_IMAGE := docker-docs$(if $(GIT_BRANCH),:$(GIT_BRANCH)) DOCKER_MOUNT := $(if $(BINDDIR),-v "$(CURDIR)/$(BINDDIR):/go/src/github.com/dotcloud/docker/$(BINDDIR)") @@ -59,6 +60,7 @@ docs-build: cp ./VERSION docs/VERSION echo "$(GIT_BRANCH)" > docs/GIT_BRANCH echo "$(AWS_S3_BUCKET)" > docs/AWS_S3_BUCKET + echo "$(GITCOMMIT)" > docs/GITCOMMIT docker build -t "$(DOCKER_DOCS_IMAGE)" docs bundles: diff --git a/README.md b/README.md index 608e638ea..3c378de6f 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ Docker can be used to run short-lived commands, long-running daemons (app servers, databases etc.), interactive shell sessions, etc. You can find a [list of real-world -examples](http://docs.docker.io/en/latest/examples/) in the +examples](http://docs.docker.com/examples/) in the documentation. Under the hood diff --git a/VERSION b/VERSION index 7dea76edb..9084fa2f7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.1 +1.1.0 diff --git a/api/client/commands.go b/api/client/commands.go index 0cdf3f1ac..df2125f5f 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -13,6 +13,7 @@ import ( "os" "os/exec" "path" + "path/filepath" "runtime" "strconv" "strings" @@ -36,6 +37,10 @@ import ( "github.com/dotcloud/docker/utils/filters" ) +const ( + tarHeaderSize = 512 +) + func (cli *DockerCli) CmdHelp(args ...string) error { if len(args) > 0 { method, exists := cli.getMethod(args[0]) @@ -51,7 +56,7 @@ func (cli *DockerCli) CmdHelp(args ...string) error { {"attach", "Attach to a running container"}, {"build", "Build an image from a Dockerfile"}, {"commit", "Create a new image from a container's changes"}, - {"cp", "Copy files/folders from the containers filesystem to the host path"}, + {"cp", "Copy files/folders from a container's filesystem to the host path"}, {"diff", "Inspect changes on a container's filesystem"}, {"events", "Get real time events from the server"}, {"export", "Stream the contents of a container as a tar archive"}, @@ -62,25 +67,25 @@ func (cli *DockerCli) CmdHelp(args ...string) error { {"inspect", "Return low-level information on a container"}, {"kill", "Kill a running container"}, {"load", "Load an image from a tar archive"}, - {"login", "Register or Login to the docker registry server"}, + {"login", "Register or log in to the Docker registry server"}, {"logs", "Fetch the logs of a container"}, - {"port", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT"}, + {"port", "Lookup the public-facing port that is NAT-ed to PRIVATE_PORT"}, {"pause", "Pause all processes within a container"}, {"ps", "List containers"}, - {"pull", "Pull an image or a repository from the docker registry server"}, - {"push", "Push an image or a repository to the docker registry server"}, + {"pull", "Pull an image or a repository from a Docker registry server"}, + {"push", "Push an image or a repository to a Docker registry server"}, {"restart", "Restart a running container"}, {"rm", "Remove one or more containers"}, {"rmi", "Remove one or more images"}, {"run", "Run a command in a new container"}, {"save", "Save an image to a tar archive"}, - {"search", "Search for an image in the docker index"}, + {"search", "Search for an image on the Docker Hub"}, {"start", "Start a stopped container"}, {"stop", "Stop a running container"}, {"tag", "Tag an image into a repository"}, {"top", "Lookup the running processes of a container"}, {"unpause", "Unpause a paused container"}, - {"version", "Show the docker version information"}, + {"version", "Show the Docker version information"}, {"wait", "Block until a container stops, then print its exit code"}, } { help += fmt.Sprintf(" %-10.10s%s\n", command[0], command[1]) @@ -113,13 +118,22 @@ func (cli *DockerCli) CmdBuild(args ...string) error { _, err = exec.LookPath("git") hasGit := err == nil if cmd.Arg(0) == "-" { - // As a special case, 'docker build -' will build from an empty context with the - // contents of stdin as a Dockerfile - dockerfile, err := ioutil.ReadAll(cli.in) - if err != nil { - return err + // As a special case, 'docker build -' will build from either an empty context with the + // contents of stdin as a Dockerfile, or a tar-ed context from stdin. + buf := bufio.NewReader(cli.in) + magic, err := buf.Peek(tarHeaderSize) + if err != nil && err != io.EOF { + return fmt.Errorf("failed to peek context header from STDIN: %v", err) + } + if !archive.IsArchive(magic) { + dockerfile, err := ioutil.ReadAll(buf) + if err != nil { + return fmt.Errorf("failed to read Dockerfile from STDIN: %v", err) + } + context, err = archive.Generate("Dockerfile", string(dockerfile)) + } else { + context = ioutil.NopCloser(buf) } - context, err = archive.Generate("Dockerfile", string(dockerfile)) } else if utils.IsURL(cmd.Arg(0)) && (!utils.IsGIT(cmd.Arg(0)) || !hasGit) { isRemote = true } else { @@ -150,7 +164,25 @@ func (cli *DockerCli) CmdBuild(args ...string) error { if err = utils.ValidateContextDirectory(root); err != nil { return fmt.Errorf("Error checking context is accessible: '%s'. Please check permissions and try again.", err) } - context, err = archive.Tar(root, archive.Uncompressed) + options := &archive.TarOptions{ + Compression: archive.Uncompressed, + } + if ignore, err := ioutil.ReadFile(path.Join(root, ".dockerignore")); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("Error reading .dockerignore: '%s'", err) + } else if err == nil { + for _, pattern := range strings.Split(string(ignore), "\n") { + ok, err := filepath.Match(pattern, "Dockerfile") + if err != nil { + utils.Errorf("Bad .dockerignore pattern: '%s', error: %s", pattern, err) + continue + } + if ok { + return fmt.Errorf("Dockerfile was excluded by .dockerignore pattern '%s'", pattern) + } + options.Excludes = append(options.Excludes, pattern) + } + } + context, err = archive.TarWithOptions(root, options) } var body io.Reader // Setup an upload progress bar @@ -216,7 +248,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error { // 'docker login': login / register a user to registry service. func (cli *DockerCli) CmdLogin(args ...string) error { - cmd := cli.Subcmd("login", "[OPTIONS] [SERVER]", "Register or Login to a docker registry server, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.") + cmd := cli.Subcmd("login", "[OPTIONS] [SERVER]", "Register or log in to a Docker registry server, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.") var username, password, email string @@ -342,7 +374,7 @@ func (cli *DockerCli) CmdWait(args ...string) error { // 'docker version': show version information func (cli *DockerCli) CmdVersion(args ...string) error { - cmd := cli.Subcmd("version", "", "Show the docker version information.") + cmd := cli.Subcmd("version", "", "Show the Docker version information.") if err := cmd.Parse(args); err != nil { return nil } @@ -439,6 +471,9 @@ func (cli *DockerCli) CmdInfo(args ...string) error { if initPath := remoteInfo.Get("InitPath"); initPath != "" { fmt.Fprintf(cli.out, "Init Path: %s\n", initPath) } + if len(remoteInfo.GetList("Sockets")) != 0 { + fmt.Fprintf(cli.out, "Sockets: %v\n", remoteInfo.GetList("Sockets")) + } } if len(remoteInfo.GetList("IndexServerAddress")) != 0 { @@ -462,8 +497,8 @@ func (cli *DockerCli) CmdInfo(args ...string) error { } func (cli *DockerCli) CmdStop(args ...string) error { - cmd := cli.Subcmd("stop", "[OPTIONS] CONTAINER [CONTAINER...]", "Stop a running container (Send SIGTERM, and then SIGKILL after grace period)") - nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to wait for the container to stop before killing it.") + cmd := cli.Subcmd("stop", "[OPTIONS] CONTAINER [CONTAINER...]", "Stop a running container by sending SIGTERM and then SIGKILL after a grace period") + nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to wait for the container to stop before killing it. Default is 10 seconds.") if err := cmd.Parse(args); err != nil { return nil } @@ -490,7 +525,7 @@ func (cli *DockerCli) CmdStop(args ...string) error { func (cli *DockerCli) CmdRestart(args ...string) error { cmd := cli.Subcmd("restart", "[OPTIONS] CONTAINER [CONTAINER...]", "Restart a running container") - nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default=10") + nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds.") if err := cmd.Parse(args); err != nil { return nil } @@ -547,8 +582,8 @@ func (cli *DockerCli) CmdStart(args ...string) error { tty bool cmd = cli.Subcmd("start", "CONTAINER [CONTAINER...]", "Restart a stopped container") - attach = cmd.Bool([]string{"a", "-attach"}, false, "Attach container's stdout/stderr and forward all signals to the process") - openStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's stdin") + attach = cmd.Bool([]string{"a", "-attach"}, false, "Attach container's STDOUT and STDERR and forward all signals to the process") + openStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's STDIN") ) if err := cmd.Parse(args); err != nil { @@ -679,7 +714,7 @@ func (cli *DockerCli) CmdPause(args ...string) error { } func (cli *DockerCli) CmdInspect(args ...string) error { - cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container/image") + cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container or image") tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template.") if err := cmd.Parse(args); err != nil { return nil @@ -759,7 +794,7 @@ func (cli *DockerCli) CmdInspect(args ...string) error { } func (cli *DockerCli) CmdTop(args ...string) error { - cmd := cli.Subcmd("top", "CONTAINER [ps OPTIONS]", "Lookup the running processes of a container") + cmd := cli.Subcmd("top", "CONTAINER [ps OPTIONS]", "Display the running processes of a container") if err := cmd.Parse(args); err != nil { return nil } @@ -794,7 +829,7 @@ func (cli *DockerCli) CmdTop(args ...string) error { } func (cli *DockerCli) CmdPort(args ...string) error { - cmd := cli.Subcmd("port", "CONTAINER PRIVATE_PORT", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT") + cmd := cli.Subcmd("port", "CONTAINER PRIVATE_PORT", "Lookup the public-facing port that is NAT-ed to PRIVATE_PORT") if err := cmd.Parse(args); err != nil { return nil } @@ -842,7 +877,7 @@ func (cli *DockerCli) CmdPort(args ...string) error { func (cli *DockerCli) CmdRmi(args ...string) error { var ( cmd = cli.Subcmd("rmi", "IMAGE [IMAGE...]", "Remove one or more images") - force = cmd.Bool([]string{"f", "-force"}, false, "Force") + force = cmd.Bool([]string{"f", "-force"}, false, "Force removal of the image") noprune = cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents") ) if err := cmd.Parse(args); err != nil { @@ -945,7 +980,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error { func (cli *DockerCli) CmdRm(args ...string) error { cmd := cli.Subcmd("rm", "[OPTIONS] CONTAINER [CONTAINER...]", "Remove one or more containers") - v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated to the container") + v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated with the container") link := cmd.Bool([]string{"l", "#link", "-link"}, false, "Remove the specified link and not the underlying container") force := cmd.Bool([]string{"f", "-force"}, false, "Force removal of running container") @@ -982,7 +1017,7 @@ func (cli *DockerCli) CmdRm(args ...string) error { // 'docker kill NAME' kills a running container func (cli *DockerCli) CmdKill(args ...string) error { - cmd := cli.Subcmd("kill", "[OPTIONS] CONTAINER [CONTAINER...]", "Kill a running container (send SIGKILL, or specified signal)") + cmd := cli.Subcmd("kill", "[OPTIONS] CONTAINER [CONTAINER...]", "Kill a running container using SIGKILL or a specified signal") signal := cmd.String([]string{"s", "-signal"}, "KILL", "Signal to send to the container") if err := cmd.Parse(args); err != nil { @@ -1114,7 +1149,7 @@ func (cli *DockerCli) CmdPush(args ...string) error { func (cli *DockerCli) CmdPull(args ...string) error { cmd := cli.Subcmd("pull", "NAME[:TAG]", "Pull an image or a repository from the registry") - tag := cmd.String([]string{"#t", "#-tag"}, "", "Download tagged image in repository") + tag := cmd.String([]string{"#t", "#-tag"}, "", "Download tagged image in a repository") if err := cmd.Parse(args); err != nil { return nil } @@ -1503,25 +1538,21 @@ func (cli *DockerCli) CmdPs(args ...string) error { func (cli *DockerCli) CmdCommit(args ...string) error { cmd := cli.Subcmd("commit", "[OPTIONS] CONTAINER [REPOSITORY[:TAG]]", "Create a new image from a container's changes") + flPause := cmd.Bool([]string{"p", "-pause"}, true, "Pause container during commit") flComment := cmd.String([]string{"m", "-message"}, "", "Commit message") - flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (eg. \"John Hannibal Smith \"") + flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (e.g., \"John Hannibal Smith \")") // FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands. - flConfig := cmd.String([]string{"#run", "#-run"}, "", "this option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands") + flConfig := cmd.String([]string{"#run", "#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands") if err := cmd.Parse(args); err != nil { return nil } - var name, repository, tag string - - if cmd.NArg() == 3 { - fmt.Fprintf(cli.err, "[DEPRECATED] The format 'CONTAINER [REPOSITORY [TAG]]' as been deprecated. Please use CONTAINER [REPOSITORY[:TAG]]\n") - name, repository, tag = cmd.Arg(0), cmd.Arg(1), cmd.Arg(2) - } else { - name = cmd.Arg(0) + var ( + name = cmd.Arg(0) repository, tag = utils.ParseRepositoryTag(cmd.Arg(1)) - } + ) - if name == "" { + if name == "" || len(cmd.Args()) > 2 { cmd.Usage() return nil } @@ -1539,6 +1570,11 @@ func (cli *DockerCli) CmdCommit(args ...string) error { v.Set("tag", tag) v.Set("comment", *flComment) v.Set("author", *flAuthor) + + if *flPause != true { + v.Set("pause", "0") + } + var ( config *runconfig.Config env engine.Env @@ -1657,6 +1693,7 @@ func (cli *DockerCli) CmdLogs(args ...string) error { cmd = cli.Subcmd("logs", "CONTAINER", "Fetch the logs of a container") follow = cmd.Bool([]string{"f", "-follow"}, false, "Follow log output") times = cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps") + tail = cmd.String([]string{"-tail"}, "all", "Output the specified number of lines at the end of logs (defaults to all logs)") ) if err := cmd.Parse(args); err != nil { @@ -1690,6 +1727,7 @@ func (cli *DockerCli) CmdLogs(args ...string) error { if *follow { v.Set("follow", "1") } + v.Set("tail", *tail) return cli.streamHelper("GET", "/containers/"+name+"/logs?"+v.Encode(), env.GetSubEnv("Config").GetBool("Tty"), nil, cli.out, cli.err, nil) } @@ -1697,8 +1735,8 @@ func (cli *DockerCli) CmdLogs(args ...string) error { func (cli *DockerCli) CmdAttach(args ...string) error { var ( cmd = cli.Subcmd("attach", "[OPTIONS] CONTAINER", "Attach to a running container") - noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach stdin") - proxy = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signal to the process (even in non-tty mode)") + noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach STDIN") + proxy = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signals to the process (even in non-TTY mode). SIGCHLD is not proxied.") ) if err := cmd.Parse(args); err != nil { @@ -1769,11 +1807,11 @@ func (cli *DockerCli) CmdAttach(args ...string) error { } func (cli *DockerCli) CmdSearch(args ...string) error { - cmd := cli.Subcmd("search", "TERM", "Search the docker index for images") + cmd := cli.Subcmd("search", "TERM", "Search the Docker Hub for images") noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output") trusted := cmd.Bool([]string{"#t", "#trusted", "#-trusted"}, false, "Only show trusted builds") automated := cmd.Bool([]string{"-automated"}, false, "Only show automated builds") - stars := cmd.Int([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least xxx stars") + stars := cmd.Int([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least x stars") if err := cmd.Parse(args); err != nil { return nil } @@ -1829,21 +1867,15 @@ func (cli *DockerCli) CmdTag(args ...string) error { if err := cmd.Parse(args); err != nil { return nil } - if cmd.NArg() != 2 && cmd.NArg() != 3 { + if cmd.NArg() != 2 { cmd.Usage() return nil } - var repository, tag string - - if cmd.NArg() == 3 { - fmt.Fprintf(cli.err, "[DEPRECATED] The format 'IMAGE [REPOSITORY [TAG]]' as been deprecated. Please use IMAGE [REGISTRYHOST/][USERNAME/]NAME[:TAG]]\n") - repository, tag = cmd.Arg(1), cmd.Arg(2) - } else { + var ( repository, tag = utils.ParseRepositoryTag(cmd.Arg(1)) - } - - v := url.Values{} + v = url.Values{} + ) //Check if the given image name can be resolved if _, _, err := registry.ResolveRepositoryName(repository); err != nil { @@ -1906,7 +1938,7 @@ func (cli *DockerCli) CmdRun(args ...string) error { } if cidFileInfo.Size() == 0 { if err := os.Remove(hostConfig.ContainerIDFile); err != nil { - fmt.Printf("failed to remove CID file '%s': %s \n", hostConfig.ContainerIDFile, err) + fmt.Printf("failed to remove Container ID file '%s': %s \n", hostConfig.ContainerIDFile, err) } } }() @@ -2156,7 +2188,7 @@ func (cli *DockerCli) CmdCp(args ...string) error { } func (cli *DockerCli) CmdSave(args ...string) error { - cmd := cli.Subcmd("save", "IMAGE", "Save an image to a tar archive (streamed to stdout by default)") + cmd := cli.Subcmd("save", "IMAGE", "Save an image to a tar archive (streamed to STDOUT by default)") outfile := cmd.String([]string{"o", "-output"}, "", "Write to an file, instead of STDOUT") if err := cmd.Parse(args); err != nil { diff --git a/api/common.go b/api/common.go index a20c5d7d1..e73705000 100644 --- a/api/common.go +++ b/api/common.go @@ -11,7 +11,7 @@ import ( ) const ( - APIVERSION version.Version = "1.12" + APIVERSION version.Version = "1.13" DEFAULTHTTPHOST = "127.0.0.1" DEFAULTUNIXSOCKET = "/var/run/docker.sock" ) diff --git a/api/server/MAINTAINERS b/api/server/MAINTAINERS new file mode 100644 index 000000000..c92a06114 --- /dev/null +++ b/api/server/MAINTAINERS @@ -0,0 +1,2 @@ +Victor Vieux (@vieux) +Johan Euphrosine (@proppy) diff --git a/api/server/server.go b/api/server/server.go index ce1bdbd39..b3a0590fd 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -370,13 +370,24 @@ func getContainersLogs(eng *engine.Engine, version version.Version, w http.Respo } var ( - job = eng.Job("container_inspect", vars["name"]) - c, err = job.Stdout.AddEnv() + inspectJob = eng.Job("container_inspect", vars["name"]) + logsJob = eng.Job("logs", vars["name"]) + c, err = inspectJob.Stdout.AddEnv() ) if err != nil { return err } - if err = job.Run(); err != nil { + logsJob.Setenv("follow", r.Form.Get("follow")) + logsJob.Setenv("tail", r.Form.Get("tail")) + logsJob.Setenv("stdout", r.Form.Get("stdout")) + logsJob.Setenv("stderr", r.Form.Get("stderr")) + logsJob.Setenv("timestamps", r.Form.Get("timestamps")) + // Validate args here, because we can't return not StatusOK after job.Run() call + stdout, stderr := logsJob.GetenvBool("stdout"), logsJob.GetenvBool("stderr") + if !(stdout || stderr) { + return fmt.Errorf("Bad parameters: you must choose at least one stream") + } + if err = inspectJob.Run(); err != nil { return err } @@ -390,14 +401,9 @@ func getContainersLogs(eng *engine.Engine, version version.Version, w http.Respo errStream = outStream } - job = eng.Job("logs", vars["name"]) - job.Setenv("follow", r.Form.Get("follow")) - job.Setenv("stdout", r.Form.Get("stdout")) - job.Setenv("stderr", r.Form.Get("stderr")) - job.Setenv("timestamps", r.Form.Get("timestamps")) - job.Stdout.Add(outStream) - job.Stderr.Set(errStream) - if err := job.Run(); err != nil { + logsJob.Stdout.Add(outStream) + logsJob.Stderr.Set(errStream) + if err := logsJob.Run(); err != nil { fmt.Fprintf(outStream, "Error running logs job: %s\n", err) } return nil @@ -434,6 +440,12 @@ func postCommit(eng *engine.Engine, version version.Version, w http.ResponseWrit utils.Errorf("%s", err) } + if r.FormValue("pause") == "" && version.GreaterThanOrEqualTo("1.13") { + job.Setenv("pause", "1") + } else { + job.Setenv("pause", r.FormValue("pause")) + } + job.Setenv("repo", r.Form.Get("repo")) job.Setenv("tag", r.Form.Get("tag")) job.Setenv("author", r.Form.Get("author")) @@ -688,8 +700,11 @@ func postContainersStart(eng *engine.Engine, version version.Version, w http.Res if vars == nil { return fmt.Errorf("Missing parameter") } - name := vars["name"] - job := eng.Job("start", name) + var ( + name = vars["name"] + job = eng.Job("start", name) + ) + // allow a nil body for backwards compatibility if r.Body != nil { if api.MatchesContentType(r.Header.Get("Content-Type"), "application/json") { @@ -699,6 +714,10 @@ func postContainersStart(eng *engine.Engine, version version.Version, w http.Res } } if err := job.Run(); err != nil { + if err.Error() == "Container already started" { + w.WriteHeader(http.StatusNotModified) + return nil + } return err } w.WriteHeader(http.StatusNoContent) @@ -715,6 +734,10 @@ func postContainersStop(eng *engine.Engine, version version.Version, w http.Resp job := eng.Job("stop", vars["name"]) job.Setenv("t", r.Form.Get("t")) if err := job.Run(); err != nil { + if err.Error() == "Container already stopped" { + w.WriteHeader(http.StatusNotModified) + return nil + } return err } w.WriteHeader(http.StatusNoContent) @@ -855,7 +878,7 @@ func getContainersByName(eng *engine.Engine, version version.Version, w http.Res } var job = eng.Job("container_inspect", vars["name"]) if version.LessThan("1.12") { - job.SetenvBool("dirty", true) + job.SetenvBool("raw", true) } streamJSON(job, w, false) return job.Run() @@ -867,7 +890,7 @@ func getImagesByName(eng *engine.Engine, version version.Version, w http.Respons } var job = eng.Job("image_inspect", vars["name"]) if version.LessThan("1.12") { - job.SetenvBool("dirty", true) + job.SetenvBool("raw", true) } streamJSON(job, w, false) return job.Run() diff --git a/api/server/server_unit_test.go b/api/server/server_unit_test.go index 32f8e42b1..2d14f8955 100644 --- a/api/server/server_unit_test.go +++ b/api/server/server_unit_test.go @@ -4,12 +4,14 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/dotcloud/docker/api" - "github.com/dotcloud/docker/engine" "io" "net/http" "net/http/httptest" + "strings" "testing" + + "github.com/dotcloud/docker/api" + "github.com/dotcloud/docker/engine" ) func TestGetBoolParam(t *testing.T) { @@ -151,6 +153,172 @@ func TestGetContainersByName(t *testing.T) { } } +func TestGetEvents(t *testing.T) { + eng := engine.New() + var called bool + eng.Register("events", func(job *engine.Job) engine.Status { + called = true + since := job.Getenv("since") + if since != "1" { + t.Fatalf("'since' should be 1, found %#v instead", since) + } + until := job.Getenv("until") + if until != "0" { + t.Fatalf("'until' should be 0, found %#v instead", until) + } + v := &engine.Env{} + v.Set("since", since) + v.Set("until", until) + if _, err := v.WriteTo(job.Stdout); err != nil { + return job.Error(err) + } + return engine.StatusOK + }) + r := serveRequest("GET", "/events?since=1&until=0", nil, eng, t) + if !called { + t.Fatal("handler was not called") + } + if r.HeaderMap.Get("Content-Type") != "application/json" { + t.Fatalf("%#v\n", r) + } + var stdout_json struct { + Since int + Until int + } + if err := json.Unmarshal(r.Body.Bytes(), &stdout_json); err != nil { + t.Fatalf("%#v", err) + } + if stdout_json.Since != 1 { + t.Fatalf("since != 1: %#v", stdout_json.Since) + } + if stdout_json.Until != 0 { + t.Fatalf("until != 0: %#v", stdout_json.Until) + } +} + +func TestLogs(t *testing.T) { + eng := engine.New() + var inspect bool + var logs bool + eng.Register("container_inspect", func(job *engine.Job) engine.Status { + inspect = true + if len(job.Args) == 0 { + t.Fatal("Job arguments is empty") + } + if job.Args[0] != "test" { + t.Fatalf("Container name %s, must be test", job.Args[0]) + } + return engine.StatusOK + }) + expected := "logs" + eng.Register("logs", func(job *engine.Job) engine.Status { + logs = true + if len(job.Args) == 0 { + t.Fatal("Job arguments is empty") + } + if job.Args[0] != "test" { + t.Fatalf("Container name %s, must be test", job.Args[0]) + } + follow := job.Getenv("follow") + if follow != "1" { + t.Fatalf("follow: %s, must be 1", follow) + } + stdout := job.Getenv("stdout") + if stdout != "1" { + t.Fatalf("stdout %s, must be 1", stdout) + } + stderr := job.Getenv("stderr") + if stderr != "" { + t.Fatalf("stderr %s, must be empty", stderr) + } + timestamps := job.Getenv("timestamps") + if timestamps != "1" { + t.Fatalf("timestamps %s, must be 1", timestamps) + } + job.Stdout.Write([]byte(expected)) + return engine.StatusOK + }) + r := serveRequest("GET", "/containers/test/logs?follow=1&stdout=1×tamps=1", nil, eng, t) + if r.Code != http.StatusOK { + t.Fatalf("Got status %d, expected %d", r.Code, http.StatusOK) + } + if !inspect { + t.Fatal("container_inspect job was not called") + } + if !logs { + t.Fatal("logs job was not called") + } + res := r.Body.String() + if res != expected { + t.Fatalf("Output %s, expected %s", res, expected) + } +} + +func TestLogsNoStreams(t *testing.T) { + eng := engine.New() + var inspect bool + var logs bool + eng.Register("container_inspect", func(job *engine.Job) engine.Status { + inspect = true + if len(job.Args) == 0 { + t.Fatal("Job arguments is empty") + } + if job.Args[0] != "test" { + t.Fatalf("Container name %s, must be test", job.Args[0]) + } + return engine.StatusOK + }) + eng.Register("logs", func(job *engine.Job) engine.Status { + logs = true + return engine.StatusOK + }) + r := serveRequest("GET", "/containers/test/logs", nil, eng, t) + if r.Code != http.StatusBadRequest { + t.Fatalf("Got status %d, expected %d", r.Code, http.StatusBadRequest) + } + if inspect { + t.Fatal("container_inspect job was called, but it shouldn't") + } + if logs { + t.Fatal("logs job was called, but it shouldn't") + } + res := strings.TrimSpace(r.Body.String()) + expected := "Bad parameters: you must choose at least one stream" + if !strings.Contains(res, expected) { + t.Fatalf("Output %s, expected %s in it", res, expected) + } +} + +func TestGetImagesHistory(t *testing.T) { + eng := engine.New() + imageName := "docker-test-image" + var called bool + eng.Register("history", func(job *engine.Job) engine.Status { + called = true + if len(job.Args) == 0 { + t.Fatal("Job arguments is empty") + } + if job.Args[0] != imageName { + t.Fatalf("name != '%s': %#v", imageName, job.Args[0]) + } + v := &engine.Env{} + if _, err := v.WriteTo(job.Stdout); err != nil { + return job.Error(err) + } + return engine.StatusOK + }) + r := serveRequest("GET", "/images/"+imageName+"/history", nil, eng, t) + if !called { + t.Fatalf("handler was not called") + } + if r.Code != http.StatusOK { + t.Fatalf("Got status %d, expected %d", r.Code, http.StatusOK) + } + if r.HeaderMap.Get("Content-Type") != "application/json" { + t.Fatalf("%#v\n", r) + } +} + func serveRequest(method, target string, body io.Reader, eng *engine.Engine, t *testing.T) *httptest.ResponseRecorder { r := httptest.NewRecorder() req, err := http.NewRequest(method, target, body) diff --git a/archive/archive.go b/archive/archive.go index 1982218b4..8d8b7412c 100644 --- a/archive/archive.go +++ b/archive/archive.go @@ -27,6 +27,7 @@ type ( Compression int TarOptions struct { Includes []string + Excludes []string Compression Compression NoLchown bool } @@ -43,6 +44,16 @@ const ( Xz ) +func IsArchive(header []byte) bool { + compression := DetectCompression(header) + if compression != Uncompressed { + return true + } + r := tar.NewReader(bytes.NewBuffer(header)) + _, err := r.Next() + return err == nil +} + func DetectCompression(source []byte) Compression { for compression, m := range map[Compression][]byte{ Bzip2: {0x42, 0x5A, 0x68}, @@ -276,7 +287,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L // Tar creates an archive from the directory at `path`, and returns it as a // stream of bytes. func Tar(path string, compression Compression) (io.ReadCloser, error) { - return TarFilter(path, &TarOptions{Compression: compression}) + return TarWithOptions(path, &TarOptions{Compression: compression}) } func escapeName(name string) string { @@ -295,12 +306,9 @@ func escapeName(name string) string { return string(escaped) } -// TarFilter creates an archive from the directory at `srcPath` with `options`, and returns it as a -// stream of bytes. -// -// Files are included according to `options.Includes`, default to including all files. -// Stream is compressed according to `options.Compression', default to Uncompressed. -func TarFilter(srcPath string, options *TarOptions) (io.ReadCloser, error) { +// TarWithOptions creates an archive from the directory at `path`, only including files whose relative +// paths are included in `options.Includes` (if non-nil) or not in `options.Excludes`. +func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) { pipeReader, pipeWriter := io.Pipe() compressWriter, err := CompressStream(pipeWriter, options.Compression) @@ -332,6 +340,21 @@ func TarFilter(srcPath string, options *TarOptions) (io.ReadCloser, error) { return nil } + for _, exclude := range options.Excludes { + matched, err := filepath.Match(exclude, relFilePath) + if err != nil { + utils.Errorf("Error matching: %s (pattern: %s)", relFilePath, exclude) + return err + } + if matched { + utils.Debugf("Skipping excluded path: %s", relFilePath) + if f.IsDir() { + return filepath.SkipDir + } + return nil + } + } + if err := addTarFile(filePath, relFilePath, tw); err != nil { utils.Debugf("Can't add file %s to tar: %s\n", srcPath, err) } @@ -355,10 +378,13 @@ func TarFilter(srcPath string, options *TarOptions) (io.ReadCloser, error) { } // Untar reads a stream of bytes from `archive`, parses it as a tar archive, -// and unpacks it into the directory at `path`. +// and unpacks it into the directory at `dest`. // The archive may be compressed with one of the following algorithms: // identity (uncompressed), gzip, bzip2, xz. -// FIXME: specify behavior when target path exists vs. doesn't exist. +// If `dest` does not exist, it is created unless there are multiple entries in `archive`. +// In the latter case, an error is returned. +// If `dest` is an existing file, it gets overwritten. +// If `dest` is an existing directory, its files get merged (with overwrite for conflicting files). func Untar(archive io.Reader, dest string, options *TarOptions) error { if archive == nil { return fmt.Errorf("Empty archive") @@ -372,7 +398,22 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { tr := tar.NewReader(decompressedArchive) - var dirs []*tar.Header + var ( + dirs []*tar.Header + create bool + multipleEntries bool + ) + + if fi, err := os.Lstat(dest); err != nil { + if !os.IsNotExist(err) { + return err + } + // destination does not exist, so it is assumed it has to be created. + create = true + } else if !fi.IsDir() { + // destination exists and is not a directory, so it will be overwritten. + create = true + } // Iterate through the files in the archive. for { @@ -385,6 +426,11 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { return err } + // Return an error if destination needs to be created and there is more than 1 entry in the tar stream. + if create && multipleEntries { + return fmt.Errorf("Trying to untar an archive with multiple entries to an inexistant target `%s`: did you mean `%s` instead?", dest, filepath.Dir(dest)) + } + // Normalize name, for safety and for a simple is-root check hdr.Name = filepath.Clean(hdr.Name) @@ -400,7 +446,12 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { } } - path := filepath.Join(dest, hdr.Name) + var path string + if create { + path = dest // we are renaming hdr.Name to dest + } else { + path = filepath.Join(dest, hdr.Name) + } // If path exits we almost always just want to remove and replace it // The only exception is when it is a directory *and* the file from @@ -416,10 +467,14 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { } } } + if err := createTarFile(path, dest, hdr, tr, options == nil || !options.NoLchown); err != nil { return err } + // Successfully added an entry. Predicting multiple entries for next iteration (not current one). + multipleEntries = true + // Directory mtimes must be handled at the end to avoid further // file creation in them to modify the directory mtime if hdr.Typeflag == tar.TypeDir { @@ -443,7 +498,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { // TarUntar aborts and returns the error. func TarUntar(src string, dst string) error { utils.Debugf("TarUntar(%s %s)", src, dst) - archive, err := TarFilter(src, &TarOptions{Compression: Uncompressed}) + archive, err := TarWithOptions(src, &TarOptions{Compression: Uncompressed}) if err != nil { return err } diff --git a/archive/archive_test.go b/archive/archive_test.go index ea34f0798..1b5e14696 100644 --- a/archive/archive_test.go +++ b/archive/archive_test.go @@ -63,8 +63,8 @@ func TestCmdStreamGood(t *testing.T) { } } -func tarUntar(t *testing.T, origin string, compression Compression) error { - archive, err := Tar(origin, compression) +func tarUntar(t *testing.T, origin string, options *TarOptions) ([]Change, error) { + archive, err := TarWithOptions(origin, options) if err != nil { t.Fatal(err) } @@ -72,37 +72,29 @@ func tarUntar(t *testing.T, origin string, compression Compression) error { buf := make([]byte, 10) if _, err := archive.Read(buf); err != nil { - return err + return nil, err } wrap := io.MultiReader(bytes.NewReader(buf), archive) detectedCompression := DetectCompression(buf) + compression := options.Compression if detectedCompression.Extension() != compression.Extension() { - return fmt.Errorf("Wrong compression detected. Actual compression: %s, found %s", compression.Extension(), detectedCompression.Extension()) + return nil, fmt.Errorf("Wrong compression detected. Actual compression: %s, found %s", compression.Extension(), detectedCompression.Extension()) } tmp, err := ioutil.TempDir("", "docker-test-untar") if err != nil { - return err + return nil, err } defer os.RemoveAll(tmp) if err := Untar(wrap, tmp, nil); err != nil { - return err + return nil, err } if _, err := os.Stat(tmp); err != nil { - return err + return nil, err } - changes, err := ChangesDirs(origin, tmp) - if err != nil { - return err - } - - if len(changes) != 0 { - t.Fatalf("Unexpected differences after tarUntar: %v", changes) - } - - return nil + return ChangesDirs(origin, tmp) } func TestTarUntar(t *testing.T) { @@ -122,9 +114,90 @@ func TestTarUntar(t *testing.T) { Uncompressed, Gzip, } { - if err := tarUntar(t, origin, c); err != nil { + changes, err := tarUntar(t, origin, &TarOptions{ + Compression: c, + }) + + if err != nil { t.Fatalf("Error tar/untar for compression %s: %s", c.Extension(), err) } + + if len(changes) != 0 { + t.Fatalf("Unexpected differences after tarUntar: %v", changes) + } + } +} + +func TestTarWithOptions(t *testing.T) { + origin, err := ioutil.TempDir("", "docker-test-untar-origin") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(origin) + if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(path.Join(origin, "2"), []byte("welcome!"), 0700); err != nil { + t.Fatal(err) + } + + cases := []struct { + opts *TarOptions + numChanges int + }{ + {&TarOptions{Includes: []string{"1"}}, 1}, + {&TarOptions{Excludes: []string{"2"}}, 1}, + } + for _, testCase := range cases { + changes, err := tarUntar(t, origin, testCase.opts) + if err != nil { + t.Fatalf("Error tar/untar when testing inclusion/exclusion: %s", err) + } + if len(changes) != testCase.numChanges { + t.Errorf("Expected %d changes, got %d for %+v:", + testCase.numChanges, len(changes), testCase.opts) + } + } +} + +func TestTarUntarFile(t *testing.T) { + origin, err := ioutil.TempDir("", "docker-test-untar-origin-file") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(origin) + + if err := os.MkdirAll(path.Join(origin, "before"), 0700); err != nil { + t.Fatal(err) + } + if err := os.MkdirAll(path.Join(origin, "after"), 0700); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(path.Join(origin, "before", "file"), []byte("hello world"), 0700); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(path.Join(origin, "after", "file2"), []byte("please overwrite me"), 0700); err != nil { + t.Fatal(err) + } + + tar, err := TarWithOptions(path.Join(origin, "before"), &TarOptions{Compression: Uncompressed, Includes: []string{"file"}}) + if err != nil { + t.Fatal(err) + } + + if err := Untar(tar, path.Join(origin, "after", "file2"), nil); err != nil { + t.Fatal(err) + } + + catCmd := exec.Command("cat", path.Join(origin, "after", "file2")) + out, err := CmdStream(catCmd, nil) + if err != nil { + t.Fatalf("Failed to start command: %s", err) + } + if output, err := ioutil.ReadAll(out); err != nil { + t.Error(err) + } else if string(output) != "hello world" { + t.Fatalf("Expected 'hello world', got '%s'", output) } } diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index f75b85ca8..89395560f 100755 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -458,10 +458,21 @@ _docker_rm() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "-v --volumes -l --link" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "-f --force -l --link -v --volumes" -- "$cur" ) ) + return ;; *) + local force= + for arg in "${COMP_WORDS[@]}"; do + case "$arg" in + -f|--force) + __docker_containers_all + return + ;; + esac + done __docker_containers_stopped + return ;; esac } diff --git a/contrib/completion/fish/docker.fish b/contrib/completion/fish/docker.fish index 00255bc0a..a4a9365f9 100644 --- a/contrib/completion/fish/docker.fish +++ b/contrib/completion/fish/docker.fish @@ -79,13 +79,13 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from build' -s t -l tag -d ' # commit complete -c docker -f -n '__fish_docker_no_subcommand' -a commit -d "Create a new image from a container's changes" -complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -s a -l author -d 'Author (eg. "John Hannibal Smith "' +complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -s a -l author -d 'Author (e.g., "John Hannibal Smith "' complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -s m -l message -d 'Commit message' complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -l run -d 'Config automatically applied when the image is run. (ex: -run=\'{"Cmd": ["cat", "/world"], "PortSpecs": ["22"]}\')' complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -a '(__fish_print_docker_containers all)' -d "Container" # cp -complete -c docker -f -n '__fish_docker_no_subcommand' -a cp -d 'Copy files/folders from the containers filesystem to the host path' +complete -c docker -f -n '__fish_docker_no_subcommand' -a cp -d 'Copy files/folders from a container's filesystem to the host path' # diff complete -c docker -f -n '__fish_docker_no_subcommand' -a diff -d "Inspect changes on a container's filesystem" diff --git a/contrib/completion/zsh/_docker b/contrib/completion/zsh/_docker index 4578d1eda..3f96f00ef 100644 --- a/contrib/completion/zsh/_docker +++ b/contrib/completion/zsh/_docker @@ -1,6 +1,6 @@ #compdef docker # -# zsh completion for docker (http://docker.io) +# zsh completion for docker (http://docker.com) # # version: 0.2.2 # author: Felix Riedel diff --git a/contrib/init/openrc/docker.initd b/contrib/init/openrc/docker.initd index 2d79a7397..a9d21b170 100755 --- a/contrib/init/openrc/docker.initd +++ b/contrib/init/openrc/docker.initd @@ -11,6 +11,9 @@ DOCKER_OPTS=${DOCKER_OPTS:-} start() { checkpath -f -m 0644 -o root:docker "$DOCKER_LOGFILE" + ulimit -n 1048576 + ulimit -u 1048576 + ebegin "Starting docker daemon" start-stop-daemon --start --background \ --exec "$DOCKER_BINARY" \ diff --git a/contrib/init/systemd/docker.service b/contrib/init/systemd/docker.service index 1bc4d1f56..6f3cc33c3 100644 --- a/contrib/init/systemd/docker.service +++ b/contrib/init/systemd/docker.service @@ -1,6 +1,6 @@ [Unit] Description=Docker Application Container Engine -Documentation=http://docs.docker.io +Documentation=http://docs.docker.com After=network.target [Service] diff --git a/contrib/init/systemd/socket-activation/docker.service b/contrib/init/systemd/socket-activation/docker.service index a3382ab41..4af71378c 100644 --- a/contrib/init/systemd/socket-activation/docker.service +++ b/contrib/init/systemd/socket-activation/docker.service @@ -1,6 +1,6 @@ [Unit] Description=Docker Application Container Engine -Documentation=http://docs.docker.io +Documentation=http://docs.docker.com After=network.target [Service] diff --git a/contrib/init/sysvinit-debian/docker b/contrib/init/sysvinit-debian/docker index 9b50fad44..6250cae05 100755 --- a/contrib/init/sysvinit-debian/docker +++ b/contrib/init/sysvinit-debian/docker @@ -22,7 +22,10 @@ BASE=$(basename $0) # modify these in /etc/default/$BASE (/etc/default/docker) DOCKER=/usr/bin/$BASE +# This is the pid file managed by docker itself DOCKER_PIDFILE=/var/run/$BASE.pid +# This is the pid file created/managed by start-stop-daemon +DOCKER_SSD_PIDFILE=/var/run/$BASE-ssd.pid DOCKER_LOGFILE=/var/log/$BASE.log DOCKER_OPTS= DOCKER_DESC="Docker" @@ -85,11 +88,15 @@ case "$1" in touch "$DOCKER_LOGFILE" chgrp docker "$DOCKER_LOGFILE" + ulimit -n 1048576 + ulimit -u 1048576 + log_begin_msg "Starting $DOCKER_DESC: $BASE" start-stop-daemon --start --background \ --no-close \ --exec "$DOCKER" \ - --pidfile "$DOCKER_PIDFILE" \ + --pidfile "$DOCKER_SSD_PIDFILE" \ + --make-pidfile \ -- \ -d -p "$DOCKER_PIDFILE" \ $DOCKER_OPTS \ @@ -100,13 +107,13 @@ case "$1" in stop) fail_unless_root log_begin_msg "Stopping $DOCKER_DESC: $BASE" - start-stop-daemon --stop --pidfile "$DOCKER_PIDFILE" + start-stop-daemon --stop --pidfile "$DOCKER_SSD_PIDFILE" log_end_msg $? ;; restart) fail_unless_root - docker_pid=`cat "$DOCKER_PIDFILE" 2>/dev/null` + docker_pid=`cat "$DOCKER_SSD_PIDFILE" 2>/dev/null` [ -n "$docker_pid" ] \ && ps -p $docker_pid > /dev/null 2>&1 \ && $0 stop @@ -119,7 +126,7 @@ case "$1" in ;; status) - status_of_proc -p "$DOCKER_PIDFILE" "$DOCKER" docker + status_of_proc -p "$DOCKER_SSD_PIDFILE" "$DOCKER" docker ;; *) diff --git a/contrib/init/sysvinit-redhat/docker b/contrib/init/sysvinit-redhat/docker index 06699f6ab..aa94c0481 100755 --- a/contrib/init/sysvinit-redhat/docker +++ b/contrib/init/sysvinit-redhat/docker @@ -2,10 +2,10 @@ # # /etc/rc.d/init.d/docker # -# Daemon for docker.io +# Daemon for docker.com # # chkconfig: 2345 95 95 -# description: Daemon for docker.io +# description: Daemon for docker.com ### BEGIN INIT INFO # Provides: docker @@ -16,7 +16,7 @@ # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: start and stop docker -# Description: Daemon for docker.io +# Description: Daemon for docker.com ### END INIT INFO # Source function library. diff --git a/contrib/man/.gitignore b/contrib/man/.gitignore deleted file mode 100644 index c2c63b5d2..000000000 --- a/contrib/man/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# these are generated by the md/md2man-all.sh script -man* diff --git a/contrib/man/md/docker-kill.1.md b/contrib/man/md/docker-kill.1.md deleted file mode 100644 index 8175002d3..000000000 --- a/contrib/man/md/docker-kill.1.md +++ /dev/null @@ -1,21 +0,0 @@ -% DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 -# NAME -docker-kill - Kill a running container (send SIGKILL, or specified signal) - -# SYNOPSIS -**docker kill** **--signal**[=*"KILL"*] CONTAINER [CONTAINER...] - -# DESCRIPTION - -The main process inside each container specified will be sent SIGKILL, - or any signal specified with option --signal. - -# OPTIONS -**-s**, **--signal**=*"KILL"* - Signal to send to the container - -# HISTORY -April 2014, Originally compiled by William Henry (whenry at redhat dot com) - based on docker.io source material and internal work. diff --git a/contrib/man/md/docker-port.1.md b/contrib/man/md/docker-port.1.md deleted file mode 100644 index 9773e4d80..000000000 --- a/contrib/man/md/docker-port.1.md +++ /dev/null @@ -1,15 +0,0 @@ -% DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 -# NAME -docker-port - Lookup the public-facing port which is NAT-ed to PRIVATE_PORT - -# SYNOPSIS -**docker port** CONTAINER PRIVATE_PORT - -# DESCRIPTION -Lookup the public-facing port which is NAT-ed to PRIVATE_PORT - -# HISTORY -April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. diff --git a/contrib/man/md/docker-restart.1.md b/contrib/man/md/docker-restart.1.md deleted file mode 100644 index 44634f661..000000000 --- a/contrib/man/md/docker-restart.1.md +++ /dev/null @@ -1,21 +0,0 @@ -% DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 -# NAME -docker-restart - Restart a running container - -# SYNOPSIS -**docker restart** [**-t**|**--time**[=*10*]] CONTAINER [CONTAINER...] - -# DESCRIPTION -Restart each container listed. - -# OPTIONS -**-t**, **--time**=NUM - Number of seconds to try to stop for before killing the container. Once -killed it will then be restarted. Default=10 - -# HISTORY -April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. - diff --git a/contrib/man/md/docker-start.1.md b/contrib/man/md/docker-start.1.md deleted file mode 100644 index 2815f1b07..000000000 --- a/contrib/man/md/docker-start.1.md +++ /dev/null @@ -1,29 +0,0 @@ -% DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 -# NAME -docker-start - Restart a stopped container - -# SYNOPSIS -**docker start** [**a**|**--attach**[=*false*]] [**-i**|**--interactive** -[=*true*] CONTAINER [CONTAINER...] - -# DESCRIPTION - -Start a stopped container. - -# OPTION -**-a**, **--attach**=*true*|*false* - When true attach to container's stdout/stderr and forward all signals to -the process - -**-i**, **--interactive**=*true*|*false* - When true attach to container's stdin - -# NOTES -If run on a started container, start takes no action and succeeds -unconditionally. - -# HISTORY -April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. diff --git a/contrib/man/md/docker-stop.1.md b/contrib/man/md/docker-stop.1.md deleted file mode 100644 index 6ec81cd47..000000000 --- a/contrib/man/md/docker-stop.1.md +++ /dev/null @@ -1,22 +0,0 @@ -% DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 -# NAME -docker-stop - Stop a running container - grace period) - -# SYNOPSIS -**docker stop** [**-t**|**--time**[=*10*]] CONTAINER [CONTAINER...] - -# DESCRIPTION -Stop a running container (Send SIGTERM, and then SIGKILL after - grace period) - -# OPTIONS -**-t**, **--time**=NUM - Wait NUM number of seconds for the container to stop before killing it. -The default is 10 seconds. - -# HISTORY -April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. diff --git a/contrib/man/old-man/docker-attach.1 b/contrib/man/old-man/docker-attach.1 deleted file mode 100644 index f0879d750..000000000 --- a/contrib/man/old-man/docker-attach.1 +++ /dev/null @@ -1,56 +0,0 @@ -.\" Process this file with -.\" nroff -man -Tascii docker-attach.1 -.\" -.TH "DOCKER" "1" "APRIL 2014" "0.1" "Docker" -.SH NAME -docker-attach \- Attach to a running container -.SH SYNOPSIS -.B docker attach -\fB--no-stdin\fR[=\fIfalse\fR] -\fB--sig-proxy\fR[=\fItrue\fR] -container -.SH DESCRIPTION -If you \fBdocker run\fR a container in detached mode (\fB-d\fR), you can reattach to the detached container with \fBdocker attach\fR using the container's ID or name. -.sp -You can detach from the container again (and leave it running) with CTRL-c (for a quiet exit) or CTRL-\ to get a stacktrace of the Docker client when it quits. When you detach from the container the exit code will be returned to the client. -.SH "OPTIONS" -.TP -.B --no-stdin=\fItrue\fR|\fIfalse\fR: -When set to true, do not attach to stdin. The default is \fIfalse\fR. -.TP -.B --sig-proxy=\fItrue\fR|\fIfalse\fR: -When set to true, proxify all received signal to the process (even in non-tty mode). The default is \fItrue\fR. -.sp -.SH EXAMPLES -.sp -.PP -.B Attaching to a container -.TP -In this example the top command is run inside a container, from an image called fedora, in detached mode. The ID from the container is passed into the \fBdocker attach\fR command: -.sp -.nf -.RS -# ID=$(sudo docker run -d fedora /usr/bin/top -b) -# sudo docker attach $ID -top - 02:05:52 up 3:05, 0 users, load average: 0.01, 0.02, 0.05 -Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie -Cpu(s): 0.1%us, 0.2%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st -Mem: 373572k total, 355560k used, 18012k free, 27872k buffers -Swap: 786428k total, 0k used, 786428k free, 221740k cached - -PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND -1 root 20 0 17200 1116 912 R 0 0.3 0:00.03 top - -top - 02:05:55 up 3:05, 0 users, load average: 0.01, 0.02, 0.05 -Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie -Cpu(s): 0.0%us, 0.2%sy, 0.0%ni, 99.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st -Mem: 373572k total, 355244k used, 18328k free, 27872k buffers -Swap: 786428k total, 0k used, 786428k free, 221776k cached - -PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND -1 root 20 0 17208 1144 932 R 0 0.3 0:00.03 top -.RE -.fi -.sp -.SH HISTORY -April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on dockier.io source material and internal work. diff --git a/contrib/man/old-man/docker-build.1 b/contrib/man/old-man/docker-build.1 deleted file mode 100644 index 2d189eb0e..000000000 --- a/contrib/man/old-man/docker-build.1 +++ /dev/null @@ -1,65 +0,0 @@ -.\" Process this file with -.\" nroff -man -Tascii docker-build.1 -.\" -.TH "DOCKER" "1" "MARCH 2014" "0.1" "Docker" -.SH NAME -docker-build \- Build an image from a Dockerfile source at PATH -.SH SYNOPSIS -.B docker build -[\fB--no-cache\fR[=\fIfalse\fR] -[\fB-q\fR|\fB--quiet\fR[=\fIfalse\fR] -[\fB--rm\fR[=\fitrue\fR]] -[\fB-t\fR|\fB--tag\fR=\fItag\fR] -PATH | URL | - -.SH DESCRIPTION -This will read the Dockerfile from the directory specified in \fBPATH\fR. It also sends any other files and directories found in the current directory to the Docker daemon. The contents of this directory would be used by ADD command found within the Dockerfile. -Warning, this will send a lot of data to the Docker daemon if the current directory contains a lot of data. -If the absolute path is provided instead of ‘.’, only the files and directories required by the ADD commands from the Dockerfile will be added to the context and transferred to the Docker daemon. -.sp -When a single Dockerfile is given as URL, then no context is set. When a Git repository is set as URL, the repository is used as context. -.SH "OPTIONS" -.TP -.B -q, --quiet=\fItrue\fR|\fIfalse\fR: -When set to true, suppress verbose build output. Default is \fIfalse\fR. -.TP -.B --rm=\fItrue\fr|\fIfalse\fR: -When true, remove intermediate containers that are created during the build process. The default is true. -.TP -.B -t, --tag=\fItag\fR: -Tag to be applied to the resulting image on successful completion of the build. -.TP -.B --no-cache=\fItrue\fR|\fIfalse\fR -When set to true, do not use a cache when building the image. The default is \fIfalse\fR. -.sp -.SH EXAMPLES -.sp -.sp -.B Building an image from current directory -.TP -USing a Dockerfile, Docker images are built using the build command: -.sp -.RS -docker build . -.RE -.sp -If, for some reasone, you do not what to remove the intermediate containers created during the build you must set--rm=false. -.sp -.RS -docker build --rm=false . -.sp -.RE -.sp -A good practice is to make a subdirectory with a related name and create the Dockerfile in that directory. E.g. a directory called mongo may contain a Dockerfile for a MongoDB image, or a directory called httpd may contain an Dockerfile for an Apache web server. -.sp -It is also good practice to add the files required for the image to the subdirectory. These files will be then specified with the `ADD` instruction in the Dockerfile. Note: if you include a tar file, which is good practice, then Docker will automatically extract the contents of the tar file specified in the `ADD` instruction into the specified target. -.sp -.B Building an image container using a URL -.TP -This will clone the Github repository and use it as context. The Dockerfile at the root of the repository is used as Dockerfile. This only works if the Github repository is a dedicated repository. Note that you can specify an arbitrary Git repository by using the ‘git://’ schema. -.sp -.RS -docker build github.com/scollier/Fedora-Dockerfiles/tree/master/apache -.RE -.sp -.SH HISTORY -March 2014, Originally compiled by William Henry (whenry at redhat dot com) based on dockier.io source material and internal work. diff --git a/contrib/man/old-man/docker-images.1 b/contrib/man/old-man/docker-images.1 deleted file mode 100644 index e540ba2b7..000000000 --- a/contrib/man/old-man/docker-images.1 +++ /dev/null @@ -1,84 +0,0 @@ -.\" Process this file with -.\" nroff -man -Tascii docker-images.1 -.\" -.TH "DOCKER" "1" "April 2014" "0.1" "Docker" -.SH NAME -docker-images \- List the images in the local repository -.SH SYNOPSIS -.B docker images -[\fB-a\fR|\fB--all\fR=\fIfalse\fR] -[\fB--no-trunc\fR[=\fIfalse\fR] -[\fB-q\fR|\fB--quiet\fR[=\fIfalse\fR] -[\fB-t\fR|\fB--tree\fR=\fIfalse\fR] -[\fB-v\fR|\fB--viz\fR=\fIfalse\fR] -[NAME] -.SH DESCRIPTION -This command lists the images stored in the local Docker repository. -.sp -By default, intermediate images, used during builds, are not listed. Some of the output, e.g. image ID, is truncated, for space reasons. However the truncated image ID, and often the first few characters, are enough to be used in other Docker commands that use the image ID. The output includes repository, tag, image ID, date created and the virtual size. -.sp -The title REPOSITORY for the first title may seem confusing. It is essentially the image name. However, because you can tag a specific image, and multiple tags (image instances) can be associated with a single name, the name is really a repository for all tagged images of the same name. -.SH "OPTIONS" -.TP -.B -a, --all=\fItrue\fR|\fIfalse\fR: -When set to true, also include all intermediate images in the list. The default is false. -.TP -.B --no-trunc=\fItrue\fR|\fIfalse\fR: -When set to true, list the full image ID and not the truncated ID. The default is false. -.TP -.B -q, --quiet=\fItrue\fR|\fIfalse\fR: -When set to true, list the complete image ID as part of the output. The default is false. -.TP -.B -t, --tree=\fItrue\fR|\fIfalse\fR: -When set to true, list the images in a tree dependency tree (hierarchy) format. The default is false. -.TP -.B -v, --viz=\fItrue\fR|\fIfalse\fR -When set to true, list the graph in graphviz format. The default is \fIfalse\fR. -.sp -.SH EXAMPLES -.sp -.B Listing the images -.TP -To list the images in a local repository (not the registry) run: -.sp -.RS -docker images -.RE -.sp -The list will contain the image repository name, a tag for the image, and an image ID, when it was created and its virtual size. Columns: REPOSITORY, TAG, IMAGE ID, CREATED, and VIRTUAL SIZE. -.sp -To get a verbose list of images which contains all the intermediate images used in builds use \fB-a\fR: -.sp -.RS -docker images -a -.RE -.sp -.B List images dependency tree hierarchy -.TP -To list the images in the local repository (not the registry) in a dependency tree format then use the \fB-t\fR|\fB--tree=true\fR option. -.sp -.RS -docker images -t -.RE -.sp -This displays a staggered hierarchy tree where the less indented image is the oldest with dependent image layers branching inward (to the right) on subsequent lines. The newest or top level image layer is listed last in any tree branch. -.sp -.B List images in GraphViz format -.TP -To display the list in a format consumable by a GraphViz tools run with \fB-v\fR|\fB--viz=true\fR. For example to produce a .png graph file of the hierarchy use: -.sp -.RS -docker images --viz | dot -Tpng -o docker.png -.sp -.RE -.sp -.B Listing only the shortened image IDs -.TP -Listing just the shortened image IDs. This can be useful for some automated tools. -.sp -.RS -docker images -q -.RE -.sp -.SH HISTORY -April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on dockier.io source material and internal work. diff --git a/contrib/man/old-man/docker-info.1 b/contrib/man/old-man/docker-info.1 deleted file mode 100644 index dca2600af..000000000 --- a/contrib/man/old-man/docker-info.1 +++ /dev/null @@ -1,39 +0,0 @@ -.\" Process this file with -.\" nroff -man -Tascii docker-info.1 -.\" -.TH "DOCKER" "1" "APRIL 2014" "0.1" "Docker" -.SH NAME -docker-info \- Display system wide information -.SH SYNOPSIS -.B docker info -.SH DESCRIPTION -This command displays system wide information regarding the Docker installation. Information displayed includes the number of containers and images, pool name, data file, metadata file, data space used, total data space, metadata space used, total metadata space, execution driver, and the kernel version. -.sp -The data file is where the images are stored and the metadata file is where the meta data regarding those images are stored. When run for the first time Docker allocates a certain amount of data space and meta data space from the space available on the volume where /var/lib/docker is mounted. -.SH "OPTIONS" -There are no available options. -.sp -.SH EXAMPLES -.sp -.B Display Docker system information -.TP -Here is a sample output: -.sp -.RS - # docker info - Containers: 18 - Images: 95 - Storage Driver: devicemapper - Pool Name: docker-8:1-170408448-pool - Data file: /var/lib/docker/devicemapper/devicemapper/data - Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata - Data Space Used: 9946.3 Mb - Data Space Total: 102400.0 Mb - Metadata Space Used: 9.9 Mb - Metadata Space Total: 2048.0 Mb - Execution Driver: native-0.1 - Kernel Version: 3.10.0-116.el7.x86_64 -.RE -.sp -.SH HISTORY -April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on dockier.io source material and internal work. diff --git a/contrib/man/old-man/docker-inspect.1 b/contrib/man/old-man/docker-inspect.1 deleted file mode 100644 index 225125e56..000000000 --- a/contrib/man/old-man/docker-inspect.1 +++ /dev/null @@ -1,237 +0,0 @@ -.\" Process this file with -.\" nroff -man -Tascii docker-inspect.1 -.\" -.TH "DOCKER" "1" "APRIL 2014" "0.1" "Docker" -.SH NAME -docker-inspect \- Return low-level information on a container/image -.SH SYNOPSIS -.B docker inspect -[\fB-f\fR|\fB--format\fR="" -CONTAINER|IMAGE [CONTAINER|IMAGE...] -.SH DESCRIPTION -This displays all the information available in Docker for a given container or image. By default, this will render all results in a JSON array. If a format is specified, the given template will be executed for each result. -.SH "OPTIONS" -.TP -.B -f, --format="": -The text/template package of Go describes all the details of the format. See examples section -.SH EXAMPLES -.sp -.PP -.B Getting information on a container -.TP -To get information on a container use it's ID or instance name -.sp -.fi -.RS -#docker inspect 1eb5fabf5a03 - -[{ - "ID": "1eb5fabf5a03807136561b3c00adcd2992b535d624d5e18b6cdc6a6844d9767b", - "Created": "2014-04-04T21:33:52.02361335Z", - "Path": "/usr/sbin/nginx", - "Args": [], - "Config": { - "Hostname": "1eb5fabf5a03", - "Domainname": "", - "User": "", - "Memory": 0, - "MemorySwap": 0, - "CpuShares": 0, - "AttachStdin": false, - "AttachStdout": false, - "AttachStderr": false, - "PortSpecs": null, - "ExposedPorts": { - "80/tcp": {} - }, - "Tty": true, - "OpenStdin": false, - "StdinOnce": false, - "Env": [ - "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - ], - "Cmd": [ - "/usr/sbin/nginx" - ], - "Dns": null, - "DnsSearch": null, - "Image": "summit/nginx", - "Volumes": null, - "VolumesFrom": "", - "WorkingDir": "", - "Entrypoint": null, - "NetworkDisabled": false, - "OnBuild": null, - "Context": { - "mount_label": "system_u:object_r:svirt_sandbox_file_t:s0:c0,c650", - "process_label": "system_u:system_r:svirt_lxc_net_t:s0:c0,c650" - } - }, - "State": { - "Running": true, - "Pid": 858, - "ExitCode": 0, - "StartedAt": "2014-04-04T21:33:54.16259207Z", - "FinishedAt": "0001-01-01T00:00:00Z", - "Ghost": false - }, - "Image": "df53773a4390e25936f9fd3739e0c0e60a62d024ea7b669282b27e65ae8458e6", - "NetworkSettings": { - "IPAddress": "172.17.0.2", - "IPPrefixLen": 16, - "Gateway": "172.17.42.1", - "Bridge": "docker0", - "PortMapping": null, - "Ports": { - "80/tcp": [ - { - "HostIp": "0.0.0.0", - "HostPort": "80" - } - ] - } - }, - "ResolvConfPath": "/etc/resolv.conf", - "HostnamePath": "/var/lib/docker/containers/1eb5fabf5a03807136561b3c00adcd2992b535d624d5e18b6cdc6a6844d9767b/hostname", - "HostsPath": "/var/lib/docker/containers/1eb5fabf5a03807136561b3c00adcd2992b535d624d5e18b6cdc6a6844d9767b/hosts", - "Name": "/ecstatic_ptolemy", - "Driver": "devicemapper", - "ExecDriver": "native-0.1", - "Volumes": {}, - "VolumesRW": {}, - "HostConfig": { - "Binds": null, - "ContainerIDFile": "", - "LxcConf": [], - "Privileged": false, - "PortBindings": { - "80/tcp": [ - { - "HostIp": "0.0.0.0", - "HostPort": "80" - } - ] - }, - "Links": null, - "PublishAllPorts": false, - "DriverOptions": { - "lxc": null - }, - "CliAddress": "" - } -.RE -.nf -.sp -.B Getting the IP address of a container instance -.TP -To get the IP address of a container use: -.sp -.fi -.RS -# docker inspect --format='{{.NetworkSettings.IPAddress}}' 1eb5fabf5a03 - -172.17.0.2 -.RE -.nf -.sp -.B Listing all port bindings -.TP -One can loop over arrays and maps in the results to produce simple text output: -.sp -.fi -.RS -# docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' 1eb5fabf5a03 - -80/tcp -> 80 -.RE -.nf -.sp -.B Getting information on an image -.TP -Use an image's ID or name (e.g. repository/name[:tag]) to get information on it. -.sp -.fi -.RS -docker inspect 58394af37342 -[{ - "id": "58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9", - "parent": "8abc22fbb04266308ff408ca61cb8f6f4244a59308f7efc64e54b08b496c58db", - "created": "2014-02-03T16:10:40.500814677Z", - "container": "f718f19a28a5147da49313c54620306243734bafa63c76942ef6f8c4b4113bc5", - "container_config": { - "Hostname": "88807319f25e", - "Domainname": "", - "User": "", - "Memory": 0, - "MemorySwap": 0, - "CpuShares": 0, - "AttachStdin": false, - "AttachStdout": false, - "AttachStderr": false, - "PortSpecs": null, - "ExposedPorts": null, - "Tty": false, - "OpenStdin": false, - "StdinOnce": false, - "Env": [ - "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - ], - "Cmd": [ - "/bin/sh", - "-c", - "#(nop) ADD fedora-20-medium.tar.xz in /" - ], - "Dns": null, - "DnsSearch": null, - "Image": "8abc22fbb04266308ff408ca61cb8f6f4244a59308f7efc64e54b08b496c58db", - "Volumes": null, - "VolumesFrom": "", - "WorkingDir": "", - "Entrypoint": null, - "NetworkDisabled": false, - "OnBuild": null, - "Context": null - }, - "docker_version": "0.6.3", - "author": "Lokesh Mandvekar \u003clsm5@redhat.com\u003e - ./buildcontainers.sh", - "config": { - "Hostname": "88807319f25e", - "Domainname": "", - "User": "", - "Memory": 0, - "MemorySwap": 0, - "CpuShares": 0, - "AttachStdin": false, - "AttachStdout": false, - "AttachStderr": false, - "PortSpecs": null, - "ExposedPorts": null, - "Tty": false, - "OpenStdin": false, - "StdinOnce": false, - "Env": [ - "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - ], - "Cmd": null, - "Dns": null, - "DnsSearch": null, - "Image": "8abc22fbb04266308ff408ca61cb8f6f4244a59308f7efc64e54b08b496c58db", - "Volumes": null, - "VolumesFrom": "", - "WorkingDir": "", - "Entrypoint": null, - "NetworkDisabled": false, - "OnBuild": null, - "Context": null - }, - "architecture": "x86_64", - "Size": 385520098 -}] -.RE -.nf -.sp -.SH HISTORY -April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on dockier.io source material and internal work. diff --git a/contrib/man/old-man/docker-rm.1 b/contrib/man/old-man/docker-rm.1 deleted file mode 100644 index b06e014d3..000000000 --- a/contrib/man/old-man/docker-rm.1 +++ /dev/null @@ -1,45 +0,0 @@ -.\" Process this file with -.\" nroff -man -Tascii docker-rm.1 -.\" -.TH "DOCKER" "1" "MARCH 2014" "0.1" "Docker" -.SH NAME -docker-rm \- Remove one or more containers. -.SH SYNOPSIS -.B docker rm -[\fB-f\fR|\fB--force\fR[=\fIfalse\fR] -[\fB-l\fR|\fB--link\fR[=\fIfalse\fR] -[\fB-v\fR|\fB--volumes\fR[=\fIfalse\fR] -CONTAINER [CONTAINER...] -.SH DESCRIPTION -This will remove one or more containers from the host node. The container name or ID can be used. This does not remove images. You cannot remove a running container unless you use the \fB-f\fR option. To see all containers on a host use the \fBdocker ps -a\fR command. -.SH "OPTIONS" -.TP -.B -f, --force=\fItrue\fR|\fIfalse\fR: -When set to true, force the removal of the container. The default is \fIfalse\fR. -.TP -.B -l, --link=\fItrue\fR|\fIfalse\fR: -When set to true, remove the specified link and not the underlying container. The default is \fIfalse\fR. -.TP -.B -v, --volumes=\fItrue\fR|\fIfalse\fR: -When set to true, remove the volumes associated to the container. The default is \fIfalse\fR. -.SH EXAMPLES -.sp -.PP -.B Removing a container using its ID -.TP -To remove a container using its ID, find either from a \fBdocker ps -a\fR command, or use the ID returned from the \fBdocker run\fR command, or retrieve it from a file used to store it using the \fBdocker run --cidfile\fR: -.sp -.RS -docker rm abebf7571666 -.RE -.sp -.B Removing a container using the container name: -.TP -The name of the container can be found using the \fBdocker ps -a\fR command. The use that name as follows: -.sp -.RS -docker rm hopeful_morse -.RE -.sp -.SH HISTORY -March 2014, Originally compiled by William Henry (whenry at redhat dot com) based on dockier.io source material and internal work. diff --git a/contrib/man/old-man/docker-rm.md b/contrib/man/old-man/docker-rm.md deleted file mode 100644 index a53aa77c9..000000000 --- a/contrib/man/old-man/docker-rm.md +++ /dev/null @@ -1,50 +0,0 @@ -DOCKER "1" "APRIL 2014" "0.1" "Docker" -======================================= - -NAME ----- - -docker-rm - Remove one or more containers. - -SYNOPSIS --------- - -`docker rm` [`-f`|`--force`[=*false*] [`-l`|`--link`[=*false*] [`-v`|`--volumes`[=*false*] -CONTAINER [CONTAINER...] - -DESCRIPTION ------------ - -`docker rm` will remove one or more containers from the host node. The container name or ID can be used. This does not remove images. You cannot remove a running container unless you use the \fB-f\fR option. To see all containers on a host use the `docker ps -a` command. - -OPTIONS -------- - -`-f`, `--force`=*true*|*false*: - When set to true, force the removal of the container. The default is *false*. - -`-l`, `--link`=*true*|*false*: - When set to true, remove the specified link and not the underlying container. The default is *false*. - -`-v`, `--volumes`=*true*|*false*: - When set to true, remove the volumes associated to the container. The default is *false*. - -EXAMPLES --------- - -##Removing a container using its ID## - -To remove a container using its ID, find either from a `docker ps -a` command, or use the ID returned from the `docker run` command, or retrieve it from a file used to store it using the `docker run --cidfile`: - - docker rm abebf7571666 - -##Removing a container using the container name## - -The name of the container can be found using the \fBdocker ps -a\fR command. The use that name as follows: - - docker rm hopeful_morse - -HISTORY -------- - -April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on dockier.io source material and internal work. diff --git a/contrib/man/old-man/docker-rmi.1 b/contrib/man/old-man/docker-rmi.1 deleted file mode 100644 index 6f33446ec..000000000 --- a/contrib/man/old-man/docker-rmi.1 +++ /dev/null @@ -1,29 +0,0 @@ -.\" Process this file with -.\" nroff -man -Tascii docker-run.1 -.\" -.TH "DOCKER" "1" "MARCH 2014" "0.1" "Docker" -.SH NAME -docker-rmi \- Remove one or more images. -.SH SYNOPSIS -.B docker rmi -[\fB-f\fR|\fB--force\fR[=\fIfalse\fR] -IMAGE [IMAGE...] -.SH DESCRIPTION -This will remove one or more images from the host node. This does not remove images from a registry. You cannot remove an image of a running container unless you use the \fB-f\fR option. To see all images on a host use the \fBdocker images\fR command. -.SH "OPTIONS" -.TP -.B -f, --force=\fItrue\fR|\fIfalse\fR: -When set to true, force the removal of the image. The default is \fIfalse\fR. -.SH EXAMPLES -.sp -.PP -.B Removing an image -.TP -Here is an example of removing and image: -.sp -.RS -docker rmi fedora/httpd -.RE -.sp -.SH HISTORY -March 2014, Originally compiled by William Henry (whenry at redhat dot com) based on dockier.io source material and internal work. diff --git a/contrib/man/old-man/docker-run.1 b/contrib/man/old-man/docker-run.1 deleted file mode 100644 index 0e06e8d68..000000000 --- a/contrib/man/old-man/docker-run.1 +++ /dev/null @@ -1,277 +0,0 @@ -.\" Process this file with -.\" nroff -man -Tascii docker-run.1 -.\" -.TH "DOCKER" "1" "MARCH 2014" "0.1" "Docker" -.SH NAME -docker-run \- Run a process in an isolated container -.SH SYNOPSIS -.B docker run -[\fB-a\fR|\fB--attach\fR[=]] [\fB-c\fR|\fB--cpu-shares\fR[=0] [\fB-m\fR|\fB--memory\fR=\fImemory-limit\fR] -[\fB--cidfile\fR=\fIfile\fR] [\fB-d\fR|\fB--detach\fR[=\fIfalse\fR]] [\fB--dns\fR=\fIIP-address\fR] -[\fB--name\fR=\fIname\fR] [\fB-u\fR|\fB--user\fR=\fIusername\fR|\fIuid\fR] -[\fB--link\fR=\fIname\fR:\fIalias\fR] -[\fB-e\fR|\fB--env\fR=\fIenvironment\fR] [\fB--entrypoint\fR=\fIcommand\fR] -[\fB--expose\fR=\fIport\fR] [\fB-P\fR|\fB--publish-all\fR[=\fIfalse\fR]] -[\fB-p\fR|\fB--publish\fR=\fIport-mappping\fR] [\fB-h\fR|\fB--hostname\fR=\fIhostname\fR] -[\fB--rm\fR[=\fIfalse\fR]] [\fB--priviledged\fR[=\fIfalse\fR] -[\fB-i\fR|\fB--interactive\fR[=\fIfalse\fR] -[\fB-t\fR|\fB--tty\fR[=\fIfalse\fR]] [\fB--lxc-conf\fR=\fIoptions\fR] -[\fB-n\fR|\fB--networking\fR[=\fItrue\fR]] -[\fB-v\fR|\fB--volume\fR=\fIvolume\fR] [\fB--volumes-from\fR=\fIcontainer-id\fR] -[\fB-w\fR|\fB--workdir\fR=\fIdirectory\fR] [\fB--sig-proxy\fR[=\fItrue\fR]] -IMAGE [COMMAND] [ARG...] -.SH DESCRIPTION -.PP -Run a process in a new container. \fBdocker run\fR starts a process with its own file system, its own networking, and its own isolated process tree. The \fIIMAGE\fR which starts the process may define defaults related to the process that will be run in the container, the networking to expose, and more, but \fBdocker run\fR gives final control to the operator or administrator who starts the container from the image. For that reason \fBdocker run\fR has more options than any other docker command. - -If the \fIIMAGE\fR is not already loaded then \fBdocker run\fR will pull the \fIIMAGE\fR, and all image dependencies, from the repository in the same way running \fBdocker pull\fR \fIIMAGE\fR, before it starts the container from that image. - - -.SH "OPTIONS" - -.TP -.B -a, --attach=\fIstdin\fR|\fIstdout\fR|\fIstderr\fR: -Attach to stdin, stdout or stderr. In foreground mode (the default when -d is not specified), \fBdocker run\fR can start the process in the container and attach the console to the process’s standard input, output, and standard error. It can even pretend to be a TTY (this is what most commandline executables expect) and pass along signals. The \fB-a\fR option can be set for each of stdin, stdout, and stderr. - -.TP -.B -c, --cpu-shares=0: -CPU shares in relative weight. You can increase the priority of a container with the -c option. By default, all containers run at the same priority and get the same proportion of CPU cycles, but you can tell the kernel to give more shares of CPU time to one or more containers when you start them via \fBdocker run\fR. - -.TP -.B -m, --memory=\fImemory-limit\fR: -Allows you to constrain the memory available to a container. If the host supports swap memory, then the -m memory setting can be larger than physical RAM. If a limit of 0 is specified, the container's memory is not limited. The memory limit format: , where unit = b, k, m or g. - -.TP -.B --cidfile=\fIfile\fR: -Write the container ID to the file specified. - -.TP -.B -d, --detach=\fItrue\fR|\fIfalse\fR: -Detached mode. This runs the container in the background. It outputs the new container's id and and error messages. At any time you can run \fBdocker ps\fR in the other shell to view a list of the running containers. You can reattach to a detached container with \fBdocker attach\fR. If you choose to run a container in the detached mode, then you cannot use the -rm option. - -.TP -.B --dns=\fIIP-address\fR: -Set custom DNS servers. This option can be used to override the DNS configuration passed to the container. Typically this is necessary when the host DNS configuration is invalid for the container (eg. 127.0.0.1). When this is the case the \fB-dns\fR flags is necessary for every run. - -.TP -.B -e, --env=\fIenvironment\fR: -Set environment variables. This option allows you to specify arbitrary environment variables that are available for the process that will be launched inside of the container. - -.TP -.B --entrypoint=\ficommand\fR: -This option allows you to overwrite the default entrypoint of the image that is set in the Dockerfile. The ENTRYPOINT of an image is similar to a COMMAND because it specifies what executable to run when the container starts, but it is (purposely) more difficult to override. The ENTRYPOINT gives a container its default nature or behavior, so that when you set an ENTRYPOINT you can run the container as if it were that binary, complete with default options, and you can pass in more options via the COMMAND. But, sometimes an operator may want to run something else inside the container, so you can override the default ENTRYPOINT at runtime by using a \fB--entrypoint\fR and a string to specify the new ENTRYPOINT. - -.TP -.B --expose=\fIport\fR: -Expose a port from the container without publishing it to your host. A containers port can be exposed to other containers in three ways: 1) The developer can expose the port using the EXPOSE parameter of the Dockerfile, 2) the operator can use the \fB--expose\fR option with \fBdocker run\fR, or 3) the container can be started with the \fB--link\fR. - -.TP -.B -P, --publish-all=\fItrue\fR|\fIfalse\fR: -When set to true publish all exposed ports to the host interfaces. The default is false. If the operator uses -P (or -p) then Docker will make the exposed port accessible on the host and the ports will be available to any client that can reach the host. To find the map between the host ports and the exposed ports, use \fBdocker port\fR. - -.TP -.B -p, --publish=[]: -Publish a container's port to the host (format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort) (use 'docker port' to see the actual mapping) - -.TP -.B -h , --hostname=\fIhostname\fR: -Sets the container host name that is available inside the container. - -.TP -.B -i , --interactive=\fItrue\fR|\fIfalse\fR: -When set to true, keep stdin open even if not attached. The default is false. - -.TP -.B --link=\fIname\fR:\fIalias\fR: -Add link to another container. The format is name:alias. If the operator uses \fB--link\fR when starting the new client container, then the client container can access the exposed port via a private networking interface. Docker will set some environment variables in the client container to help indicate which interface and port to use. - -.TP -.B -n, --networking=\fItrue\fR|\fIfalse\fR: -By default, all containers have networking enabled (true) and can make outgoing connections. The operator can disable networking with \fB--networking\fR to false. This disables all incoming and outgoing networking. In cases like this, I/O can only be performed through files or by using STDIN/STDOUT. - -Also by default, the container will use the same DNS servers as the host. but you canThe operator may override this with \fB-dns\fR. - -.TP -.B --name=\fIname\fR: -Assign a name to the container. The operator can identify a container in three ways: -.sp -.nf -UUID long identifier (“f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778”) -UUID short identifier (“f78375b1c487”) -Name (“jonah”) -.fi -.sp -The UUID identifiers come from the Docker daemon, and if a name is not assigned to the container with \fB--name\fR then the daemon will also generate a random string name. The name is useful when defining links (see \fB--link\fR) (or any other place you need to identify a container). This works for both background and foreground Docker containers. - -.TP -.B --privileged=\fItrue\fR|\fIfalse\fR: -Give extended privileges to this container. By default, Docker containers are “unprivileged” (=false) and cannot, for example, run a Docker daemon inside the Docker container. This is because by default a container is not allowed to access any devices. A “privileged” container is given access to all devices. - -When the operator executes \fBdocker run -privileged\fR, Docker will enable access to all devices on the host as well as set some configuration in AppArmor (\fB???\fR) to allow the container nearly all the same access to the host as processes running outside of a container on the host. - -.TP -.B --rm=\fItrue\fR|\fIfalse\fR: -If set to \fItrue\fR the container is automatically removed when it exits. The default is \fIfalse\fR. This option is incompatible with \fB-d\fR. - -.TP -.B --sig-proxy=\fItrue\fR|\fIfalse\fR: -When set to true, proxify all received signals to the process (even in non-tty mode). The default is true. - -.TP -.B -t, --tty=\fItrue\fR|\fIfalse\fR: -When set to true Docker can allocate a pseudo-tty and attach to the standard input of any container. This can be used, for example, to run a throwaway interactive shell. The default is value is false. - -.TP -.B -u, --user=\fIusername\fR,\fRuid\fR: -Set a username or UID for the container. - -.TP -.B -v, --volume=\fIvolume\fR: -Bind mount a volume to the container. The \fB-v\fR option can be used one or more times to add one or more mounts to a container. These mounts can then be used in other containers using the \fB--volumes-from\fR option. See examples. - -.TP -.B --volumes-from=\fIcontainer-id\fR: -Will mount volumes from the specified container identified by container-id. Once a volume is mounted in a one container it can be shared with other containers using the \fB--volumes-from\fR option when running those other containers. The volumes can be shared even if the original container with the mount is not running. - -.TP -.B -w, --workdir=\fIdirectory\fR: -Working directory inside the container. The default working directory for running binaries within a container is the root directory (/). The developer can set a different default with the Dockerfile WORKDIR instruction. The operator can override the working directory by using the \fB-w\fR option. - -.TP -.B IMAGE: -The image name or ID. - -.TP -.B COMMAND: -The command or program to run inside the image. - -.TP -.B ARG: -The arguments for the command to be run in the container. - -.SH EXAMPLES -.sp -.sp -.B Exposing log messages from the container to the host's log -.TP -If you want messages that are logged in your container to show up in the host's syslog/journal then you should bind mount the /var/log directory as follows. -.sp -.RS -docker run -v /dev/log:/dev/log -i -t fedora /bin/bash -.RE -.sp -From inside the container you can test this by sending a message to the log. -.sp -.RS -logger "Hello from my container" -.sp -.RE -Then exit and check the journal. -.RS -.sp -exit -.sp -journalctl -b | grep hello -.RE -.sp -This should list the message sent to logger. -.sp -.B Attaching to one or more from STDIN, STDOUT, STDERR -.TP -If you do not specify -a then Docker will attach everything (stdin,stdout,stderr). You can specify to which of the three standard streams (stdin, stdout, stderr) you’d like to connect instead, as in: -.sp -.RS -docker run -a stdin -a stdout -i -t fedora /bin/bash -.RE -.sp -.B Linking Containers -.TP -The link feature allows multiple containers to communicate with each other. For example, a container whose Dockerfile has exposed port 80 can be run and named as follows: -.sp -.RS -docker run --name=link-test -d -i -t fedora/httpd -.RE -.sp -.TP -A second container, in this case called linker, can communicate with the httpd container, named link-test, by running with the \fB--link=:\fR -.sp -.RS -docker run -t -i --link=link-test:lt --name=linker fedora /bin/bash -.RE -.sp -.TP -Now the container linker is linked to container link-test with the alias lt. Running the \fBenv\fR command in the linker container shows environment variables with the LT (alias) context (\fBLT_\fR) -.sp -.nf -.RS -# env -HOSTNAME=668231cb0978 -TERM=xterm -LT_PORT_80_TCP=tcp://172.17.0.3:80 -LT_PORT_80_TCP_PORT=80 -LT_PORT_80_TCP_PROTO=tcp -LT_PORT=tcp://172.17.0.3:80 -PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -PWD=/ -LT_NAME=/linker/lt -SHLVL=1 -HOME=/ -LT_PORT_80_TCP_ADDR=172.17.0.3 -_=/usr/bin/env -.RE -.fi -.sp -.TP -When linking two containers Docker will use the exposed ports of the container to create a secure tunnel for the parent to access. -.TP -.sp -.B Mapping Ports for External Usage -.TP -The exposed port of an application can be mapped to a host port using the \fB-p\fR flag. For example a httpd port 80 can be mapped to the host port 8080 using the following: -.sp -.RS -docker run -p 8080:80 -d -i -t fedora/httpd -.RE -.sp -.TP -.B Creating and Mounting a Data Volume Container -.TP -Many applications require the sharing of persistent data across several containers. Docker allows you to create a Data Volume Container that other containers can mount from. For example, create a named container that contains directories /var/volume1 and /tmp/volume2. The image will need to contain these directories so a couple of RUN mkdir instructions might be required for you fedora-data image: -.sp -.RS -docker run --name=data -v /var/volume1 -v /tmp/volume2 -i -t fedora-data true -.sp -docker run --volumes-from=data --name=fedora-container1 -i -t fedora bash -.RE -.sp -.TP -Multiple --volumes-from parameters will bring together multiple data volumes from multiple containers. And it's possible to mount the volumes that came from the DATA container in yet another container via the fedora-container1 intermidiery container, allowing to abstract the actual data source from users of that data: -.sp -.RS -docker run --volumes-from=fedora-container1 --name=fedora-container2 -i -t fedora bash -.RE -.TP -.sp -.B Mounting External Volumes -.TP -To mount a host directory as a container volume, specify the absolute path to the directory and the absolute path for the container directory separated by a colon: -.sp -.RS -docker run -v /var/db:/data1 -i -t fedora bash -.RE -.sp -.TP -When using SELinux, be aware that the host has no knowledge of container SELinux policy. Therefore, in the above example, if SELinux policy is enforced, the /var/db directory is not writable to the container. A "Permission Denied" message will occur and an avc: message in the host's syslog. -.sp -.TP -To work around this, at time of writing this man page, the following command needs to be run in order for the proper SELinux policy type label to be attached to the host directory: -.sp -.RS -chcon -Rt svirt_sandbox_file_t /var/db -.RE -.sp -.TP -Now, writing to the /data1 volume in the container will be allowed and the changes will also be reflected on the host in /var/db. -.sp -.SH HISTORY -March 2014, Originally compiled by William Henry (whenry at redhat dot com) based on dockier.io source material and internal work. diff --git a/contrib/man/old-man/docker-tag.1 b/contrib/man/old-man/docker-tag.1 deleted file mode 100644 index df85a1e8c..000000000 --- a/contrib/man/old-man/docker-tag.1 +++ /dev/null @@ -1,49 +0,0 @@ -.\" Process this file with -.\" nroff -man -Tascii docker-tag.1 -.\" -.TH "DOCKER" "1" "APRIL 2014" "0.1" "Docker" -.SH NAME -docker-tag \- Tag an image in the repository -.SH SYNOPSIS -.B docker tag -[\fB-f\fR|\fB--force\fR[=\fIfalse\fR] -\fBIMAGE\fR [REGISTRYHOST/][USERNAME/]NAME[:TAG] -.SH DESCRIPTION -This will tag an image in the repository. -.SH "OPTIONS" -.TP -.B -f, --force=\fItrue\fR|\fIfalse\fR: -When set to true, force the tag name. The default is \fIfalse\fR. -.TP -.B REGISTRYHOST: -The hostname of the registry if required. This may also include the port separated by a ':' -.TP -.B USERNAME: -The username or other qualifying identifier for the image. -.TP -.B NAME: -The image name. -.TP -.B TAG: -The tag you are assigning to the image. -.SH EXAMPLES -.sp -.PP -.B Tagging an image -.TP -Here is an example where an image is tagged with the tag 'Version-1.0' : -.sp -.RS -docker tag 0e5574283393 fedora/httpd:Version-1.0 -.RE -.sp -.B Tagging an image for an internal repository -.TP -To push an image to an internal Registry and not the default docker.io based registry you must tag it with the registry hostname and port (if needed). -.sp -.RS -docker tag 0e5574283393 myregistryhost:5000/fedora/httpd:version1.0 -.RE -.sp -.SH HISTORY -April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on dockier.io source material and internal work. diff --git a/contrib/man/old-man/docker.1 b/contrib/man/old-man/docker.1 deleted file mode 100644 index 95f60891c..000000000 --- a/contrib/man/old-man/docker.1 +++ /dev/null @@ -1,172 +0,0 @@ -.\" Process this file with -.\" nroff -man -Tascii docker.1 -.\" -.TH "DOCKER" "1" "APRIL 2014" "0.1" "Docker" -.SH NAME -docker \- Docker image and container command line interface -.SH SYNOPSIS -.B docker [OPTIONS] [COMMAND] [arg...] -.SH DESCRIPTION -\fBdocker\fR has two distinct functions. It is used for starting the Docker daemon and to run the CLI (i.e., to command the daemon to manage images, containers etc.) So \fBdocker\fR is both a server as deamon and a client to the daemon through the CLI. -.sp -To run the Docker deamon you do not specify any of the commands listed below but must specify the \fB-d\fR option. The other options listed below are for the daemon only. -.sp -The Docker CLI has over 30 commands. The commands are listed below and each has its own man page which explain usage and arguements. -.sp -To see the man page for a command run \fBman docker \fR. -.SH "OPTIONS" -.B \-D=false: -Enable debug mode -.TP -.B\-H=[unix:///var/run/docker.sock]: tcp://[host[:port]] to bind or unix://[/path/to/socket] to use. -When host=[0.0.0.0], port=[2375] or path -=[/var/run/docker.sock] is omitted, default values are used. -.TP -.B \-\-api-enable-cors=false -Enable CORS headers in the remote API -.TP -.B \-b="" -Attach containers to a pre\-existing network bridge; use 'none' to disable container networking -.TP -.B \-\-bip="" -Use the provided CIDR notation address for the dynamically created bridge (docker0); Mutually exclusive of \-b -.TP -.B \-d=false -Enable daemon mode -.TP -.B \-\-dns="" -Force Docker to use specific DNS servers -.TP -.B \-g="/var/lib/docker" -Path to use as the root of the Docker runtime -.TP -.B \-\-icc=true -Enable inter\-container communication -.TP -.B \-\-ip="0.0.0.0" -Default IP address to use when binding container ports -.TP -.B \-\-iptables=true -Disable Docker's addition of iptables rules -.TP -.B \-\-mtu=1500 -Set the containers network mtu -.TP -.B \-p="/var/run/docker.pid" -Path to use for daemon PID file -.TP -.B \-r=true -Restart previously running containers -.TP -.B \-s="" -Force the Docker runtime to use a specific storage driver -.TP -.B \-v=false -Print version information and quit -.SH "COMMANDS" -.TP -.B attach -Attach to a running container -.TP -.B build -Build an image from a Dockerfile -.TP -.B commit -Create a new image from a container's changes -.TP -.B cp -Copy files/folders from the containers filesystem to the host at path -.TP -.B diff -Inspect changes on a container's filesystem - -.TP -.B events -Get real time events from the server -.TP -.B export -Stream the contents of a container as a tar archive -.TP -.B history -Show the history of an image -.TP -.B images -List images -.TP -.B import -Create a new filesystem image from the contents of a tarball -.TP -.B info -Display system-wide information -.TP -.B insert -Insert a file in an image -.TP -.B inspect -Return low-level information on a container -.TP -.B kill -Kill a running container (which includes the wrapper process and everything inside it) -.TP -.B load -Load an image from a tar archive -.TP -.B login -Register or Login to a Docker registry server -.TP -.B logs -Fetch the logs of a container -.TP -.B port -Lookup the public-facing port which is NAT-ed to PRIVATE_PORT -.TP -.B ps -List containers -.TP -.B pull -Pull an image or a repository from a Docker registry server -.TP -.B push -Push an image or a repository to a Docker registry server -.TP -.B restart -Restart a running container -.TP -.B rm -Remove one or more containers -.TP -.B rmi -Remove one or more images -.TP -.B run -Run a command in a new container -.TP -.B save -Save an image to a tar archive -.TP -.B search -Search for an image in the Docker index -.TP -.B start -Start a stopped container -.TP -.B stop -Stop a running container -.TP -.B tag -Tag an image into a repository -.TP -.B top -Lookup the running processes of a container -.TP -.B version -Show the Docker version information -.TP -.B wait -Block until a container stops, then print its exit code -.SH EXAMPLES -.sp -For specific examples please see the man page for the specific Docker command. -.sp -.SH HISTORY -April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on dockier.io source material and internal work. diff --git a/contrib/mkimage-alpine.sh b/contrib/mkimage-alpine.sh index 7444ffafb..0bf328efa 100755 --- a/contrib/mkimage-alpine.sh +++ b/contrib/mkimage-alpine.sh @@ -13,8 +13,8 @@ usage() { } tmp() { - TMP=$(mktemp -d /tmp/alpine-docker-XXXXXXXXXX) - ROOTFS=$(mktemp -d /tmp/alpine-docker-rootfs-XXXXXXXXXX) + TMP=$(mktemp -d ${TMPDIR:-/var/tmp}/alpine-docker-XXXXXXXXXX) + ROOTFS=$(mktemp -d ${TMPDIR:-/var/tmp}/alpine-docker-rootfs-XXXXXXXXXX) trap "rm -rf $TMP $ROOTFS" EXIT TERM INT } diff --git a/contrib/mkimage-arch.sh b/contrib/mkimage-arch.sh index dc2106747..1f52cbc1a 100755 --- a/contrib/mkimage-arch.sh +++ b/contrib/mkimage-arch.sh @@ -9,31 +9,13 @@ hash pacstrap &>/dev/null || { exit 1 } -hash expect &>/dev/null || { - echo "Could not find expect. Run pacman -S expect" - exit 1 -} - -ROOTFS=$(mktemp -d /tmp/rootfs-archlinux-XXXXXXXXXX) +ROOTFS=$(mktemp -d ${TMPDIR:-/var/tmp}/rootfs-archlinux-XXXXXXXXXX) chmod 755 $ROOTFS # packages to ignore for space savings PKGIGNORE=linux,jfsutils,lvm2,cryptsetup,groff,man-db,man-pages,mdadm,pciutils,pcmciautils,reiserfsprogs,s-nail,xfsprogs -expect <&2 "usage: $mkimg [-d dir] [-t tag] script [script-args]" echo >&2 " ie: $mkimg -t someuser/debian debootstrap --variant=minbase jessie" - echo >&2 " $mkimg -t someuser/ubuntu debootstrap --include=ubuntu-minimal trusty" + echo >&2 " $mkimg -t someuser/ubuntu debootstrap --include=ubuntu-minimal --components main,universe trusty" echo >&2 " $mkimg -t someuser/busybox busybox-static" echo >&2 " $mkimg -t someuser/centos:5 rinse --distribution centos-5" + echo >&2 " $mkimg -t someuser/mageia:4 mageia-urpmi --version=4" + echo >&2 " $mkimg -t someuser/mageia:4 mageia-urpmi --version=4 --mirror=http://somemirror/" exit 1 } @@ -48,7 +50,7 @@ fi delDir= if [ -z "$dir" ]; then - dir="$(mktemp -d ${TMPDIR:-/tmp}/docker-mkimage.XXXXXXXXXX)" + dir="$(mktemp -d ${TMPDIR:-/var/tmp}/docker-mkimage.XXXXXXXXXX)" delDir=1 fi diff --git a/contrib/mkimage/.febootstrap-minimize b/contrib/mkimage/.febootstrap-minimize index 7dab4eb8b..8a71f5ed6 100755 --- a/contrib/mkimage/.febootstrap-minimize +++ b/contrib/mkimage/.febootstrap-minimize @@ -13,7 +13,7 @@ shift # docs rm -rf usr/share/{man,doc,info,gnome/help} # cracklib - #rm -rf usr/share/cracklib + rm -rf usr/share/cracklib # i18n rm -rf usr/share/i18n # yum cache diff --git a/contrib/mkimage/debootstrap b/contrib/mkimage/debootstrap index 4747a84d3..96d22dddd 100755 --- a/contrib/mkimage/debootstrap +++ b/contrib/mkimage/debootstrap @@ -23,9 +23,14 @@ shift # now for some Docker-specific tweaks # prevent init scripts from running during install/update -echo >&2 "+ cat > '$rootfsDir/usr/sbin/policy-rc.d'" +echo >&2 "+ echo exit 101 > '$rootfsDir/usr/sbin/policy-rc.d'" cat > "$rootfsDir/usr/sbin/policy-rc.d" <<'EOF' #!/bin/sh + +# For most Docker users, "apt-get install" only happens during "docker build", +# where starting services doesn't work and often fails in humorous ways. This +# prevents those failures by stopping the services from attempting to start. + exit 101 EOF chmod +x "$rootfsDir/usr/sbin/policy-rc.d" @@ -34,17 +39,25 @@ chmod +x "$rootfsDir/usr/sbin/policy-rc.d" ( set -x chroot "$rootfsDir" dpkg-divert --local --rename --add /sbin/initctl - ln -sf /bin/true "$rootfsDir/sbin/initctl" + cp -a "$rootfsDir/usr/sbin/policy-rc.d" "$rootfsDir/sbin/initctl" + sed -i 's/^exit.*/exit 0/' "$rootfsDir/sbin/initctl" ) -# shrink the image, since apt makes us fat (wheezy: ~157.5MB vs ~120MB) +# shrink a little, since apt makes us cache-fat (wheezy: ~157.5MB vs ~120MB) ( set -x; chroot "$rootfsDir" apt-get clean ) # Ubuntu 10.04 sucks... :) if strings "$rootfsDir/usr/bin/dpkg" | grep -q unsafe-io; then # force dpkg not to call sync() after package extraction (speeding up installs) echo >&2 "+ echo force-unsafe-io > '$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup'" - echo 'force-unsafe-io' > "$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup" + cat > "$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup" <<-'EOF' + # For most Docker users, package installs happen during "docker build", which + # doesn't survive power loss and gets restarted clean afterwards anyhow, so + # this minor tweak gives us a nice speedup (much nicer on spinning disks, + # obviously). + + force-unsafe-io + EOF fi if [ -d "$rootfsDir/etc/apt/apt.conf.d" ]; then @@ -52,16 +65,36 @@ if [ -d "$rootfsDir/etc/apt/apt.conf.d" ]; then aptGetClean='"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true";' echo >&2 "+ cat > '$rootfsDir/etc/apt/apt.conf.d/docker-clean'" cat > "$rootfsDir/etc/apt/apt.conf.d/docker-clean" <<-EOF + # Since for most Docker users, package installs happen in "docker build" steps, + # they essentially become individual layers due to the way Docker handles + # layering, especially using CoW filesystems. What this means for us is that + # the caches that APT keeps end up just wasting space in those layers, making + # our layers unnecessarily large (especially since we'll normally never use + # these caches again and will instead just "docker build" again and make a brand + # new image). + + # Ideally, these would just be invoking "apt-get clean", but in our testing, + # that ended up being cyclic and we got stuck on APT's lock, so we get this fun + # creation that's essentially just "apt-get clean". DPkg::Post-Invoke { ${aptGetClean} }; APT::Update::Post-Invoke { ${aptGetClean} }; Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache ""; + + # Note that we do realize this isn't the ideal way to do this, and are always + # open to better suggestions (https://github.com/dotcloud/docker/issues). EOF # remove apt-cache translations for fast "apt-get update" - echo >&2 "+ cat > '$rootfsDir/etc/apt/apt.conf.d/docker-no-languages'" - echo 'Acquire::Languages "none";' > "$rootfsDir/etc/apt/apt.conf.d/docker-no-languages" + echo >&2 "+ echo Acquire::Languages 'none' > '$rootfsDir/etc/apt/apt.conf.d/docker-no-languages'" + cat > "$rootfsDir/etc/apt/apt.conf.d/docker-no-languages" <<-'EOF' + # In Docker, we don't often need the "Translations" files, so we're just wasting + # time and space by downloading them, and this inhibits that. For users that do + # need them, it's a simple matter to delete this file and "apt-get update". :) + + Acquire::Languages "none"; + EOF fi if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then @@ -76,39 +109,53 @@ if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then if [ -z "$lsbDist" -a -r "$rootfsDir/etc/debian_version" ]; then lsbDist='Debian' fi + # normalize to lowercase for easier matching + lsbDist="$(echo "$lsbDist" | tr '[:upper:]' '[:lower:]')" case "$lsbDist" in - debian|Debian) + debian) # updates and security! if [ "$suite" != 'sid' -a "$suite" != 'unstable' ]; then ( set -x - sed -i "p; s/ $suite main$/ ${suite}-updates main/" "$rootfsDir/etc/apt/sources.list" + sed -i " + p; + s/ $suite / ${suite}-updates / + " "$rootfsDir/etc/apt/sources.list" echo "deb http://security.debian.org $suite/updates main" >> "$rootfsDir/etc/apt/sources.list" + # LTS + if [ "$suite" = 'squeeze' ]; then + head -1 "$rootfsDir/etc/apt/sources.list" \ + | sed "s/ $suite / ${suite}-lts /" \ + >> "$rootfsDir/etc/apt/sources.list" + fi ) fi ;; - ubuntu|Ubuntu) - # add the universe, updates, and security repositories + ubuntu) + # add the updates and security repositories ( set -x sed -i " - s/ $suite main$/ $suite main universe/; p; - s/ $suite main/ ${suite}-updates main/; p; - s/ $suite-updates main/ ${suite}-security main/ + p; + s/ $suite / ${suite}-updates /; p; + s/ $suite-updates / ${suite}-security / " "$rootfsDir/etc/apt/sources.list" ) ;; - tanglu|Tanglu) + tanglu) # add the updates repository if [ "$suite" != 'devel' ]; then ( set -x - sed -i "p; s/ $suite main$/ ${suite}-updates main/" "$rootfsDir/etc/apt/sources.list" + sed -i " + p; + s/ $suite / ${suite}-updates / + " "$rootfsDir/etc/apt/sources.list" ) fi ;; - steamos|SteamOS) - # add contrib and non-free + steamos) + # add contrib and non-free if "main" is the only component ( set -x sed -i "s/ $suite main$/ $suite main contrib non-free/" "$rootfsDir/etc/apt/sources.list" @@ -117,9 +164,13 @@ if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then esac fi -# make sure we're fully up-to-date, too ( set -x - chroot "$rootfsDir" apt-get update - chroot "$rootfsDir" apt-get dist-upgrade -y + + # make sure we're fully up-to-date + chroot "$rootfsDir" bash -c 'apt-get update && apt-get dist-upgrade -y' + + # delete all the apt list files since they're big and get stale quickly + rm -rf "$rootfsDir/var/lib/apt/lists"/* + # this forces "apt-get update" in dependent images, which is also good ) diff --git a/contrib/mkimage/mageia-urpmi b/contrib/mkimage/mageia-urpmi new file mode 100755 index 000000000..93fb289ca --- /dev/null +++ b/contrib/mkimage/mageia-urpmi @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# +# Needs to be run from Mageia 4 or greater for kernel support for docker. +# +# Mageia 4 does not have docker available in official repos, so please +# install and run the docker binary manually. +# +# Tested working versions are for Mageia 2 onwards (inc. cauldron). +# +set -e + +rootfsDir="$1" +shift + +optTemp=$(getopt --options '+v:,m:' --longoptions 'version:,mirror:' --name mageia-urpmi -- "$@") +eval set -- "$optTemp" +unset optTemp + +installversion= +mirror= +while true; do + case "$1" in + -v|--version) installversion="$2" ; shift 2 ;; + -m|--mirror) mirror="$2" ; shift 2 ;; + --) shift ; break ;; + esac +done + +if [ -z $installversion ]; then + # Attempt to match host version + if [ -r /etc/mageia-release ]; then + installversion="$(sed 's/^[^0-9\]*\([0-9.]\+\).*$/\1/' /etc/mageia-release)" + else + echo "Error: no version supplied and unable to detect host mageia version" + exit 1 + fi +fi + +if [ -z $mirror ]; then + # No mirror provided, default to mirrorlist + mirror="--mirrorlist https://mirrors.mageia.org/api/mageia.$installversion.x86_64.list" +fi + +( + set -x + urpmi.addmedia --distrib \ + $mirror \ + --urpmi-root "$rootfsDir" + urpmi basesystem-minimal urpmi \ + --auto \ + --no-suggests \ + --urpmi-root "$rootfsDir" \ + --root "$rootfsDir" +) + +"$(dirname "$BASH_SOURCE")/.febootstrap-minimize" "$rootfsDir" + +if [ -d "$rootfsDir/etc/sysconfig" ]; then + # allow networking init scripts inside the container to work without extra steps + echo 'NETWORKING=yes' > "$rootfsDir/etc/sysconfig/network" +fi diff --git a/daemon/container.go b/daemon/container.go index 2fd827eb9..5b4143868 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -53,7 +53,7 @@ type Container struct { Args []string Config *runconfig.Config - State State + State *State Image string NetworkSettings *NetworkSettings @@ -74,8 +74,7 @@ type Container struct { daemon *Daemon MountLabel, ProcessLabel string - waitLock chan struct{} - Volumes map[string]string + Volumes map[string]string // Store rw/ro in a separate structure to preserve reverse-compatibility on-disk. // Easier than migrating older container configs :) VolumesRW map[string]bool @@ -284,7 +283,6 @@ func (container *Container) Start() (err error) { if err := container.startLoggingToDisk(); err != nil { return err } - container.waitLock = make(chan struct{}) return container.waitForStart() } @@ -293,7 +291,7 @@ func (container *Container) Run() error { if err := container.Start(); err != nil { return err } - container.Wait() + container.State.WaitStop(-1 * time.Second) return nil } @@ -307,7 +305,7 @@ func (container *Container) Output() (output []byte, err error) { return nil, err } output, err = ioutil.ReadAll(pipe) - container.Wait() + container.State.WaitStop(-1 * time.Second) return output, err } @@ -467,6 +465,7 @@ func (container *Container) monitor(callback execdriver.StartCallback) error { if err != nil { utils.Errorf("Error running container: %s", err) } + container.State.SetStopped(exitCode) // Cleanup container.cleanup() @@ -475,28 +474,17 @@ func (container *Container) monitor(callback execdriver.StartCallback) error { if container.Config.OpenStdin { container.stdin, container.stdinPipe = io.Pipe() } - if container.daemon != nil && container.daemon.srv != nil { container.daemon.srv.LogEvent("die", container.ID, container.daemon.repositories.ImageName(container.Image)) } - - close(container.waitLock) - if container.daemon != nil && container.daemon.srv != nil && container.daemon.srv.IsRunning() { - container.State.SetStopped(exitCode) - - // FIXME: there is a race condition here which causes this to fail during the unit tests. - // If another goroutine was waiting for Wait() to return before removing the container's root - // from the filesystem... At this point it may already have done so. - // This is because State.setStopped() has already been called, and has caused Wait() - // to return. - // FIXME: why are we serializing running state to disk in the first place? - //log.Printf("%s: Failed to dump configuration to the disk: %s", container.ID, err) + // FIXME: here is race condition between two RUN instructions in Dockerfile + // because they share same runconfig and change image. Must be fixed + // in server/buildfile.go if err := container.ToDisk(); err != nil { - utils.Errorf("Error dumping container state to disk: %s\n", err) + utils.Errorf("Error dumping container %s state to disk: %s\n", container.ID, err) } } - return err } @@ -532,6 +520,7 @@ func (container *Container) cleanup() { } func (container *Container) KillSig(sig int) error { + utils.Debugf("Sending %d to %s", sig, container.ID) container.Lock() defer container.Unlock() @@ -577,9 +566,9 @@ func (container *Container) Kill() error { } // 2. Wait for the process to die, in last resort, try to kill the process directly - if err := container.WaitTimeout(10 * time.Second); err != nil { + if _, err := container.State.WaitStop(10 * time.Second); err != nil { // Ensure that we don't kill ourselves - if pid := container.State.Pid; pid != 0 { + if pid := container.State.GetPid(); pid != 0 { log.Printf("Container %s failed to exit within 10 seconds of kill - trying direct SIGKILL", utils.TruncateID(container.ID)) if err := syscall.Kill(pid, 9); err != nil { return err @@ -587,7 +576,7 @@ func (container *Container) Kill() error { } } - container.Wait() + container.State.WaitStop(-1 * time.Second) return nil } @@ -605,11 +594,11 @@ func (container *Container) Stop(seconds int) error { } // 2. Wait for the process to exit on its own - if err := container.WaitTimeout(time.Duration(seconds) * time.Second); err != nil { + if _, err := container.State.WaitStop(time.Duration(seconds) * time.Second); err != nil { log.Printf("Container %v failed to exit within %d seconds of SIGTERM - using the force", container.ID, seconds) // 3. If it doesn't, then send SIGKILL if err := container.Kill(); err != nil { - container.Wait() + container.State.WaitStop(-1 * time.Second) return err } } @@ -630,12 +619,6 @@ func (container *Container) Restart(seconds int) error { return container.Start() } -// Wait blocks until the container stops running, then returns its exit code. -func (container *Container) Wait() int { - <-container.waitLock - return container.State.GetExitCode() -} - func (container *Container) Resize(h, w int) error { return container.command.Terminal.Resize(h, w) } @@ -678,21 +661,6 @@ func (container *Container) Export() (archive.Archive, error) { nil } -func (container *Container) WaitTimeout(timeout time.Duration) error { - done := make(chan bool, 1) - go func() { - container.Wait() - done <- true - }() - - select { - case <-time.After(timeout): - return fmt.Errorf("Timed Out") - case <-done: - return nil - } -} - func (container *Container) Mount() error { return container.daemon.Mount(container) } @@ -813,7 +781,7 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) { basePath = path.Dir(basePath) } - archive, err := archive.TarFilter(basePath, &archive.TarOptions{ + archive, err := archive.TarWithOptions(basePath, &archive.TarOptions{ Compression: archive.Uncompressed, Includes: filter, }) @@ -1103,9 +1071,7 @@ func (container *Container) startLoggingToDisk() error { } func (container *Container) waitForStart() error { - callbackLock := make(chan struct{}) callback := func(command *execdriver.Command) { - container.State.SetRunning(command.Pid()) if command.Tty { // The callback is called after the process Start() // so we are in the parent process. In TTY mode, stdin/out/err is the PtySlace @@ -1117,16 +1083,23 @@ func (container *Container) waitForStart() error { if err := container.ToDisk(); err != nil { utils.Debugf("%s", err) } - close(callbackLock) + container.State.SetRunning(command.Pid()) } // We use a callback here instead of a goroutine and an chan for // syncronization purposes cErr := utils.Go(func() error { return container.monitor(callback) }) + waitStart := make(chan struct{}) + + go func() { + container.State.WaitRunning(-1 * time.Second) + close(waitStart) + }() + // Start should not return until the process is actually running select { - case <-callbackLock: + case <-waitStart: case err := <-cErr: return err } diff --git a/daemon/daemon.go b/daemon/daemon.go index c21ba3a38..23402d951 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -31,6 +31,7 @@ import ( "github.com/dotcloud/docker/pkg/namesgenerator" "github.com/dotcloud/docker/pkg/networkfs/resolvconf" "github.com/dotcloud/docker/pkg/sysinfo" + "github.com/dotcloud/docker/pkg/truncindex" "github.com/dotcloud/docker/runconfig" "github.com/dotcloud/docker/utils" ) @@ -87,7 +88,7 @@ type Daemon struct { containers *contStore graph *graph.Graph repositories *graph.TagStore - idIndex *utils.TruncIndex + idIndex *truncindex.TruncIndex sysInfo *sysinfo.SysInfo volumes *graph.Graph srv Server @@ -96,6 +97,7 @@ type Daemon struct { containerGraph *graphdb.Database driver graphdriver.Driver execDriver execdriver.Driver + Sockets []string } // Install installs daemon capabilities to eng. @@ -136,7 +138,7 @@ func (daemon *Daemon) containerRoot(id string) string { // Load reads the contents of a container from disk // This is typically done at startup. func (daemon *Daemon) load(id string) (*Container, error) { - container := &Container{root: daemon.containerRoot(id)} + container := &Container{root: daemon.containerRoot(id), State: NewState()} if err := container.FromDisk(); err != nil { return nil, err } @@ -180,11 +182,7 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool, con // don't update the Suffixarray if we're starting up // we'll waste time if we update it for every container - if updateSuffixarray { - daemon.idIndex.Add(container.ID) - } else { - daemon.idIndex.AddWithoutSuffixarrayUpdate(container.ID) - } + daemon.idIndex.Add(container.ID) // FIXME: if the container is supposed to be running but is not, auto restart it? // if so, then we need to restart monitor and init a new lock @@ -238,12 +236,6 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool, con } } } - } else { - // When the container is not running, we still initialize the waitLock - // chan and close it. Receiving on nil chan blocks whereas receiving on a - // closed chan does not. In this case we do not want to block. - container.waitLock = make(chan struct{}) - close(container.waitLock) } return nil } @@ -375,8 +367,6 @@ func (daemon *Daemon) restore() error { } } - daemon.idIndex.UpdateSuffixarray() - for _, container := range containersToStart { utils.Debugf("Starting container %d", container.ID) if err := container.Start(); err != nil { @@ -592,6 +582,7 @@ func (daemon *Daemon) newContainer(name string, config *runconfig.Config, img *i Name: name, Driver: daemon.driver.String(), ExecDriver: daemon.execDriver.Name(), + State: NewState(), } container.root = daemon.containerRoot(container.ID) @@ -629,8 +620,12 @@ func (daemon *Daemon) createRootfs(container *Container, img *image.Image) error // Commit creates a new filesystem image from the current state of a container. // The image can optionally be tagged into a repository -func (daemon *Daemon) Commit(container *Container, repository, tag, comment, author string, config *runconfig.Config) (*image.Image, error) { - // FIXME: freeze the container before copying it to avoid data corruption? +func (daemon *Daemon) Commit(container *Container, repository, tag, comment, author string, pause bool, config *runconfig.Config) (*image.Image, error) { + if pause { + container.Pause() + defer container.Unpause() + } + if err := container.Mount(); err != nil { return nil, err } @@ -841,7 +836,7 @@ func NewDaemonFromDirectory(config *daemonconfig.Config, eng *engine.Engine) (*D localCopy := path.Join(config.Root, "init", fmt.Sprintf("dockerinit-%s", dockerversion.VERSION)) sysInitPath := utils.DockerInitPath(localCopy) if sysInitPath == "" { - return nil, fmt.Errorf("Could not locate dockerinit: This usually means docker was built incorrectly. See http://docs.docker.io/en/latest/contributing/devenvironment for official build instructions.") + return nil, fmt.Errorf("Could not locate dockerinit: This usually means docker was built incorrectly. See http://docs.docker.com/contributing/devenvironment for official build instructions.") } if sysInitPath != localCopy { @@ -869,7 +864,7 @@ func NewDaemonFromDirectory(config *daemonconfig.Config, eng *engine.Engine) (*D containers: &contStore{s: make(map[string]*Container)}, graph: g, repositories: repositories, - idIndex: utils.NewTruncIndex([]string{}), + idIndex: truncindex.NewTruncIndex([]string{}), sysInfo: sysInfo, volumes: volumes, config: config, @@ -878,6 +873,7 @@ func NewDaemonFromDirectory(config *daemonconfig.Config, eng *engine.Engine) (*D sysInitPath: sysInitPath, execDriver: ed, eng: eng, + Sockets: config.Sockets, } if err := daemon.checkLocaldns(); err != nil { @@ -903,7 +899,7 @@ func (daemon *Daemon) shutdown() error { if err := c.KillSig(15); err != nil { utils.Debugf("kill 15 error for %s - %s", c.ID, err) } - c.Wait() + c.State.WaitStop(-1 * time.Second) utils.Debugf("container stopped %s", c.ID) }() } diff --git a/daemon/execdriver/MAINTAINERS b/daemon/execdriver/MAINTAINERS index 1e998f8ac..68a97d2fc 100644 --- a/daemon/execdriver/MAINTAINERS +++ b/daemon/execdriver/MAINTAINERS @@ -1 +1,2 @@ Michael Crosby (@crosbymichael) +Victor Vieux (@vieux) diff --git a/daemon/execdriver/lxc/lxc_init_linux.go b/daemon/execdriver/lxc/lxc_init_linux.go index 3b15d096a..1fd497e9a 100644 --- a/daemon/execdriver/lxc/lxc_init_linux.go +++ b/daemon/execdriver/lxc/lxc_init_linux.go @@ -29,7 +29,7 @@ func finalizeNamespace(args *execdriver.InitArgs) error { if !args.Privileged { // drop capabilities in bounding set before changing user - if err := capabilities.DropBoundingSet(container); err != nil { + if err := capabilities.DropBoundingSet(container.Capabilities); err != nil { return fmt.Errorf("drop bounding set %s", err) } @@ -49,7 +49,7 @@ func finalizeNamespace(args *execdriver.InitArgs) error { } // drop all other capabilities - if err := capabilities.DropCapabilities(container); err != nil { + if err := capabilities.DropCapabilities(container.Capabilities); err != nil { return fmt.Errorf("drop capabilities %s", err) } } diff --git a/daemon/execdriver/native/configuration/parse.go b/daemon/execdriver/native/configuration/parse.go index 77d4b297c..8fb1b452b 100644 --- a/daemon/execdriver/native/configuration/parse.go +++ b/daemon/execdriver/native/configuration/parse.go @@ -11,7 +11,7 @@ import ( "github.com/dotcloud/docker/pkg/units" ) -type Action func(*libcontainer.Container, interface{}, string) error +type Action func(*libcontainer.Config, interface{}, string) error var actions = map[string]Action{ "cap.add": addCap, // add a cap @@ -35,7 +35,7 @@ var actions = map[string]Action{ "fs.readonly": readonlyFs, // make the rootfs of the container read only } -func cpusetCpus(container *libcontainer.Container, context interface{}, value string) error { +func cpusetCpus(container *libcontainer.Config, context interface{}, value string) error { if container.Cgroups == nil { return fmt.Errorf("cannot set cgroups when they are disabled") } @@ -44,7 +44,7 @@ func cpusetCpus(container *libcontainer.Container, context interface{}, value st return nil } -func systemdSlice(container *libcontainer.Container, context interface{}, value string) error { +func systemdSlice(container *libcontainer.Config, context interface{}, value string) error { if container.Cgroups == nil { return fmt.Errorf("cannot set slice when cgroups are disabled") } @@ -53,12 +53,12 @@ func systemdSlice(container *libcontainer.Container, context interface{}, value return nil } -func apparmorProfile(container *libcontainer.Container, context interface{}, value string) error { - container.Context["apparmor_profile"] = value +func apparmorProfile(container *libcontainer.Config, context interface{}, value string) error { + container.AppArmorProfile = value return nil } -func cpuShares(container *libcontainer.Container, context interface{}, value string) error { +func cpuShares(container *libcontainer.Config, context interface{}, value string) error { if container.Cgroups == nil { return fmt.Errorf("cannot set cgroups when they are disabled") } @@ -70,7 +70,7 @@ func cpuShares(container *libcontainer.Container, context interface{}, value str return nil } -func memory(container *libcontainer.Container, context interface{}, value string) error { +func memory(container *libcontainer.Config, context interface{}, value string) error { if container.Cgroups == nil { return fmt.Errorf("cannot set cgroups when they are disabled") } @@ -83,7 +83,7 @@ func memory(container *libcontainer.Container, context interface{}, value string return nil } -func memoryReservation(container *libcontainer.Container, context interface{}, value string) error { +func memoryReservation(container *libcontainer.Config, context interface{}, value string) error { if container.Cgroups == nil { return fmt.Errorf("cannot set cgroups when they are disabled") } @@ -96,7 +96,7 @@ func memoryReservation(container *libcontainer.Container, context interface{}, v return nil } -func memorySwap(container *libcontainer.Container, context interface{}, value string) error { +func memorySwap(container *libcontainer.Config, context interface{}, value string) error { if container.Cgroups == nil { return fmt.Errorf("cannot set cgroups when they are disabled") } @@ -108,12 +108,12 @@ func memorySwap(container *libcontainer.Container, context interface{}, value st return nil } -func addCap(container *libcontainer.Container, context interface{}, value string) error { +func addCap(container *libcontainer.Config, context interface{}, value string) error { container.Capabilities = append(container.Capabilities, value) return nil } -func dropCap(container *libcontainer.Container, context interface{}, value string) error { +func dropCap(container *libcontainer.Config, context interface{}, value string) error { // If the capability is specified multiple times, remove all instances. for i, capability := range container.Capabilities { if capability == value { @@ -125,27 +125,27 @@ func dropCap(container *libcontainer.Container, context interface{}, value strin return nil } -func addNamespace(container *libcontainer.Container, context interface{}, value string) error { +func addNamespace(container *libcontainer.Config, context interface{}, value string) error { container.Namespaces[value] = true return nil } -func dropNamespace(container *libcontainer.Container, context interface{}, value string) error { +func dropNamespace(container *libcontainer.Config, context interface{}, value string) error { container.Namespaces[value] = false return nil } -func readonlyFs(container *libcontainer.Container, context interface{}, value string) error { +func readonlyFs(container *libcontainer.Config, context interface{}, value string) error { switch value { case "1", "true": - container.ReadonlyFs = true + container.MountConfig.ReadonlyFs = true default: - container.ReadonlyFs = false + container.MountConfig.ReadonlyFs = false } return nil } -func joinNetNamespace(container *libcontainer.Container, context interface{}, value string) error { +func joinNetNamespace(container *libcontainer.Config, context interface{}, value string) error { var ( running = context.(map[string]*exec.Cmd) cmd = running[value] @@ -154,28 +154,13 @@ func joinNetNamespace(container *libcontainer.Container, context interface{}, va if cmd == nil || cmd.Process == nil { return fmt.Errorf("%s is not a valid running container to join", value) } + nspath := filepath.Join("/proc", fmt.Sprint(cmd.Process.Pid), "ns", "net") container.Networks = append(container.Networks, &libcontainer.Network{ - Type: "netns", - Context: libcontainer.Context{ - "nspath": nspath, - }, + Type: "netns", + NsPath: nspath, }) - return nil -} -func vethMacAddress(container *libcontainer.Container, context interface{}, value string) error { - var veth *libcontainer.Network - for _, network := range container.Networks { - if network.Type == "veth" { - veth = network - break - } - } - if veth == nil { - return fmt.Errorf("not veth configured for container") - } - veth.Context["mac"] = value return nil } @@ -183,7 +168,7 @@ func vethMacAddress(container *libcontainer.Container, context interface{}, valu // container's default configuration. // // TODO: this can be moved to a general utils or parser in pkg -func ParseConfiguration(container *libcontainer.Container, running map[string]*exec.Cmd, opts []string) error { +func ParseConfiguration(container *libcontainer.Config, running map[string]*exec.Cmd, opts []string) error { for _, opt := range opts { kv := strings.SplitN(opt, "=", 2) if len(kv) < 2 { diff --git a/daemon/execdriver/native/configuration/parse_test.go b/daemon/execdriver/native/configuration/parse_test.go index c561f5e2d..0401d7b37 100644 --- a/daemon/execdriver/native/configuration/parse_test.go +++ b/daemon/execdriver/native/configuration/parse_test.go @@ -3,7 +3,7 @@ package configuration import ( "testing" - "github.com/docker/libcontainer" + "github.com/docker/libcontainer/security/capabilities" "github.com/dotcloud/docker/daemon/execdriver/native/template" ) @@ -25,14 +25,14 @@ func TestSetReadonlyRootFs(t *testing.T) { } ) - if container.ReadonlyFs { + if container.MountConfig.ReadonlyFs { t.Fatal("container should not have a readonly rootfs by default") } if err := ParseConfiguration(container, nil, opts); err != nil { t.Fatal(err) } - if !container.ReadonlyFs { + if !container.MountConfig.ReadonlyFs { t.Fatal("container should have a readonly rootfs") } } @@ -84,8 +84,9 @@ func TestAppArmorProfile(t *testing.T) { if err := ParseConfiguration(container, nil, opts); err != nil { t.Fatal(err) } - if expected := "koye-the-protector"; container.Context["apparmor_profile"] != expected { - t.Fatalf("expected profile %s got %s", expected, container.Context["apparmor_profile"]) + + if expected := "koye-the-protector"; container.AppArmorProfile != expected { + t.Fatalf("expected profile %s got %s", expected, container.AppArmorProfile) } } @@ -165,7 +166,7 @@ func TestDropCap(t *testing.T) { } ) // enabled all caps like in privileged mode - container.Capabilities = libcontainer.GetAllCapabilities() + container.Capabilities = capabilities.GetAllCapabilities() if err := ParseConfiguration(container, nil, opts); err != nil { t.Fatal(err) } diff --git a/daemon/execdriver/native/create.go b/daemon/execdriver/native/create.go index b19620514..f28507b04 100644 --- a/daemon/execdriver/native/create.go +++ b/daemon/execdriver/native/create.go @@ -9,6 +9,8 @@ import ( "github.com/docker/libcontainer" "github.com/docker/libcontainer/apparmor" "github.com/docker/libcontainer/devices" + "github.com/docker/libcontainer/mount" + "github.com/docker/libcontainer/security/capabilities" "github.com/dotcloud/docker/daemon/execdriver" "github.com/dotcloud/docker/daemon/execdriver/native/configuration" "github.com/dotcloud/docker/daemon/execdriver/native/template" @@ -16,7 +18,7 @@ import ( // createContainer populates and configures the container type with the // data provided by the execdriver.Command -func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Container, error) { +func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Config, error) { container := template.New() container.Hostname = getEnv("HOSTNAME", c.Env) @@ -26,65 +28,71 @@ func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Container container.Env = c.Env container.Cgroups.Name = c.ID container.Cgroups.AllowedDevices = c.AllowedDevices - container.DeviceNodes = c.AutoCreatedDevices + container.MountConfig.DeviceNodes = c.AutoCreatedDevices + // check to see if we are running in ramdisk to disable pivot root - container.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != "" - container.Context["restrictions"] = "true" + container.MountConfig.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != "" + container.RestrictSys = true if err := d.createNetwork(container, c); err != nil { return nil, err } + if c.Privileged { if err := d.setPrivileged(container); err != nil { return nil, err } } + if err := d.setupCgroups(container, c); err != nil { return nil, err } + if err := d.setupMounts(container, c); err != nil { return nil, err } + if err := d.setupLabels(container, c); err != nil { return nil, err } + cmds := make(map[string]*exec.Cmd) d.Lock() for k, v := range d.activeContainers { cmds[k] = v.cmd } d.Unlock() + if err := configuration.ParseConfiguration(container, cmds, c.Config["native"]); err != nil { return nil, err } + return container, nil } -func (d *driver) createNetwork(container *libcontainer.Container, c *execdriver.Command) error { +func (d *driver) createNetwork(container *libcontainer.Config, c *execdriver.Command) error { if c.Network.HostNetworking { container.Namespaces["NEWNET"] = false return nil } + container.Networks = []*libcontainer.Network{ { Mtu: c.Network.Mtu, Address: fmt.Sprintf("%s/%d", "127.0.0.1", 0), Gateway: "localhost", Type: "loopback", - Context: libcontainer.Context{}, }, } if c.Network.Interface != nil { vethNetwork := libcontainer.Network{ - Mtu: c.Network.Mtu, - Address: fmt.Sprintf("%s/%d", c.Network.Interface.IPAddress, c.Network.Interface.IPPrefixLen), - Gateway: c.Network.Interface.Gateway, - Type: "veth", - Context: libcontainer.Context{ - "prefix": "veth", - "bridge": c.Network.Interface.Bridge, - }, + Mtu: c.Network.Mtu, + Address: fmt.Sprintf("%s/%d", c.Network.Interface.IPAddress, c.Network.Interface.IPPrefixLen), + Gateway: c.Network.Interface.Gateway, + Type: "veth", + Bridge: c.Network.Interface.Bridge, + VethPrefix: "veth", } container.Networks = append(container.Networks, &vethNetwork) } @@ -93,6 +101,7 @@ func (d *driver) createNetwork(container *libcontainer.Container, c *execdriver. d.Lock() active := d.activeContainers[c.Network.ContainerID] d.Unlock() + if active == nil || active.cmd.Process == nil { return fmt.Errorf("%s is not a valid running container to join", c.Network.ContainerID) } @@ -100,34 +109,34 @@ func (d *driver) createNetwork(container *libcontainer.Container, c *execdriver. nspath := filepath.Join("/proc", fmt.Sprint(cmd.Process.Pid), "ns", "net") container.Networks = append(container.Networks, &libcontainer.Network{ - Type: "netns", - Context: libcontainer.Context{ - "nspath": nspath, - }, + Type: "netns", + NsPath: nspath, }) } + return nil } -func (d *driver) setPrivileged(container *libcontainer.Container) (err error) { - container.Capabilities = libcontainer.GetAllCapabilities() +func (d *driver) setPrivileged(container *libcontainer.Config) (err error) { + container.Capabilities = capabilities.GetAllCapabilities() container.Cgroups.AllowAllDevices = true hostDeviceNodes, err := devices.GetHostDeviceNodes() if err != nil { return err } - container.DeviceNodes = hostDeviceNodes + container.MountConfig.DeviceNodes = hostDeviceNodes - delete(container.Context, "restrictions") + container.RestrictSys = false if apparmor.IsEnabled() { - container.Context["apparmor_profile"] = "unconfined" + container.AppArmorProfile = "unconfined" } + return nil } -func (d *driver) setupCgroups(container *libcontainer.Container, c *execdriver.Command) error { +func (d *driver) setupCgroups(container *libcontainer.Config, c *execdriver.Command) error { if c.Resources != nil { container.Cgroups.CpuShares = c.Resources.CpuShares container.Cgroups.Memory = c.Resources.Memory @@ -135,12 +144,13 @@ func (d *driver) setupCgroups(container *libcontainer.Container, c *execdriver.C container.Cgroups.MemorySwap = c.Resources.MemorySwap container.Cgroups.CpusetCpus = c.Resources.Cpuset } + return nil } -func (d *driver) setupMounts(container *libcontainer.Container, c *execdriver.Command) error { +func (d *driver) setupMounts(container *libcontainer.Config, c *execdriver.Command) error { for _, m := range c.Mounts { - container.Mounts = append(container.Mounts, libcontainer.Mount{ + container.MountConfig.Mounts = append(container.MountConfig.Mounts, mount.Mount{ Type: "bind", Source: m.Source, Destination: m.Destination, @@ -148,11 +158,13 @@ func (d *driver) setupMounts(container *libcontainer.Container, c *execdriver.Co Private: m.Private, }) } + return nil } -func (d *driver) setupLabels(container *libcontainer.Container, c *execdriver.Command) error { - container.Context["process_label"] = c.Config["process_label"][0] - container.Context["mount_label"] = c.Config["mount_label"][0] +func (d *driver) setupLabels(container *libcontainer.Config, c *execdriver.Command) error { + container.ProcessLabel = c.Config["process_label"][0] + container.MountConfig.MountLabel = c.Config["mount_label"][0] + return nil } diff --git a/daemon/execdriver/native/driver.go b/daemon/execdriver/native/driver.go index 840d9fbc4..90333703c 100644 --- a/daemon/execdriver/native/driver.go +++ b/daemon/execdriver/native/driver.go @@ -27,7 +27,7 @@ const ( func init() { execdriver.RegisterInitFunc(DriverName, func(args *execdriver.InitArgs) error { - var container *libcontainer.Container + var container *libcontainer.Config f, err := os.Open(filepath.Join(args.Root, "container.json")) if err != nil { return err @@ -54,7 +54,7 @@ func init() { } type activeContainer struct { - container *libcontainer.Container + container *libcontainer.Config cmd *exec.Cmd } @@ -83,7 +83,7 @@ func NewDriver(root, initPath string) (*driver, error) { } func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) { - // take the Command and populate the libcontainer.Container from it + // take the Command and populate the libcontainer.Config from it container, err := d.createContainer(c) if err != nil { return -1, err @@ -110,7 +110,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba term := getTerminal(c, pipes) - return namespaces.Exec(container, term, c.Rootfs, dataPath, args, func(container *libcontainer.Container, console, rootfs, dataPath, init string, child *os.File, args []string) *exec.Cmd { + return namespaces.Exec(container, term, c.Rootfs, dataPath, args, func(container *libcontainer.Config, console, rootfs, dataPath, init string, child *os.File, args []string) *exec.Cmd { // we need to join the rootfs because namespaces will setup the rootfs and chroot initPath := filepath.Join(c.Rootfs, c.InitPath) @@ -171,21 +171,30 @@ func (d *driver) Unpause(c *execdriver.Command) error { func (d *driver) Terminate(p *execdriver.Command) error { // lets check the start time for the process - started, err := d.readStartTime(p) + state, err := libcontainer.GetState(filepath.Join(d.root, p.ID)) if err != nil { - // if we don't have the data on disk then we can assume the process is gone - // because this is only removed after we know the process has stopped - if os.IsNotExist(err) { - return nil + if !os.IsNotExist(err) { + return err } - return err + // TODO: Remove this part for version 1.2.0 + // This is added only to ensure smooth upgrades from pre 1.1.0 to 1.1.0 + data, err := ioutil.ReadFile(filepath.Join(d.root, p.ID, "start")) + if err != nil { + // if we don't have the data on disk then we can assume the process is gone + // because this is only removed after we know the process has stopped + if os.IsNotExist(err) { + return nil + } + return err + } + state = &libcontainer.State{InitStartTime: string(data)} } currentStartTime, err := system.GetProcessStartTime(p.Process.Pid) if err != nil { return err } - if started == currentStartTime { + if state.InitStartTime == currentStartTime { err = syscall.Kill(p.Process.Pid, 9) syscall.Wait4(p.Process.Pid, nil, 0, nil) } @@ -194,14 +203,6 @@ func (d *driver) Terminate(p *execdriver.Command) error { } -func (d *driver) readStartTime(p *execdriver.Command) (string, error) { - data, err := ioutil.ReadFile(filepath.Join(d.root, p.ID, "start")) - if err != nil { - return "", err - } - return string(data), nil -} - func (d *driver) Info(id string) execdriver.Info { return &info{ ID: id, @@ -229,7 +230,7 @@ func (d *driver) GetPidsForContainer(id string) ([]int, error) { return fs.GetPids(c) } -func (d *driver) writeContainerFile(container *libcontainer.Container, id string) error { +func (d *driver) writeContainerFile(container *libcontainer.Config, id string) error { data, err := json.Marshal(container) if err != nil { return err diff --git a/daemon/execdriver/native/info.go b/daemon/execdriver/native/info.go index aef2f85c6..c34d0297b 100644 --- a/daemon/execdriver/native/info.go +++ b/daemon/execdriver/native/info.go @@ -3,6 +3,8 @@ package native import ( "os" "path/filepath" + + "github.com/docker/libcontainer" ) type info struct { @@ -14,6 +16,11 @@ type info struct { // pid file for a container. If the file exists then the // container is currently running func (i *info) IsRunning() bool { + if _, err := libcontainer.GetState(filepath.Join(i.driver.root, i.ID)); err == nil { + return true + } + // TODO: Remove this part for version 1.2.0 + // This is added only to ensure smooth upgrades from pre 1.1.0 to 1.1.0 if _, err := os.Stat(filepath.Join(i.driver.root, i.ID, "pid")); err == nil { return true } diff --git a/daemon/execdriver/native/template/default_template.go b/daemon/execdriver/native/template/default_template.go index e2f52f444..d0894a0c9 100644 --- a/daemon/execdriver/native/template/default_template.go +++ b/daemon/execdriver/native/template/default_template.go @@ -7,8 +7,8 @@ import ( ) // New returns the docker default configuration for libcontainer -func New() *libcontainer.Container { - container := &libcontainer.Container{ +func New() *libcontainer.Config { + container := &libcontainer.Config{ Capabilities: []string{ "CHOWN", "DAC_OVERRIDE", @@ -34,10 +34,12 @@ func New() *libcontainer.Container { Parent: "docker", AllowAllDevices: false, }, - Context: libcontainer.Context{}, + MountConfig: &libcontainer.MountConfig{}, } + if apparmor.IsEnabled() { - container.Context["apparmor_profile"] = "docker-default" + container.AppArmorProfile = "docker-default" } + return container } diff --git a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go index eb8ff77cd..0206b92e1 100644 --- a/daemon/graphdriver/aufs/aufs.go +++ b/daemon/graphdriver/aufs/aufs.go @@ -295,7 +295,7 @@ func (a *Driver) Put(id string) { // Returns an archive of the contents for the id func (a *Driver) Diff(id string) (archive.Archive, error) { - return archive.TarFilter(path.Join(a.rootPath(), "diff", id), &archive.TarOptions{ + return archive.TarWithOptions(path.Join(a.rootPath(), "diff", id), &archive.TarOptions{ Compression: archive.Uncompressed, }) } diff --git a/daemon/graphdriver/vfs/driver.go b/daemon/graphdriver/vfs/driver.go index 992af0e14..7eaa22461 100644 --- a/daemon/graphdriver/vfs/driver.go +++ b/daemon/graphdriver/vfs/driver.go @@ -1,6 +1,7 @@ package vfs import ( + "bytes" "fmt" "github.com/dotcloud/docker/daemon/graphdriver" "os" @@ -35,8 +36,24 @@ func (d *Driver) Cleanup() error { return nil } +func isGNUcoreutils() bool { + if stdout, err := exec.Command("cp", "--version").Output(); err == nil { + return bytes.Contains(stdout, []byte("GNU coreutils")) + } + + return false +} + func copyDir(src, dst string) error { - if output, err := exec.Command("cp", "-aT", "--reflink=auto", src, dst).CombinedOutput(); err != nil { + argv := make([]string, 0, 4) + + if isGNUcoreutils() { + argv = append(argv, "-aT", "--reflink=auto", src, dst) + } else { + argv = append(argv, "-a", src+"/.", dst+"/.") + } + + if output, err := exec.Command("cp", argv...).CombinedOutput(); err != nil { return fmt.Errorf("Error VFS copying directory: %s (%s)", err, output) } return nil diff --git a/daemon/inspect.go b/daemon/inspect.go index af6d4520f..b93aec505 100644 --- a/daemon/inspect.go +++ b/daemon/inspect.go @@ -2,6 +2,7 @@ package daemon import ( "encoding/json" + "fmt" "github.com/dotcloud/docker/engine" "github.com/dotcloud/docker/runconfig" @@ -15,7 +16,7 @@ func (daemon *Daemon) ContainerInspect(job *engine.Job) engine.Status { if container := daemon.Get(name); container != nil { container.Lock() defer container.Unlock() - if job.GetenvBool("dirty") { + if job.GetenvBool("raw") { b, err := json.Marshal(&struct { *Container HostConfig *runconfig.HostConfig @@ -46,7 +47,16 @@ func (daemon *Daemon) ContainerInspect(job *engine.Job) engine.Status { out.Set("ProcessLabel", container.ProcessLabel) out.SetJson("Volumes", container.Volumes) out.SetJson("VolumesRW", container.VolumesRW) + + if children, err := daemon.Children(container.Name); err == nil { + for linkAlias, child := range children { + container.hostConfig.Links = append(container.hostConfig.Links, fmt.Sprintf("%s:%s", child.Name, linkAlias)) + } + } + out.SetJson("HostConfig", container.hostConfig) + + container.hostConfig.Links = nil if _, err := out.WriteTo(job.Stdout); err != nil { return job.Error(err) } diff --git a/daemon/networkdriver/bridge/driver.go b/daemon/networkdriver/bridge/driver.go index 8c5db9f84..a843da049 100644 --- a/daemon/networkdriver/bridge/driver.go +++ b/daemon/networkdriver/bridge/driver.go @@ -20,7 +20,8 @@ import ( ) const ( - DefaultNetworkBridge = "docker0" + DefaultNetworkBridge = "docker0" + MaxAllocatedPortAttempts = 10 ) // Network interface represents the networking stack of a container @@ -354,9 +355,6 @@ func Release(job *engine.Job) engine.Status { var ( id = job.Args[0] containerInterface = currentInterfaces.Get(id) - ip net.IP - port int - proto string ) if containerInterface == nil { @@ -367,22 +365,6 @@ func Release(job *engine.Job) engine.Status { if err := portmapper.Unmap(nat); err != nil { log.Printf("Unable to unmap port %s: %s", nat, err) } - - // this is host mappings - switch a := nat.(type) { - case *net.TCPAddr: - proto = "tcp" - ip = a.IP - port = a.Port - case *net.UDPAddr: - proto = "udp" - ip = a.IP - port = a.Port - } - - if err := portallocator.ReleasePort(ip, proto, port); err != nil { - log.Printf("Unable to release port %s", nat) - } } if err := ipallocator.ReleaseIP(bridgeNetwork, &containerInterface.IP); err != nil { @@ -399,7 +381,7 @@ func AllocatePort(job *engine.Job) engine.Status { ip = defaultBindingIP id = job.Args[0] hostIP = job.Getenv("HostIP") - origHostPort = job.GetenvInt("HostPort") + hostPort = job.GetenvInt("HostPort") containerPort = job.GetenvInt("ContainerPort") proto = job.Getenv("Proto") network = currentInterfaces.Get(id) @@ -409,39 +391,46 @@ func AllocatePort(job *engine.Job) engine.Status { ip = net.ParseIP(hostIP) } - var ( - hostPort int - container net.Addr - host net.Addr - ) + // host ip, proto, and host port + var container net.Addr + switch proto { + case "tcp": + container = &net.TCPAddr{IP: network.IP, Port: containerPort} + case "udp": + container = &net.UDPAddr{IP: network.IP, Port: containerPort} + default: + return job.Errorf("unsupported address type %s", proto) + } - /* - Try up to 10 times to get a port that's not already allocated. + // + // Try up to 10 times to get a port that's not already allocated. + // + // In the event of failure to bind, return the error that portmapper.Map + // yields. + // - In the event of failure to bind, return the error that portmapper.Map - yields. - */ - for i := 0; i < 10; i++ { - // host ip, proto, and host port - hostPort, err = portallocator.RequestPort(ip, proto, origHostPort) - - if err != nil { - return job.Error(err) - } - - if proto == "tcp" { - host = &net.TCPAddr{IP: ip, Port: hostPort} - container = &net.TCPAddr{IP: network.IP, Port: containerPort} - } else { - host = &net.UDPAddr{IP: ip, Port: hostPort} - container = &net.UDPAddr{IP: network.IP, Port: containerPort} - } - - if err = portmapper.Map(container, ip, hostPort); err == nil { + var host net.Addr + for i := 0; i < MaxAllocatedPortAttempts; i++ { + if host, err = portmapper.Map(container, ip, hostPort); err == nil { break } - job.Logf("Failed to bind %s:%d for container address %s:%d. Trying another port.", ip.String(), hostPort, network.IP.String(), containerPort) + switch allocerr := err.(type) { + case portallocator.ErrPortAlreadyAllocated: + // There is no point in immediately retrying to map an explicitly + // chosen port. + if hostPort != 0 { + job.Logf("Failed to bind %s for container address %s: %s", allocerr.IPPort(), container.String(), allocerr.Error()) + break + } + + // Automatically chosen 'free' port failed to bind: move on the next. + job.Logf("Failed to bind %s for container address %s. Trying another port.", allocerr.IPPort(), container.String()) + default: + // some other error during mapping + job.Logf("Received an unexpected error during port allocation: %s", err.Error()) + break + } } if err != nil { @@ -451,12 +440,18 @@ func AllocatePort(job *engine.Job) engine.Status { network.PortMappings = append(network.PortMappings, host) out := engine.Env{} - out.Set("HostIP", ip.String()) - out.SetInt("HostPort", hostPort) - + switch netAddr := host.(type) { + case *net.TCPAddr: + out.Set("HostIP", netAddr.IP.String()) + out.SetInt("HostPort", netAddr.Port) + case *net.UDPAddr: + out.Set("HostIP", netAddr.IP.String()) + out.SetInt("HostPort", netAddr.Port) + } if _, err := out.WriteTo(job.Stdout); err != nil { return job.Error(err) } + return engine.StatusOK } diff --git a/daemon/networkdriver/bridge/driver_test.go b/daemon/networkdriver/bridge/driver_test.go new file mode 100644 index 000000000..f8ddd4c64 --- /dev/null +++ b/daemon/networkdriver/bridge/driver_test.go @@ -0,0 +1,106 @@ +package bridge + +import ( + "fmt" + "net" + "strconv" + "testing" + + "github.com/dotcloud/docker/engine" +) + +func findFreePort(t *testing.T) int { + l, err := net.Listen("tcp", ":0") + if err != nil { + t.Fatal("Failed to find a free port") + } + defer l.Close() + + result, err := net.ResolveTCPAddr("tcp", l.Addr().String()) + if err != nil { + t.Fatal("Failed to resolve address to identify free port") + } + return result.Port +} + +func newPortAllocationJob(eng *engine.Engine, port int) (job *engine.Job) { + strPort := strconv.Itoa(port) + + job = eng.Job("allocate_port", "container_id") + job.Setenv("HostIP", "127.0.0.1") + job.Setenv("HostPort", strPort) + job.Setenv("Proto", "tcp") + job.Setenv("ContainerPort", strPort) + return +} + +func TestAllocatePortDetection(t *testing.T) { + eng := engine.New() + eng.Logging = false + + freePort := findFreePort(t) + + // Init driver + job := eng.Job("initdriver") + if res := InitDriver(job); res != engine.StatusOK { + t.Fatal("Failed to initialize network driver") + } + + // Allocate interface + job = eng.Job("allocate_interface", "container_id") + if res := Allocate(job); res != engine.StatusOK { + t.Fatal("Failed to allocate network interface") + } + + // Allocate same port twice, expect failure on second call + job = newPortAllocationJob(eng, freePort) + if res := AllocatePort(job); res != engine.StatusOK { + t.Fatal("Failed to find a free port to allocate") + } + if res := AllocatePort(job); res == engine.StatusOK { + t.Fatal("Duplicate port allocation granted by AllocatePort") + } +} + +func TestAllocatePortReclaim(t *testing.T) { + eng := engine.New() + eng.Logging = false + + freePort := findFreePort(t) + + // Init driver + job := eng.Job("initdriver") + if res := InitDriver(job); res != engine.StatusOK { + t.Fatal("Failed to initialize network driver") + } + + // Allocate interface + job = eng.Job("allocate_interface", "container_id") + if res := Allocate(job); res != engine.StatusOK { + t.Fatal("Failed to allocate network interface") + } + + // Occupy port + listenAddr := fmt.Sprintf(":%d", freePort) + tcpListenAddr, err := net.ResolveTCPAddr("tcp", listenAddr) + if err != nil { + t.Fatalf("Failed to resolve TCP address '%s'", listenAddr) + } + + l, err := net.ListenTCP("tcp", tcpListenAddr) + if err != nil { + t.Fatalf("Fail to listen on port %d", freePort) + } + + // Allocate port, expect failure + job = newPortAllocationJob(eng, freePort) + if res := AllocatePort(job); res == engine.StatusOK { + t.Fatal("Successfully allocated currently used port") + } + + // Reclaim port, retry allocation + l.Close() + if res := AllocatePort(job); res != engine.StatusOK { + t.Fatal("Failed to allocate previously reclaimed port") + } +} diff --git a/daemon/networkdriver/portallocator/portallocator.go b/daemon/networkdriver/portallocator/portallocator.go index 251ab9447..c722ba98b 100644 --- a/daemon/networkdriver/portallocator/portallocator.go +++ b/daemon/networkdriver/portallocator/portallocator.go @@ -2,13 +2,18 @@ package portallocator import ( "errors" + "fmt" "net" "sync" ) +type portMap struct { + p map[int]struct{} + last int +} + type ( - portMap map[int]bool - protocolMap map[string]portMap + protocolMap map[string]*portMap ipMapping map[string]protocolMap ) @@ -18,9 +23,8 @@ const ( ) var ( - ErrAllPortsAllocated = errors.New("all ports are allocated") - ErrPortAlreadyAllocated = errors.New("port has already been allocated") - ErrUnknownProtocol = errors.New("unknown protocol") + ErrAllPortsAllocated = errors.New("all ports are allocated") + ErrUnknownProtocol = errors.New("unknown protocol") ) var ( @@ -30,6 +34,34 @@ var ( globalMap = ipMapping{} ) +type ErrPortAlreadyAllocated struct { + ip string + port int +} + +func NewErrPortAlreadyAllocated(ip string, port int) ErrPortAlreadyAllocated { + return ErrPortAlreadyAllocated{ + ip: ip, + port: port, + } +} + +func (e ErrPortAlreadyAllocated) IP() string { + return e.ip +} + +func (e ErrPortAlreadyAllocated) Port() int { + return e.port +} + +func (e ErrPortAlreadyAllocated) IPPort() string { + return fmt.Sprintf("%s:%d", e.ip, e.port) +} + +func (e ErrPortAlreadyAllocated) Error() string { + return fmt.Sprintf("Bind for %s:%d failed: port is already allocated", e.ip, e.port) +} + func RequestPort(ip net.IP, proto string, port int) (int, error) { mutex.Lock() defer mutex.Unlock() @@ -43,11 +75,11 @@ func RequestPort(ip net.IP, proto string, port int) (int, error) { mapping := getOrCreate(ip) if port > 0 { - if !mapping[proto][port] { - mapping[proto][port] = true + if _, ok := mapping[proto].p[port]; !ok { + mapping[proto].p[port] = struct{}{} return port, nil } else { - return 0, ErrPortAlreadyAllocated + return 0, NewErrPortAlreadyAllocated(ip.String(), port) } } else { port, err := findPort(ip, proto) @@ -66,8 +98,8 @@ func ReleasePort(ip net.IP, proto string, port int) error { ip = getDefault(ip) - mapping := getOrCreate(ip) - delete(mapping[proto], port) + mapping := getOrCreate(ip)[proto] + delete(mapping.p, port) return nil } @@ -86,8 +118,8 @@ func getOrCreate(ip net.IP) protocolMap { if _, ok := globalMap[ipstr]; !ok { globalMap[ipstr] = protocolMap{ - "tcp": portMap{}, - "udp": portMap{}, + "tcp": &portMap{p: map[int]struct{}{}, last: 0}, + "udp": &portMap{p: map[int]struct{}{}, last: 0}, } } @@ -95,21 +127,28 @@ func getOrCreate(ip net.IP) protocolMap { } func findPort(ip net.IP, proto string) (int, error) { - port := BeginPortRange + mapping := getOrCreate(ip)[proto] - mapping := getOrCreate(ip) - - for mapping[proto][port] { - port++ - - if port > EndPortRange { - return 0, ErrAllPortsAllocated - } + if mapping.last == 0 { + mapping.p[BeginPortRange] = struct{}{} + mapping.last = BeginPortRange + return BeginPortRange, nil } - mapping[proto][port] = true + for port := mapping.last + 1; port != mapping.last; port++ { + if port > EndPortRange { + port = BeginPortRange + } - return port, nil + if _, ok := mapping.p[port]; !ok { + mapping.p[port] = struct{}{} + mapping.last = port + return port, nil + } + + } + + return 0, ErrAllPortsAllocated } func getDefault(ip net.IP) net.IP { diff --git a/daemon/networkdriver/portallocator/portallocator_test.go b/daemon/networkdriver/portallocator/portallocator_test.go index 5a4765ddd..9869c332e 100644 --- a/daemon/networkdriver/portallocator/portallocator_test.go +++ b/daemon/networkdriver/portallocator/portallocator_test.go @@ -83,8 +83,11 @@ func TestReleaseUnreadledPort(t *testing.T) { } port, err = RequestPort(defaultIP, "tcp", 5000) - if err != ErrPortAlreadyAllocated { - t.Fatalf("Expected error %s got %s", ErrPortAlreadyAllocated, err) + + switch err.(type) { + case ErrPortAlreadyAllocated: + default: + t.Fatalf("Expected port allocation error got %s", err) } } diff --git a/daemon/networkdriver/portmapper/mapper.go b/daemon/networkdriver/portmapper/mapper.go index e29959a24..1bd332271 100644 --- a/daemon/networkdriver/portmapper/mapper.go +++ b/daemon/networkdriver/portmapper/mapper.go @@ -3,10 +3,12 @@ package portmapper import ( "errors" "fmt" - "github.com/dotcloud/docker/pkg/iptables" - "github.com/dotcloud/docker/pkg/proxy" "net" "sync" + + "github.com/dotcloud/docker/daemon/networkdriver/portallocator" + "github.com/dotcloud/docker/pkg/iptables" + "github.com/dotcloud/docker/pkg/proxy" ) type mapping struct { @@ -35,43 +37,66 @@ func SetIptablesChain(c *iptables.Chain) { chain = c } -func Map(container net.Addr, hostIP net.IP, hostPort int) error { +func Map(container net.Addr, hostIP net.IP, hostPort int) (net.Addr, error) { lock.Lock() defer lock.Unlock() - var m *mapping + var ( + m *mapping + err error + proto string + allocatedHostPort int + ) + + // release the port on any error during return. + defer func() { + if err != nil { + portallocator.ReleasePort(hostIP, proto, allocatedHostPort) + } + }() + switch container.(type) { case *net.TCPAddr: + proto = "tcp" + if allocatedHostPort, err = portallocator.RequestPort(hostIP, proto, hostPort); err != nil { + return nil, err + } m = &mapping{ - proto: "tcp", - host: &net.TCPAddr{IP: hostIP, Port: hostPort}, + proto: proto, + host: &net.TCPAddr{IP: hostIP, Port: allocatedHostPort}, container: container, } case *net.UDPAddr: + proto = "udp" + if allocatedHostPort, err = portallocator.RequestPort(hostIP, proto, hostPort); err != nil { + return nil, err + } m = &mapping{ - proto: "udp", - host: &net.UDPAddr{IP: hostIP, Port: hostPort}, + proto: proto, + host: &net.UDPAddr{IP: hostIP, Port: allocatedHostPort}, container: container, } default: - return ErrUnknownBackendAddressType + err = ErrUnknownBackendAddressType + return nil, err } key := getKey(m.host) if _, exists := currentMappings[key]; exists { - return ErrPortMappedForIP + err = ErrPortMappedForIP + return nil, err } containerIP, containerPort := getIPAndPort(m.container) - if err := forward(iptables.Add, m.proto, hostIP, hostPort, containerIP.String(), containerPort); err != nil { - return err + if err := forward(iptables.Add, m.proto, hostIP, allocatedHostPort, containerIP.String(), containerPort); err != nil { + return nil, err } p, err := newProxy(m.host, m.container) if err != nil { - // need to undo the iptables rules before we reutrn - forward(iptables.Delete, m.proto, hostIP, hostPort, containerIP.String(), containerPort) - return err + // need to undo the iptables rules before we return + forward(iptables.Delete, m.proto, hostIP, allocatedHostPort, containerIP.String(), containerPort) + return nil, err } m.userlandProxy = p @@ -79,7 +104,7 @@ func Map(container net.Addr, hostIP net.IP, hostPort int) error { go p.Run() - return nil + return m.host, nil } func Unmap(host net.Addr) error { @@ -100,6 +125,18 @@ func Unmap(host net.Addr) error { if err := forward(iptables.Delete, data.proto, hostIP, hostPort, containerIP.String(), containerPort); err != nil { return err } + + switch a := host.(type) { + case *net.TCPAddr: + if err := portallocator.ReleasePort(a.IP, "tcp", a.Port); err != nil { + return err + } + case *net.UDPAddr: + if err := portallocator.ReleasePort(a.IP, "udp", a.Port); err != nil { + return err + } + } + return nil } diff --git a/daemon/networkdriver/portmapper/mapper_test.go b/daemon/networkdriver/portmapper/mapper_test.go index 4c09f3c65..6affdc544 100644 --- a/daemon/networkdriver/portmapper/mapper_test.go +++ b/daemon/networkdriver/portmapper/mapper_test.go @@ -1,6 +1,7 @@ package portmapper import ( + "github.com/dotcloud/docker/daemon/networkdriver/portallocator" "github.com/dotcloud/docker/pkg/iptables" "github.com/dotcloud/docker/pkg/proxy" "net" @@ -44,19 +45,26 @@ func TestMapPorts(t *testing.T) { srcAddr1 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")} srcAddr2 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.2")} - if err := Map(srcAddr1, dstIp1, 80); err != nil { + addrEqual := func(addr1, addr2 net.Addr) bool { + return (addr1.Network() == addr2.Network()) && (addr1.String() == addr2.String()) + } + + if host, err := Map(srcAddr1, dstIp1, 80); err != nil { t.Fatalf("Failed to allocate port: %s", err) + } else if !addrEqual(dstAddr1, host) { + t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s", + dstAddr1.String(), dstAddr1.Network(), host.String(), host.Network()) } - if Map(srcAddr1, dstIp1, 80) == nil { + if _, err := Map(srcAddr1, dstIp1, 80); err == nil { t.Fatalf("Port is in use - mapping should have failed") } - if Map(srcAddr2, dstIp1, 80) == nil { + if _, err := Map(srcAddr2, dstIp1, 80); err == nil { t.Fatalf("Port is in use - mapping should have failed") } - if err := Map(srcAddr2, dstIp2, 80); err != nil { + if _, err := Map(srcAddr2, dstIp2, 80); err != nil { t.Fatalf("Failed to allocate port: %s", err) } @@ -105,3 +113,40 @@ func TestGetUDPIPAndPort(t *testing.T) { t.Fatalf("expected port %d got %d", ep, port) } } + +func TestMapAllPortsSingleInterface(t *testing.T) { + dstIp1 := net.ParseIP("0.0.0.0") + srcAddr1 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")} + + hosts := []net.Addr{} + var host net.Addr + var err error + + defer func() { + for _, val := range hosts { + Unmap(val) + } + }() + + for i := 0; i < 10; i++ { + for i := portallocator.BeginPortRange; i < portallocator.EndPortRange; i++ { + if host, err = Map(srcAddr1, dstIp1, 0); err != nil { + t.Fatal(err) + } + + hosts = append(hosts, host) + } + + if _, err := Map(srcAddr1, dstIp1, portallocator.BeginPortRange); err == nil { + t.Fatal("Port %d should be bound but is not", portallocator.BeginPortRange) + } + + for _, val := range hosts { + if err := Unmap(val); err != nil { + t.Fatal(err) + } + } + + hosts = []net.Addr{} + } +} diff --git a/daemon/state.go b/daemon/state.go index 7ee8fc48c..3f904d782 100644 --- a/daemon/state.go +++ b/daemon/state.go @@ -16,6 +16,13 @@ type State struct { ExitCode int StartedAt time.Time FinishedAt time.Time + waitChan chan struct{} +} + +func NewState() *State { + return &State{ + waitChan: make(chan struct{}), + } } // String returns a human-readable description of the state @@ -35,56 +42,118 @@ func (s *State) String() string { return fmt.Sprintf("Exited (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt))) } +func wait(waitChan <-chan struct{}, timeout time.Duration) error { + if timeout < 0 { + <-waitChan + return nil + } + select { + case <-time.After(timeout): + return fmt.Errorf("Timed out: %v", timeout) + case <-waitChan: + return nil + } +} + +// WaitRunning waits until state is running. If state already running it returns +// immediatly. If you want wait forever you must supply negative timeout. +// Returns pid, that was passed to SetRunning +func (s *State) WaitRunning(timeout time.Duration) (int, error) { + s.RLock() + if s.IsRunning() { + pid := s.Pid + s.RUnlock() + return pid, nil + } + waitChan := s.waitChan + s.RUnlock() + if err := wait(waitChan, timeout); err != nil { + return -1, err + } + return s.GetPid(), nil +} + +// WaitStop waits until state is stopped. If state already stopped it returns +// immediatly. If you want wait forever you must supply negative timeout. +// Returns exit code, that was passed to SetStopped +func (s *State) WaitStop(timeout time.Duration) (int, error) { + s.RLock() + if !s.Running { + exitCode := s.ExitCode + s.RUnlock() + return exitCode, nil + } + waitChan := s.waitChan + s.RUnlock() + if err := wait(waitChan, timeout); err != nil { + return -1, err + } + return s.GetExitCode(), nil +} + func (s *State) IsRunning() bool { s.RLock() - defer s.RUnlock() + res := s.Running + s.RUnlock() + return res +} - return s.Running +func (s *State) GetPid() int { + s.RLock() + res := s.Pid + s.RUnlock() + return res } func (s *State) GetExitCode() int { s.RLock() - defer s.RUnlock() - - return s.ExitCode + res := s.ExitCode + s.RUnlock() + return res } func (s *State) SetRunning(pid int) { s.Lock() - defer s.Unlock() - - s.Running = true - s.Paused = false - s.ExitCode = 0 - s.Pid = pid - s.StartedAt = time.Now().UTC() + if !s.Running { + s.Running = true + s.Paused = false + s.ExitCode = 0 + s.Pid = pid + s.StartedAt = time.Now().UTC() + close(s.waitChan) // fire waiters for start + s.waitChan = make(chan struct{}) + } + s.Unlock() } func (s *State) SetStopped(exitCode int) { s.Lock() - defer s.Unlock() - - s.Running = false - s.Pid = 0 - s.FinishedAt = time.Now().UTC() - s.ExitCode = exitCode + if s.Running { + s.Running = false + s.Pid = 0 + s.FinishedAt = time.Now().UTC() + s.ExitCode = exitCode + close(s.waitChan) // fire waiters for stop + s.waitChan = make(chan struct{}) + } + s.Unlock() } func (s *State) SetPaused() { s.Lock() - defer s.Unlock() s.Paused = true + s.Unlock() } func (s *State) SetUnpaused() { s.Lock() - defer s.Unlock() s.Paused = false + s.Unlock() } func (s *State) IsPaused() bool { s.RLock() - defer s.RUnlock() - - return s.Paused + res := s.Paused + s.RUnlock() + return res } diff --git a/daemon/state_test.go b/daemon/state_test.go new file mode 100644 index 000000000..7b02f3aea --- /dev/null +++ b/daemon/state_test.go @@ -0,0 +1,102 @@ +package daemon + +import ( + "sync/atomic" + "testing" + "time" +) + +func TestStateRunStop(t *testing.T) { + s := NewState() + for i := 1; i < 3; i++ { // full lifecycle two times + started := make(chan struct{}) + var pid int64 + go func() { + runPid, _ := s.WaitRunning(-1 * time.Second) + atomic.StoreInt64(&pid, int64(runPid)) + close(started) + }() + s.SetRunning(i + 100) + if !s.IsRunning() { + t.Fatal("State not running") + } + if s.Pid != i+100 { + t.Fatalf("Pid %v, expected %v", s.Pid, i+100) + } + if s.ExitCode != 0 { + t.Fatalf("ExitCode %v, expected 0", s.ExitCode) + } + select { + case <-time.After(100 * time.Millisecond): + t.Fatal("Start callback doesn't fire in 100 milliseconds") + case <-started: + t.Log("Start callback fired") + } + runPid := int(atomic.LoadInt64(&pid)) + if runPid != i+100 { + t.Fatalf("Pid %v, expected %v", runPid, i+100) + } + if pid, err := s.WaitRunning(-1 * time.Second); err != nil || pid != i+100 { + t.Fatal("WaitRunning returned pid: %v, err: %v, expected pid: %v, err: %v", pid, err, i+100, nil) + } + + stopped := make(chan struct{}) + var exit int64 + go func() { + exitCode, _ := s.WaitStop(-1 * time.Second) + atomic.StoreInt64(&exit, int64(exitCode)) + close(stopped) + }() + s.SetStopped(i) + if s.IsRunning() { + t.Fatal("State is running") + } + if s.ExitCode != i { + t.Fatalf("ExitCode %v, expected %v", s.ExitCode, i) + } + if s.Pid != 0 { + t.Fatalf("Pid %v, expected 0", s.Pid) + } + select { + case <-time.After(100 * time.Millisecond): + t.Fatal("Stop callback doesn't fire in 100 milliseconds") + case <-stopped: + t.Log("Stop callback fired") + } + exitCode := int(atomic.LoadInt64(&exit)) + if exitCode != i { + t.Fatalf("ExitCode %v, expected %v", exitCode, i) + } + if exitCode, err := s.WaitStop(-1 * time.Second); err != nil || exitCode != i { + t.Fatal("WaitStop returned exitCode: %v, err: %v, expected exitCode: %v, err: %v", exitCode, err, i, nil) + } + } +} + +func TestStateTimeoutWait(t *testing.T) { + s := NewState() + started := make(chan struct{}) + go func() { + s.WaitRunning(100 * time.Millisecond) + close(started) + }() + select { + case <-time.After(200 * time.Millisecond): + t.Fatal("Start callback doesn't fire in 100 milliseconds") + case <-started: + t.Log("Start callback fired") + } + s.SetRunning(42) + stopped := make(chan struct{}) + go func() { + s.WaitRunning(100 * time.Millisecond) + close(stopped) + }() + select { + case <-time.After(200 * time.Millisecond): + t.Fatal("Start callback doesn't fire in 100 milliseconds") + case <-stopped: + t.Log("Start callback fired") + } + +} diff --git a/daemonconfig/config.go b/daemonconfig/config.go index 9f77d84a5..1d2bb60dd 100644 --- a/daemonconfig/config.go +++ b/daemonconfig/config.go @@ -31,6 +31,7 @@ type Config struct { DisableNetwork bool EnableSelinuxSupport bool Context map[string][]string + Sockets []string } // ConfigFromJob creates and returns a new DaemonConfig object @@ -66,6 +67,9 @@ func ConfigFromJob(job *engine.Job) *Config { config.Mtu = GetDefaultNetworkMtu() } config.DisableNetwork = config.BridgeIface == DisableNetworkBridge + if sockets := job.GetenvList("Sockets"); sockets != nil { + config.Sockets = sockets + } return config } diff --git a/docker/docker.go b/docker/docker.go index 56bcb04e4..30d43bc6a 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -6,6 +6,7 @@ import ( "fmt" "io/ioutil" "log" + "net" "os" "runtime" "strings" @@ -47,7 +48,7 @@ func main() { bridgeName = flag.String([]string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking") bridgeIp = flag.String([]string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b") pidfile = flag.String([]string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file") - flRoot = flag.String([]string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the docker runtime") + flRoot = flag.String([]string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the Docker runtime") flSocketGroup = flag.String([]string{"G", "-group"}, "docker", "Group to assign the unix socket specified by -H when running in daemon mode\nuse '' (the empty string) to disable setting of a group") flEnableCors = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API") flDns = opts.NewListOpts(opts.ValidateIp4Address) @@ -56,8 +57,8 @@ func main() { flEnableIpForward = flag.Bool([]string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward") flDefaultIp = flag.String([]string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports") flInterContainerComm = flag.Bool([]string{"#icc", "-icc"}, true, "Enable inter-container communication") - flGraphDriver = flag.String([]string{"s", "-storage-driver"}, "", "Force the docker runtime to use a specific storage driver") - flExecDriver = flag.String([]string{"e", "-exec-driver"}, "native", "Force the docker runtime to use a specific exec driver") + flGraphDriver = flag.String([]string{"s", "-storage-driver"}, "", "Force the Docker runtime to use a specific storage driver") + flExecDriver = flag.String([]string{"e", "-exec-driver"}, "native", "Force the Docker runtime to use a specific exec driver") flHosts = opts.NewListOpts(api.ValidateHost) flMtu = flag.Int([]string{"#mtu", "-mtu"}, 0, "Set the containers network MTU\nif no value is provided: default to the default route MTU or 1500 if no default route is available") flTls = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by tls-verify flags") @@ -67,7 +68,7 @@ func main() { flKey = flag.String([]string{"-tlskey"}, dockerConfDir+defaultKeyFile, "Path to TLS key file") flSelinuxEnabled = flag.Bool([]string{"-selinux-enabled"}, false, "Enable selinux support") ) - flag.Var(&flDns, []string{"#dns", "-dns"}, "Force docker to use specific DNS servers") + flag.Var(&flDns, []string{"#dns", "-dns"}, "Force Docker to use specific DNS servers") flag.Var(&flDnsSearch, []string{"-dns-search"}, "Force Docker to use specific DNS search domains") flag.Var(&flHosts, []string{"H", "-host"}, "The socket(s) to bind to in daemon mode\nspecified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.") flag.Var(&flGraphOpts, []string{"-storage-opt"}, "Set storage driver options") @@ -95,6 +96,14 @@ func main() { log.Fatal("You specified -b & --bip, mutually exclusive options. Please specify only one.") } + if !*flEnableIptables && !*flInterContainerComm { + log.Fatal("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.") + } + + if net.ParseIP(*flDefaultIp) == nil { + log.Fatalf("Specified --ip=%s is not in correct format \"0.0.0.0\".", *flDefaultIp) + } + if *flDebug { os.Setenv("DEBUG", "1") } @@ -162,6 +171,7 @@ func main() { job.Setenv("ExecDriver", *flExecDriver) job.SetenvInt("Mtu", *flMtu) job.SetenvBool("EnableSelinuxSupport", *flSelinuxEnabled) + job.SetenvList("Sockets", flHosts.GetAll()) if err := job.Run(); err != nil { log.Fatal(err) } @@ -259,7 +269,7 @@ func showVersion() { func checkKernelAndArch() error { // Check for unsupported architectures if runtime.GOARCH != "amd64" { - return fmt.Errorf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH) + return fmt.Errorf("The Docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH) } // Check for unsupported kernel versions // FIXME: it would be cleaner to not test for specific versions, but rather diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..8da058a80 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,5 @@ +# generated by man/man/md2man-all.sh +man1/ +man5/ +# avoid commiting the awsconfig file used for releases +awsconfig diff --git a/docs/Dockerfile b/docs/Dockerfile index 68dbbec59..329646ed0 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -28,8 +28,12 @@ WORKDIR /docs RUN VERSION=$(cat /docs/VERSION) &&\ GIT_BRANCH=$(cat /docs/GIT_BRANCH) &&\ + GITCOMMIT=$(cat /docs/GITCOMMIT) &&\ AWS_S3_BUCKET=$(cat /docs/AWS_S3_BUCKET) &&\ - echo "{% set docker_version = \"${VERSION}\" %}{% set docker_branch = \"${GIT_BRANCH}\" %}{% set aws_bucket = \"${AWS_S3_BUCKET}\" %}{% include \"beta_warning.html\" %}" > /docs/theme/mkdocs/version.html + sed -i "s/\$VERSION/$VERSION/g" /docs/theme/mkdocs/base.html &&\ + sed -i "s/\$GITCOMMIT/$GITCOMMIT/g" /docs/theme/mkdocs/base.html &&\ + sed -i "s/\$GIT_BRANCH/$GIT_BRANCH/g" /docs/theme/mkdocs/base.html &&\ + sed -i "s/\$AWS_S3_BUCKET/$AWS_S3_BUCKET/g" /docs/theme/mkdocs/base.html # note, EXPOSE is only last because of https://github.com/dotcloud/docker/issues/3525 EXPOSE 8000 diff --git a/docs/MAINTAINERS b/docs/MAINTAINERS index afbbde409..55489fd5c 100644 --- a/docs/MAINTAINERS +++ b/docs/MAINTAINERS @@ -1,3 +1,4 @@ James Turnbull (@jamtur01) Sven Dowideit (@SvenDowideit) O.S. Tezer (@OSTezer) +Fred Lifton (@fredlf) diff --git a/docs/README.md b/docs/README.md index d74ec4ee8..17299401e 100755 --- a/docs/README.md +++ b/docs/README.md @@ -3,7 +3,7 @@ The source for Docker documentation is here under `sources/` and uses extended Markdown, as implemented by [MkDocs](http://mkdocs.org). -The HTML files are built and hosted on `https://docs.docker.io`, and update +The HTML files are built and hosted on `https://docs.docker.com`, and update automatically after each change to the master or release branch of [Docker on GitHub](https://github.com/dotcloud/docker) thanks to post-commit hooks. The `docs` branch maps to the "latest" documentation and the `master` (unreleased @@ -21,14 +21,14 @@ In the rare case where your change is not forward-compatible, you may need to base your changes on the `docs` branch. Also, now that we have a `docs` branch, we can keep the -[http://docs.docker.io](http://docs.docker.io) docs up to date with any bugs +[http://docs.docker.com](http://docs.docker.com) docs up to date with any bugs found between Docker code releases. **Warning**: When *reading* the docs, the -[http://beta-docs.docker.io](http://beta-docs.docker.io) documentation may +[http://docs-stage.docker.com](http://docs-stage.docker.com) documentation may include features not yet part of any official Docker release. The `beta-docs` site should be used only for understanding bleeding-edge development and -`docs.docker.io` (which points to the `docs` branch`) should be used for the +`docs.docker.com` (which points to the `docs` branch`) should be used for the latest official release. ## Contributing @@ -70,7 +70,7 @@ in their shell: ### Images -When you need to add images, try to make them as small as possible (e.g. as +When you need to add images, try to make them as small as possible (e.g., as gifs). Usually images should go in the same directory as the `.md` file which references them, or in a subdirectory if one already exists. diff --git a/docs/docs-update.py b/docs/docs-update.py new file mode 100755 index 000000000..31bb47db3 --- /dev/null +++ b/docs/docs-update.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python + +# +# Sven's quick hack script to update the documentation +# +# call with: +# ./docs/update.py /usr/bin/docker +# + +import re +from sys import argv +import subprocess +import os +import os.path + +script, docker_cmd = argv + +def print_usage(outtext, docker_cmd, command): + help = "" + try: + #print "RUN ", "".join((docker_cmd, " ", command, " --help")) + help = subprocess.check_output("".join((docker_cmd, " ", command, " --help")), stderr=subprocess.STDOUT, shell=True) + except subprocess.CalledProcessError, e: + help = e.output + for l in str(help).strip().split("\n"): + l = l.rstrip() + if l == '': + outtext.write("\n") + else: + # `docker --help` tells the user the path they called it with + l = re.sub(docker_cmd, "docker", l) + outtext.write(" "+l+"\n") + outtext.write("\n") + +# TODO: look for an complain about any missing commands +def update_cli_reference(): + originalFile = "docs/sources/reference/commandline/cli.md" + os.rename(originalFile, originalFile+".bak") + + intext = open(originalFile+".bak", "r") + outtext = open(originalFile, "w") + + mode = 'p' + space = " " + command = "" + # 2 mode line-by line parser + for line in intext: + if mode=='p': + # Prose + match = re.match("( \s*)Usage: docker ([a-z]+)", line) + if match: + # the begining of a Docker command usage block + space = match.group(1) + command = match.group(2) + mode = 'c' + else: + match = re.match("( \s*)Usage of .*docker.*:", line) + if match: + # the begining of the Docker --help usage block + space = match.group(1) + command = "" + mode = 'c' + else: + outtext.write(line) + else: + # command usage block + match = re.match("("+space+")(.*)|^$", line) + #print "CMD ", command + if not match: + # The end of the current usage block - Shell out to run docker to see the new output + print_usage(outtext, docker_cmd, command) + outtext.write(line) + mode = 'p' + if mode == 'c': + print_usage(outtext, docker_cmd, command) + +def update_man_pages(): + cmds = [] + try: + help = subprocess.check_output("".join((docker_cmd)), stderr=subprocess.STDOUT, shell=True) + except subprocess.CalledProcessError, e: + help = e.output + for l in str(help).strip().split("\n"): + l = l.rstrip() + if l != "": + match = re.match(" (.*?) .*", l) + if match: + cmds.append(match.group(1)) + + desc_re = re.compile(r".*# DESCRIPTION(.*?)# (OPTIONS|EXAMPLES?).*", re.MULTILINE|re.DOTALL) + example_re = re.compile(r".*# EXAMPLES?(.*)# HISTORY.*", re.MULTILINE|re.DOTALL) + history_re = re.compile(r".*# HISTORY(.*)", re.MULTILINE|re.DOTALL) + + for command in cmds: + print "COMMAND: "+command + history = "" + description = "" + examples = "" + if os.path.isfile("docs/man/docker-"+command+".1.md"): + intext = open("docs/man/docker-"+command+".1.md", "r") + txt = intext.read() + intext.close() + match = desc_re.match(txt) + if match: + description = match.group(1) + match = example_re.match(txt) + if match: + examples = match.group(1) + match = history_re.match(txt) + if match: + history = match.group(1).strip() + + usage = "" + usage_description = "" + params = {} + key_params = {} + + help = "" + try: + help = subprocess.check_output("".join((docker_cmd, " ", command, " --help")), stderr=subprocess.STDOUT, shell=True) + except subprocess.CalledProcessError, e: + help = e.output + last_key = "" + for l in str(help).split("\n"): + l = l.rstrip() + if l != "": + match = re.match("Usage: docker "+command+"(.*)", l) + if match: + usage = match.group(1).strip() + else: + #print ">>>>"+l + match = re.match(" (-+)(.*) \s+(.*)", l) + if match: + last_key = match.group(2).rstrip() + #print " found "+match.group(1) + key_params[last_key] = match.group(1)+last_key + params[last_key] = match.group(3) + else: + if last_key != "": + params[last_key] = params[last_key] + "\n" + l + else: + if usage_description != "": + usage_description = usage_description + "\n" + usage_description = usage_description + l + + # replace [OPTIONS] with the list of params + options = "" + match = re.match("\[OPTIONS\](.*)", usage) + if match: + usage = match.group(1) + + new_usage = "" + # TODO: sort without the `-`'s + for key in sorted(params.keys(), key=lambda s: s.lower()): + # split on commas, remove --?.*=.*, put in *'s mumble + ps = [] + opts = [] + for k in key_params[key].split(","): + #print "......"+k + match = re.match("(-+)([A-Za-z-0-9]*)(?:=(.*))?", k.lstrip()) + if match: + p = "**"+match.group(1)+match.group(2)+"**" + o = "**"+match.group(1)+match.group(2)+"**" + if match.group(3): + # if ="" then use UPPERCASE(group(2))" + val = match.group(3) + if val == "\"\"": + val = match.group(2).upper() + p = p+"[=*"+val+"*]" + val = match.group(3) + if val in ("true", "false"): + params[key] = params[key].rstrip() + if not params[key].endswith('.'): + params[key] = params[key]+ "." + params[key] = params[key] + " The default is *"+val+"*." + val = "*true*|*false*" + o = o+"="+val + ps.append(p) + opts.append(o) + else: + print "nomatch:"+k + new_usage = new_usage+ "\n["+"|".join(ps)+"]" + options = options + ", ".join(opts) + "\n "+ params[key]+"\n\n" + if new_usage != "": + new_usage = new_usage.strip() + "\n" + usage = new_usage + usage + + + outtext = open("docs/man/docker-"+command+".1.md", "w") + outtext.write("""% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +""") + outtext.write("docker-"+command+" - "+usage_description+"\n\n") + outtext.write("# SYNOPSIS\n**docker "+command+"**\n"+usage+"\n\n") + if description != "": + outtext.write("# DESCRIPTION"+description) + if options == "": + options = "There are no available options.\n\n" + outtext.write("# OPTIONS\n"+options) + if examples != "": + outtext.write("# EXAMPLES"+examples) + outtext.write("# HISTORY\n") + if history != "": + outtext.write(history+"\n") + recent_history_re = re.compile(".*June 2014.*", re.MULTILINE|re.DOTALL) + if not recent_history_re.match(history): + outtext.write("June 2014, updated by Sven Dowideit \n") + outtext.close() + +# main +update_cli_reference() +update_man_pages() diff --git a/contrib/man/md/Dockerfile b/docs/man/Dockerfile similarity index 100% rename from contrib/man/md/Dockerfile rename to docs/man/Dockerfile diff --git a/contrib/man/md/Dockerfile.5.md b/docs/man/Dockerfile.5.md similarity index 98% rename from contrib/man/md/Dockerfile.5.md rename to docs/man/Dockerfile.5.md index d66912210..b0a863f65 100644 --- a/contrib/man/md/Dockerfile.5.md +++ b/docs/man/Dockerfile.5.md @@ -93,7 +93,7 @@ or they omit the executable, an ENTRYPOINT must be specified. When used in the shell or exec formats, the CMD instruction sets the command to be executed when running the image. - If you use the shell form of of the CMD, the executes in /bin/sh -c: + If you use the shell form of the CMD, the executes in /bin/sh -c: **FROM ubuntu** **CMD echo "This is a test." | wc -** If you run wihtout a shell, then you must express the command as a @@ -203,4 +203,4 @@ or run later, during the next build stage. # HISTORY -*May 2014, Compiled by Zac Dover (zdover at redhat dot com) based on docker.io Dockerfile documentation. +*May 2014, Compiled by Zac Dover (zdover at redhat dot com) based on docker.com Dockerfile documentation. diff --git a/contrib/man/md/README.md b/docs/man/README.md similarity index 84% rename from contrib/man/md/README.md rename to docs/man/README.md index d49b39b7a..45f1a91c0 100644 --- a/contrib/man/md/README.md +++ b/docs/man/README.md @@ -51,7 +51,7 @@ saving you from dealing with Pandoc and dependencies on your own computer. ## Building the Fedora / Pandoc image -There is a Dockerfile provided in the `docker/contrib/man/md` directory. +There is a Dockerfile provided in the `docker/docs/man` directory. Using this Dockerfile, create a Docker image tagged `fedora/pandoc`: @@ -61,11 +61,11 @@ Using this Dockerfile, create a Docker image tagged `fedora/pandoc`: Once the image is built, run a container using the image with *volumes*: - docker run -v //docker/contrib/man:/pandoc:rw \ - -w /pandoc -i fedora/pandoc /pandoc/md/md2man-all.sh + docker run -v //docker/docs/man:/pandoc:rw \ + -w /pandoc -i fedora/pandoc /pandoc/md2man-all.sh The Pandoc Docker container will process the Markdown files and generate -the man pages inside the `docker/contrib/man/man1` directory using +the man pages inside the `docker/docs/man/man1` directory using Docker volumes. For more information on Docker volumes see the man page for `docker run` and also look at the article [Sharing Directories via Volumes] -(http://docs.docker.io/use/working_with_volumes/). +(http://docs.docker.com/use/working_with_volumes/). diff --git a/contrib/man/md/docker-attach.1.md b/docs/man/docker-attach.1.md similarity index 82% rename from contrib/man/md/docker-attach.1.md rename to docs/man/docker-attach.1.md index 5a3b7a285..1b4e68b65 100644 --- a/contrib/man/md/docker-attach.1.md +++ b/docs/man/docker-attach.1.md @@ -1,11 +1,14 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-attach - Attach to a running container # SYNOPSIS -**docker attach** **--no-stdin**[=*false*] **--sig-proxy**[=*true*] CONTAINER +**docker attach** +[**--no-stdin**[=*false*]] +[**--sig-proxy**[=*true*]] + CONTAINER # DESCRIPTION If you **docker run** a container in detached mode (**-d**), you can reattach to @@ -19,11 +22,10 @@ the client. # OPTIONS **--no-stdin**=*true*|*false* -When set to true, do not attach to stdin. The default is *false*. + Do not attach STDIN. The default is *false*. -**--sig-proxy**=*true*|*false*: -When set to true, proxify all received signal to the process (even in non-tty -mode). The default is *true*. +**--sig-proxy**=*true*|*false* + Proxify all received signals to the process (even in non-TTY mode). SIGCHLD is not proxied. The default is *true*. # EXAMPLES @@ -55,4 +57,5 @@ attach** command: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-build.1.md b/docs/man/docker-build.1.md similarity index 81% rename from contrib/man/md/docker-build.1.md rename to docs/man/docker-build.1.md index 3c031445a..c562660b6 100644 --- a/contrib/man/md/docker-build.1.md +++ b/docs/man/docker-build.1.md @@ -1,12 +1,17 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-build - Build an image from a Dockerfile source at PATH +docker-build - Build a new image from the source code at PATH # SYNOPSIS -**docker build** [**--no-cache**[=*false*]] [**-q**|**--quiet**[=*false*]] - [**--rm**] [**-t**|**--tag**=TAG] PATH | URL | - +**docker build** +[**--force-rm**[=*false*]] +[**--no-cache**[=*false*]] +[**-q**|**--quiet**[=*false*]] +[**--rm**[=*true*]] +[**-t**|**--tag**[=*TAG*]] + PATH | URL | - # DESCRIPTION This will read the Dockerfile from the directory specified in **PATH**. @@ -25,22 +30,20 @@ When a Git repository is set as the **URL**, the repository is used as context. # OPTIONS - -**-q**, **--quiet**=*true*|*false* - When set to true, suppress verbose build output. Default is *false*. - -**--rm**=*true*|*false* - When true, remove intermediate containers that are created during the -build process. The default is true. - -**-t**, **--tag**=*tag* - The name to be applied to the resulting image on successful completion of -the build. `tag` in this context means the entire image name including the -optional TAG after the ':'. +**--force-rm**=*true*|*false* + Always remove intermediate containers, even after unsuccessful builds. The default is *false*. **--no-cache**=*true*|*false* - When set to true, do not use a cache when building the image. The -default is *false*. + Do not use cache when building the image. The default is *false*. + +**-q**, **--quiet**=*true*|*false* + Suppress the verbose output generated by the containers. The default is *false*. + +**--rm**=*true*|*false* + Remove intermediate containers after a successful build. The default is *true*. + +**-t**, **--tag**="" + Repository name (and optionally a tag) to be applied to the resulting image in case of success # EXAMPLES @@ -114,4 +117,5 @@ Note: You can set an arbitrary Git repository via the `git://` schema. # HISTORY March 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-commit.1.md b/docs/man/docker-commit.1.md similarity index 57% rename from contrib/man/md/docker-commit.1.md rename to docs/man/docker-commit.1.md index 03bf17872..bbd1db21b 100644 --- a/contrib/man/md/docker-commit.1.md +++ b/docs/man/docker-commit.1.md @@ -1,24 +1,28 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-commit - Create a new image from the changes to an existing -container +docker-commit - Create a new image from a container's changes # SYNOPSIS -**docker commit** **-a**|**--author**[=""] **-m**|**--message**[=""] -CONTAINER [REPOSITORY[:TAG]] +**docker commit** +[**-a**|**--author**[=*AUTHOR*]] +[**-m**|**--message**[=*MESSAGE*]] + CONTAINER [REPOSITORY[:TAG]] # DESCRIPTION Using an existing container's name or ID you can create a new image. # OPTIONS -**-a, --author**="" - Author name. (eg. "John Hannibal Smith " +**-a**, **--author**="" + Author (e.g., "John Hannibal Smith ") -**-m, --message**="" +**-m**, **--message**="" Commit message +**-p, --pause**=true + Pause container during commit + # EXAMPLES ## Creating a new image from an existing container @@ -31,4 +35,5 @@ create a new image run docker ps to find the container's ID and then run: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and in +based on docker.com source material and in +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-cp.1.md b/docs/man/docker-cp.1.md similarity index 62% rename from contrib/man/md/docker-cp.1.md rename to docs/man/docker-cp.1.md index f78719866..dc8f295bb 100644 --- a/contrib/man/md/docker-cp.1.md +++ b/docs/man/docker-cp.1.md @@ -1,18 +1,22 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-cp - Copy files/folders from the PATH to the HOSTPATH # SYNOPSIS -**docker cp** CONTAINER:PATH HOSTPATH +**docker cp** +CONTAINER:PATH HOSTPATH # DESCRIPTION -Copy files/folders from the containers filesystem to the host +Copy files/folders from a container's filesystem to the host path. Paths are relative to the root of the filesystem. Files can be copied from a running or stopped container. -# EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES An important shell script file, created in a bash shell, is copied from the exited container to the current dir on the host: @@ -20,5 +24,5 @@ the exited container to the current dir on the host: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. - +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-diff.1.md b/docs/man/docker-diff.1.md similarity index 79% rename from contrib/man/md/docker-diff.1.md rename to docs/man/docker-diff.1.md index 2053f2c3d..acf0911b0 100644 --- a/contrib/man/md/docker-diff.1.md +++ b/docs/man/docker-diff.1.md @@ -1,18 +1,22 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-diff - Inspect changes on a container's filesystem # SYNOPSIS -**docker diff** CONTAINER +**docker diff** +CONTAINER # DESCRIPTION Inspect changes on a container's filesystem. You can use the full or shortened container ID or the container name set using **docker run --name** option. -# EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES Inspect the changes to on a nginx container: # docker diff 1fdfd1f54c1b @@ -39,6 +43,5 @@ Inspect the changes to on a nginx container: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. - - +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-events.1.md b/docs/man/docker-events.1.md similarity index 84% rename from contrib/man/md/docker-events.1.md rename to docs/man/docker-events.1.md index 2ebe9247d..8fa85871a 100644 --- a/contrib/man/md/docker-events.1.md +++ b/docs/man/docker-events.1.md @@ -1,10 +1,14 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-events - Get real time events from the server -**docker events** **--since**=""|*epoch-time* +# SYNOPSIS +**docker events** +[**--since**[=*SINCE*]] +[**--until**[=*UNTIL*]] + # DESCRIPTION Get event information from the Docker daemon. Information can include historical @@ -12,8 +16,10 @@ information and real-time information. # OPTIONS **--since**="" -Show previously created events and then stream. This can be in either -seconds since epoch, or date string. + Show all events created since timestamp + +**--until**="" + Stream events until this timestamp # EXAMPLES @@ -43,4 +49,5 @@ Again the output container IDs have been shortened for the purposes of this docu # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-export.1.md b/docs/man/docker-export.1.md similarity index 69% rename from contrib/man/md/docker-export.1.md rename to docs/man/docker-export.1.md index ab11aa126..8fd7834a1 100644 --- a/contrib/man/md/docker-export.1.md +++ b/docs/man/docker-export.1.md @@ -1,19 +1,22 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-export - Export the contents of a filesystem as a tar archive to -STDOUT. +docker-export - Export the contents of a filesystem as a tar archive to STDOUT # SYNOPSIS -**docker export** CONTAINER +**docker export** +CONTAINER # DESCRIPTION Export the contents of a container's filesystem using the full or shortened container ID or container name. The output is exported to STDOUT and can be redirected to a tar file. -# EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES Export the contents of the container called angry_bell to a tar file called test.tar: @@ -23,4 +26,5 @@ called test.tar: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-history.1.md b/docs/man/docker-history.1.md similarity index 65% rename from contrib/man/md/docker-history.1.md rename to docs/man/docker-history.1.md index 1b3a9858b..ddb164e50 100644 --- a/contrib/man/md/docker-history.1.md +++ b/docs/man/docker-history.1.md @@ -1,11 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-history - Show the history of an image # SYNOPSIS -**docker history** **--no-trunc**[=*false*] [**-q**|**--quiet**[=*false*]] +**docker history** +[**--no-trunc**[=*false*]] +[**-q**|**--quiet**[=*false*]] IMAGE # DESCRIPTION @@ -13,14 +15,13 @@ docker-history - Show the history of an image Show the history of when and how an image was created. # OPTIONS - **--no-trunc**=*true*|*false* - When true don't truncate output. Default is false + Don't truncate output. The default is *false*. -**-q**, **--quiet=*true*|*false* - When true only show numeric IDs. Default is false. +**-q**, **--quiet**=*true*|*false* + Only show numeric IDs. The default is *false*. -# EXAMPLE +# EXAMPLES $ sudo docker history fedora IMAGE CREATED CREATED BY SIZE 105182bb5e8b 5 days ago /bin/sh -c #(nop) ADD file:71356d2ad59aa3119d 372.7 MB @@ -29,4 +30,5 @@ Show the history of when and how an image was created. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-images.1.md b/docs/man/docker-images.1.md similarity index 71% rename from contrib/man/md/docker-images.1.md rename to docs/man/docker-images.1.md index a46679809..c572ee674 100644 --- a/contrib/man/md/docker-images.1.md +++ b/docs/man/docker-images.1.md @@ -1,23 +1,22 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-images - List the images in the local repository +docker-images - List images # SYNOPSIS **docker images** -[**-a**|**--all**=*false*] -[**--no-trunc**[=*false*] -[**-q**|**--quiet**[=*false*] -[**-t**|**--tree**=*false*] -[**-v**|**--viz**=*false*] -[NAME] +[**-a**|**--all**[=*false*]] +[**-f**|**--filter**[=*[]*]] +[**--no-trunc**[=*false*]] +[**-q**|**--quiet**[=*false*]] + [NAME] # DESCRIPTION This command lists the images stored in the local Docker repository. By default, intermediate images, used during builds, are not listed. Some of the -output, e.g. image ID, is truncated, for space reasons. However the truncated +output, e.g., image ID, is truncated, for space reasons. However the truncated image ID, and often the first few characters, are enough to be used in other Docker commands that use the image ID. The output includes repository, tag, image ID, date created and the virtual size. @@ -30,26 +29,17 @@ called fedora. It may be tagged with 18, 19, or 20, etc. to manage different versions. # OPTIONS - **-a**, **--all**=*true*|*false* - When set to true, also include all intermediate images in the list. The -default is false. + Show all images (by default filter out the intermediate image layers). The default is *false*. + +**-f**, **--filter**=[] + Provide filter values (i.e. 'dangling=true') **--no-trunc**=*true*|*false* - When set to true, list the full image ID and not the truncated ID. The -default is false. + Don't truncate output. The default is *false*. **-q**, **--quiet**=*true*|*false* - When set to true, list the complete image ID as part of the output. The -default is false. - -**-t**, **--tree**=*true*|*false* - When set to true, list the images in a tree dependency tree (hierarchy) -format. The default is false. - -**-v**, **--viz**=*true*|*false* - When set to true, list the graph in graphviz format. The default is -*false*. + Only show numeric IDs. The default is *false*. # EXAMPLES @@ -96,4 +86,5 @@ tools. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-import.1.md b/docs/man/docker-import.1.md similarity index 59% rename from contrib/man/md/docker-import.1.md rename to docs/man/docker-import.1.md index a0db89eef..2d67b8bc7 100644 --- a/contrib/man/md/docker-import.1.md +++ b/docs/man/docker-import.1.md @@ -1,16 +1,19 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-import - Create an empty filesystem image and import the contents -of the tarball into it. +docker-import - Create an empty filesystem image and import the contents of the tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then optionally tag it. # SYNOPSIS -**docker import** URL|- [REPOSITORY[:TAG]] +**docker import** +URL|- [REPOSITORY[:TAG]] # DESCRIPTION -Create a new filesystem image from the contents of a tarball (.tar, -.tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then optionally tag it. +Create a new filesystem image from the contents of a tarball (`.tar`, +`.tar.gz`, `.tgz`, `.bzip`, `.tar.xz`, `.txz`) into it, then optionally tag it. + +# OPTIONS +There are no available options. # EXAMPLES @@ -36,4 +39,5 @@ Import to docker via pipe and stdin: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-info.1.md b/docs/man/docker-info.1.md similarity index 87% rename from contrib/man/md/docker-info.1.md rename to docs/man/docker-info.1.md index 8c03945db..2945d61df 100644 --- a/contrib/man/md/docker-info.1.md +++ b/docs/man/docker-info.1.md @@ -1,12 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-info - Display system wide information +docker-info - Display system-wide information # SYNOPSIS **docker info** + # DESCRIPTION This command displays system wide information regarding the Docker installation. Information displayed includes the number of containers and images, pool name, @@ -43,4 +44,5 @@ Here is a sample output: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-inspect.1.md b/docs/man/docker-inspect.1.md similarity index 94% rename from contrib/man/md/docker-inspect.1.md rename to docs/man/docker-inspect.1.md index a49e42138..a52d57c97 100644 --- a/contrib/man/md/docker-inspect.1.md +++ b/docs/man/docker-inspect.1.md @@ -1,12 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-inspect - Return low-level information on a container/image +docker-inspect - Return low-level information on a container or image # SYNOPSIS -**docker inspect** [**-f**|**--format**="" CONTAINER|IMAGE -[CONTAINER|IMAGE...] +**docker inspect** +[**-f**|**--format**[=*FORMAT*]] +CONTAINER|IMAGE [CONTAINER|IMAGE...] # DESCRIPTION @@ -17,8 +18,7 @@ each result. # OPTIONS **-f**, **--format**="" - The text/template package of Go describes all the details of the -format. See examples section + Format the output using the given go template. # EXAMPLES @@ -142,7 +142,7 @@ output: ## Getting information on an image -Use an image's ID or name (e.g. repository/name[:tag]) to get information +Use an image's ID or name (e.g., repository/name[:tag]) to get information on it. # docker inspect 58394af37342 @@ -224,6 +224,6 @@ Use an image's ID or name (e.g. repository/name[:tag]) to get information }] # HISTORY - April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-kill.1.md b/docs/man/docker-kill.1.md new file mode 100644 index 000000000..3c8d59e6d --- /dev/null +++ b/docs/man/docker-kill.1.md @@ -0,0 +1,24 @@ +% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +docker-kill - Kill a running container using SIGKILL or a specified signal + +# SYNOPSIS +**docker kill** +[**-s**|**--signal**[=*"KILL"*]] + CONTAINER [CONTAINER...] + +# DESCRIPTION + +The main process inside each container specified will be sent SIGKILL, + or any signal specified with option --signal. + +# OPTIONS +**-s**, **--signal**="KILL" + Signal to send to the container + +# HISTORY +April 2014, Originally compiled by William Henry (whenry at redhat dot com) + based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-load.1.md b/docs/man/docker-load.1.md similarity index 85% rename from contrib/man/md/docker-load.1.md rename to docs/man/docker-load.1.md index 535b701cc..07dac4613 100644 --- a/contrib/man/md/docker-load.1.md +++ b/docs/man/docker-load.1.md @@ -1,11 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-load - Load an image from a tar archive on STDIN # SYNOPSIS -**docker load** **--input**="" +**docker load** +[**-i**|**--input**[=*INPUT*]] + # DESCRIPTION @@ -13,11 +15,10 @@ Loads a tarred repository from a file or the standard input stream. Restores both images and tags. # OPTIONS - **-i**, **--input**="" Read from a tar archive file, instead of STDIN -# EXAMPLE +# EXAMPLES $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE @@ -33,4 +34,5 @@ Restores both images and tags. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-login.1.md b/docs/man/docker-login.1.md similarity index 55% rename from contrib/man/md/docker-login.1.md rename to docs/man/docker-login.1.md index 0a9cb283d..c26935307 100644 --- a/contrib/man/md/docker-login.1.md +++ b/docs/man/docker-login.1.md @@ -1,12 +1,15 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-login - Register or Login to a docker registry server. +docker-login - Register or log in to a Docker registry server, if no server is specified "https://index.docker.io/v1/" is the default. # SYNOPSIS -**docker login** [**-e**|**-email**=""] [**-p**|**--password**=""] - [**-u**|**--username**=""] [SERVER] +**docker login** +[**-e**|**--email**[=*EMAIL*]] +[**-p**|**--password**[=*PASSWORD*]] +[**-u**|**--username**[=*USERNAME*]] + [SERVER] # DESCRIPTION Register or Login to a docker registry server, if no server is @@ -15,7 +18,7 @@ login to a private registry you can specify this by adding the server name. # OPTIONS **-e**, **--email**="" - Email address + Email **-p**, **--password**="" Password @@ -23,7 +26,7 @@ login to a private registry you can specify this by adding the server name. **-u**, **--username**="" Username -# EXAMPLE +# EXAMPLES ## Login to a local registry @@ -31,5 +34,5 @@ login to a private registry you can specify this by adding the server name. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. - +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-logs.1.md b/docs/man/docker-logs.1.md similarity index 63% rename from contrib/man/md/docker-logs.1.md rename to docs/man/docker-logs.1.md index 0b9ce867e..5c3df75b9 100644 --- a/contrib/man/md/docker-logs.1.md +++ b/docs/man/docker-logs.1.md @@ -1,11 +1,14 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-logs - Fetch the logs of a container # SYNOPSIS -**docker logs** **--follow**[=*false*] CONTAINER +**docker logs** +[**-f**|**--follow**[=*false*]] +[**-t**|**--timestamps**[=*false*]] +CONTAINER # DESCRIPTION The **docker logs** command batch-retrieves whatever logs are present for @@ -18,9 +21,13 @@ The **docker logs --follow** command combines commands **docker logs** and then continue streaming new output from the container’s stdout and stderr. # OPTIONS -**-f, --follow**=*true*|*false* - When *true*, follow log output. The default is false. +**-f**, **--follow**=*true*|*false* + Follow log output. The default is *false*. + +**-t**, **--timestamps**=*true*|*false* + Show timestamps. The default is *false*. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-pause.1.md b/docs/man/docker-pause.1.md new file mode 100644 index 000000000..e6c0c2455 --- /dev/null +++ b/docs/man/docker-pause.1.md @@ -0,0 +1,15 @@ +% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +docker-pause - Pause all processes within a container + +# SYNOPSIS +**docker pause** +CONTAINER + +# OPTIONS +There are no available options. + +# HISTORY +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-port.1.md b/docs/man/docker-port.1.md new file mode 100644 index 000000000..07b84b12d --- /dev/null +++ b/docs/man/docker-port.1.md @@ -0,0 +1,16 @@ +% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +docker-port - Lookup the public-facing port that is NAT-ed to PRIVATE_PORT + +# SYNOPSIS +**docker port** +CONTAINER PRIVATE_PORT + +# OPTIONS +There are no available options. + +# HISTORY +April 2014, Originally compiled by William Henry (whenry at redhat dot com) +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-ps.1.md b/docs/man/docker-ps.1.md similarity index 64% rename from contrib/man/md/docker-ps.1.md rename to docs/man/docker-ps.1.md index 60fce0213..9264d53a6 100644 --- a/contrib/man/md/docker-ps.1.md +++ b/docs/man/docker-ps.1.md @@ -1,14 +1,20 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-ps - List containers # SYNOPSIS -**docker ps** [**-a**|**--all**=*false*] [**--before**=""] -[**-l**|**--latest**=*false*] [**-n**=*-1*] [**--no-trunc**=*false*] -[**-q**|**--quiet**=*false*] [**-s**|**--size**=*false*] -[**--since**=""] +**docker ps** +[**-a**|**--all**[=*false*]] +[**--before**[=*BEFORE*]] +[**-l**|**--latest**[=*false*]] +[**-n**[=*-1*]] +[**--no-trunc**[=*false*]] +[**-q**|**--quiet**[=*false*]] +[**-s**|**--size**[=*false*]] +[**--since**[=*SINCE*]] + # DESCRIPTION @@ -16,36 +22,31 @@ List the containers in the local repository. By default this show only the running containers. # OPTIONS - **-a**, **--all**=*true*|*false* - When true show all containers. Only running containers are shown by -default. Default is false. + Show all containers. Only running containers are shown by default. The default is *false*. **--before**="" - Show only container created before Id or Name, include non-running -ones. + Show only container created before Id or Name, include non-running ones. **-l**, **--latest**=*true*|*false* - When true show only the latest created container, include non-running -ones. The default is false. + Show only the latest created container, include non-running ones. The default is *false*. -**-n**=NUM - Show NUM (integer) last created containers, include non-running ones. -The default is -1 (none) +**-n**=-1 + Show n last created containers, include non-running ones. **--no-trunc**=*true*|*false* - When true truncate output. Default is false. + Don't truncate output. The default is *false*. **-q**, **--quiet**=*true*|*false* - When false only display numeric IDs. Default is false. + Only display numeric IDs. The default is *false*. **-s**, **--size**=*true*|*false* - When true display container sizes. Default is false. + Display sizes. The default is *false*. **--since**="" Show only containers created since Id or Name, include non-running ones. -# EXAMPLE +# EXAMPLES # Display all containers, including non-running # docker ps -a @@ -65,4 +66,5 @@ The default is -1 (none) # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-pull.1.md b/docs/man/docker-pull.1.md similarity index 83% rename from contrib/man/md/docker-pull.1.md rename to docs/man/docker-pull.1.md index 40b7425f7..465c97aad 100644 --- a/contrib/man/md/docker-pull.1.md +++ b/docs/man/docker-pull.1.md @@ -1,19 +1,23 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-pull - Pull an image or a repository from the registry # SYNOPSIS -**docker pull** [REGISTRY_PATH/]NAME[:TAG] +**docker pull** +NAME[:TAG] # DESCRIPTION This command pulls down an image or a repository from the registry. If -there is more than one image for a repository (e.g. fedora) then all +there is more than one image for a repository (e.g., fedora) then all images for that repository name are pulled down including any tags. It is also possible to specify a non-default registry to pull from. +# OPTIONS +There are no available options. + # EXAMPLES # Pull a repository with multiple images @@ -47,5 +51,5 @@ It is also possible to specify a non-default registry to pull from. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. - +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-push.1.md b/docs/man/docker-push.1.md similarity index 76% rename from contrib/man/md/docker-push.1.md rename to docs/man/docker-push.1.md index dbb6e7d1b..8523cb539 100644 --- a/contrib/man/md/docker-push.1.md +++ b/docs/man/docker-push.1.md @@ -1,19 +1,23 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-push - Push an image or a repository to the registry # SYNOPSIS -**docker push** NAME[:TAG] +**docker push** +NAME[:TAG] # DESCRIPTION Push an image or a repository to a registry. The default registry is the Docker -Index located at [index.docker.io](https://index.docker.io/v1/). However the +Hub located at [hub.docker.com](https://hub.docker.com/). However the image can be pushed to another, perhaps private, registry as demonstrated in the example below. -# EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES # Pushing a new image to a registry @@ -24,7 +28,7 @@ and then committing it to a new image name: Now push the image to the registry using the image ID. In this example the registry is on host named registry-host and listening on port 5000. -Default Docker commands will push to the default `index.docker.io` +Default Docker commands will push to the default `hub.docker.com` registry. Instead, push to the local registry, which is on a host called registry-host*. To do this, tag the image with the host name or IP address, and the port of the registry: @@ -41,4 +45,5 @@ listed. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-restart.1.md b/docs/man/docker-restart.1.md new file mode 100644 index 000000000..2a08caa5e --- /dev/null +++ b/docs/man/docker-restart.1.md @@ -0,0 +1,22 @@ +% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +docker-restart - Restart a running container + +# SYNOPSIS +**docker restart** +[**-t**|**--time**[=*10*]] + CONTAINER [CONTAINER...] + +# DESCRIPTION +Restart each container listed. + +# OPTIONS +**-t**, **--time**=10 + Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds. + +# HISTORY +April 2014, Originally compiled by William Henry (whenry at redhat dot com) +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-rm.1.md b/docs/man/docker-rm.1.md similarity index 65% rename from contrib/man/md/docker-rm.1.md rename to docs/man/docker-rm.1.md index ae85af527..1b4537697 100644 --- a/contrib/man/md/docker-rm.1.md +++ b/docs/man/docker-rm.1.md @@ -1,16 +1,15 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 - +% Docker Community +% JUNE 2014 # NAME - -docker-rm - Remove one or more containers. +docker-rm - Remove one or more containers # SYNOPSIS - -**docker rm** [**-f**|**--force**[=*false*] [**-l**|**--link**[=*false*] [**-v**| -**--volumes**[=*false*] -CONTAINER [CONTAINER...] +**docker rm** +[**-f**|**--force**[=*false*]] +[**-l**|**--link**[=*false*]] +[**-v**|**--volumes**[=*false*]] + CONTAINER [CONTAINER...] # DESCRIPTION @@ -20,18 +19,14 @@ remove a running container unless you use the \fB-f\fR option. To see all containers on a host use the **docker ps -a** command. # OPTIONS - **-f**, **--force**=*true*|*false* - When set to true, force the removal of the container. The default is -*false*. + Force removal of running container. The default is *false*. **-l**, **--link**=*true*|*false* - When set to true, remove the specified link and not the underlying -container. The default is *false*. + Remove the specified link and not the underlying container. The default is *false*. **-v**, **--volumes**=*true*|*false* - When set to true, remove the volumes associated to the container. The -default is *false*. + Remove the volumes associated with the container. The default is *false*. # EXAMPLES @@ -51,6 +46,6 @@ command. The use that name as follows: docker rm hopeful_morse # HISTORY - April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-rmi.1.md b/docs/man/docker-rmi.1.md similarity index 56% rename from contrib/man/md/docker-rmi.1.md rename to docs/man/docker-rmi.1.md index b728dc16a..08d740a3b 100644 --- a/contrib/man/md/docker-rmi.1.md +++ b/docs/man/docker-rmi.1.md @@ -1,12 +1,14 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-rmi \- Remove one or more images. +docker-rmi - Remove one or more images # SYNOPSIS - -**docker rmi** [**-f**|**--force**[=*false*] IMAGE [IMAGE...] +**docker rmi** +[**-f**|**--force**[=*false*]] +[**--no-prune**[=*false*]] +IMAGE [IMAGE...] # DESCRIPTION @@ -16,10 +18,11 @@ container unless you use the **-f** option. To see all images on a host use the **docker images** command. # OPTIONS - **-f**, **--force**=*true*|*false* - When set to true, force the removal of the image. The default is -*false*. + Force removal of the image. The default is *false*. + +**--no-prune**=*true*|*false* + Do not delete untagged parents. The default is *false*. # EXAMPLES @@ -30,6 +33,6 @@ Here is an example of removing and image: docker rmi fedora/httpd # HISTORY - April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-run.1.md b/docs/man/docker-run.1.md similarity index 85% rename from contrib/man/md/docker-run.1.md rename to docs/man/docker-run.1.md index 447d9e13c..e7571ac21 100644 --- a/contrib/man/md/docker-run.1.md +++ b/docs/man/docker-run.1.md @@ -1,26 +1,40 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-run - Run a process in an isolated container +docker-run - Run a command in a new container # SYNOPSIS **docker run** -[**-a**|**--attach**[=]] [**-c**|**--cpu-shares**[=0] -[**-m**|**--memory**=*memory-limit*] -[**--cidfile**=*file*] [**-d**|**--detach**[=*false*]] [**--dns**=*IP-address*] -[**--name**=*name*] [**-u**|**--user**=*username*|*uid*] -[**--link**=*name*:*alias*] -[**-e**|**--env**=*environment*] [**--entrypoint**=*command*] -[**--expose**=*port*] [**-P**|**--publish-all**[=*false*]] -[**-p**|**--publish**=*port-mappping*] [**-h**|**--hostname**=*hostname*] -[**--rm**[=*false*]] [**--privileged**[=*false*]] +[**-a**|**--attach**[=*[]*]] +[**-c**|**--cpu-shares**[=*0*]] +[**--cidfile**[=*CIDFILE*]] +[**--cpuset**[=*CPUSET*]] +[**-d**|**--detach**[=*false*]] +[**--dns-search**[=*[]*]] +[**--dns**[=*[]*]] +[**-e**|**--env**[=*[]*]] +[**--entrypoint**[=*ENTRYPOINT*]] +[**--env-file**[=*[]*]] +[**--expose**[=*[]*]] +[**-h**|**--hostname**[=*HOSTNAME*]] [**-i**|**--interactive**[=*false*]] -[**-t**|**--tty**[=*false*]] [**--lxc-conf**=*options*] -[**-n**|**--networking**[=*true*]] -[**-v**|**--volume**=*volume*] [**--volumes-from**=*container-id*] -[**-w**|**--workdir**=*directory*] [**--sig-proxy**[=*true*]] -IMAGE [COMMAND] [ARG...] +[**--link**[=*[]*]] +[**--lxc-conf**[=*[]*]] +[**-m**|**--memory**[=*MEMORY*]] +[**--name**[=*NAME*]] +[**--net**[=*"bridge"*]] +[**-P**|**--publish-all**[=*false*]] +[**-p**|**--publish**[=*[]*]] +[**--privileged**[=*false*]] +[**--rm**[=*false*]] +[**--sig-proxy**[=*true*]] +[**-t**|**--tty**[=*false*]] +[**-u**|**--user**[=*USER*]] +[**-v**|**--volume**[=*[]*]] +[**--volumes-from**[=*[]*]] +[**-w**|**--workdir**[=*WORKDIR*]] + IMAGE [COMMAND] [ARG...] # DESCRIPTION @@ -56,6 +70,8 @@ run**. **--cidfile**=*file* Write the container ID to the file specified. +**--cpuset**="" + CPUs in which to allow execution (0-3, 0,1) **-d**, **-detach**=*true*|*false* Detached mode. This runs the container in the background. It outputs the new @@ -67,11 +83,13 @@ the detached mode, then you cannot use the **-rm** option. When attached in the tty mode, you can detach from a running container without stopping the process by pressing the keys CTRL-P CTRL-Q. +**--dns-search**=[] + Set custom dns search domains **--dns**=*IP-address* Set custom DNS servers. This option can be used to override the DNS configuration passed to the container. Typically this is necessary when the -host DNS configuration is invalid for the container (eg. 127.0.0.1). When this +host DNS configuration is invalid for the container (e.g., 127.0.0.1). When this is the case the **-dns** flags is necessary for every run. @@ -92,6 +110,8 @@ pass in more options via the COMMAND. But, sometimes an operator may want to run something else inside the container, so you can override the default ENTRYPOINT at runtime by using a **--entrypoint** and a string to specify the new ENTRYPOINT. +**--env-file**=[] + Read in a line delimited file of ENV variables **--expose**=*port* Expose a port from the container without publishing it to your host. A @@ -100,34 +120,12 @@ developer can expose the port using the EXPOSE parameter of the Dockerfile, 2) the operator can use the **--expose** option with **docker run**, or 3) the container can be started with the **--link**. -**-m**, **-memory**=*memory-limit* - Allows you to constrain the memory available to a container. If the host -supports swap memory, then the -m memory setting can be larger than physical -RAM. If a limit of 0 is specified, the container's memory is not limited. The -memory limit format: , where unit = b, k, m or g. - -**-P**, **-publish-all**=*true*|*false* - When set to true publish all exposed ports to the host interfaces. The -default is false. If the operator uses -P (or -p) then Docker will make the -exposed port accessible on the host and the ports will be available to any -client that can reach the host. To find the map between the host ports and the -exposed ports, use **docker port**. - - -**-p**, **-publish**=[] - Publish a container's port to the host (format: ip:hostPort:containerPort | -ip::containerPort | hostPort:containerPort) (use **docker port** to see the -actual mapping) - - **-h**, **-hostname**=*hostname* Sets the container host name that is available inside the container. - **-i**, **-interactive**=*true*|*false* When set to true, keep stdin open even if not attached. The default is false. - **--link**=*name*:*alias* Add link to another container. The format is name:alias. If the operator uses **--link** when starting the new client container, then the client @@ -135,16 +133,16 @@ container can access the exposed port via a private networking interface. Docker will set some environment variables in the client container to help indicate which interface and port to use. +**--lxc-conf**=[] + (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1" -**-n**, **-networking**=*true*|*false* - By default, all containers have networking enabled (true) and can make -outgoing connections. The operator can disable networking with **--networking** -to false. This disables all incoming and outgoing networking. In cases like this -, I/O can only be performed through files or by using STDIN/STDOUT. - -Also by default, the container will use the same DNS servers as the host. The -operator may override this with **-dns**. - +**-m**, **-memory**=*memory-limit* + Allows you to constrain the memory available to a container. If the host +supports swap memory, then the -m memory setting can be larger than physical +RAM. If a limit of 0 is specified, the container's memory is not limited. The +actual limit may be rounded up to a multiple of the operating system's page +size, if it is not already. The memory limit should be formatted as follows: +``, where unit = b, k, m or g. **--name**=*name* Assign a name to the container. The operator can identify a container in @@ -160,6 +158,24 @@ string name. The name is useful when defining links (see **--link**) (or any other place you need to identify a container). This works for both background and foreground Docker containers. +**--net**="bridge" + Set the Network mode for the container + 'bridge': creates a new network stack for the container on the docker bridge + 'none': no networking for this container + 'container:': reuses another container network stack + 'host': use the host network stack inside the container. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure. + +**-P**, **-publish-all**=*true*|*false* + When set to true publish all exposed ports to the host interfaces. The +default is false. If the operator uses -P (or -p) then Docker will make the +exposed port accessible on the host and the ports will be available to any +client that can reach the host. To find the map between the host ports and the +exposed ports, use **docker port**. + +**-p**, **-publish**=[] + Publish a container's port to the host (format: ip:hostPort:containerPort | +ip::containerPort | hostPort:containerPort) (use **docker port** to see the +actual mapping) **--privileged**=*true*|*false* Give extended privileges to this container. By default, Docker containers are @@ -179,8 +195,8 @@ default is *false*. This option is incompatible with **-d**. **--sig-proxy**=*true*|*false* - When set to true, proxify all received signals to the process (even in -non-tty mode). The default is true. + When set to true, proxify received signals to the process (even in +non-tty mode). SIGCHLD is not proxied. The default is *true*. **-t**, **-tty**=*true*|*false* @@ -353,4 +369,5 @@ changes will also be reflected on the host in /var/db. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-save.1.md b/docs/man/docker-save.1.md similarity index 79% rename from contrib/man/md/docker-save.1.md rename to docs/man/docker-save.1.md index 126af6b15..533b4c843 100644 --- a/contrib/man/md/docker-save.1.md +++ b/docs/man/docker-save.1.md @@ -1,11 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-save - Save an image to a tar archive (streamed to STDOUT by default) # SYNOPSIS -**docker save** [**-o**|**--output**=""] IMAGE +**docker save** +[**-o**|**--output**[=*OUTPUT*]] +IMAGE # DESCRIPTION Produces a tarred repository to the standard output stream. Contains all @@ -17,7 +19,7 @@ Stream to a file instead of STDOUT by using **-o**. **-o**, **--output**="" Write to an file, instead of STDOUT -# EXAMPLE +# EXAMPLES Save all fedora repository images to a fedora-all.tar and save the latest fedora image to a fedora-latest.tar: @@ -31,5 +33,5 @@ fedora image to a fedora-latest.tar: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. - +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-search.1.md b/docs/man/docker-search.1.md similarity index 75% rename from contrib/man/md/docker-search.1.md rename to docs/man/docker-search.1.md index 945dd34e5..3937b870a 100644 --- a/contrib/man/md/docker-search.1.md +++ b/docs/man/docker-search.1.md @@ -1,12 +1,15 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-search - Search the docker index for images +docker-search - Search the Docker Hub for images # SYNOPSIS -**docker search** **--no-trunc**[=*false*] **--automated**[=*false*] - **-s**|**--stars**[=*0*] TERM +**docker search** +[**--automated**[=*false*]] +[**--no-trunc**[=*false*]] +[**-s**|**--stars**[=*0*]] +TERM # DESCRIPTION @@ -16,17 +19,16 @@ number of stars awarded, whether the image is official, and whether it is automated. # OPTIONS -**--no-trunc**=*true*|*false* - When true display the complete description. The default is false. - -**-s**, **--stars**=NUM - Only displays with at least NUM (integer) stars. I.e. only those images -ranked >=NUM. - **--automated**=*true*|*false* - When true only show automated builds. The default is false. + Only show automated builds. The default is *false*. -# EXAMPLE +**--no-trunc**=*true*|*false* + Don't truncate output. The default is *false*. + +**-s**, **--stars**=0 + Only displays with at least x stars + +# EXAMPLES ## Search the registry for ranked images @@ -52,4 +54,5 @@ ranked 1 or higher: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-start.1.md b/docs/man/docker-start.1.md new file mode 100644 index 000000000..e23fd70ab --- /dev/null +++ b/docs/man/docker-start.1.md @@ -0,0 +1,27 @@ +% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +docker-start - Restart a stopped container + +# SYNOPSIS +**docker start** +[**-a**|**--attach**[=*false*]] +[**-i**|**--interactive**[=*false*]] +CONTAINER [CONTAINER...] + +# DESCRIPTION + +Start a stopped container. + +# OPTIONS +**-a**, **--attach**=*true*|*false* + Attach container's STDOUT and STDERR and forward all signals to the process. The default is *false*. + +**-i**, **--interactive**=*true*|*false* + Attach container's STDIN. The default is *false*. + +# HISTORY +April 2014, Originally compiled by William Henry (whenry at redhat dot com) +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-stop.1.md b/docs/man/docker-stop.1.md new file mode 100644 index 000000000..0cc19918c --- /dev/null +++ b/docs/man/docker-stop.1.md @@ -0,0 +1,23 @@ +% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +docker-stop - Stop a running container by sending SIGTERM and then SIGKILL after a grace period + +# SYNOPSIS +**docker stop** +[**-t**|**--time**[=*10*]] + CONTAINER [CONTAINER...] + +# DESCRIPTION +Stop a running container (Send SIGTERM, and then SIGKILL after + grace period) + +# OPTIONS +**-t**, **--time**=10 + Number of seconds to wait for the container to stop before killing it. Default is 10 seconds. + +# HISTORY +April 2014, Originally compiled by William Henry (whenry at redhat dot com) +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-tag.1.md b/docs/man/docker-tag.1.md similarity index 74% rename from contrib/man/md/docker-tag.1.md rename to docs/man/docker-tag.1.md index 0c4276990..041c9e1cb 100644 --- a/contrib/man/md/docker-tag.1.md +++ b/docs/man/docker-tag.1.md @@ -1,12 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-tag - Tag an image in the repository +docker-tag - Tag an image into a repository # SYNOPSIS -**docker tag** [**-f**|**--force**[=*false*] -IMAGE [REGISTRYHOST/][USERNAME/]NAME[:TAG] +**docker tag** +[**-f**|**--force**[=*false*]] + IMAGE [REGISTRYHOST/][USERNAME/]NAME[:TAG] # DESCRIPTION This will give a new alias to an image in the repository. This refers to the @@ -31,11 +32,15 @@ separated by a ':' recommended to be used for a version to disinguish images with the same name. Note that here TAG is a part of the overall name or "tag". +# OPTIONS +**-f**, **--force**=*true*|*false* + Force. The default is *false*. + # EXAMPLES ## Giving an image a new alias -Here is an example of aliasing an image (e.g. 0e5574283393) as "httpd" and +Here is an example of aliasing an image (e.g., 0e5574283393) as "httpd" and tagging it into the "fedora" repository with "version1.0": docker tag 0e5574283393 fedora/httpd:version1.0 @@ -49,4 +54,5 @@ registry you must tag it with the registry hostname and port (if needed). # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-top.1.md b/docs/man/docker-top.1.md similarity index 61% rename from contrib/man/md/docker-top.1.md rename to docs/man/docker-top.1.md index 2c00c527a..9781739cd 100644 --- a/contrib/man/md/docker-top.1.md +++ b/docs/man/docker-top.1.md @@ -1,18 +1,22 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-top - Lookup the running processes of a container +docker-top - Display the running processes of a container # SYNOPSIS -**docker top** CONTAINER [ps-OPTION] +**docker top** +CONTAINER [ps OPTIONS] # DESCRIPTION Look up the running process of the container. ps-OPTION can be any of the options you would pass to a Linux ps command. -# EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES Run **docker top** with the ps option of -x: @@ -23,5 +27,5 @@ Run **docker top** with the ps option of -x: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. - +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-unpause.1.md b/docs/man/docker-unpause.1.md new file mode 100644 index 000000000..8949548b6 --- /dev/null +++ b/docs/man/docker-unpause.1.md @@ -0,0 +1,15 @@ +% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +docker-unpause - Unpause all processes within a container + +# SYNOPSIS +**docker unpause** +CONTAINER + +# OPTIONS +There are no available options. + +# HISTORY +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-version.1.md b/docs/man/docker-version.1.md new file mode 100644 index 000000000..9c029b239 --- /dev/null +++ b/docs/man/docker-version.1.md @@ -0,0 +1,15 @@ +% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +docker-version - Show the Docker version information. + +# SYNOPSIS +**docker version** + + +# OPTIONS +There are no available options. + +# HISTORY +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker-wait.1.md b/docs/man/docker-wait.1.md similarity index 64% rename from contrib/man/md/docker-wait.1.md rename to docs/man/docker-wait.1.md index 6754151f0..798f6d652 100644 --- a/contrib/man/md/docker-wait.1.md +++ b/docs/man/docker-wait.1.md @@ -1,16 +1,21 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-wait - Block until a container stops, then print its exit code. # SYNOPSIS -**docker wait** CONTAINER [CONTAINER...] +**docker wait** +CONTAINER [CONTAINER...] # DESCRIPTION + Block until a container stops, then print its exit code. -#EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES $ sudo docker run -d fedora sleep 99 079b83f558a2bc52ecad6b2a5de13622d584e6bb1aea058c11b36511e85e7622 @@ -19,5 +24,5 @@ Block until a container stops, then print its exit code. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. - +based on docker.com source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/contrib/man/md/docker.1.md b/docs/man/docker.1.md similarity index 94% rename from contrib/man/md/docker.1.md rename to docs/man/docker.1.md index ab5b67d11..a7a826ed9 100644 --- a/contrib/man/md/docker.1.md +++ b/docs/man/docker.1.md @@ -87,7 +87,7 @@ unix://[/path/to/socket] to use. Create a new image from a container's changes **docker-cp(1)** - Copy files/folders from the containers filesystem to the host at path + Copy files/folders from a container's filesystem to the host at path **docker-diff(1)** Inspect changes on a container's filesystem @@ -127,6 +127,9 @@ inside it) **docker-logs(1)** Fetch the logs of a container +**docker-pause(1)** + Pause all processes within a container + **docker-port(1)** Lookup the public-facing port which is NAT-ed to PRIVATE_PORT @@ -169,7 +172,10 @@ inside it) **docker-top(1)** Lookup the running processes of a container -**version** +**docker-unpause(1)** + Unpause all processes within a container + +**docker-version(1)** Show the Docker version information **docker-wait(1)** @@ -184,4 +190,4 @@ For example: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based - on docker.io source material and internal work. + on docker.com source material and internal work. diff --git a/contrib/man/md/md2man-all.sh b/docs/man/md2man-all.sh similarity index 82% rename from contrib/man/md/md2man-all.sh rename to docs/man/md2man-all.sh index def876f47..12d84de23 100755 --- a/contrib/man/md/md2man-all.sh +++ b/docs/man/md2man-all.sh @@ -17,6 +17,6 @@ for FILE in *.md; do # skip files that aren't of the format xxxx.N.md (like README.md) continue fi - mkdir -p "../man${num}" - pandoc -s -t man "$FILE" -o "../man${num}/${name}" + mkdir -p "./man${num}" + pandoc -s -t man "$FILE" -o "./man${num}/${name}" done diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 5c3147a28..f4ebcb68f 100755 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -1,5 +1,5 @@ site_name: Docker Documentation -#site_url: http://docs.docker.io/ +#site_url: http://docs.docker.com/ site_url: / site_description: Documentation for fast and lightweight Docker container based virtualization framework. site_favicon: img/favicon.png @@ -87,6 +87,7 @@ pages: - ['articles/cfengine_process_management.md', 'Articles', 'Process management with CFEngine'] - ['articles/puppet.md', 'Articles', 'Using Puppet'] - ['articles/chef.md', 'Articles', 'Using Chef'] +- ['articles/dsc.md', 'Articles', 'Using PowerShell DSC'] - ['articles/ambassador_pattern_linking.md', 'Articles', 'Cross-Host linking using Ambassador Containers'] - ['articles/runmetrics.md', 'Articles', 'Runtime metrics'] - ['articles/baseimages.md', 'Articles', 'Creating a Base Image'] @@ -103,6 +104,7 @@ pages: - ['reference/api/registry_api.md', 'Reference', 'Docker Registry API'] - ['reference/api/hub_registry_spec.md', 'Reference', 'Docker Hub and Registry Spec'] - ['reference/api/docker_remote_api.md', 'Reference', 'Docker Remote API'] +- ['reference/api/docker_remote_api_v1.13.md', 'Reference', 'Docker Remote API v1.13'] - ['reference/api/docker_remote_api_v1.12.md', 'Reference', 'Docker Remote API v1.12'] - ['reference/api/docker_remote_api_v1.11.md', 'Reference', 'Docker Remote API v1.11'] - ['reference/api/docker_remote_api_v1.10.md', '**HIDDEN**'] diff --git a/docs/release.sh b/docs/release.sh index 2168dfe1e..f6dc2ec59 100755 --- a/docs/release.sh +++ b/docs/release.sh @@ -9,7 +9,7 @@ To publish the Docker documentation you need to set your access_key and secret_k (with the keys in a [profile $AWS_S3_BUCKET] section - so you can have more than one set of keys in your file) and set the AWS_S3_BUCKET env var to the name of your bucket. -make AWS_S3_BUCKET=beta-docs.docker.io docs-release +make AWS_S3_BUCKET=docs-stage.docker.com docs-release will then push the documentation site to your s3 bucket. EOF @@ -18,7 +18,15 @@ EOF [ "$AWS_S3_BUCKET" ] || usage -#VERSION=$(cat VERSION) +VERSION=$(cat VERSION) + +if [ "$$AWS_S3_BUCKET" == "docs.docker.com" ]; then + if [ "${VERSION%-dev}" != "$VERSION" ]; then + echo "Please do not push '-dev' documentation to docs.docker.com ($VERSION)" + exit 1 + fi +fi + export BUCKET=$AWS_S3_BUCKET export AWS_CONFIG_FILE=$(pwd)/awsconfig @@ -50,7 +58,7 @@ build_current_documentation() { upload_current_documentation() { src=site/ - dst=s3://$BUCKET + dst=s3://$BUCKET$1 echo echo "Uploading $src" @@ -61,7 +69,7 @@ upload_current_documentation() { # a really complicated way to send only the files we want # if there are too many in any one set, aws s3 sync seems to fall over with 2 files to go - endings=( json html xml css js gif png JPG ) + endings=( json html xml css js gif png JPG ttf svg woff) for i in ${endings[@]}; do include="" for j in ${endings[@]}; do @@ -78,11 +86,8 @@ upload_current_documentation() { --exclude *.DS_Store \ --exclude *.psd \ --exclude *.ai \ - --exclude *.svg \ --exclude *.eot \ --exclude *.otf \ - --exclude *.ttf \ - --exclude *.woff \ --exclude *.rej \ --exclude *.rst \ --exclude *.orig \ @@ -99,3 +104,10 @@ setup_s3 build_current_documentation upload_current_documentation +# Remove the last version - 1.0.2-dev -> 1.0 +MAJOR_MINOR="v${VERSION%.*}" + +#build again with /v1.0/ prefix +sed -i "s/^site_url:.*/site_url: \/$MAJOR_MINOR\//" mkdocs.yml +build_current_documentation +upload_current_documentation "/$MAJOR_MINOR/" diff --git a/docs/s3_website.json b/docs/s3_website.json index 8a6f99beb..224ba816e 100644 --- a/docs/s3_website.json +++ b/docs/s3_website.json @@ -27,6 +27,7 @@ { "Condition": { "KeyPrefixEquals": "docker-io/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/" } }, { "Condition": { "KeyPrefixEquals": "examples/cfengine_process_management/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/cfengine_process_management/" } }, { "Condition": { "KeyPrefixEquals": "examples/https/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/https/" } }, + { "Condition": { "KeyPrefixEquals": "examples/ambassador_pattern_linking/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/ambassador_pattern_linking/" } }, { "Condition": { "KeyPrefixEquals": "examples/using_supervisord/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/using_supervisord/" } }, { "Condition": { "KeyPrefixEquals": "reference/api/registry_index_spec/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "reference/api/hub_registry_spec/" } }, { "Condition": { "KeyPrefixEquals": "use/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "examples/" } } diff --git a/docs/sources/articles/cfengine_process_management.md b/docs/sources/articles/cfengine_process_management.md index ee5ba238a..6bb4df66a 100644 --- a/docs/sources/articles/cfengine_process_management.md +++ b/docs/sources/articles/cfengine_process_management.md @@ -87,7 +87,7 @@ The first two steps can be done as part of a Dockerfile, as follows. ENTRYPOINT ["/var/cfengine/bin/docker_processes_run.sh"] By saving this file as Dockerfile to a working directory, you can then build -your image with the docker build command, e.g. +your image with the docker build command, e.g., `docker build -t managed_image`. ### Testing the container diff --git a/docs/sources/articles/dsc.md b/docs/sources/articles/dsc.md new file mode 100644 index 000000000..94f5e9d4d --- /dev/null +++ b/docs/sources/articles/dsc.md @@ -0,0 +1,117 @@ +page_title: PowerShell DSC Usage +page_description: Using DSC to configure a new Docker host +page_keywords: powershell, dsc, installation, usage, docker, documentation + +# Using PowerShell DSC + +Windows PowerShell Desired State Configuration (DSC) is a configuration +management tool that extends the existing functionality of Windows PowerShell. +DSC uses a declarative syntax to define the state in which a target should be +configured. More information about PowerShell DSC can be found at +http://technet.microsoft.com/en-us/library/dn249912.aspx. + +## Requirements + +To use this guide you'll need a Windows host with PowerShell v4.0 or newer. + +The included DSC configuration script also uses the official PPA so +only an Ubuntu target is supported. The Ubuntu target must already have the +required OMI Server and PowerShell DSC for Linux providers installed. More +information can be found at https://github.com/MSFTOSSMgmt/WPSDSCLinux. The +source repository listed below also includes PowerShell DSC for Linux +installation and init scripts along with more detailed installation information. + +## Installation + +The DSC configuration example source is available in the following repository: +https://github.com/anweiss/DockerClientDSC. It can be cloned with: + + $ git clone https://github.com/anweiss/DockerClientDSC.git + +## Usage + +The DSC configuration utilizes a set of shell scripts to determine whether or +not the specified Docker components are configured on the target node(s). The +source repository also includes a script (`RunDockerClientConfig.ps1`) that can +be used to establish the required CIM session(s) and execute the +`Set-DscConfiguration` cmdlet. + +More detailed usage information can be found at +https://github.com/anweiss/DockerClientDSC. + +### Run Configuration +The Docker installation configuration is equivalent to running: + +``` +apt-get install docker.io +ln -sf /usr/bin/docker.io /usr/local/bin/docker +sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io +``` + +Ensure that your current working directory is set to the `DockerClientDSC` +source and load the DockerClient configuration into the current PowerShell +session + +```powershell +. .\DockerClient.ps1 +``` + +Generate the required DSC configuration .mof file for the targeted node + +```powershell +DockerClient -Hostname "myhost" +``` + +A sample DSC configuration data file has also been included and can be modified +and used in conjunction with or in place of the `Hostname` parameter: + +```powershell +DockerClient -ConfigurationData .\DockerConfigData.psd1 +``` + +Start the configuration application process on the targeted node + +```powershell +.\RunDockerClientConfig.ps1 -Hostname "myhost" +``` + +The `RunDockerClientConfig.ps1` script can also parse a DSC configuration data +file and execute configurations against multiple nodes as such: + +```powershell +.\RunDockerClientConfig.ps1 -ConfigurationData .\DockerConfigData.psd1 +``` + +### Images +Image configuration is equivalent to running: `docker pull [image]`. + +Using the same Run Configuration steps defined above, execute `DockerClient` +with the `Image` parameter: + +```powershell +DockerClient -Hostname "myhost" -Image node +``` + +The configuration process can be initiated as before: + +```powershell +.\RunDockerClientConfig.ps1 -Hostname "myhost" +``` + +### Containers +Container configuration is equivalent to running: +`docker run -d --name="[containername]" [image] '[command]'`. + +Using the same Run Configuration steps defined above, execute `DockerClient` +with the `Image`, `ContainerName`, and `Command` parameters: + +```powershell +DockerClient -Hostname "myhost" -Image node -ContainerName "helloworld" ` +-Command 'echo "Hello World!"' +``` + +The configuration process can be initiated as before: + +```powershell +.\RunDockerClientConfig.ps1 -Hostname "myhost" +``` diff --git a/docs/sources/articles/https.md b/docs/sources/articles/https.md index cc8c6a976..b6ae4ef37 100644 --- a/docs/sources/articles/https.md +++ b/docs/sources/articles/https.md @@ -29,7 +29,7 @@ keys: $ openssl req -new -x509 -days 365 -key ca-key.pem -out ca.pem Now that we have a CA, you can create a server key and certificate -signing request. Make sure that "Common Name (e.g. server FQDN or YOUR +signing request. Make sure that "Common Name (e.g., server FQDN or YOUR name)" matches the hostname you will use to connect to Docker or just use `\*` for a certificate valid for any hostname: diff --git a/docs/sources/articles/networking.md b/docs/sources/articles/networking.md index 927cd8087..bf46b90ea 100644 --- a/docs/sources/articles/networking.md +++ b/docs/sources/articles/networking.md @@ -26,7 +26,7 @@ bridge* that automatically forwards packets between any other network interfaces that are attached to it. This lets containers communicate both with the host machine and with each other. Every time Docker creates a container, it creates a pair of “peer” interfaces that are -like opposite ends of a pipe — a packet send on one will be received on +like opposite ends of a pipe — a packet sent on one will be received on the other. It gives one of the peers to the container to become its `eth0` interface and keeps the other peer, with a unique name like `vethAQI2QT`, out in the namespace of the host machine. By binding diff --git a/docs/sources/articles/runmetrics.md b/docs/sources/articles/runmetrics.md index bf4fe21c4..9c871a24f 100644 --- a/docs/sources/articles/runmetrics.md +++ b/docs/sources/articles/runmetrics.md @@ -35,7 +35,7 @@ known to the system, the hierarchy they belong to, and how many groups they cont You can also look at `/proc//cgroup` to see which control groups a process belongs to. The control group will be shown as a path relative to the root of -the hierarchy mountpoint; e.g. `/` means “this process has not been assigned into +the hierarchy mountpoint; e.g., `/` means “this process has not been assigned into a particular group”, while `/lxc/pumpkin` means that the process is likely to be a member of a container named `pumpkin`. @@ -106,9 +106,9 @@ to the processes within the cgroup, excluding sub-cgroups. The second half (with the `total_` prefix) includes sub-cgroups as well. Some metrics are "gauges", i.e. values that can increase or decrease -(e.g. swap, the amount of swap space used by the members of the cgroup). +(e.g., swap, the amount of swap space used by the members of the cgroup). Some others are "counters", i.e. values that can only go up, because -they represent occurrences of a specific event (e.g. pgfault, which +they represent occurrences of a specific event (e.g., pgfault, which indicates the number of page faults which happened since the creation of the cgroup; this number can never decrease). @@ -410,7 +410,7 @@ used. Docker makes this difficult because it relies on `lxc-start`, which carefully cleans up after itself, but it is still possible. It is -usually easier to collect metrics at regular intervals (e.g. every +usually easier to collect metrics at regular intervals (e.g., every minute, with the collectd LXC plugin) and rely on that instead. But, if you'd still like to gather the stats when a container stops, diff --git a/docs/sources/articles/security.md b/docs/sources/articles/security.md index cdf5fdddd..dcc61f386 100644 --- a/docs/sources/articles/security.md +++ b/docs/sources/articles/security.md @@ -5,7 +5,7 @@ page_keywords: Docker, Docker documentation, security # Docker Security > *Adapted from* [Containers & Docker: How Secure are -> They?](http://blog.docker.io/2013/08/containers-docker-how-secure-are-they/) +> They?](http://blog.docker.com/2013/08/containers-docker-how-secure-are-they/) There are three major areas to consider when reviewing Docker security: @@ -17,15 +17,10 @@ There are three major areas to consider when reviewing Docker security: ## Kernel Namespaces -Docker containers are essentially LXC containers, and they come with the -same security features. When you start a container with -`docker run`, behind the scenes Docker uses -`lxc-start` to execute the Docker container. This -creates a set of namespaces and control groups for the container. Those -namespaces and control groups are not created by Docker itself, but by -`lxc-start`. This means that as the LXC userland -tools evolve (and provide additional namespaces and isolation features), -Docker will automatically make use of them. +Docker containers are very similar to LXC containers, and they come with +the similar security features. When you start a container with `docker +run`, behind the scenes Docker creates a set of namespaces and control +groups for the container. **Namespaces provide the first and most straightforward form of isolation**: processes running within a container cannot see, and even @@ -55,10 +50,9 @@ ago), namespace code has been exercised and scrutinized on a large number of production systems. And there is more: the design and inspiration for the namespaces code are even older. Namespaces are actually an effort to reimplement the features of [OpenVZ]( -http://en.wikipedia.org/wiki/OpenVZ) in such a way that they -could be merged within the mainstream kernel. And OpenVZ was initially -released in 2005, so both the design and the implementation are pretty -mature. +http://en.wikipedia.org/wiki/OpenVZ) in such a way that they could be +merged within the mainstream kernel. And OpenVZ was initially released +in 2005, so both the design and the implementation are pretty mature. ## Control Groups @@ -82,7 +76,7 @@ started in 2006, and initially merged in kernel 2.6.24. ## Docker Daemon Attack Surface Running containers (and applications) with Docker implies running the -Docker daemon. This daemon currently requires root privileges, and you +Docker daemon. This daemon currently requires `root` privileges, and you should therefore be aware of some important details. First of all, **only trusted users should be allowed to control your @@ -97,8 +91,8 @@ without any restriction. This sounds crazy? Well, you have to know that same way**. Nothing prevents you from sharing your root filesystem (or even your root block device) with a virtual machine. -This has a strong security implication: if you instrument Docker from -e.g. a web server to provision containers through an API, you should be +This has a strong security implication: for example, if you instrument Docker +from a web server to provision containers through an API, you should be even more careful than usual with parameter checking, to make sure that a malicious user cannot pass crafted parameters causing Docker to create arbitrary containers. @@ -114,8 +108,9 @@ socket. You can also expose the REST API over HTTP if you explicitly decide so. However, if you do that, being aware of the above mentioned security implication, you should ensure that it will be reachable only from a -trusted network or VPN; or protected with e.g. `stunnel` -and client SSL certificates. +trusted network or VPN; or protected with e.g., `stunnel` and client SSL +certificates. You can also secure them with [HTTPS and +certificates](/articles/https/). Recent improvements in Linux namespaces will soon allow to run full-featured containers without root privileges, thanks to the new user @@ -141,7 +136,7 @@ Finally, if you run Docker on a server, it is recommended to run exclusively Docker in the server, and move all other services within containers controlled by Docker. Of course, it is fine to keep your favorite admin tools (probably at least an SSH server), as well as -existing monitoring/supervision processes (e.g. NRPE, collectd, etc). +existing monitoring/supervision processes (e.g., NRPE, collectd, etc). ## Linux Kernel Capabilities @@ -159,8 +154,8 @@ This means a lot for container security; let's see why! Your average server (bare metal or virtual machine) needs to run a bunch of processes as root. Those typically include SSH, cron, syslogd; -hardware management tools (to e.g. load modules), network configuration -tools (to handle e.g. DHCP, WPA, or VPNs), and much more. A container is +hardware management tools (e.g., load modules), network configuration +tools (e.g., to handle DHCP, WPA, or VPNs), and much more. A container is very different, because almost all of those tasks are handled by the infrastructure around the container: @@ -199,15 +194,18 @@ container, it will be much harder to do serious damage, or to escalate to the host. This won't affect regular web apps; but malicious users will find that -the arsenal at their disposal has shrunk considerably! You can see [the -list of dropped capabilities in the Docker -code](https://github.com/dotcloud/docker/blob/v0.5.0/lxc_template.go#L97), -and a full list of available capabilities in [Linux +the arsenal at their disposal has shrunk considerably! By default Docker +drops all capabilities except [those +needed](https://github.com/dotcloud/docker/blob/master/daemon/execdriver/native/template/default_template.go), +a whitelist instead of a blacklist approach. You can see a full list of +available capabilities in [Linux manpages](http://man7.org/linux/man-pages/man7/capabilities.7.html). Of course, you can always enable extra capabilities if you really need them (for instance, if you want to use a FUSE-based filesystem), but by -default, Docker containers will be locked down to ensure maximum safety. +default, Docker containers use only a +[whitelist](https://github.com/dotcloud/docker/blob/master/daemon/execdriver/native/template/default_template.go) +of kernel capabilities by default. ## Other Kernel Security Features @@ -222,20 +220,19 @@ harden a Docker host. Here are a few examples. - You can run a kernel with GRSEC and PAX. This will add many safety checks, both at compile-time and run-time; it will also defeat many - exploits, thanks to techniques like address randomization. It - doesn't require Docker-specific configuration, since those security - features apply system-wide, independently of containers. - - If your distribution comes with security model templates for LXC - containers, you can use them out of the box. For instance, Ubuntu - comes with AppArmor templates for LXC, and those templates provide - an extra safety net (even though it overlaps greatly with - capabilities). + exploits, thanks to techniques like address randomization. It doesn't + require Docker-specific configuration, since those security features + apply system-wide, independently of containers. + - If your distribution comes with security model templates for + Docker containers, you can use them out of the box. For instance, we + ship a template that works with AppArmor and Red Hat comes with SELinux + policies for Docker. These templates provide an extra safety net (even + though it overlaps greatly with capabilities). - You can define your own policies using your favorite access control - mechanism. Since Docker containers are standard LXC containers, - there is nothing “magic” or specific to Docker. + mechanism. Just like there are many third-party tools to augment Docker containers -with e.g. special network topologies or shared filesystems, you can +with e.g., special network topologies or shared filesystems, you can expect to see tools to harden existing Docker containers without affecting Docker's core. @@ -243,7 +240,7 @@ affecting Docker's core. Docker containers are, by default, quite secure; especially if you take care of running your processes inside the containers as non-privileged -users (i.e. non root). +users (i.e. non-`root`). You can add an extra layer of safety by enabling Apparmor, SELinux, GRSEC, or your favorite hardening solution. @@ -254,4 +251,4 @@ with Docker, since everything is provided by the kernel anyway. For more context and especially for comparisons with VMs and other container systems, please also see the [original blog post]( -http://blog.docker.io/2013/08/containers-docker-how-secure-are-they/). +http://blog.docker.com/2013/08/containers-docker-how-secure-are-they/). diff --git a/docs/sources/articles/using_supervisord.md b/docs/sources/articles/using_supervisord.md index fd7c07cab..91b8976d7 100644 --- a/docs/sources/articles/using_supervisord.md +++ b/docs/sources/articles/using_supervisord.md @@ -27,7 +27,7 @@ Let's start by creating a basic `Dockerfile` for our new image. FROM ubuntu:13.04 - MAINTAINER examples@docker.io + MAINTAINER examples@docker.com RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list RUN apt-get update RUN apt-get upgrade -y diff --git a/docs/sources/contributing/devenvironment.md b/docs/sources/contributing/devenvironment.md index 54b867cf4..606f9302f 100644 --- a/docs/sources/contributing/devenvironment.md +++ b/docs/sources/contributing/devenvironment.md @@ -16,7 +16,7 @@ Docker's build environment itself is a Docker container, so the first step is to install Docker on your system. You can follow the [install instructions most relevant to your -system](https://docs.docker.io/installation/). Make sure you +system](https://docs.docker.com/installation/). Make sure you have a working, up-to-date docker installation, then continue to the next step. @@ -113,7 +113,7 @@ something like this ok github.com/dotcloud/docker/utils 0.017s If $TESTFLAGS is set in the environment, it is passed as extra arguments -to `go test`. You can use this to select certain tests to run, e.g. +to `go test`. You can use this to select certain tests to run, e.g., $ TESTFLAGS=`-run \^TestBuild\$` make test diff --git a/docs/sources/docker-hub/accounts.md b/docs/sources/docker-hub/accounts.md index 7e951448d..304010fb5 100644 --- a/docs/sources/docker-hub/accounts.md +++ b/docs/sources/docker-hub/accounts.md @@ -36,8 +36,8 @@ page. Also available on the Docker Hub are organizations and groups that allow you to collaborate across your organization or team. You can see what -organizations [you belong to and add new organizations](Sam Alba -) from the Account +organizations [you belong to and add new organizations]( +https://hub.docker.com/account/organizations/) from the Account tab. ![organizations](/docker-hub/orgs.png) diff --git a/docs/sources/examples/nodejs_web_app.md b/docs/sources/examples/nodejs_web_app.md index cf00e88be..a7b8eea7e 100644 --- a/docs/sources/examples/nodejs_web_app.md +++ b/docs/sources/examples/nodejs_web_app.md @@ -24,7 +24,7 @@ describes your app and its dependencies: "name": "docker-centos-hello", "private": true, "version": "0.0.1", - "description": "Node.js Hello World app on CentOS using docker", + "description": "Node.js Hello world app on CentOS using docker", "author": "Daniel Gasienica ", "dependencies": { "express": "3.2.4" @@ -42,7 +42,7 @@ app using the [Express.js](http://expressjs.com/) framework: // App var app = express(); app.get('/', function (req, res) { - res.send('Hello World\n'); + res.send('Hello world\n'); }); app.listen(PORT); @@ -137,9 +137,9 @@ Your image will now be listed by Docker: $ sudo docker images # Example - REPOSITORY TAG ID CREATED - centos 6.4 539c0211cd76 8 weeks ago - gasi/centos-node-hello latest d64d3505b0d2 2 hours ago + REPOSITORY TAG ID CREATED + centos 6.4 539c0211cd76 8 weeks ago + /centos-node-hello latest d64d3505b0d2 2 hours ago ## Run the image @@ -167,8 +167,8 @@ To test your app, get the the port of your app that Docker mapped: $ sudo docker ps # Example - ID IMAGE COMMAND ... PORTS - ecce33b30ebf gasi/centos-node-hello:latest node /src/index.js 49160->8080 + ID IMAGE COMMAND ... PORTS + ecce33b30ebf /centos-node-hello:latest node /src/index.js 49160->8080 In the example above, Docker mapped the `8080` port of the container to `49160`. @@ -184,7 +184,7 @@ Now you can call your app using `curl` (install if needed via: Date: Sun, 02 Jun 2013 03:53:22 GMT Connection: keep-alive - Hello World + Hello world We hope this tutorial helped you get up and running with Node.js and CentOS on Docker. You can get the full source code at diff --git a/docs/sources/examples/postgresql_service.Dockerfile b/docs/sources/examples/postgresql_service.Dockerfile index 219a53788..364a18a81 100644 --- a/docs/sources/examples/postgresql_service.Dockerfile +++ b/docs/sources/examples/postgresql_service.Dockerfile @@ -1,5 +1,5 @@ # -# example Dockerfile for http://docs.docker.io/en/latest/examples/postgresql_service/ +# example Dockerfile for http://docs.docker.com/examples/postgresql_service/ # FROM ubuntu diff --git a/docs/sources/examples/postgresql_service.md b/docs/sources/examples/postgresql_service.md index b9fae49d9..5265935e3 100644 --- a/docs/sources/examples/postgresql_service.md +++ b/docs/sources/examples/postgresql_service.md @@ -21,7 +21,7 @@ Start by creating a new `Dockerfile`: > suitably secure. # - # example Dockerfile for http://docs.docker.io/examples/postgresql_service/ + # example Dockerfile for http://docs.docker.com/examples/postgresql_service/ # FROM ubuntu diff --git a/docs/sources/examples/running_ssh_service.Dockerfile b/docs/sources/examples/running_ssh_service.Dockerfile index 978e61042..57baf88ce 100644 --- a/docs/sources/examples/running_ssh_service.Dockerfile +++ b/docs/sources/examples/running_ssh_service.Dockerfile @@ -2,7 +2,7 @@ # # VERSION 0.0.1 -FROM debian +FROM ubuntu:12.04 MAINTAINER Thatcher R. Peskens "thatcher@dotcloud.com" # make sure the package repository is up to date diff --git a/docs/sources/examples/running_ssh_service.md b/docs/sources/examples/running_ssh_service.md index 27439f998..579d372ba 100644 --- a/docs/sources/examples/running_ssh_service.md +++ b/docs/sources/examples/running_ssh_service.md @@ -12,7 +12,7 @@ quick access to a test container. # # VERSION 0.0.1 - FROM debian + FROM ubuntu:12.04 MAINTAINER Thatcher R. Peskens "thatcher@dotcloud.com" # make sure the package repository is up to date diff --git a/docs/sources/faq.md b/docs/sources/faq.md index 2d38cf2ff..667058c86 100644 --- a/docs/sources/faq.md +++ b/docs/sources/faq.md @@ -178,15 +178,53 @@ Cloud: ### How do I report a security issue with Docker? You can learn about the project's security policy -[here](https://www.docker.io/security/) and report security issues to +[here](https://www.docker.com/security/) and report security issues to this [mailbox](mailto:security@docker.com). ### Why do I need to sign my commits to Docker with the DCO? Please read [our blog post]( -http://blog.docker.io/2014/01/docker-code-contributions-require-developer-certificate-of-origin/) +http://blog.docker.com/2014/01/docker-code-contributions-require-developer-certificate-of-origin/) on the introduction of the DCO. +### When building an image, should I prefer system libraries or bundled ones? + +*This is a summary of a discussion on the [docker-dev mailing list]( +https://groups.google.com/forum/#!topic/docker-dev/L2RBSPDu1L0).* + +Virtually all programs depend on third-party libraries. Most frequently, +they will use dynamic linking and some kind of package dependency, so +that when multiple programs need the same library, it is installed only once. + +Some programs, however, will bundle their third-party libraries, because +they rely on very specific versions of those libraries. For instance, +Node.js bundles OpenSSL; MongoDB bundles V8 and Boost (among others). + +When creating a Docker image, is it better to use the bundled libraries, +or should you build those programs so that they use the default system +libraries instead? + +The key point about system libraries is not about saving disk or memory +space. It is about security. All major distributions handle security +seriously, by having dedicated security teams, following up closely +with published vulnerabilities, and disclosing advisories themselves. +(Look at the [Debian Security Information](https://www.debian.org/security/) +for an example of those procedures.) Upstream developers, however, +do not always implement similar practices. + +Before setting up a Docker image to compile a program from source, +if you want to use bundled libraries, you should check if the upstream +authors provide a convenient way to announce security vulnerabilities, +and if they update their bundled libraries in a timely manner. If they +don't, you are exposing yourself (and the users of your image) to +security vulnerabilities. + +Likewise, before using packages built by others, you should check if the +channels providing those packages implement similar security best practices. +Downloading and installing an "all-in-one" .deb or .rpm sounds great at first, +except if you have no way to figure out that it contains a copy of the +OpenSSL library vulnerable to the [Heartbleed](http://heartbleed.com/) bug. + ### Can I help by adding some questions and answers? Definitely! You can fork [the repo](https://github.com/dotcloud/docker) and diff --git a/docs/sources/index.md b/docs/sources/index.md index 06e1ac6d5..75414b436 100644 --- a/docs/sources/index.md +++ b/docs/sources/index.md @@ -6,7 +6,7 @@ page_keywords: docker, introduction, documentation, about, technology, understan **Develop, Ship and Run Any Application, Anywhere** -[**Docker**](https://www.docker.io) is a platform for developers and sysadmins +[**Docker**](https://www.docker.com) is a platform for developers and sysadmins to develop, ship, and run applications. Docker lets you quickly assemble applications from components and eliminates the friction that can come when shipping code. Docker lets you get your code tested and deployed into production @@ -22,8 +22,9 @@ Docker consists of: ## Why Docker? -- **Faster delivery of your applications** - * We want your environment to work better. Docker containers, +*Faster delivery of your applications* + +* We want your environment to work better. Docker containers, and the work flow that comes with them, help your developers, sysadmins, QA folks, and release engineers work together to get your code into production and make it useful. We've created a standard @@ -31,40 +32,42 @@ Docker consists of: inside containers while sysadmins and operators can work on running the container in your deployment. This separation of duties streamlines and simplifies the management and deployment of code. - * We make it easy to build new containers, enable rapid iteration of +* We make it easy to build new containers, enable rapid iteration of your applications, and increase the visibility of changes. This helps everyone in your organization understand how an application works and how it is built. - * Docker containers are lightweight and fast! Containers have +* Docker containers are lightweight and fast! Containers have sub-second launch times, reducing the cycle time of development, testing, and deployment. -- **Deploy and scale more easily** - * Docker containers run (almost) everywhere. You can deploy +*Deploy and scale more easily* + +* Docker containers run (almost) everywhere. You can deploy containers on desktops, physical servers, virtual machines, into data centers, and up to public and private clouds. - * Since Docker runs on so many platforms, it's easy to move your +* Since Docker runs on so many platforms, it's easy to move your applications around. You can easily move an application from a testing environment into the cloud and back whenever you need. - * Docker's lightweight containers Docker also make scaling up and +* Docker's lightweight containers also make scaling up and down fast and easy. You can quickly launch more containers when needed and then shut them down easily when they're no longer needed. -- **Get higher density and run more workloads** - * Docker containers don't need a hypervisor, so you can pack more of +*Get higher density and run more workloads* + +* Docker containers don't need a hypervisor, so you can pack more of them onto your hosts. This means you get more value out of every server and can potentially reduce what you spend on equipment and licenses. -- **Faster deployment makes for easier management** - * As Docker speeds up your work flow, it gets easier to make lots +*Faster deployment makes for easier management* + +* As Docker speeds up your work flow, it gets easier to make lots of small changes instead of huge, big bang updates. Smaller changes mean reduced risk and more uptime. ## About this guide -First, the [Understanding Docker -section](introduction/understanding-docker.md) will help you: +The [Understanding Docker section](introduction/understanding-docker.md) will help you: - See how Docker works at a high level - Understand the architecture of Docker @@ -72,22 +75,59 @@ section](introduction/understanding-docker.md) will help you: - See how Docker compares to virtual machines - See some common use cases. -> [Click here to go to the Understanding -> Docker section](introduction/understanding-docker.md). - ### Installation Guides -Next, we'll show you how to install Docker on a variety of platforms in the -[installation](/installation/#installation) section. +The [installation section](/installation/#installation) will show you how to install +Docker on a variety of platforms. -> [Click here to go to the Installation -> section](/installation/#installation). ### Docker User Guide -Once you've gotten Docker installed we recommend you work through the -[Docker User Guide](/userguide/), to learn about Docker in more detail and -answer questions about usage and implementation. +To learn about Docker in more detail and to answer questions about usage and implementation, check out the [Docker User Guide](/userguide/). + +## Release Notes + +Version 1.1.0 + +### New Features + +*`.dockerignore` support* + +You can now add a `.dockerignore` file next to your `Dockerfile` and Docker will ignore files and directories specified in that file when sending the build context to the daemon. +Example: https://github.com/dotcloud/docker/blob/master/.dockerignore + +*Pause containers during commit* + +Doing a commit on a running container was not recommended because you could end up with files in an inconsistent state (for example, if they were being written during the commit). Containers are now paused when a commit is made to them. +You can disable this feature by doing a `docker commit --pause=false ` + +*Tailing logs* + +You can now tail the logs of a container. For example, you can get the last ten lines of a log by using `docker logs --tail 10 `. You can also follow the logs of a container without having to read the whole log file with `docker logs --tail 0 -f `. + +*Allow a tar file as context for docker build* + +You can now pass a tar archive to `docker build` as context. This can be used to automate docker builds, for example: `cat context.tar | docker build -` or `docker run builder_image | docker build -` + +*Bind mounting your whole filesystem in a container* + +`/` is now allowed as source of `--volumes`. This means you can bind-mount your whole system in a container if you need to. For example: `docker run -v /:/my_host ubuntu:ro ls /my_host`. However, it is now forbidden to mount to /. + + +### Other Improvements & Changes + +* Port allocation has been improved. In the previous release, Docker could prevent you from starting a container with previously allocated ports which seemed to be in use when in fact they were not. This has been fixed. + +* A bug in `docker save` was introduced in the last release. The `docker save` command could produce images with invalid metadata. The command now produces images with correct metadata. + +* Running `docker inspect` in a container now returns which containers it is linked to. + +* Parsing of the `docker commit` flag has improved validation, to better prevent you from committing an image with a name such as `-m`. Image names with dashes in them potentially conflict with command line flags. + +* The API now has Improved status codes for `start` and `stop`. Trying to start a running container will now return a 304 error. + +* Performance has been improved overall. Starting the daemon is faster than in previous releases. The daemon’s performance has also been improved when it is working with large numbers of images and containers. + +* Fixed an issue with white-spaces and multi-lines in Dockerfiles. -> [Click here to go to the Docker User Guide](/userguide/). diff --git a/docs/sources/installation/binaries.md b/docs/sources/installation/binaries.md index 97e2f93c4..f6eb44fa6 100644 --- a/docs/sources/installation/binaries.md +++ b/docs/sources/installation/binaries.md @@ -36,7 +36,7 @@ In general, a 3.8 Linux kernel (or higher) is preferred, as some of the prior versions have known issues that are triggered by Docker. Note that Docker also has a client mode, which can run on virtually any -Linux kernel (it even builds on OSX!). +Linux kernel (it even builds on OS X!). ## Get the docker binary: diff --git a/docs/sources/installation/fedora.md b/docs/sources/installation/fedora.md index bcd54e6bd..a230aa6cf 100644 --- a/docs/sources/installation/fedora.md +++ b/docs/sources/installation/fedora.md @@ -48,6 +48,44 @@ Now let's verify that Docker is working. $ sudo docker run -i -t fedora /bin/bash +## Granting rights to users to use Docker + +Fedora 19 and 20 shipped with Docker 0.11. The package has already been updated +to 1.0 in Fedora 20. If you are still using the 0.11 version you will need to +grant rights to users of Docker. + +The `docker` command line tool contacts the `docker` daemon process via a +socket file `/var/run/docker.sock` owned by group `docker`. One must be +member of that group in order to contact the `docker -d` process. + + $ usermod -a -G docker login_name + +Adding users to the `docker` group is *not* necessary for Docker versions 1.0 +and above. + +## HTTP Proxy + +If you are behind a HTTP proxy server, for example in corporate settings, +you will need to add this configuration in the Docker *systemd service file*. + +Edit file `/lib/systemd/system/docker.service`. Add the following to +section `[Service]` : + + Environment="HTTP_PROXY=http://proxy.example.com:80/" + +If you have internal Docker registries that you need to contact without +proxying you can specify them via the `NO_PROXY` environment variable: + + Environment="HTTP_PROXY=http://proxy.example.com:80/" "NO_PROXY=localhost,127.0.0.0/8,docker-registry.somecorporation.com" + +Flush changes: + + $ systemctl daemon-reload + +Restart Docker: + + $ systemctl start docker + ## What next? Continue with the [User Guide](/userguide/). diff --git a/docs/sources/installation/google.md b/docs/sources/installation/google.md index c91d13612..b6c1b3d27 100644 --- a/docs/sources/installation/google.md +++ b/docs/sources/installation/google.md @@ -12,16 +12,15 @@ page_keywords: Docker, Docker documentation, installation, google, Google Comput 2. Download and configure the [Google Cloud SDK][3] to use your project with the following commands: - $ curl https://dl.google.com/dl/cloudsdk/release/install_google_cloud_sdk.bash | bash + $ curl https://sdk.cloud.google.com | bash $ gcloud auth login - Enter a cloud project id (or leave blank to not set): - ... + $ gcloud config set project 3. Start a new instance using the latest [Container-optimized image][4]: (select a zone close to you and the desired instance size) $ gcloud compute instances create docker-playground \ - --image projects/google-containers/global/images/container-vm-v20140522 \ + --image https://www.googleapis.com/compute/v1/projects/google-containers/global/images/container-vm-v20140522 \ --zone us-central1-a \ --machine-type f1-micro diff --git a/docs/sources/installation/mac.md b/docs/sources/installation/mac.md index a982c5984..2aff0e5b8 100644 --- a/docs/sources/installation/mac.md +++ b/docs/sources/installation/mac.md @@ -21,7 +21,7 @@ virtual machine and runs the Docker daemon. ## Installation -1. Download the latest release of the [Docker for OSX Installer]( +1. Download the latest release of the [Docker for OS X Installer]( https://github.com/boot2docker/osx-installer/releases) 2. Run the installer, which will install VirtualBox and the Boot2Docker management @@ -31,22 +31,18 @@ virtual machine and runs the Docker daemon. 3. Run the `Boot2Docker` app in the `Applications` folder: ![](/installation/images/osx-Boot2Docker-Start-app.png) - Or, to initiate Boot2Docker manually, open a terminal and run: + Or, to initialize Boot2Docker manually, open a terminal and run: $ boot2docker init $ boot2docker start $ export DOCKER_HOST=tcp://$(boot2docker ip 2>/dev/null):2375 - The `boot2docker init` command will ask you to enter an SSH key passphrase - the simplest - (but least secure) is to just hit [Enter]. This passphrase is used by the - `boot2docker ssh` command. - Once you have an initialized virtual machine, you can control it with `boot2docker stop` and `boot2docker start`. ## Upgrading -1. Download the latest release of the [Docker for OSX Installer]( +1. Download the latest release of the [Docker for OS X Installer]( https://github.com/boot2docker/osx-installer/releases) 2. Run the installer, which will update VirtualBox and the Boot2Docker management @@ -78,7 +74,7 @@ If you run a container with an exposed port, then you should be able to access that Nginx server using the IP address reported by: - $ boot2docker ssh ip addr show dev eth1 + $ boot2docker ip Typically, it is 192.168.59.103, but it could get changed by Virtualbox's DHCP implementation. @@ -91,7 +87,7 @@ The Boot2Docker management tool provides several commands: $ ./boot2docker Usage: ./boot2docker [] - {help|init|up|ssh|save|down|poweroff|reset|restart|config|status|info|delete|download|version} + {help|init|up|ssh|save|down|poweroff|reset|restart|config|status|info|ip|delete|download|version} [] Continue with the [User Guide](/userguide/). diff --git a/docs/sources/installation/openSUSE.md b/docs/sources/installation/openSUSE.md index ce79de269..c03c74a81 100644 --- a/docs/sources/installation/openSUSE.md +++ b/docs/sources/installation/openSUSE.md @@ -19,9 +19,11 @@ repository. # openSUSE 12.3 $ sudo zypper ar -f http://download.opensuse.org/repositories/Virtualization/openSUSE_12.3/ Virtualization + $ sudo rpm --import http://download.opensuse.org/repositories/Virtualization/openSUSE_12.3/repodata/repomd.xml.key # openSUSE 13.1 $ sudo zypper ar -f http://download.opensuse.org/repositories/Virtualization/openSUSE_13.1/ Virtualization + $ sudo rpm --import http://download.opensuse.org/repositories/Virtualization/openSUSE_13.1/repodata/repomd.xml.key Install the Docker package. @@ -43,9 +45,15 @@ If we want Docker to start at boot, we should also: The docker package creates a new group named docker. Users, other than root user, need to be part of this group in order to interact with the -Docker daemon. +Docker daemon. You can add users with: - $ sudo usermod -G docker + $ sudo usermod -a -G docker + +To verify that everything has worked as expected: + + $ sudo docker run --rm -i -t ubuntu /bin/bash + +This should download and import the `ubuntu` image, and then start `bash` in a container. To exit the container type `exit`. **Done!** diff --git a/docs/sources/installation/rackspace.md b/docs/sources/installation/rackspace.md index 1aa969d1e..9fddf5e45 100644 --- a/docs/sources/installation/rackspace.md +++ b/docs/sources/installation/rackspace.md @@ -15,7 +15,7 @@ will need to install it. And this is a little more difficult on Rackspace. Rackspace boots their servers using grub's `menu.lst` -and does not like non `virtual` packages (e.g. Xen compatible) +and does not like non `virtual` packages (e.g., Xen compatible) kernels there, although they do work. This results in `update-grub` not having the expected result, and you will need to set the kernel manually. diff --git a/docs/sources/installation/ubuntulinux.md b/docs/sources/installation/ubuntulinux.md index f1ba4971e..5d1b6c3fb 100644 --- a/docs/sources/installation/ubuntulinux.md +++ b/docs/sources/installation/ubuntulinux.md @@ -244,18 +244,18 @@ To install the latest version of docker, use the standard If you want to enable memory and swap accounting, you must add the following command-line parameters to your kernel: - $ cgroup_enable=memory swapaccount=1 + cgroup_enable=memory swapaccount=1 On systems using GRUB (which is the default for Ubuntu), you can add those parameters by editing `/etc/default/grub` and extending `GRUB_CMDLINE_LINUX`. Look for the following line: - $ GRUB_CMDLINE_LINUX="" + GRUB_CMDLINE_LINUX="" And replace it by the following one: - $ GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1" + GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1" Then run `sudo update-grub`, and reboot. @@ -283,7 +283,7 @@ forwarding: # Change: # DEFAULT_FORWARD_POLICY="DROP" # to - $ DEFAULT_FORWARD_POLICY="ACCEPT" + DEFAULT_FORWARD_POLICY="ACCEPT" Then reload UFW: @@ -316,7 +316,7 @@ Docker daemon for the containers: $ sudo nano /etc/default/docker --- # Add: - $ DOCKER_OPTS="--dns 8.8.8.8" + DOCKER_OPTS="--dns 8.8.8.8" # 8.8.8.8 could be replaced with a local DNS server, such as 192.168.1.1 # multiple DNS servers can be specified: --dns 8.8.8.8 --dns 192.168.1.1 diff --git a/docs/sources/installation/windows.md b/docs/sources/installation/windows.md index 447d8b280..9908c053d 100644 --- a/docs/sources/installation/windows.md +++ b/docs/sources/installation/windows.md @@ -5,7 +5,7 @@ page_keywords: Docker, Docker documentation, Windows, requirements, virtualbox, # Windows > **Note:** > Docker has been tested on Windows 7.1 and 8; it may also run on older versions. - +> Your processor needs to support hardware virtualization. The Docker Engine uses Linux-specific kernel features, so to run it on Windows we need to use a lightweight virtual machine (vm). You use the Windows Docker client to @@ -25,7 +25,7 @@ virtual machine and runs the Docker daemon. 2. Run the installer, which will install VirtualBox, MSYS-git, the boot2docker Linux ISO, and the Boot2Docker management tool. ![](/installation/images/windows-installer.png) -3. Run the `Boot2Docker Start` shell script from your Desktop or Program Files > Docker. +3. Run the `Boot2Docker Start` shell script from your Desktop or Program Files > Boot2Docker for Windows. The Start script will ask you to enter an ssh key passphrase - the simplest (but least secure) is to just hit [Enter]. @@ -63,7 +63,7 @@ This will download the small busybox image and print "hello world". The Boot2Docker management tool provides several commands: $ ./boot2docker - Usage: ./boot2docker [] {help|init|up|ssh|save|down|poweroff|reset|restart|config|status|info|delete|download|version} [] + Usage: ./boot2docker [] {help|init|up|ssh|save|down|poweroff|reset|restart|config|status|info|ip|delete|download|version} [] ## Container port redirection diff --git a/docs/sources/introduction/understanding-docker.md b/docs/sources/introduction/understanding-docker.md index 3a7615ebc..c79573a63 100644 --- a/docs/sources/introduction/understanding-docker.md +++ b/docs/sources/introduction/understanding-docker.md @@ -112,7 +112,7 @@ Docker images are the **build** component of Docker. #### Docker Registries Docker registries hold images. These are public or private stores from which you upload or download images. The public Docker registry is called -[Docker Hub](http://index.docker.io). It provides a huge collection of existing +[Docker Hub](http://hub.docker.com). It provides a huge collection of existing images for your use. These can be images you create yourself or you can use images that others have previously created. Docker registries are the **distribution** component of Docker. @@ -156,7 +156,7 @@ basis for a new image, for example if you have a base Apache image you could use this as the base of all your web application images. > **Note:** Docker usually gets these base images from -> [Docker Hub](https://index.docker.io). +> [Docker Hub](https://hub.docker.com). > Docker images are then built from these base images using a simple, descriptive set of steps we call *instructions*. Each instruction creates a new layer in our @@ -173,17 +173,17 @@ returns a final image. ### How does a Docker registry work? The Docker registry is the store for your Docker images. Once you build a Docker -image you can *push* it to a public registry [Docker Hub](https://index.docker.io) or to +image you can *push* it to a public registry [Docker Hub](https://hub.docker.com) or to your own registry running behind your firewall. Using the Docker client, you can search for already published images and then pull them down to your Docker host to build containers from them. -[Docker Hub](https://index.docker.io) provides both public and private storage +[Docker Hub](https://hub.docker.com) provides both public and private storage for images. Public storage is searchable and can be downloaded by anyone. Private storage is excluded from search results and only you and your users can pull images down and use them to build containers. You can [sign up for a storage plan -here](https://index.docker.io/plans). +here](https://hub.docker.com/plans). ### How does a container work? A container consists of an operating system, user-added files, and meta-data. As @@ -216,7 +216,7 @@ In order, Docker does the following: - **Pulls the `ubuntu` image:** Docker checks for the presence of the `ubuntu` image and, if it doesn't exist locally on the host, then Docker downloads it from -[Docker Hub](https://index.docker.io). If the image already exists, then Docker +[Docker Hub](https://hub.docker.com). If the image already exists, then Docker uses it for the new container. - **Creates a new container:** Once Docker has the image, it uses it to create a container. diff --git a/docs/sources/reference/api/docker_remote_api.md b/docs/sources/reference/api/docker_remote_api.md index 38cfc244e..36f35383e 100644 --- a/docs/sources/reference/api/docker_remote_api.md +++ b/docs/sources/reference/api/docker_remote_api.md @@ -18,14 +18,42 @@ page_keywords: API, Docker, rcli, REST, documentation encoded (JSON) string with credentials: `{'username': string, 'password': string, 'email': string, 'serveraddress' : string}` -The current version of the API is v1.12 +The current version of the API is v1.13 Calling `/images//insert` is the same as calling -`/v1.12/images//insert`. +`/v1.13/images//insert`. You can still call an old version of the API using `/v1.12/images//insert`. +## v1.13 + +### Full Documentation + +[*Docker Remote API v1.13*](/reference/api/docker_remote_api_v1.13/) + +### What's new + +`GET /containers/(name)/json` + +**New!** +The `HostConfig.Links` field is now filled correctly + +**New!** +`Sockets` parameter added to the `/info` endpoint listing all the sockets the +daemon is configured to listen on. + +`POST /containers/(name)/start` +`POST /containers/(name)/stop` + +**New!** +`start` and `stop` will now return 304 if the container's status is not modified + +`POST /commit` + +**New!** +Added a `pause` parameter (default `true`) to pause the container during commit + ## v1.12 ### Full Documentation @@ -350,7 +378,7 @@ List containers (/containers/json): Start containers (/containers//start): - - You can now pass host-specific configuration (e.g. bind mounts) in + - You can now pass host-specific configuration (e.g., bind mounts) in the POST body for start calls ## v1.2 diff --git a/docs/sources/reference/api/docker_remote_api_v1.0.md b/docs/sources/reference/api/docker_remote_api_v1.0.md index 2f17b2a74..b906298b8 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.0.md +++ b/docs/sources/reference/api/docker_remote_api_v1.0.md @@ -605,8 +605,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"" @@ -935,7 +935,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.1.md b/docs/sources/reference/api/docker_remote_api_v1.1.md index e777901c6..4e449bcce 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.1.md +++ b/docs/sources/reference/api/docker_remote_api_v1.1.md @@ -612,8 +612,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"" @@ -946,7 +946,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.10.md b/docs/sources/reference/api/docker_remote_api_v1.10.md index 0292c1ab2..264cdefc2 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.10.md +++ b/docs/sources/reference/api/docker_remote_api_v1.10.md @@ -286,7 +286,7 @@ List processes running inside the container `id`   - - **ps\_args** – ps arguments to use (eg. aux) + - **ps\_args** – ps arguments to use (e.g., aux) Status Codes: @@ -530,7 +530,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -1181,7 +1181,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.11.md b/docs/sources/reference/api/docker_remote_api_v1.11.md index 90a5e7f36..ae2daae40 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.11.md +++ b/docs/sources/reference/api/docker_remote_api_v1.11.md @@ -290,7 +290,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -570,7 +570,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -791,8 +791,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1099,9 +1099,15 @@ Display system-wide information { "Containers":11, "Images":16, + "Driver":"btrfs", + "ExecutionDriver":"native-0.1", + "KernelVersion":"3.12.0-1-amd64" "Debug":false, "NFd": 11, "NGoroutines":21, + "NEventsListener":0, + "InitPath":"/usr/bin/docker", + "IndexServerAddress":["https://index.docker.io/v1/"], "MemoryLimit":true, "SwapLimit":false, "IPv4Forwarding":true @@ -1217,7 +1223,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.12.md b/docs/sources/reference/api/docker_remote_api_v1.12.md index 5b6d79d2f..19fb24fe4 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.12.md +++ b/docs/sources/reference/api/docker_remote_api_v1.12.md @@ -290,7 +290,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -509,6 +509,46 @@ Kill the container `id` - **404** – no such container - **500** – server error +### Pause a container + +`POST /containers/(id)/pause` + +Pause the container `id` + + **Example request**: + + POST /containers/e90e34656806/pause HTTP/1.1 + + **Example response**: + + HTTP/1.1 204 OK + + Status Codes: + + - **204** – no error + - **404** – no such container + - **500** – server error + +### Unpause a container + +`POST /containers/(id)/unpause` + +Unpause the container `id` + + **Example request**: + + POST /containers/e90e34656806/unpause HTTP/1.1 + + **Example response**: + + HTTP/1.1 204 OK + + Status Codes: + + - **204** – no error + - **404** – no such container + - **500** – server error + ### Attach to a container `POST /containers/(id)/attach` @@ -571,7 +611,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -720,7 +760,7 @@ Copy files or folders of container `id` - **all** – 1/True/true or 0/False/false, default false - **filters** – a json encoded value of the filters (a map[string][]string) to process on the images list. - + ### Create an image @@ -825,8 +865,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1136,9 +1176,15 @@ Display system-wide information { "Containers":11, "Images":16, + "Driver":"btrfs", + "ExecutionDriver":"native-0.1", + "KernelVersion":"3.12.0-1-amd64" "Debug":false, "NFd": 11, "NGoroutines":21, + "NEventsListener":0, + "InitPath":"/usr/bin/docker", + "IndexServerAddress":["https://index.docker.io/v1/"], "MemoryLimit":true, "SwapLimit":false, "IPv4Forwarding":true @@ -1255,7 +1301,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.13.md b/docs/sources/reference/api/docker_remote_api_v1.13.md new file mode 100644 index 000000000..e0ad95794 --- /dev/null +++ b/docs/sources/reference/api/docker_remote_api_v1.13.md @@ -0,0 +1,1422 @@ +page_title: Remote API v1.12 +page_description: API Documentation for Docker +page_keywords: API, Docker, rcli, REST, documentation + +# Docker Remote API v1.13 + +## 1. Brief introduction + + - The Remote API has replaced `rcli`. + - The daemon listens on `unix:///var/run/docker.sock` but you can + [*Bind Docker to another host/port or a Unix socket*]( + /use/basics/#bind-docker). + - The API tends to be REST, but for some complex commands, like `attach` + or `pull`, the HTTP connection is hijacked to transport `STDOUT`, + `STDIN` and `STDERR`. + +# 2. Endpoints + +## 2.1 Containers + +### List containers + +`GET /containers/json` + +List containers + + **Example request**: + + GET /containers/json?all=1&before=8dfafdbc3a40&size=1 HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Id": "8dfafdbc3a40", + "Image": "base:latest", + "Command": "echo 1", + "Created": 1367854155, + "Status": "Exit 0", + "Ports":[{"PrivatePort": 2222, "PublicPort": 3333, "Type": "tcp"}], + "SizeRw":12288, + "SizeRootFs":0 + }, + { + "Id": "9cd87474be90", + "Image": "base:latest", + "Command": "echo 222222", + "Created": 1367854155, + "Status": "Exit 0", + "Ports":[], + "SizeRw":12288, + "SizeRootFs":0 + }, + { + "Id": "3176a2479c92", + "Image": "base:latest", + "Command": "echo 3333333333333333", + "Created": 1367854154, + "Status": "Exit 0", + "Ports":[], + "SizeRw":12288, + "SizeRootFs":0 + }, + { + "Id": "4cb07b47f9fb", + "Image": "base:latest", + "Command": "echo 444444444444444444444444444444444", + "Created": 1367854152, + "Status": "Exit 0", + "Ports":[], + "SizeRw":12288, + "SizeRootFs":0 + } + ] + + Query Parameters: + +   + + - **all** – 1/True/true or 0/False/false, Show all containers. + Only running containers are shown by default + - **limit** – Show `limit` last created + containers, include non-running ones. + - **since** – Show only containers created since Id, include + non-running ones. + - **before** – Show only containers created before Id, include + non-running ones. + - **size** – 1/True/true or 0/False/false, Show the containers + sizes + + Status Codes: + + - **200** – no error + - **400** – bad parameter + - **500** – server error + +### Create a container + +`POST /containers/create` + +Create a container + + **Example request**: + + POST /containers/create HTTP/1.1 + Content-Type: application/json + + { + "Hostname":"", + "User":"", + "Memory":0, + "MemorySwap":0, + "AttachStdin":false, + "AttachStdout":true, + "AttachStderr":true, + "PortSpecs":null, + "Tty":false, + "OpenStdin":false, + "StdinOnce":false, + "Env":null, + "Cmd":[ + "date" + ], + "Image":"base", + "Volumes":{ + "/tmp": {} + }, + "WorkingDir":"", + "DisableNetwork": false, + "ExposedPorts":{ + "22/tcp": {} + } + } + + **Example response**: + + HTTP/1.1 201 OK + Content-Type: application/json + + { + "Id":"e90e34656806" + "Warnings":[] + } + + Json Parameters: + +   + + - **config** – the container's configuration + + Query Parameters: + +   + + - **name** – Assign the specified name to the container. Must + match `/?[a-zA-Z0-9_-]+`. + + Status Codes: + + - **201** – no error + - **404** – no such container + - **406** – impossible to attach (container not running) + - **500** – server error + +### Inspect a container + +`GET /containers/(id)/json` + +Return low-level information on the container `id` + + + **Example request**: + + GET /containers/4fa6e0f0c678/json HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2", + "Created": "2013-05-07T14:51:42.041847+02:00", + "Path": "date", + "Args": [], + "Config": { + "Hostname": "4fa6e0f0c678", + "User": "", + "Memory": 0, + "MemorySwap": 0, + "AttachStdin": false, + "AttachStdout": true, + "AttachStderr": true, + "PortSpecs": null, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Env": null, + "Cmd": [ + "date" + ], + "Dns": null, + "Image": "base", + "Volumes": {}, + "VolumesFrom": "", + "WorkingDir":"" + + }, + "State": { + "Running": false, + "Pid": 0, + "ExitCode": 0, + "StartedAt": "2013-05-07T14:51:42.087658+02:01360", + "Ghost": false + }, + "Image": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc", + "NetworkSettings": { + "IpAddress": "", + "IpPrefixLen": 0, + "Gateway": "", + "Bridge": "", + "PortMapping": null + }, + "SysInitPath": "/home/kitty/go/src/github.com/dotcloud/docker/bin/docker", + "ResolvConfPath": "/etc/resolv.conf", + "Volumes": {}, + "HostConfig": { + "Binds": null, + "ContainerIDFile": "", + "LxcConf": [], + "Privileged": false, + "PortBindings": { + "80/tcp": [ + { + "HostIp": "0.0.0.0", + "HostPort": "49153" + } + ] + }, + "Links": ["/name:alias"], + "PublishAllPorts": false + } + } + + Status Codes: + + - **200** – no error + - **404** – no such container + - **500** – server error + +### List processes running inside a container + +`GET /containers/(id)/top` + +List processes running inside the container `id` + + **Example request**: + + GET /containers/4fa6e0f0c678/top HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Titles":[ + "USER", + "PID", + "%CPU", + "%MEM", + "VSZ", + "RSS", + "TTY", + "STAT", + "START", + "TIME", + "COMMAND" + ], + "Processes":[ + ["root","20147","0.0","0.1","18060","1864","pts/4","S","10:06","0:00","bash"], + ["root","20271","0.0","0.0","4312","352","pts/4","S+","10:07","0:00","sleep","10"] + ] + } + + Query Parameters: + +   + + - **ps_args** – ps arguments to use (e.g., aux) + + Status Codes: + + - **200** – no error + - **404** – no such container + - **500** – server error + +### Get container logs + +`GET /containers/(id)/logs` + +Get stdout and stderr logs from the container ``id`` + + **Example request**: + + GET /containers/4fa6e0f0c678/logs?stderr=1&stdout=1×tamps=1&follow=1&tail=10 HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/vnd.docker.raw-stream + + {{ STREAM }} + + Query Parameters: + +   + + - **follow** – 1/True/true or 0/False/false, return stream. Default false + - **stdout** – 1/True/true or 0/False/false, show stdout log. Default false + - **stderr** – 1/True/true or 0/False/false, show stderr log. Default false + - **timestamps** – 1/True/true or 0/False/false, print timestamps for + every log line. Default false + - **tail** – Output specified number of lines at the end of logs: `all` or ``. Default all + + Status Codes: + + - **200** – no error + - **404** – no such container + - **500** – server error + +### Inspect changes on a container's filesystem + +`GET /containers/(id)/changes` + +Inspect changes on container `id`'s filesystem + + **Example request**: + + GET /containers/4fa6e0f0c678/changes HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Path":"/dev", + "Kind":0 + }, + { + "Path":"/dev/kmsg", + "Kind":1 + }, + { + "Path":"/test", + "Kind":1 + } + ] + + Status Codes: + + - **200** – no error + - **404** – no such container + - **500** – server error + +### Export a container + +`GET /containers/(id)/export` + +Export the contents of container `id` + + **Example request**: + + GET /containers/4fa6e0f0c678/export HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/octet-stream + + {{ STREAM }} + + Status Codes: + + - **200** – no error + - **404** – no such container + - **500** – server error + +### Start a container + +`POST /containers/(id)/start` + +Start the container `id` + + **Example request**: + + POST /containers/(id)/start HTTP/1.1 + Content-Type: application/json + + { + "Binds":["/tmp:/tmp"], + "Links":["redis3:redis"], + "LxcConf":{"lxc.utsname":"docker"}, + "PortBindings":{ "22/tcp": [{ "HostPort": "11022" }] }, + "PublishAllPorts":false, + "Privileged":false, + "Dns": ["8.8.8.8"], + "VolumesFrom": ["parent", "other:ro"] + } + + **Example response**: + + HTTP/1.1 204 No Content + Content-Type: text/plain + + Json Parameters: + +   + + - **hostConfig** – the container's host configuration (optional) + + Status Codes: + + - **204** – no error + - **304** – container already started + - **404** – no such container + - **500** – server error + +### Stop a container + +`POST /containers/(id)/stop` + +Stop the container `id` + + **Example request**: + + POST /containers/e90e34656806/stop?t=5 HTTP/1.1 + + **Example response**: + + HTTP/1.1 204 OK + + Query Parameters: + +   + + - **t** – number of seconds to wait before killing the container + + Status Codes: + + - **204** – no error + - **304** – container already stopped + - **404** – no such container + - **500** – server error + +### Restart a container + +`POST /containers/(id)/restart` + +Restart the container `id` + + **Example request**: + + POST /containers/e90e34656806/restart?t=5 HTTP/1.1 + + **Example response**: + + HTTP/1.1 204 OK + + Query Parameters: + +   + + - **t** – number of seconds to wait before killing the container + + Status Codes: + + - **204** – no error + - **404** – no such container + - **500** – server error + +### Kill a container + +`POST /containers/(id)/kill` + +Kill the container `id` + + **Example request**: + + POST /containers/e90e34656806/kill HTTP/1.1 + + **Example response**: + + HTTP/1.1 204 OK + + Query Parameters + + - **signal** - Signal to send to the container: integer or string like "SIGINT". + When not set, SIGKILL is assumed and the call will waits for the container to exit. + + Status Codes: + + - **204** – no error + - **404** – no such container + - **500** – server error + +### Pause a container + +`POST /containers/(id)/pause` + +Pause the container `id` + + **Example request**: + + POST /containers/e90e34656806/pause HTTP/1.1 + + **Example response**: + + HTTP/1.1 204 OK + + Status Codes: + + - **204** – no error + - **404** – no such container + - **500** – server error + +### Unpause a container + +`POST /containers/(id)/unpause` + +Unpause the container `id` + + **Example request**: + + POST /containers/e90e34656806/unpause HTTP/1.1 + + **Example response**: + + HTTP/1.1 204 OK + + Status Codes: + + - **204** – no error + - **404** – no such container + - **500** – server error + +### Attach to a container + +`POST /containers/(id)/attach` + +Attach to the container `id` + + **Example request**: + + POST /containers/16253994b7c4/attach?logs=1&stream=0&stdout=1 HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/vnd.docker.raw-stream + + {{ STREAM }} + + Query Parameters: + +   + + - **logs** – 1/True/true or 0/False/false, return logs. Default + false + - **stream** – 1/True/true or 0/False/false, return stream. + Default false + - **stdin** – 1/True/true or 0/False/false, if stream=true, attach + to stdin. Default false + - **stdout** – 1/True/true or 0/False/false, if logs=true, return + stdout log, if stream=true, attach to stdout. Default false + - **stderr** – 1/True/true or 0/False/false, if logs=true, return + stderr log, if stream=true, attach to stderr. Default false + + Status Codes: + + - **200** – no error + - **400** – bad parameter + - **404** – no such container + - **500** – server error + + **Stream details**: + + When using the TTY setting is enabled in + [`POST /containers/create` + ](../docker_remote_api_v1.9/#post--containers-create "POST /containers/create"), + the stream is the raw data from the process PTY and client's stdin. + When the TTY is disabled, then the stream is multiplexed to separate + stdout and stderr. + + The format is a **Header** and a **Payload** (frame). + + **HEADER** + + The header will contain the information on which stream write the + stream (stdout or stderr). It also contain the size of the + associated frame encoded on the last 4 bytes (uint32). + + It is encoded on the first 8 bytes like this: + + header := [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4} + + `STREAM_TYPE` can be: + + - 0: stdin (will be written on stdout) + - 1: stdout + - 2: stderr + + `SIZE1, SIZE2, SIZE3, SIZE4` are the 4 bytes of + the uint32 size encoded as big endian. + + **PAYLOAD** + + The payload is the raw stream. + + **IMPLEMENTATION** + + The simplest way to implement the Attach protocol is the following: + + 1. Read 8 bytes + 2. chose stdout or stderr depending on the first byte + 3. Extract the frame size from the last 4 byets + 4. Read the extracted size and output it on the correct output + 5. Goto 1) + +### Wait a container + +`POST /containers/(id)/wait` + +Block until container `id` stops, then returns the exit code + + **Example request**: + + POST /containers/16253994b7c4/wait HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + {"StatusCode":0} + + Status Codes: + + - **200** – no error + - **404** – no such container + - **500** – server error + +### Remove a container + +`DELETE /containers/(id)` + +Remove the container `id` from the filesystem + + **Example request**: + + DELETE /containers/16253994b7c4?v=1 HTTP/1.1 + + **Example response**: + + HTTP/1.1 204 OK + + Query Parameters: + +   + + - **v** – 1/True/true or 0/False/false, Remove the volumes + associated to the container. Default false + - **force** – 1/True/true or 0/False/false, Removes the container + even if it was running. Default false + + Status Codes: + + - **204** – no error + - **400** – bad parameter + - **404** – no such container + - **500** – server error + +### Copy files or folders from a container + +`POST /containers/(id)/copy` + +Copy files or folders of container `id` + + **Example request**: + + POST /containers/4fa6e0f0c678/copy HTTP/1.1 + Content-Type: application/json + + { + "Resource":"test.txt" + } + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/octet-stream + + {{ STREAM }} + + Status Codes: + + - **200** – no error + - **404** – no such container + - **500** – server error + +## 2.2 Images + +### List Images + +`GET /images/json` + +**Example request**: + + GET /images/json?all=0 HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "RepoTags": [ + "ubuntu:12.04", + "ubuntu:precise", + "ubuntu:latest" + ], + "Id": "8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c", + "Created": 1365714795, + "Size": 131506275, + "VirtualSize": 131506275 + }, + { + "RepoTags": [ + "ubuntu:12.10", + "ubuntu:quantal" + ], + "ParentId": "27cf784147099545", + "Id": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc", + "Created": 1364102658, + "Size": 24653, + "VirtualSize": 180116135 + } + ] + + + Query Parameters: + +   + + - **all** – 1/True/true or 0/False/false, default false + - **filters** – a json encoded value of the filters (a map[string][]string) to process on the images list. + + + +### Create an image + +`POST /images/create` + +Create an image, either by pull it from the registry or by importing it + + **Example request**: + + POST /images/create?fromImage=base HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + {"status":"Pulling..."} + {"status":"Pulling", "progress":"1 B/ 100 B", "progressDetail":{"current":1, "total":100}} + {"error":"Invalid..."} + ... + + When using this endpoint to pull an image from the registry, the + `X-Registry-Auth` header can be used to include + a base64-encoded AuthConfig object. + + Query Parameters: + +   + + - **fromImage** – name of the image to pull + - **fromSrc** – source to import, - means stdin + - **repo** – repository + - **tag** – tag + - **registry** – the registry to pull from + + Request Headers: + +   + + - **X-Registry-Auth** – base64-encoded AuthConfig object + + Status Codes: + + - **200** – no error + - **500** – server error + +### Insert a file in an image + +`POST /images/(name)/insert` + +Insert a file from `url` in the image `name` at `path` + + **Example request**: + + POST /images/test/insert?path=/usr&url=myurl HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + {"status":"Inserting..."} + {"status":"Inserting", "progress":"1/? (n/a)", "progressDetail":{"current":1}} + {"error":"Invalid..."} + ... + + Status Codes: + + - **200** – no error + - **500** – server error + +### Inspect an image + +`GET /images/(name)/json` + +Return low-level information on the image `name` + + **Example request**: + + GET /images/base/json HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Created":"2013-03-23T22:24:18.818426-07:00", + "Container":"3d67245a8d72ecf13f33dffac9f79dcdf70f75acb84d308770391510e0c23ad0", + "ContainerConfig": + { + "Hostname":"", + "User":"", + "Memory":0, + "MemorySwap":0, + "AttachStdin":false, + "AttachStdout":false, + "AttachStderr":false, + "PortSpecs":null, + "Tty":true, + "OpenStdin":true, + "StdinOnce":false, + "Env":null, + "Cmd": ["/bin/bash"], + "Dns":null, + "Image":"base", + "Volumes":null, + "VolumesFrom":"", + "WorkingDir":"" + }, + "Id":"b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc", + "Parent":"27cf784147099545", + "Size": 6824592 + } + + Status Codes: + + - **200** – no error + - **404** – no such image + - **500** – server error + +### Get the history of an image + +`GET /images/(name)/history` + +Return the history of the image `name` + + **Example request**: + + GET /images/base/history HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Id":"b750fe79269d", + "Created":1364102658, + "CreatedBy":"/bin/bash" + }, + { + "Id":"27cf78414709", + "Created":1364068391, + "CreatedBy":"" + } + ] + + Status Codes: + + - **200** – no error + - **404** – no such image + - **500** – server error + +### Push an image on the registry + +`POST /images/(name)/push` + +Push the image `name` on the registry + + **Example request**: + + POST /images/test/push HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + {"status":"Pushing..."} + {"status":"Pushing", "progress":"1/? (n/a)", "progressDetail":{"current":1}}} + {"error":"Invalid..."} + ... + + Query Parameters: + +   + + - **registry** – the registry you wan to push, optional + + Request Headers: + +   + + - **X-Registry-Auth** – include a base64-encoded AuthConfig + object. + + Status Codes: + + - **200** – no error + - **404** – no such image + - **500** – server error + +### Tag an image into a repository + +`POST /images/(name)/tag` + +Tag the image `name` into a repository + + **Example request**: + + POST /images/test/tag?repo=myrepo&force=0 HTTP/1.1 + + **Example response**: + + HTTP/1.1 201 OK + + Query Parameters: + +   + + - **repo** – The repository to tag in + - **force** – 1/True/true or 0/False/false, default false + + Status Codes: + + - **201** – no error + - **400** – bad parameter + - **404** – no such image + - **409** – conflict + - **500** – server error + +### Remove an image + +`DELETE /images/(name)` + +Remove the image `name` from the filesystem + + **Example request**: + + DELETE /images/test HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-type: application/json + + [ + {"Untagged":"3e2f21a89f"}, + {"Deleted":"3e2f21a89f"}, + {"Deleted":"53b4f83ac9"} + ] + + Query Parameters: + +   + + - **force** – 1/True/true or 0/False/false, default false + - **noprune** – 1/True/true or 0/False/false, default false + + Status Codes: + + - **200** – no error + - **404** – no such image + - **409** – conflict + - **500** – server error + +### Search images + +`GET /images/search` + +Search for an image on [Docker Hub](https://hub.docker.com). + +> **Note**: +> The response keys have changed from API v1.6 to reflect the JSON +> sent by the registry server to the docker daemon's request. + + **Example request**: + + GET /images/search?term=sshd HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "description": "", + "is_official": false, + "is_automated": false, + "name": "wma55/u1210sshd", + "star_count": 0 + }, + { + "description": "", + "is_official": false, + "is_automated": false, + "name": "jdswinbank/sshd", + "star_count": 0 + }, + { + "description": "", + "is_official": false, + "is_automated": false, + "name": "vgauthier/sshd", + "star_count": 0 + } + ... + ] + + Query Parameters: + +   + + - **term** – term to search + + Status Codes: + + - **200** – no error + - **500** – server error + +## 2.3 Misc + +### Build an image from Dockerfile via stdin + +`POST /build` + +Build an image from Dockerfile via stdin + + **Example request**: + + POST /build HTTP/1.1 + + {{ STREAM }} + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + {"stream":"Step 1..."} + {"stream":"..."} + {"error":"Error...", "errorDetail":{"code": 123, "message": "Error..."}} + + The stream must be a tar archive compressed with one of the + following algorithms: identity (no compression), gzip, bzip2, xz. + + The archive must include a file called `Dockerfile` + at its root. It may include any number of other files, + which will be accessible in the build context (See the [*ADD build + command*](/reference/builder/#dockerbuilder)). + + Query Parameters: + +   + + - **t** – repository name (and optionally a tag) to be applied to + the resulting image in case of success + - **q** – suppress verbose build output + - **nocache** – do not use the cache when building the image + - **rm** - remove intermediate containers after a successful build (default behavior) + - **forcerm - always remove intermediate containers (includes rm) + + Request Headers: + +   + + - **Content-type** – should be set to + `"application/tar"`. + - **X-Registry-Config** – base64-encoded ConfigFile object + + Status Codes: + + - **200** – no error + - **500** – server error + +### Check auth configuration + +`POST /auth` + +Get the default username and email + + **Example request**: + + POST /auth HTTP/1.1 + Content-Type: application/json + + { + "username":"hannibal", + "password:"xxxx", + "email":"hannibal@a-team.com", + "serveraddress":"https://index.docker.io/v1/" + } + + **Example response**: + + HTTP/1.1 200 OK + + Status Codes: + + - **200** – no error + - **204** – no error + - **500** – server error + +### Display system-wide information + +`GET /info` + +Display system-wide information + + **Example request**: + + GET /info HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Containers":11, + "Images":16, + "Driver":"btrfs", + "ExecutionDriver":"native-0.1", + "KernelVersion":"3.12.0-1-amd64" + "Debug":false, + "NFd": 11, + "NGoroutines":21, + "NEventsListener":0, + "InitPath":"/usr/bin/docker", + "Sockets":["unix:///var/run/docker.sock"], + "IndexServerAddress":["https://index.docker.io/v1/"], + "MemoryLimit":true, + "SwapLimit":false, + "IPv4Forwarding":true + } + + Status Codes: + + - **200** – no error + - **500** – server error + +### Show the docker version information + +`GET /version` + +Show the docker version information + + **Example request**: + + GET /version HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "ApiVersion":"1.12", + "Version":"0.2.2", + "GitCommit":"5a2a5cc+CHANGES", + "GoVersion":"go1.0.3" + } + + Status Codes: + + - **200** – no error + - **500** – server error + +### Ping the docker server + +`GET /_ping` + +Ping the docker server + + **Example request**: + + GET /_ping HTTP/1.1 + + **Example response**: + + HTTP/1.1 200 OK + + OK + + Status Codes: + + - **200** - no error + - **500** - server error + +### Create a new image from a container's changes + +`POST /commit` + +Create a new image from a container's changes + + **Example request**: + + POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1 + Content-Type: application/json + + { + "Hostname":"", + "User":"", + "Memory":0, + "MemorySwap":0, + "AttachStdin":false, + "AttachStdout":true, + "AttachStderr":true, + "PortSpecs":null, + "Tty":false, + "OpenStdin":false, + "StdinOnce":false, + "Env":null, + "Cmd":[ + "date" + ], + "Volumes":{ + "/tmp": {} + }, + "WorkingDir":"", + "DisableNetwork": false, + "ExposedPorts":{ + "22/tcp": {} + } + } + + **Example response**: + + HTTP/1.1 201 OK + Content-Type: application/vnd.docker.raw-stream + + {"Id":"596069db4bf5"} + + Json Parameters: + + + + - **config** - the container's configuration + + Query Parameters: + +   + + - **container** – source container + - **repo** – repository + - **tag** – tag + - **m** – commit message + - **author** – author (e.g., "John Hannibal Smith + <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") + + Status Codes: + + - **201** – no error + - **404** – no such container + - **500** – server error + +### Monitor Docker's events + +`GET /events` + +Get events from docker, either in real time via streaming, or +via polling (using since) + + **Example request**: + + GET /events?since=1374067924 + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/json + + {"status":"create","id":"dfdf82bd3881","from":"base:latest","time":1374067924} + {"status":"start","id":"dfdf82bd3881","from":"base:latest","time":1374067924} + {"status":"stop","id":"dfdf82bd3881","from":"base:latest","time":1374067966} + {"status":"destroy","id":"dfdf82bd3881","from":"base:latest","time":1374067970} + + Query Parameters: + +   + + - **since** – timestamp used for polling + - **until** – timestamp used for polling + + Status Codes: + + - **200** – no error + - **500** – server error + +### Get a tarball containing all images and tags in a repository + +`GET /images/(name)/get` + +Get a tarball containing all images and metadata for the repository +specified by `name`. + + **Example request** + + GET /images/ubuntu/get + + **Example response**: + + HTTP/1.1 200 OK + Content-Type: application/x-tar + + Binary data stream + + Status Codes: + + - **200** – no error + - **500** – server error + +### Load a tarball with a set of images and tags into docker + +`POST /images/load` + +Load a set of images and tags into the docker repository. + + **Example request** + + POST /images/load + + Tarball in body + + **Example response**: + + HTTP/1.1 200 OK + + Status Codes: + + - **200** – no error + - **500** – server error + +# 3. Going further + +## 3.1 Inside `docker run` + +Here are the steps of `docker run`: + +- Create the container + +- If the status code is 404, it means the image doesn't exists: + - Try to pull it + - Then retry to create the container + +- Start the container + +- If you are not in detached mode: + - Attach to the container, using logs=1 (to have stdout and + stderr from the container's start) and stream=1 + +- If in detached mode or only stdin is attached: + - Display the container's id + +## 3.2 Hijacking + +In this version of the API, /attach, uses hijacking to transport stdin, +stdout and stderr on the same socket. This might change in the future. + +## 3.3 CORS Requests + +To enable cross origin requests to the remote api add the flag +"–api-enable-cors" when running docker in daemon mode. + + $ docker -d -H="192.168.1.9:2375" --api-enable-cors diff --git a/docs/sources/reference/api/docker_remote_api_v1.2.md b/docs/sources/reference/api/docker_remote_api_v1.2.md index cecab5bb4..37a8e1c01 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.2.md +++ b/docs/sources/reference/api/docker_remote_api_v1.2.md @@ -628,8 +628,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"" @@ -959,7 +959,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.3.md b/docs/sources/reference/api/docker_remote_api_v1.3.md index 1d60b4300..b510f660f 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.3.md +++ b/docs/sources/reference/api/docker_remote_api_v1.3.md @@ -678,8 +678,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"" @@ -1009,7 +1009,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.4.md b/docs/sources/reference/api/docker_remote_api_v1.4.md index f7d6e82c1..0e4940262 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.4.md +++ b/docs/sources/reference/api/docker_remote_api_v1.4.md @@ -264,7 +264,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -724,8 +724,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"", @@ -1055,7 +1055,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.5.md b/docs/sources/reference/api/docker_remote_api_v1.5.md index 53d970acc..33c1aeca1 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.5.md +++ b/docs/sources/reference/api/docker_remote_api_v1.5.md @@ -261,7 +261,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -725,8 +725,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"", @@ -1067,7 +1067,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.6.md b/docs/sources/reference/api/docker_remote_api_v1.6.md index 9b7cded33..4500c1554 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.6.md +++ b/docs/sources/reference/api/docker_remote_api_v1.6.md @@ -311,7 +311,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -558,7 +558,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -832,8 +832,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1163,7 +1163,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.7.md b/docs/sources/reference/api/docker_remote_api_v1.7.md index 3432e9bb2..402efa426 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.7.md +++ b/docs/sources/reference/api/docker_remote_api_v1.7.md @@ -267,7 +267,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -507,7 +507,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -751,8 +751,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1112,7 +1112,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") - **run** – config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]}) diff --git a/docs/sources/reference/api/docker_remote_api_v1.8.md b/docs/sources/reference/api/docker_remote_api_v1.8.md index 184e107cd..78fccaf28 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.8.md +++ b/docs/sources/reference/api/docker_remote_api_v1.8.md @@ -303,7 +303,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -549,7 +549,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -793,8 +793,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1157,7 +1157,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") - **run** – config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]}) diff --git a/docs/sources/reference/api/docker_remote_api_v1.9.md b/docs/sources/reference/api/docker_remote_api_v1.9.md index fc9f9b8d5..741a9ac95 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.9.md +++ b/docs/sources/reference/api/docker_remote_api_v1.9.md @@ -303,7 +303,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -553,7 +553,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -797,8 +797,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1194,7 +1194,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/hub_registry_spec.md b/docs/sources/reference/api/hub_registry_spec.md index bb0e4ec7e..1a2cf9423 100644 --- a/docs/sources/reference/api/hub_registry_spec.md +++ b/docs/sources/reference/api/hub_registry_spec.md @@ -77,11 +77,11 @@ grasp the context, here are some examples of registries: > - local mount point; > - remote docker addressed through SSH. -The latter would only require two new commands in docker, e.g. +The latter would only require two new commands in docker, e.g., `registryget` and `registryput`, wrapping access to the local filesystem (and optionally doing consistency checks). Authentication and authorization are then delegated -to SSH (e.g. with public keys). +to SSH (e.g., with public keys). ### Docker diff --git a/docs/sources/reference/api/registry_api.md b/docs/sources/reference/api/registry_api.md index f8bdd6657..2840693fa 100644 --- a/docs/sources/reference/api/registry_api.md +++ b/docs/sources/reference/api/registry_api.md @@ -62,10 +62,10 @@ grasp the context, here are some examples of registries: > - local mount point; > - remote docker addressed through SSH. -The latter would only require two new commands in docker, e.g. +The latter would only require two new commands in docker, e.g., `registryget` and `registryput`, wrapping access to the local filesystem (and optionally doing consistency checks). Authentication and authorization -are then delegated to SSH (e.g. with public keys). +are then delegated to SSH (e.g., with public keys). # Endpoints diff --git a/docs/sources/reference/api/remote_api_client_libraries.md b/docs/sources/reference/api/remote_api_client_libraries.md index e299e6ed8..d1d26a1dd 100644 --- a/docs/sources/reference/api/remote_api_client_libraries.md +++ b/docs/sources/reference/api/remote_api_client_libraries.md @@ -123,12 +123,18 @@ will add the libraries here. Active + Scala + tugboat + https://github.com/softprops/tugboat + Active + + Scala reactive-docker https://github.com/almoehi/reactive-docker Active - + Java docker-client https://github.com/spotify/docker-client diff --git a/docs/sources/reference/builder.md b/docs/sources/reference/builder.md index 8717eb7bf..91190933c 100644 --- a/docs/sources/reference/builder.md +++ b/docs/sources/reference/builder.md @@ -15,7 +15,7 @@ To [*build*](../commandline/cli/#cli-build) an image from a source repository, create a description file called Dockerfile at the root of your repository. This file will describe the steps to assemble the image. -Then call `docker build` with the path of you source repository as argument +Then call `docker build` with the path of your source repository as the argument (for example, `.`): $ sudo docker build . @@ -83,6 +83,38 @@ be treated as an argument. This allows statements like: Here is the set of instructions you can use in a Dockerfile for building images. +## .dockerignore + +If a file named `.dockerignore` exists in the source repository, then it +is interpreted as a newline-separated list of exclusion patterns. +Exclusion patterns match files or directories relative to the source repository +that will be excluded from the context. Globbing is done using Go's +[filepath.Match](http://golang.org/pkg/path/filepath#Match) rules. + +The following example shows the use of the `.dockerignore` file to exclude the +`.git` directory from the context. Its effect can be seen in the changed size of +the uploaded context. + + $ docker build . + Uploading context 18.829 MB + Uploading context + Step 0 : FROM busybox + ---> 769b9341d937 + Step 1 : CMD echo Hello World + ---> Using cache + ---> 99cc1ad10469 + Successfully built 99cc1ad10469 + $ echo ".git" > .dockerignore + $ docker build . + Uploading context 6.76 MB + Uploading context + Step 0 : FROM busybox + ---> 769b9341d937 + Step 1 : CMD echo Hello World + ---> Using cache + ---> 99cc1ad10469 + Successfully built 99cc1ad10469 + ## FROM FROM @@ -238,14 +270,19 @@ All new files and directories are created with a uid and gid of 0. In the case where `` is a remote file URL, the destination will have permissions 600. > **Note**: -> If you build using STDIN (`docker build - < somefile`), there is no -> build context, so the Dockerfile can only contain an URL based ADD -> statement. +> If you build by passing a Dockerfile through STDIN (`docker build - < somefile`), +> there is no build context, so the Dockerfile can only contain a URL +> based ADD statement. +> You can also pass a compressed archive through STDIN: +> (`docker build - < archive.tar.gz`), the `Dockerfile` at the root of +> the archive and the rest of the archive will get used at the context +> of the build. +> > **Note**: > If your URL files are protected using authentication, you will need to -> use an `RUN wget` , `RUN curl` -> or other tool from within the container as ADD does not support +> use `RUN wget` , `RUN curl` +> or use another tool from within the container as ADD does not support > authentication. The copy obeys the following rules: @@ -361,7 +398,7 @@ execute in `/bin/sh -c`: FROM ubuntu ENTRYPOINT wc -l - -For example, that Dockerfile's image will *always* take stdin as input +For example, that Dockerfile's image will *always* take STDIN as input ("-") and print the number of lines ("-l"). If you wanted to make this optional but default, you could use a CMD: diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index e496ce425..301593f2f 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -54,14 +54,14 @@ expect an integer, and they can only be specified once. -b, --bridge="" Attach containers to a pre-existing network bridge use 'none' to disable container networking --bip="" Use this CIDR notation address for the network bridge's IP, not compatible with -b - -d, --daemon=false Enable daemon mode -D, --debug=false Enable debug mode - --dns=[] Force docker to use specific DNS servers + -d, --daemon=false Enable daemon mode + --dns=[] Force Docker to use specific DNS servers --dns-search=[] Force Docker to use specific DNS search domains - -e, --exec-driver="native" Force the docker runtime to use a specific exec driver + -e, --exec-driver="native" Force the Docker runtime to use a specific exec driver -G, --group="docker" Group to assign the unix socket specified by -H when running in daemon mode use '' (the empty string) to disable setting of a group - -g, --graph="/var/lib/docker" Path to use as the root of the docker runtime + -g, --graph="/var/lib/docker" Path to use as the root of the Docker runtime -H, --host=[] The socket(s) to bind to in daemon mode specified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd. --icc=true Enable inter-container communication @@ -72,9 +72,9 @@ expect an integer, and they can only be specified once. if no value is provided: default to the default route MTU or 1500 if no default route is available -p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file -r, --restart=true Restart previously running containers - -s, --storage-driver="" Force the docker runtime to use a specific storage driver - --storage-opt=[] Set storage driver options + -s, --storage-driver="" Force the Docker runtime to use a specific storage driver --selinux-enabled=false Enable selinux support + --storage-opt=[] Set storage driver options --tls=false Use TLS; implied by tls-verify flags --tlscacert="/home/sven/.docker/ca.pem" Trust only remotes providing a certificate signed by the CA given here --tlscert="/home/sven/.docker/cert.pem" Path to TLS certificate file @@ -134,8 +134,8 @@ like this: Attach to a running container - --no-stdin=false Do not attach stdin - --sig-proxy=true Proxify all received signal to the process (even in non-tty mode) + --no-stdin=false Do not attach STDIN + --sig-proxy=true Proxify all received signals to the process (even in non-TTY mode). SIGCHLD is not proxied. The `attach` command will allow you to view or interact with any running container, detached (`-d`) @@ -199,25 +199,31 @@ To kill the container, use `docker kill`. --rm=true Remove intermediate containers after a successful build -t, --tag="" Repository name (and optionally a tag) to be applied to the resulting image in case of success -Use this command to build Docker images from a Dockerfile -and a "context". +Use this command to build Docker images from a Dockerfile and a +"context". -The files at `PATH` or `URL` are called the "context" of the build. The build -process may refer to any of the files in the context, for example when using an -[*ADD*](/reference/builder/#dockerfile-add) instruction. When a single Dockerfile is -given as `URL` or is piped through STDIN (`docker build - < Dockerfile`), then -no context is set. +The files at `PATH` or `URL` are called the "context" of the build. The +build process may refer to any of the files in the context, for example +when using an [*ADD*](/reference/builder/#dockerfile-add) instruction. +When a single Dockerfile is given as `URL` or is piped through `STDIN` +(`docker build - < Dockerfile`), then no context is set. -When a Git repository is set as `URL`, then the -repository is used as the context. The Git repository is cloned with its -submodules (git clone –recursive). A fresh git clone occurs in a -temporary directory on your local host, and then this is sent to the -Docker daemon as the context. This way, your local user credentials and -vpn's etc can be used to access private repositories. +When a Git repository is set as `URL`, then the repository is used as +the context. The Git repository is cloned with its submodules (`git +clone -recursive`). A fresh `git clone` occurs in a temporary directory +on your local host, and then this is sent to the Docker daemon as the +context. This way, your local user credentials and VPN's etc can be +used to access private repositories. + +If a file named `.dockerignore` exists in the root of `PATH` then it +is interpreted as a newline-separated list of exclusion patterns. +Exclusion patterns match files or directories relative to `PATH` that +will be excluded from the context. Globbing is done using Go's +[filepath.Match](http://golang.org/pkg/path/filepath#Match) rules. See also: -[*Dockerfile Reference*](/reference/builder/#dockerbuilder). +[*Dockerfile Reference*](/reference/builder). ### Examples: @@ -240,7 +246,7 @@ See also: drwxr-xr-x 2 root root 4.0K Mar 12 2013 tmp drwxr-xr-x 2 root root 4.0K Nov 15 23:34 usr ---> b35f4035db3f - Step 3 : CMD echo Hello World + Step 3 : CMD echo Hello world ---> Running in 02071fceb21b ---> f52f38b7823e Successfully built f52f38b7823e @@ -266,6 +272,30 @@ If you wish to keep the intermediate containers after the build is complete, you must use `--rm=false`. This does not affect the build cache. + $ docker build . + Uploading context 18.829 MB + Uploading context + Step 0 : FROM busybox + ---> 769b9341d937 + Step 1 : CMD echo Hello world + ---> Using cache + ---> 99cc1ad10469 + Successfully built 99cc1ad10469 + $ echo ".git" > .dockerignore + $ docker build . + Uploading context 6.76 MB + Uploading context + Step 0 : FROM busybox + ---> 769b9341d937 + Step 1 : CMD echo Hello world + ---> Using cache + ---> 99cc1ad10469 + Successfully built 99cc1ad10469 + +This example shows the use of the `.dockerignore` file to exclude the `.git` +directory from the context. Its effect can be seen in the changed size of the +uploaded context. + $ sudo docker build -t vieux/apache:2.0 . This will build like the previous example, but it will then tag the @@ -274,11 +304,15 @@ and the tag will be `2.0` $ sudo docker build - < Dockerfile -This will read a Dockerfile from *stdin* without -context. Due to the lack of a context, no contents of any local -directory will be sent to the `docker` daemon. Since -there is no context, a Dockerfile `ADD` -only works if it refers to a remote URL. +This will read a Dockerfile from `STDIN` without context. Due to the +lack of a context, no contents of any local directory will be sent to +the Docker daemon. Since there is no context, a Dockerfile `ADD` only +works if it refers to a remote URL. + + $ sudo docker build - < context.tar.gz + +This will build an image for a compressed context read from `STDIN`. +Supported formats are: bzip2, gzip and xz. $ sudo docker build github.com/creack/docker-firefox @@ -301,8 +335,9 @@ schema. Create a new image from a container's changes - -a, --author="" Author (eg. "John Hannibal Smith " + -a, --author="" Author (e.g., "John Hannibal Smith ") -m, --message="" Commit message + -p, --pause=true Pause container during commit It can be useful to commit a container's file changes or settings into a new image. This allows you debug a container by running an interactive @@ -310,6 +345,11 @@ shell, or to export a working dataset to another server. Generally, it is better to use Dockerfiles to manage your images in a documented and maintainable way. +By default, the container being committed and its processes will be paused +while the image is committed. This reduces the likelihood of +encountering data corruption during the process of creating the commit. +If this behavior is undesired, set the 'p' option to false. + ### Commit an existing container $ sudo docker ps @@ -324,7 +364,7 @@ maintainable way. ## cp -Copy files/folders from the containers filesystem to the host +Copy files/folders from a container's filesystem to the host path. Paths are relative to the root of the filesystem. Usage: docker cp CONTAINER:PATH HOSTPATH @@ -441,7 +481,7 @@ To see how the `docker:latest` image was built: List images -a, --all=false Show all images (by default filter out the intermediate image layers) - -f, --filter=[]: Provide filter values (i.e. 'dangling=true') + -f, --filter=[] Provide filter values (i.e. 'dangling=true') --no-trunc=false Don't truncate output -q, --quiet=false Only show numeric IDs @@ -483,8 +523,8 @@ by default. ### Filtering -The filtering flag (-f or --filter) format is of "key=value". If there are more -than one filter, then pass multiple flags (e.g. `--filter "foo=bar" --filter "bif=baz"`) +The filtering flag (`-f` or `--filter`) format is of "key=value". If there are more +than one filter, then pass multiple flags (e.g., `--filter "foo=bar" --filter "bif=baz"`) Current filters: * dangling (boolean - true or false) @@ -527,11 +567,10 @@ NOTE: Docker will warn you if any containers exist that are using these untagged Create an empty filesystem image and import the contents of the tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then optionally tag it. -URLs must start with `http` and point to a single -file archive (.tar, .tar.gz, .tgz, .bzip, .tar.xz, or .txz) containing a -root filesystem. If you would like to import from a local directory or -archive, you can use the `-` parameter to take the -data from *stdin*. +URLs must start with `http` and point to a single file archive (.tar, +.tar.gz, .tgz, .bzip, .tar.xz, or .txz) containing a root filesystem. If +you would like to import from a local directory or archive, you can use +the `-` parameter to take the data from `STDIN`. ### Examples @@ -543,7 +582,7 @@ This will create a new untagged image. **Import from a local file:** -Import to docker via pipe and *stdin*. +Import to docker via pipe and `STDIN`. $ cat exampleimage.tgz | sudo docker import - exampleimagelocal:new @@ -558,32 +597,39 @@ tar, then the ownerships might not get preserved. ## info + Usage: docker info Display system-wide information For example: - $ sudo docker info - Containers: 292 - Images: 194 + $ sudo docker -D info + Containers: 16 + Images: 2138 + Storage Driver: btrfs + Execution Driver: native-0.1 + Kernel Version: 3.12.0-1-amd64 Debug mode (server): false - Debug mode (client): false - Fds: 22 - Goroutines: 67 - LXC Version: 0.9.0 - EventsListeners: 115 - Kernel Version: 3.8.0-33-generic - WARNING: No swap limit support + Debug mode (client): true + Fds: 16 + Goroutines: 104 + EventsListeners: 0 + Init Path: /usr/bin/docker + Sockets: [unix:///var/run/docker.sock tcp://0.0.0.0:4243] + Username: svendowideit + Registry: [https://index.docker.io/v1/] -When sending issue reports, please use `docker version` and `docker info` to +The global `-D` option tells all `docker` comands to output debug information. + +When sending issue reports, please use `docker version` and `docker -D info` to ensure we know how your setup is configured. ## inspect Usage: docker inspect CONTAINER|IMAGE [CONTAINER|IMAGE...] - Return low-level information on a container/image + Return low-level information on a container or image -f, --format="" Format the output using the given go template. @@ -637,11 +683,11 @@ contains complex json object, so to grab it as JSON, you use Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...] - Kill a running container (send SIGKILL, or specified signal) + Kill a running container using SIGKILL or a specified signal -s, --signal="KILL" Signal to send to the container -The main process inside the container will be sent SIGKILL, or any +The main process inside the container will be sent `SIGKILL`, or any signal specified with option `--signal`. ## load @@ -674,7 +720,7 @@ Restores both images and tags. Usage: docker login [OPTIONS] [SERVER] - Register or Login to a docker registry server, if no server is specified "https://index.docker.io/v1/" is the default. + Register or log in to a Docker registry server, if no server is specified "https://index.docker.io/v1/" is the default. -e, --email="" Email -p, --password="" Password @@ -694,19 +740,21 @@ specify this by adding the server name. -f, --follow=false Follow log output -t, --timestamps=false Show timestamps + --tail="all" Output the specified number of lines at the end of logs (defaults to all logs) -The `docker logs` command batch-retrieves all logs -present at the time of execution. +The `docker logs` command batch-retrieves logs present at the time of execution. -The ``docker logs --follow`` command will first return all logs from the -beginning and then continue streaming new output from the container's stdout -and stderr. +The `docker logs --follow` command will continue streaming the new output from +the container's `STDOUT` and `STDERR`. + +Passing a negative number or a non-integer to `--tail` is invalid and the +value is set to `all` in that case. This behavior may change in the future. ## port Usage: docker port CONTAINER PRIVATE_PORT - Lookup the public-facing port which is NAT-ed to PRIVATE_PORT + Lookup the public-facing port that is NAT-ed to PRIVATE_PORT ## ps @@ -735,7 +783,7 @@ Running `docker ps` showing 2 linked containers. ## pull - Usage: docker pull [REGISTRY_PATH/]NAME[:TAG] + Usage: docker pull NAME[:TAG] Pull an image or a repository from the registry @@ -778,7 +826,7 @@ registry or to a self-hosted one. Restart a running container - -t, --time=10 Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default=10 + -t, --time=10 Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds. ## rm @@ -788,7 +836,7 @@ registry or to a self-hosted one. -f, --force=false Force removal of running container -l, --link=false Remove the specified link and not the underlying container - -v, --volumes=false Remove the volumes associated to the container + -v, --volumes=false Remove the volumes associated with the container ### Known Issues (rm) @@ -824,7 +872,7 @@ delete them. Any running containers will not be deleted. Remove one or more images - -f, --force=false Force + -f, --force=false Force removal of the image --no-prune=false Do not delete untagged parents ### Removing tagged images @@ -864,6 +912,7 @@ removed before the image is removed. -a, --attach=[] Attach to stdin, stdout or stderr. -c, --cpu-shares=0 CPU shares (relative weight) --cidfile="" Write the container ID to the file + --cpuset="" CPUs in which to allow execution (0-3, 0,1) -d, --detach=false Detached mode: Run container in the background, print new container id --dns=[] Set custom dns servers --dns-search=[] Set custom dns search domains @@ -881,17 +930,17 @@ removed before the image is removed. 'bridge': creates a new network stack for the container on the docker bridge 'none': no networking for this container 'container:': reuses another container network stack - 'host': use the host network stack inside the container + 'host': use the host network stack inside the container. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure. + -P, --publish-all=false Publish all exposed ports to the host interfaces -p, --publish=[] Publish a container's port to the host format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort (use 'docker port' to see the actual mapping) - -P, --publish-all=false Publish all exposed ports to the host interfaces --privileged=false Give extended privileges to this container --rm=false Automatically remove the container when it exits (incompatible with -d) - --sig-proxy=true Proxify all received signal to the process (even in non-tty mode) + --sig-proxy=true Proxify received signals to the process (even in non-tty mode). SIGCHLD is not proxied. -t, --tty=false Allocate a pseudo-tty -u, --user="" Username or UID - -v, --volume=[] Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container) + -v, --volume=[] Bind mount a volume (e.g., from the host: -v /host:/container, from docker: -v /container) --volumes-from=[] Mount volumes from the specified container(s) -w, --workdir="" Working directory inside the container @@ -1034,7 +1083,7 @@ This will create and run a new container with the container name being The `--link` flag will link the container named `/redis` into the newly created container with the alias `redis`. The new container can access the -network and environment of the redis container via environment variables. +network and environment of the `redis` container via environment variables. The `--name` flag will assign the name `console` to the newly created container. @@ -1047,19 +1096,19 @@ optionally suffixed with `:ro` or `:rw` to mount the volumes in read-only or read-write mode, respectively. By default, the volumes are mounted in the same mode (read write or read only) as the reference container. -The `-a` flag tells `docker run` to bind to the container's stdin, stdout or -stderr. This makes it possible to manipulate the output and input as needed. +The `-a` flag tells `docker run` to bind to the container's `STDIN`, `STDOUT` or +`STDERR`. This makes it possible to manipulate the output and input as needed. $ echo "test" | sudo docker run -i -a stdin ubuntu cat - This pipes data into a container and prints the container's ID by attaching -only to the container'sstdin. +only to the container's `STDIN`. $ sudo docker run -a stderr ubuntu echo test -This isn't going to print anything unless there's an error because We've -only attached to the stderr of the container. The container's logs still - store what's been written to stderr and stdout. +This isn't going to print anything unless there's an error because we've +only attached to the `STDERR` of the container. The container's logs +still store what's been written to `STDERR` and `STDOUT`. $ cat somefile | sudo docker run -i -a stdin mybuilder dobuild @@ -1104,7 +1153,7 @@ application change: Usage: docker save IMAGE - Save an image to a tar archive (streamed to stdout by default) + Save an image to a tar archive (streamed to STDOUT by default) -o, --output="" Write to an file, instead of STDOUT @@ -1129,11 +1178,11 @@ Search [Docker Hub](https://hub.docker.com) for images Usage: docker search TERM - Search the docker index for images + Search the Docker Hub for images - --no-trunc=false Don't truncate output - -s, --stars=0 Only displays with at least xxx stars - --automated=false Only show automated builds + --automated=false Only show automated builds + --no-trunc=false Don't truncate output + -s, --stars=0 Only displays with at least x stars See [*Find Public Images on Docker Hub*]( /userguide/dockerrepos/#find-public-images-on-docker-hub) for @@ -1145,8 +1194,8 @@ more details on finding shared images from the command line. Restart a stopped container - -a, --attach=false Attach container's stdout/stderr and forward all signals to the process - -i, --interactive=false Attach container's stdin + -a, --attach=false Attach container's STDOUT and STDERR and forward all signals to the process + -i, --interactive=false Attach container's STDIN When run on a container that has already been started, takes no action and succeeds unconditionally. @@ -1155,9 +1204,9 @@ takes no action and succeeds unconditionally. Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...] - Stop a running container (Send SIGTERM, and then SIGKILL after grace period) + Stop a running container by sending SIGTERM and then SIGKILL after a grace period - -t, --time=10 Number of seconds to wait for the container to stop before killing it. + -t, --time=10 Number of seconds to wait for the container to stop before killing it. Default is 10 seconds. The main process inside the container will receive SIGTERM, and after a grace period, SIGKILL @@ -1178,13 +1227,13 @@ them to [*Share Images via Repositories*]( Usage: docker top CONTAINER [ps OPTIONS] - Lookup the running processes of a container + Display the running processes of a container ## version Usage: docker version - Show the docker version information. + Show the Docker version information. Show the Docker version, API version, Git commit, and Go version of both Docker client and daemon. @@ -1194,3 +1243,4 @@ both Docker client and daemon. Usage: docker wait CONTAINER [CONTAINER...] Block until a container stops, then print its exit code. + diff --git a/docs/sources/reference/run.md b/docs/sources/reference/run.md index 5cb050c02..a539ab0d1 100644 --- a/docs/sources/reference/run.md +++ b/docs/sources/reference/run.md @@ -5,13 +5,13 @@ page_keywords: docker, run, configure, runtime # Docker Run Reference **Docker runs processes in isolated containers**. When an operator -executes `docker run`, she starts a process with its -own file system, its own networking, and its own isolated process tree. -The [*Image*](/terms/image/#image-def) which starts the process may -define defaults related to the binary to run, the networking to expose, -and more, but `docker run` gives final control to -the operator who starts the container from the image. That's the main -reason [*run*](/reference/commandline/cli/#cli-run) has more options than any +executes `docker run`, she starts a process with its own file system, +its own networking, and its own isolated process tree. The +[*Image*](/terms/image/#image-def) which starts the process may define +defaults related to the binary to run, the networking to expose, and +more, but `docker run` gives final control to the operator who starts +the container from the image. That's the main reason +[*run*](/reference/commandline/cli/#cli-run) has more options than any other `docker` command. ## General Form @@ -36,10 +36,10 @@ The list of `[OPTIONS]` breaks down into two groups: 2. Setting shared between operators and developers, where operators can override defaults developers set in images at build time. -Together, the `docker run [OPTIONS]` give complete -control over runtime behavior to the operator, allowing them to override -all defaults set by the developer during `docker build` -and nearly all the defaults set by the Docker runtime itself. +Together, the `docker run [OPTIONS]` give complete control over runtime +behavior to the operator, allowing them to override all defaults set by +the developer during `docker build` and nearly all the defaults set by +the Docker runtime itself. ## Operator Exclusive Options @@ -54,10 +54,8 @@ following options. - [PID Equivalent](#pid-equivalent) - [Network Settings](#network-settings) - [Clean Up (--rm)](#clean-up-rm) - - [Runtime Constraints on CPU and - Memory](#runtime-constraints-on-cpu-and-memory) - - [Runtime Privilege and LXC - Configuration](#runtime-privilege-and-lxc-configuration) + - [Runtime Constraints on CPU and Memory](#runtime-constraints-on-cpu-and-memory) + - [Runtime Privilege and LXC Configuration](#runtime-privilege-and-lxc-configuration) ## Detached vs Foreground @@ -78,32 +76,32 @@ container in the detached mode, then you cannot use the `--rm` option. ### Foreground -In foreground mode (the default when `-d` is not specified), `docker run` -can start the process in the container and attach the console to the process's -standard input, output, and standard error. It can even pretend to be a TTY -(this is what most command line executables expect) and pass along signals. All -of that is configurable: +In foreground mode (the default when `-d` is not specified), `docker +run` can start the process in the container and attach the console to +the process's standard input, output, and standard error. It can even +pretend to be a TTY (this is what most command line executables expect) +and pass along signals. All of that is configurable: - -a=[] : Attach to ``stdin``, ``stdout`` and/or ``stderr`` + -a=[] : Attach to `STDIN`, `STDOUT` and/or `STDERR` -t=false : Allocate a pseudo-tty --sig-proxy=true: Proxify all received signal to the process (even in non-tty mode) -i=false : Keep STDIN open even if not attached -If you do not specify `-a` then Docker will [attach everything (stdin,stdout,stderr)]( -https://github.com/dotcloud/docker/blob/ -75a7f4d90cde0295bcfb7213004abce8d4779b75/commands.go#L1797). You can specify to which -of the three standard streams (`stdin`, `stdout`, `stderr`) you'd like to connect -instead, as in: +If you do not specify `-a` then Docker will [attach all standard +streams]( https://github.com/dotcloud/docker/blob/ +75a7f4d90cde0295bcfb7213004abce8d4779b75/commands.go#L1797). You can +specify to which of the three standard streams (`STDIN`, `STDOUT`, +`STDERR`) you'd like to connect instead, as in: $ docker run -a stdin -a stdout -i -t ubuntu /bin/bash -For interactive processes (like a shell) you will typically want a tty as well as -persistent standard input (`stdin`), so you'll use `-i -t` together in most -interactive cases. +For interactive processes (like a shell) you will typically want a tty +as well as persistent standard input (`STDIN`), so you'll use `-i -t` +together in most interactive cases. ## Container Identification -### Name (–name) +### Name (–-name) The operator can identify a container in three ways: @@ -113,19 +111,18 @@ The operator can identify a container in three ways: - Name ("evil_ptolemy") The UUID identifiers come from the Docker daemon, and if you do not -assign a name to the container with `--name` then -the daemon will also generate a random string name too. The name can -become a handy way to add meaning to a container since you can use this -name when defining -[*links*](/userguide/dockerlinks/#working-with-links-names) -(or any other place you need to identify a container). This works for -both background and foreground Docker containers. +assign a name to the container with `--name` then the daemon will also +generate a random string name too. The name can become a handy way to +add meaning to a container since you can use this name when defining +[*links*](/userguide/dockerlinks/#working-with-links-names) (or any +other place you need to identify a container). This works for both +background and foreground Docker containers. -### PID Equivalent +### PID Equivalent -And finally, to help with automation, you can have Docker write the +Finally, to help with automation, you can have Docker write the container ID out to a file of your choosing. This is similar to how some -programs might write out their process ID to a file (you`ve seen them as +programs might write out their process ID to a file (you've seen them as PID files): --cidfile="": Write the container ID to the file @@ -141,14 +138,14 @@ PID files): By default, all containers have networking enabled and they can make any outgoing connections. The operator can completely disable networking -with `docker run --net none` which disables all incoming and -outgoing networking. In cases like this, you would perform I/O through -files or STDIN/STDOUT only. +with `docker run --net none` which disables all incoming and outgoing +networking. In cases like this, you would perform I/O through files or +`STDIN` and `STDOUT` only. Your container will use the same DNS servers as the host by default, but you can override this with `--dns`. -Supported networking modes are: +Supported networking modes are: * none - no networking in the container * bridge - (default) connect the container to the bridge via veth interfaces @@ -156,41 +153,46 @@ Supported networking modes are: * container - use another container's network stack #### Mode: none -With the networking mode set to `none` a container will not have a access to -any external routes. The container will still have a `loopback` interface -enabled in the container but it does not have any routes to external traffic. + +With the networking mode set to `none` a container will not have a +access to any external routes. The container will still have a +`loopback` interface enabled in the container but it does not have any +routes to external traffic. #### Mode: bridge -With the networking mode set to `bridge` a container will use docker's default -networking setup. A bridge is setup on the host, commonly named `docker0`, -and a pair of veth interfaces will be created for the container. One side of -the veth pair will remain on the host attached to the bridge while the other -side of the pair will be placed inside the container's namespaces in addition -to the `loopback` interface. An IP address will be allocated for containers -on the bridge's network and trafic will be routed though this bridge to the -container. + +With the networking mode set to `bridge` a container will use docker's +default networking setup. A bridge is setup on the host, commonly named +`docker0`, and a pair of `veth` interfaces will be created for the +container. One side of the `veth` pair will remain on the host attached +to the bridge while the other side of the pair will be placed inside the +container's namespaces in addition to the `loopback` interface. An IP +address will be allocated for containers on the bridge's network and +traffic will be routed though this bridge to the container. #### Mode: host + With the networking mode set to `host` a container will share the host's -network stack and all interfaces from the host will be available to the -container. The container's hostname will match the hostname on the host -system. Publishing ports and linking to other containers will not work -when sharing the host's network stack. +network stack and all interfaces from the host will be available to the +container. The container's hostname will match the hostname on the host +system. Publishing ports and linking to other containers will not work +when sharing the host's network stack. #### Mode: container -With the networking mode set to `container` a container will share the -network stack of another container. The other container's name must be + +With the networking mode set to `container` a container will share the +network stack of another container. The other container's name must be provided in the format of `--net container:`. -Example running a redis container with redis binding to localhost then -running the redis-cli and connecting to the redis server over the -localhost interface. +Example running a Redis container with Redis binding to `localhost` then +running the `redis-cli` command and connecting to the Redis server over the +`localhost` interface. $ docker run -d --name redis example/redis --bind 127.0.0.1 $ # use the redis container's network stack to access localhost $ docker run --rm -ti --net container:redis example/redis-cli -h 127.0.0.1 -## Clean Up (–rm) +## Clean Up (–-rm) By default a container's file system persists even after the container exits. This makes debugging a lot easier (since you can inspect the @@ -211,15 +213,14 @@ container: -c=0 : CPU shares (relative weight) The operator can constrain the memory available to a container easily -with `docker run -m`. If the host supports swap -memory, then the `-m` memory setting can be larger -than physical RAM. +with `docker run -m`. If the host supports swap memory, then the `-m` +memory setting can be larger than physical RAM. Similarly the operator can increase the priority of this container with -the `-c` option. By default, all containers run at -the same priority and get the same proportion of CPU cycles, but you can -tell the kernel to give more shares of CPU time to one or more -containers when you start them via Docker. +the `-c` option. By default, all containers run at the same priority and +get the same proportion of CPU cycles, but you can tell the kernel to +give more shares of CPU time to one or more containers when you start +them via Docker. ## Runtime Privilege and LXC Configuration @@ -239,7 +240,7 @@ to access to all devices on the host as well as set some configuration in AppArmor to allow the container nearly all the same access to the host as processes running outside containers on the host. Additional information about running with `--privileged` is available on the -[Docker Blog](http://blog.docker.io/2013/09/docker-can-now-run-within-docker/). +[Docker Blog](http://blog.docker.com/2013/09/docker-can-now-run-within-docker/). If the Docker daemon was started using the `lxc` exec-driver (`docker -d --exec-driver=lxc`) then the operator can also specify LXC options @@ -277,19 +278,20 @@ commandline: $ docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...] -This command is optional because the person who created the `IMAGE` may have -already provided a default `COMMAND` using the Dockerfile `CMD`. As the -operator (the person running a container from the image), you can override that -`CMD` just by specifying a new `COMMAND`. +This command is optional because the person who created the `IMAGE` may +have already provided a default `COMMAND` using the Dockerfile `CMD` +instruction. As the operator (the person running a container from the +image), you can override that `CMD` instruction just by specifying a new +`COMMAND`. -If the image also specifies an `ENTRYPOINT` then the `CMD` or `COMMAND` get -appended as arguments to the `ENTRYPOINT`. +If the image also specifies an `ENTRYPOINT` then the `CMD` or `COMMAND` +get appended as arguments to the `ENTRYPOINT`. ## ENTRYPOINT (Default Command to Execute at Runtime) --entrypoint="": Overwrite the default entrypoint set by the image -The ENTRYPOINT of an image is similar to a `COMMAND` because it +The `ENTRYPOINT` of an image is similar to a `COMMAND` because it specifies what executable to run when the container starts, but it is (purposely) more difficult to override. The `ENTRYPOINT` gives a container its default nature or behavior, so that when you set an @@ -310,10 +312,10 @@ or two examples of how to pass more parameters to that ENTRYPOINT: ## EXPOSE (Incoming Ports) -The Dockerfile doesn't give much control over networking, only providing the -`EXPOSE` instruction to give a hint to the operator about what incoming ports -might provide services. The following options work with or override the -Dockerfile's exposed defaults: +The Dockerfile doesn't give much control over networking, only providing +the `EXPOSE` instruction to give a hint to the operator about what +incoming ports might provide services. The following options work with +or override the Dockerfile's exposed defaults: --expose=[]: Expose a port from the container without publishing it to your host @@ -324,34 +326,34 @@ Dockerfile's exposed defaults: (use 'docker port' to see the actual mapping) --link="" : Add link to another container (name:alias) -As mentioned previously, `EXPOSE` (and `--expose`) make a port available **in** -a container for incoming connections. The port number on the inside of the -container (where the service listens) does not need to be the same number as the -port exposed on the outside of the container (where clients connect), so inside -the container you might have an HTTP service listening on port 80 (and so you -`EXPOSE 80` in the Dockerfile), but outside the container the port might be -42800. +As mentioned previously, `EXPOSE` (and `--expose`) make a port available +**in** a container for incoming connections. The port number on the +inside of the container (where the service listens) does not need to be +the same number as the port exposed on the outside of the container +(where clients connect), so inside the container you might have an HTTP +service listening on port 80 (and so you `EXPOSE 80` in the Dockerfile), +but outside the container the port might be 42800. -To help a new client container reach the server container's internal port -operator `--expose`'d by the operator or `EXPOSE`'d by the developer, the -operator has three choices: start the server container with `-P` or `-p,` or -start the client container with `--link`. +To help a new client container reach the server container's internal +port operator `--expose`'d by the operator or `EXPOSE`'d by the +developer, the operator has three choices: start the server container +with `-P` or `-p,` or start the client container with `--link`. If the operator uses `-P` or `-p` then Docker will make the exposed port -accessible on the host and the ports will be available to any client that -can reach the host. To find the map between the host ports and the exposed -ports, use `docker port`) +accessible on the host and the ports will be available to any client +that can reach the host. To find the map between the host ports and the +exposed ports, use `docker port`) -If the operator uses `--link` when starting the new client container, then the -client container can access the exposed port via a private networking interface. -Docker will set some environment variables in the client container to help -indicate which interface and port to use. +If the operator uses `--link` when starting the new client container, +then the client container can access the exposed port via a private +networking interface. Docker will set some environment variables in the +client container to help indicate which interface and port to use. ## ENV (Environment Variables) -The operator can **set any environment variable** in the container by using one -or more `-e` flags, even overriding those already defined by the developer with -a Dockefile `ENV`: +The operator can **set any environment variable** in the container by +using one or more `-e` flags, even overriding those already defined by +the developer with a Dockerfile `ENV`: $ docker run -e "deep=purple" --rm ubuntu /bin/bash -c export declare -x HOME="/" @@ -420,18 +422,19 @@ mechanism to communicate with a linked container by its alias: If "container-dir" is missing, then docker creates a new volume. --volumes-from="": Mount all volumes from the given container(s) -The volumes commands are complex enough to have their own documentation in -section [*Share Directories via Volumes*](/userguide/dockervolumes/#volume-def). -A developer can define one or more `VOLUME's associated with an image, but only the -operator can give access from one container to another (or from a container to a +The volumes commands are complex enough to have their own documentation +in section [*Share Directories via +Volumes*](/userguide/dockervolumes/#volume-def). A developer can define +one or more `VOLUME`'s associated with an image, but only the operator +can give access from one container to another (or from a container to a volume mounted on the host). ## USER -The default user within a container is `root` (id = 0), but if the developer -created additional users, those are accessible too. The developer can set a -default user to run the first process with the `Dockerfile USER` command, -but the operator can override it: +The default user within a container is `root` (id = 0), but if the +developer created additional users, those are accessible too. The +developer can set a default user to run the first process with the +Dockerfile `USER` instruction, but the operator can override it: -u="": Username or UID diff --git a/docs/sources/terms/repository.md b/docs/sources/terms/repository.md index 52c83d45d..c4d1d4353 100644 --- a/docs/sources/terms/repository.md +++ b/docs/sources/terms/repository.md @@ -13,10 +13,10 @@ server. Images can be associated with a repository (or multiple) by giving them an image name using one of three different commands: -1. At build time (e.g. `sudo docker build -t IMAGENAME`), -2. When committing a container (e.g. +1. At build time (e.g., `sudo docker build -t IMAGENAME`), +2. When committing a container (e.g., `sudo docker commit CONTAINERID IMAGENAME`) or -3. When tagging an image id with an image name (e.g. +3. When tagging an image id with an image name (e.g., `sudo docker tag IMAGEID IMAGENAME`). A Fully Qualified Image Name (FQIN) can be made up of 3 parts: diff --git a/docs/sources/userguide/dockerhub.md b/docs/sources/userguide/dockerhub.md index 99e9a0a92..5bb1edec8 100644 --- a/docs/sources/userguide/dockerhub.md +++ b/docs/sources/userguide/dockerhub.md @@ -65,7 +65,7 @@ Your Docker Hub account is now active and ready for you to use! ## Next steps -Next, let's start learning how to Dockerize applications with our "Hello World!" +Next, let's start learning how to Dockerize applications with our "Hello world" exercise. Go to [Dockerizing Applications](/userguide/dockerizing). diff --git a/docs/sources/userguide/dockerimages.md b/docs/sources/userguide/dockerimages.md index b58be9044..c3f5461c2 100644 --- a/docs/sources/userguide/dockerimages.md +++ b/docs/sources/userguide/dockerimages.md @@ -239,7 +239,7 @@ Let's create a directory and a `Dockerfile` first. $ cd sinatra $ touch Dockerfile -Each instructions creates a new layer of the image. Let's look at a simple +Each instruction creates a new layer of the image. Let's look at a simple example now for building our own Sinatra image for our development team. # This is a comment @@ -380,7 +380,7 @@ containers]( Let's delete the `training/sinatra` image as we don't need it anymore. - $ docker rmi training/sinatra + $ sudo docker rmi training/sinatra Untagged: training/sinatra:latest Deleted: 5bc342fa0b91cabf65246837015197eecfa24b2213ed6a51a8974ae250fedd8d Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f diff --git a/docs/sources/userguide/dockerizing.md b/docs/sources/userguide/dockerizing.md index afe18ce8d..02ac90306 100644 --- a/docs/sources/userguide/dockerizing.md +++ b/docs/sources/userguide/dockerizing.md @@ -1,20 +1,20 @@ -page_title: Dockerizing Applications: A "Hello World!" -page_description: A simple "Hello World!" exercise that introduced you to Docker. +page_title: Dockerizing Applications: A "Hello world" +page_description: A simple "Hello world" exercise that introduced you to Docker. page_keywords: docker guide, docker, docker platform, virtualization framework, how to, dockerize, dockerizing apps, dockerizing applications, container, containers -# Dockerizing Applications: A "Hello World!" +# Dockerizing Applications: A "Hello world" *So what's this Docker thing all about?* Docker allows you to run applications inside containers. Running an application inside a container takes a single command: `docker run`. -## Hello World! +## Hello world Let's try it now. - $ sudo docker run ubuntu:14.04 /bin/echo 'Hello World' - Hello World! + $ sudo docker run ubuntu:14.04 /bin/echo 'Hello world' + Hello world And you just launched your first container! @@ -34,17 +34,17 @@ image registry: [Docker Hub](https://hub.docker.com). Next we told Docker what command to run inside our new container: - /bin/echo 'Hello World!' + /bin/echo 'Hello world' When our container was launched Docker created a new Ubuntu 14.04 environment and then executed the `/bin/echo` command inside it. We saw the result on the command line: - Hello World! + Hello world So what happened to our container after that? Well Docker containers only run as long as the command you specify is active. Here, as soon as -`Hello World!` was echoed, the container stopped. +`Hello world` was echoed, the container stopped. ## An Interactive Container @@ -88,7 +88,7 @@ use the `exit` command to finish. As with our previous container, once the Bash shell process has finished, the container is stopped. -## A Daemonized Hello World! +## A Daemonized Hello world Now a container that runs a command and then exits has some uses but it's not overly helpful. Let's create a container that runs as a daemon, @@ -99,7 +99,7 @@ Again we can do this with the `docker run` command: $ sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done" 1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147 -Wait what? Where's our "Hello World!" Let's look at what we've run here. +Wait what? Where's our "Hello world" Let's look at what we've run here. It should look pretty familiar. We ran `docker run` but this time we specified a flag: `-d`. The `-d` flag tells Docker to run the container and put it in the background, to daemonize it. @@ -131,7 +131,7 @@ world` daemon. Firstly let's make sure our container is running. We can do that with the `docker ps` command. The `docker ps` command queries -the Docker daemon for information about all the container it knows +the Docker daemon for information about all the containers it knows about. $ sudo docker ps diff --git a/docs/sources/userguide/dockerlinks.md b/docs/sources/userguide/dockerlinks.md index 833f4aed9..20a5c1a17 100644 --- a/docs/sources/userguide/dockerlinks.md +++ b/docs/sources/userguide/dockerlinks.md @@ -94,7 +94,7 @@ yourself. This naming provides two useful functions: that makes it easier for you to remember them, for example naming a container with a web application in it `web`. -2. It provides Docker with reference point that allows it to refer to other +2. It provides Docker with a reference point that allows it to refer to other containers, for example link container `web` to container `db`. You can name your container by using the `--name` flag, for example: @@ -169,10 +169,12 @@ Docker exposes connectivity information for the parent container inside the child container in two ways: * Environment variables, -* Updating the `/etc/host` file. +* Updating the `/etc/hosts` file. Let's look first at the environment variables Docker sets. Let's run the `env` command to list the container's environment variables. + +``` $ sudo docker run --rm --name web2 --link db:db training/webapp env . . . DB_NAME=/web2/db @@ -182,6 +184,7 @@ command to list the container's environment variables. DB_PORT_5000_TCP_PORT=5432 DB_PORT_5000_TCP_ADDR=172.17.0.5 . . . +``` > **Note**: > These Environment variables are only set for the first process in the @@ -189,8 +192,8 @@ command to list the container's environment variables. > will scrub them when spawning shells for connection. We can see that Docker has created a series of environment variables with -useful information about our `db` container. Each variables is prefixed with -`DB` which is populated from the `alias` we specified above. If our `alias` +useful information about our `db` container. Each variable is prefixed with +`DB_` which is populated from the `alias` we specified above. If our `alias` were `db1` the variables would be prefixed with `DB1_`. You can use these environment variables to configure your applications to connect to the database on the `db` container. The connection will be secure, private and only the diff --git a/docs/sources/userguide/dockerrepos.md b/docs/sources/userguide/dockerrepos.md index 5babfc76f..a73c4b783 100644 --- a/docs/sources/userguide/dockerrepos.md +++ b/docs/sources/userguide/dockerrepos.md @@ -1,37 +1,49 @@ page_title: Working with Docker Hub -page_description: Learning how to use Docker Hub to manage images and work flow +page_description: Learn how to use the Docker Hub to manage Docker images and work flow page_keywords: repo, Docker Hub, Docker Hub, registry, index, repositories, usage, pull image, push image, image, documentation # Working with Docker Hub -So far we've seen a lot about how to use Docker on the command line and -your local host. We've seen [how to pull down -images](/userguide/usingdocker/) that you can run your containers from -and we've seen how to [create your own images](/userguide/dockerimages). +So far you've learned how to use the command line to run Docker on your local host. +You've learned how to [pull down images](/userguide/usingdocker/) to build containers +from existing images and you've learned how to [create your own images](/userguide/dockerimages). -Now we're going to learn a bit more about -[Docker Hub](https://hub.docker.com) and how you can use it to enhance -your Docker work flows. +Next, you're going to learn how to use the [Docker Hub](https://hub.docker.com) to +simplify and enhance your Docker workflows. -[Docker Hub](https://hub.docker.com) is the public registry that Docker -Inc maintains. It contains a huge collection of images, over 15,000, -that you can download and use to build your containers. It also provides -authentication, structure (you can setup teams and organizations), work -flow tools like webhooks and build triggers as well as privacy features -like private repositories for storing images you don't want to publicly -share. +The [Docker Hub](https://hub.docker.com) is a public registry maintained by Docker, +Inc. It contains over 15,000 images you can download and use to build containers. It also +provides authentication, work group structure, workflow tools like webhooks and build +triggers, and privacy tools like private repositories for storing images you don't want +to share publicly. ## Docker commands and Docker Hub -Docker acts as a client for these services via the `docker search`, -`pull`, `login` and `push` commands. +Docker itself provides access to Docker Hub services via the `docker search`, +`pull`, `login`, and `push` commands. This page will show you how these commands work. + +### Account creation and login +Typically, you'll want to start by creating an account on Docker Hub (if you haven't +already) and logging in. You can create your account directly on +[Docker Hub](https://hub.docker.com/account/signup/), or by running: + + $ sudo docker login + +This will prompt you for a user name, which will become the public namespace for your +public repositories. +If your user name is available, Docker will prompt you to enter a password and your +e-mail address. It will then automatically log you in. You can now commit and +push your own images up to your repos on Docker Hub. + +> **Note:** +> Your authentication credentials will be stored in the [`.dockercfg` +> authentication file](#authentication-file) in your home directory. ## Searching for images -As we've already seen we can search the -[Docker Hub](https://hub.docker.com) registry via it's search interface -or using the command line interface. Searching can find images by name, -user name or description: +You can search the [Docker Hub](https://hub.docker.com) registry via its search +interface or by using the command line interface. Searching can find images by image +name, user name, or description: $ sudo docker search centos NAME DESCRIPTION STARS OFFICIAL TRUSTED @@ -41,12 +53,12 @@ user name or description: There you can see two example results: `centos` and `tianon/centos`. The second result shows that it comes from -the public repository of a user, `tianon/`, while the first result, -`centos`, doesn't explicitly list a repository so it comes from the +the public repository of a user, named `tianon/`, while the first result, +`centos`, doesn't explicitly list a repository which means that it comes from the trusted top-level namespace. The `/` character separates a user's -repository and the image name. +repository from the image name. -Once you have found the image you want, you can download it: +Once you've found the image you want, you can download it with `docker pull `: $ sudo docker pull centos Pulling repository centos @@ -55,84 +67,63 @@ Once you have found the image you want, you can download it: 511136ea3c5a: Download complete 7064731afe90: Download complete -The image is now available to run a container from. +You now have an image from which you can run containers. ## Contributing to Docker Hub Anyone can pull public images from the [Docker Hub](https://hub.docker.com) registry, but if you would like to share your own images, then you must -register a user first as we saw in the [first section of the Docker User +register first, as we saw in the [first section of the Docker User Guide](/userguide/dockerhub/). -To refresh your memory, you can create your user name and login to -[Docker Hub](https://hub.docker.com/account/signup/), or by running: - - $ sudo docker login - -This will prompt you for a user name, which will become a public -namespace for your public repositories, for example: - - training/webapp - -Here `training` is the user name and `webapp` is a repository owned by -that user. - -If your user name is available then `docker` will also prompt you to -enter a password and your e-mail address. It will then automatically log -you in. Now you're ready to commit and push your own images! - -> **Note:** -> Your authentication credentials will be stored in the [`.dockercfg` -> authentication file](#authentication-file) in your home directory. - ## Pushing a repository to Docker Hub -In order to push an repository to its registry you need to have named an image, +In order to push a repository to its registry, you need to have named an image or committed your container to a named image as we saw [here](/userguide/dockerimages). -Now you can push this repository to the registry designated by its name -or tag. +Now you can push this repository to the registry designated by its name or tag. $ sudo docker push yourname/newimage -The image will then be uploaded and available for use. +The image will then be uploaded and available for use by your team-mates and/or the +community. ## Features of Docker Hub -Now let's look at some of the features of Docker Hub. You can find more -information [here](/docker-io/). +Let's take a closer look at some of the features of Docker Hub. You can find more +information [here](http://docs.docker.com/docker-hub/). * Private repositories * Organizations and teams * Automated Builds * Webhooks -## Private Repositories +### Private Repositories Sometimes you have images you don't want to make public and share with everyone. So Docker Hub allows you to have private repositories. You can sign up for a plan [here](https://registry.hub.docker.com/plans/). -## Organizations and teams +### Organizations and teams One of the useful aspects of private repositories is that you can share them only with members of your organization or team. Docker Hub lets you create organizations where you can collaborate with your colleagues and -manage private repositories. You can create and manage an organization +manage private repositories. You can learn how to create and manage an organization [here](https://registry.hub.docker.com/account/organizations/). -## Automated Builds +### Automated Builds -Automated Builds automate the building and updating of images from [GitHub](https://www.github.com) -or [BitBucket](http://bitbucket.com), directly on Docker Hub. It works by adding a commit hook to -your selected GitHub or BitBucket repository, triggering a build and update when you push a -commit. +Automated Builds automate the building and updating of images from +[GitHub](https://www.github.com) or [BitBucket](http://bitbucket.com), directly on Docker +Hub. It works by adding a commit hook to your selected GitHub or BitBucket repository, +triggering a build and update when you push a commit. -### To setup an Automated Build +#### To setup an Automated Build 1. Create a [Docker Hub account](https://hub.docker.com/) and login. -2. Link your GitHub or BitBucket account through the [`Link Accounts`](https://registry.hub.docker.com/account/accounts/) menu. +2. Link your GitHub or BitBucket account through the ["Link Accounts"](https://registry.hub.docker.com/account/accounts/) menu. 3. [Configure an Automated Build](https://registry.hub.docker.com/builds/). 4. Pick a GitHub or BitBucket project that has a `Dockerfile` that you want to build. 5. Pick the branch you want to build (the default is the `master` branch). @@ -141,33 +132,32 @@ commit. 8. Specify where the `Dockerfile` is located. The default is `/`. Once the Automated Build is configured it will automatically trigger a -build, and in a few minutes, if there are no errors, you will see your -new Automated Build on the [Docker Hub](https://hub.docker.com) Registry. -It will stay in sync with your GitHub and BitBucket repository until you +build and, in a few minutes, you should see your new Automated Build on the [Docker Hub](https://hub.docker.com) +Registry. It will stay in sync with your GitHub and BitBucket repository until you deactivate the Automated Build. -If you want to see the status of your Automated Builds you can go to your +If you want to see the status of your Automated Builds, you can go to your [Automated Builds page](https://registry.hub.docker.com/builds/) on the Docker Hub, -and it will show you the status of your builds, and the build history. +and it will show you the status of your builds and their build history. Once you've created an Automated Build you can deactivate or delete it. You -cannot however push to an Automated Build with the `docker push` command. +cannot, however, push to an Automated Build with the `docker push` command. You can only manage it by committing code to your GitHub or BitBucket repository. You can create multiple Automated Builds per repository and configure them to point to specific `Dockerfile`'s or Git branches. -### Build Triggers +#### Build Triggers Automated Builds can also be triggered via a URL on Docker Hub. This allows you to rebuild an Automated build image on demand. -## Webhooks +### Webhooks Webhooks are attached to your repositories and allow you to trigger an event when an image or updated image is pushed to the repository. With -a webhook you can specify a target URL and a JSON payload will be +a webhook you can specify a target URL and a JSON payload that will be delivered when the image is pushed. ## Next steps diff --git a/docs/sources/userguide/dockervolumes.md b/docs/sources/userguide/dockervolumes.md index 0c2f6cfac..93ac37b1c 100644 --- a/docs/sources/userguide/dockervolumes.md +++ b/docs/sources/userguide/dockervolumes.md @@ -80,23 +80,23 @@ it. Let's create a new named container with a volume to share. - $ docker run -d -v /dbdata --name dbdata training/postgres + $ sudo docker run -d -v /dbdata --name dbdata training/postgres You can then use the `--volumes-from` flag to mount the `/dbdata` volume in another container. - $ docker run -d --volumes-from dbdata --name db1 training/postgres + $ sudo docker run -d --volumes-from dbdata --name db1 training/postgres And another: - $ docker run -d --volumes-from dbdata --name db2 training/postgres + $ sudo docker run -d --volumes-from dbdata --name db2 training/postgres -You can use multiple `-volumes-from` parameters to bring together multiple data +You can use multiple `--volumes-from` parameters to bring together multiple data volumes from multiple containers. You can also extend the chain by mounting the volume that came from the `dbdata` container in yet another container via the `db1` or `db2` containers. - $ docker run -d --name db3 --volumes-from db1 training/postgres + $ sudo docker run -d --name db3 --volumes-from db1 training/postgres If you remove containers that mount volumes, including the initial `dbdata` container, or the subsequent containers `db1` and `db2`, the volumes will not @@ -122,7 +122,7 @@ we'll be left with a backup of our `dbdata` volume. You could then to restore to the same container, or another that you've made elsewhere. Create a new container. - $ sudo docker run -v /dbdata --name dbdata2 ubuntu + $ sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash Then un-tar the backup file in the new container's data volume. diff --git a/docs/sources/userguide/index.md b/docs/sources/userguide/index.md index 87dab67cc..eef59c000 100644 --- a/docs/sources/userguide/index.md +++ b/docs/sources/userguide/index.md @@ -29,7 +29,7 @@ environment. To learn more; Go to [Using Docker Hub](/userguide/dockerhub). -## Dockerizing Applications: A "Hello World!" +## Dockerizing Applications: A "Hello world" *How do I run applications inside containers?* @@ -82,11 +82,11 @@ Go to [Working with Docker Hub](/userguide/dockerrepos). ## Getting help -* [Docker homepage](http://www.docker.io/) +* [Docker homepage](http://www.docker.com/) * [Docker Hub](https://hub.docker.com) -* [Docker blog](http://blog.docker.io/) -* [Docker documentation](http://docs.docker.io/) -* [Docker Getting Started Guide](http://www.docker.io/gettingstarted/) +* [Docker blog](http://blog.docker.com/) +* [Docker documentation](http://docs.docker.com/) +* [Docker Getting Started Guide](http://www.docker.com/gettingstarted/) * [Docker code on GitHub](https://github.com/dotcloud/docker) * [Docker mailing list](https://groups.google.com/forum/#!forum/docker-user) diff --git a/docs/sources/userguide/usingdocker.md b/docs/sources/userguide/usingdocker.md index 54c094bfa..857eac5e5 100644 --- a/docs/sources/userguide/usingdocker.md +++ b/docs/sources/userguide/usingdocker.md @@ -19,7 +19,7 @@ In the process we learned about several Docker commands: > **Tip:** > Another way to learn about `docker` commands is our -> [interactive tutorial](https://www.docker.io/gettingstarted). +> [interactive tutorial](https://www.docker.com/tryit/). The `docker` client is pretty simple. Each action you can take with Docker is a command and each command can take a series of @@ -87,11 +87,6 @@ This will display the help text and all available flags: --no-stdin=false: Do not attach stdin --sig-proxy=true: Proxify all received signal to the process (even in non-tty mode) - -None of the containers we've run did anything particularly useful -though. So let's build on that experience by running an example web -application in Docker. - > **Note:** > You can see a full list of Docker's commands > [here](/reference/commandline/cli/). @@ -140,8 +135,8 @@ command. This tells the `docker ps` command to return the details of the *last* container started. > **Note:** -> The `docker ps` command only shows running containers. If you want to -> see stopped containers too use the `-a` flag. +> By default, the `docker ps` command only shows information about running +> containers. If you want to see stopped containers too use the `-a` flag. We can see the same details we saw [when we first Dockerized a container](/userguide/dockerizing) with one important addition in the `PORTS` @@ -184,8 +179,9 @@ see the application. Our Python application is live! > **Note:** -> If you have used boot2docker on OSX you'll need to get the IP of the virtual -> host instead of using localhost. You can do this by running the following in +> If you have used the boot2docker virtual machine on OS X, Windows or Linux, +> you'll need to get the IP of the virtual host instead of using localhost. +> You can do this by running the following in > the boot2docker shell. > > $ boot2docker ip diff --git a/docs/theme/mkdocs/base.html b/docs/theme/mkdocs/base.html index f931be2c9..8f2bd0603 100644 --- a/docs/theme/mkdocs/base.html +++ b/docs/theme/mkdocs/base.html @@ -4,6 +4,11 @@ +{% set docker_version = "$VERSION" %}{% set docker_commit = "$GITCOMMIT" %}{% set docker_branch = "$GIT_BRANCH" %}{% set aws_bucket = "$AWS_S3_BUCKET" %} + + + + {% if meta.page_description %}{% endif %} {% if meta.page_keywords %}{% endif %} {% if site_author %}{% endif %} @@ -60,7 +65,7 @@
- {% include "version.html" %} + {% include "beta_warning.html" %} {{ content }}
diff --git a/docs/theme/mkdocs/css/main.css b/docs/theme/mkdocs/css/main.css index 42a7a18a5..18e65ebd3 100644 --- a/docs/theme/mkdocs/css/main.css +++ b/docs/theme/mkdocs/css/main.css @@ -4,7 +4,7 @@ Core Docker style file used on - www.docker.io + www.docker.com docker-index ****************************** */ /* this is about 10% darker, but slightly different */ @@ -2146,4 +2146,4 @@ a:hover { background: url("../img/homepage/docker-whale-home-logo+@2x.png"); background-size: 459px 261px; } -} \ No newline at end of file +} diff --git a/docs/theme/mkdocs/header.html b/docs/theme/mkdocs/header.html index 785797f0d..3560929ca 100644 --- a/docs/theme/mkdocs/header.html +++ b/docs/theme/mkdocs/header.html @@ -25,14 +25,14 @@