Compare commits

..

1 Commits

Author SHA1 Message Date
Jessica Frazelle 7ddecf74be Bump version to v1.7.0
Signed-off-by: Jessica Frazelle <princess@docker.com>
2015-06-04 12:14:27 -07:00
459 changed files with 3898 additions and 4991 deletions
-3
View File
@@ -30,8 +30,5 @@ docs/_build
docs/_static
docs/_templates
docs/changed-files
# generated by man/man/md2man-all.sh
man/man1
man/man5
pyenv
vendor/pkg/
+3 -28
View File
@@ -1,36 +1,11 @@
# Changelog
## 1.7.1 (2015-07-02)
#### Runtime
- Fix default user spawning exec process with `docker exec`
- Make `--bridge=none` to not configure the network bridge
- Publish networking stats properly
- Fix implicit devicemapper selection with static binaries
- Fix socket connections that hanged internitently
- Fix bridge interface creation on CentOS/RHEL 6.6
- Fix local dns lookups added to resolv.conf
- Fix copy command mounting volumes
- Fix read/write privileges in volumes mounted with --volumes-from
#### Remote API
- Fix unmarshalling of Command and Entrypoint
- Set limit for minimum client version supported
- Validate port specification
- Return proper errors when attach/reattach fail
#### Distribution
- Fix pulling private images
- Fix fallback between registry V2 and V1
## 1.7.0 (2015-06-16)
#### Runtime
+ Experimental feature: support for out-of-process volume plugins
+ Experimental feature: support for out-of-process network plugins
* Logging: syslog logging driver is available
* The userland proxy can be disabled in favor of hairpin NAT using the daemons `--userland-proxy=false` flag
* The `exec` command supports the `-u|--user` flag to specify the new process owner
+ Default gateway for containers can be specified daemon-wide using the `--default-gateway` and `--default-gateway-v6` flags
@@ -42,7 +17,7 @@
#### Quality
* Networking stack was entirely rewritten as part of the libnetwork effort
* Engine internals refactoring
* Engine internals refactoring (shout out to the contributors?)
* Volumes code was entirely rewritten to support the plugins effort
+ Sending SIGUSR1 to a daemon will dump all goroutines stacks without exiting
+1 -1
View File
@@ -4,7 +4,7 @@ Want to hack on Docker? Awesome! We have a contributor's guide that explains
[setting up a Docker development environment and the contribution
process](https://docs.docker.com/project/who-written-for/).
![Contributors guide](docs/static_files/contributors.png)
![Contributors guide](docs/sources/static_files/contributors.png)
This page contains information about reporting issues as well as some tips and
guidelines useful to experienced open source contributors. Finally, make sure
+26
View File
@@ -22,6 +22,11 @@ DOCKER_ENVS := \
BIND_DIR := $(if $(BINDDIR),$(BINDDIR),$(if $(DOCKER_HOST),,bundles))
DOCKER_MOUNT := $(if $(BIND_DIR),-v "$(CURDIR)/$(BIND_DIR):/go/src/github.com/docker/docker/$(BIND_DIR)")
# to allow `make DOCSDIR=docs docs-shell` (to create a bind mount in docs)
DOCS_MOUNT := $(if $(DOCSDIR),-v $(CURDIR)/$(DOCSDIR):/$(DOCSDIR))
# to allow `make DOCSPORT=9000 docs`
DOCSPORT := 8000
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)
DOCKER_IMAGE := docker-dev$(if $(GIT_BRANCH),:$(GIT_BRANCH))
@@ -45,6 +50,19 @@ binary: build
cross: build
$(DOCKER_RUN_DOCKER) hack/make.sh binary cross
docs: docs-build
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 "$(DOCKER_DOCS_IMAGE)" mkdocs serve
docs-shell: docs-build
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 "$(DOCKER_DOCS_IMAGE)" bash
docs-release: docs-build
$(DOCKER_RUN_DOCS) -e OPTIONS -e BUILD_ROOT -e DISTRIBUTION_ID \
-v $(CURDIR)/docs/awsconfig:/docs/awsconfig \
"$(DOCKER_DOCS_IMAGE)" ./release.sh
docs-test: docs-build
$(DOCKER_RUN_DOCS) "$(DOCKER_DOCS_IMAGE)" ./test.sh
test: build
$(DOCKER_RUN_DOCKER) hack/make.sh binary cross test-unit test-integration-cli test-docker-py
@@ -67,5 +85,13 @@ shell: build
build: bundles
docker build -t "$(DOCKER_IMAGE)" .
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 pull docs/base
docker build -t "$(DOCKER_DOCS_IMAGE)" docs
bundles:
mkdir bundles
+2 -2
View File
@@ -18,7 +18,7 @@ It benefits directly from the experience accumulated over several years
of large-scale operation and support of hundreds of thousands of
applications and databases.
![Docker L](docs/static_files/docker-logo-compressed.png "Docker")
![Docker L](docs/sources/static_files/docker-logo-compressed.png "Docker")
## Security Disclosure
@@ -30,7 +30,7 @@ security@docker.com and not by creating a github issue.
A common method for distributing applications and sandboxing their
execution is to use virtual machines, or VMs. Typical VM formats are
VMware's vmdk, Oracle Virtualbox's vdi, and Amazon EC2's ami. In theory
VMWare's vmdk, Oracle Virtualbox's vdi, and Amazon EC2's ami. In theory
these formats should allow every developer to automatically package
their application into a "machine" for easy distribution and deployment.
In practice, that almost never happens, for a few reasons:
+1 -1
View File
@@ -1 +1 @@
1.7.1-rc3
1.7.0-rc2
+1 -1
View File
@@ -138,7 +138,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea
if err != nil {
return err
}
req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.Version, path), params)
req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.APIVERSION, path), params)
if err != nil {
return err
}
+1 -1
View File
@@ -53,7 +53,7 @@ func (cli *DockerCli) clientRequest(method, path string, in io.Reader, headers m
if expectedPayload && in == nil {
in = bytes.NewReader([]byte{})
}
req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.Version, path), in)
req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.APIVERSION, path), in)
if err != nil {
return nil, "", -1, err
}
+1 -1
View File
@@ -26,7 +26,7 @@ func (cli *DockerCli) CmdVersion(args ...string) error {
if dockerversion.VERSION != "" {
fmt.Fprintf(cli.out, "Client version: %s\n", dockerversion.VERSION)
}
fmt.Fprintf(cli.out, "Client API version: %s\n", api.Version)
fmt.Fprintf(cli.out, "Client API version: %s\n", api.APIVERSION)
fmt.Fprintf(cli.out, "Go version (client): %s\n", runtime.Version())
if dockerversion.GITCOMMIT != "" {
fmt.Fprintf(cli.out, "Git commit (client): %s\n", dockerversion.GITCOMMIT)
+2 -8
View File
@@ -16,14 +16,8 @@ import (
// Common constants for daemon and client.
const (
// Current REST API version
Version version.Version = "1.19"
// Minimun REST API version supported
MinVersion version.Version = "1.12"
// Default filename with Docker commands, read by docker build
DefaultDockerfileName string = "Dockerfile"
APIVERSION version.Version = "1.19" // Current REST API version
DefaultDockerfileName string = "Dockerfile" // Default filename with Docker commands, read by docker build
)
type ByPrivatePort []types.Port
+50 -44
View File
@@ -36,6 +36,7 @@ import (
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/utils"
"github.com/docker/libnetwork/portallocator"
)
type ServerConfig struct {
@@ -247,7 +248,7 @@ func (s *Server) postAuth(version version.Version, w http.ResponseWriter, r *htt
func (s *Server) getVersion(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
v := &types.Version{
Version: dockerversion.VERSION,
ApiVersion: api.Version,
ApiVersion: api.APIVERSION,
GitCommit: dockerversion.GITCOMMIT,
GoVersion: runtime.Version(),
Os: runtime.GOOS,
@@ -398,7 +399,6 @@ func (s *Server) getEvents(version version.Version, w http.ResponseWriter, r *ht
}
until = u
}
timer := time.NewTimer(0)
timer.Stop()
if until > 0 {
@@ -457,9 +457,6 @@ func (s *Server) getEvents(version version.Version, w http.ResponseWriter, r *ht
}
current, l := es.Subscribe()
if since == -1 {
current = nil
}
defer es.Evict(l)
for _, ev := range current {
if ev.Time < since {
@@ -575,16 +572,7 @@ func (s *Server) getContainersStats(version version.Version, w http.ResponseWrit
return fmt.Errorf("Missing parameter")
}
stream := boolValueOrDefault(r, "stream", true)
var out io.Writer
if !stream {
w.Header().Set("Content-Type", "application/json")
out = w
} else {
out = ioutils.NewWriteFlusher(w)
}
return s.daemon.ContainerStats(vars["name"], stream, out)
return s.daemon.ContainerStats(vars["name"], boolValueOrDefault(r, "stream", true), ioutils.NewWriteFlusher(w))
}
func (s *Server) getContainersLogs(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
@@ -668,6 +656,10 @@ func (s *Server) postCommit(version version.Version, w http.ResponseWriter, r *h
return err
}
if c == nil {
c = &runconfig.Config{}
}
containerCommitConfig := &daemon.ContainerCommitConfig{
Pause: pause,
Repo: r.Form.Get("repo"),
@@ -903,7 +895,6 @@ func (s *Server) postContainersCreate(version version.Version, w http.ResponseWr
if err != nil {
return err
}
adjustCpuShares(version, hostConfig)
containerId, warnings, err := s.daemon.ContainerCreate(name, config, hostConfig)
if err != nil {
@@ -1101,11 +1092,6 @@ func (s *Server) postContainersAttach(version version.Version, w http.ResponseWr
return fmt.Errorf("Missing parameter")
}
cont, err := s.daemon.Get(vars["name"])
if err != nil {
return err
}
inStream, outStream, err := hijackServer(w)
if err != nil {
return err
@@ -1129,7 +1115,7 @@ func (s *Server) postContainersAttach(version version.Version, w http.ResponseWr
Multiplex: version.GreaterThanOrEqualTo("1.6"),
}
if err := s.daemon.ContainerAttachWithLogs(cont, attachWithLogsConfig); err != nil {
if err := s.daemon.ContainerAttachWithLogs(vars["name"], attachWithLogsConfig); err != nil {
fmt.Fprintf(outStream, "Error attaching: %s\n", err)
}
@@ -1144,11 +1130,6 @@ func (s *Server) wsContainersAttach(version version.Version, w http.ResponseWrit
return fmt.Errorf("Missing parameter")
}
cont, err := s.daemon.Get(vars["name"])
if err != nil {
return err
}
h := websocket.Handler(func(ws *websocket.Conn) {
defer ws.Close()
@@ -1160,7 +1141,7 @@ func (s *Server) wsContainersAttach(version version.Version, w http.ResponseWrit
Stream: boolValue(r, "stream"),
}
if err := s.daemon.ContainerWsAttachWithLogs(cont, wsAttachWithLogsConfig); err != nil {
if err := s.daemon.ContainerWsAttachWithLogs(vars["name"], wsAttachWithLogsConfig); err != nil {
logrus.Errorf("Error attaching websocket: %s", err)
}
})
@@ -1217,17 +1198,18 @@ func (s *Server) getImagesByName(version version.Version, w http.ResponseWriter,
func (s *Server) postBuild(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var (
authConfigs = map[string]cliconfig.AuthConfig{}
authConfigsEncoded = r.Header.Get("X-Registry-Config")
buildConfig = builder.NewBuildConfig()
authConfig = &cliconfig.AuthConfig{}
configFileEncoded = r.Header.Get("X-Registry-Config")
configFile = &cliconfig.ConfigFile{}
buildConfig = builder.NewBuildConfig()
)
if authConfigsEncoded != "" {
authConfigsJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authConfigsEncoded))
if err := json.NewDecoder(authConfigsJSON).Decode(&authConfigs); err != nil {
if configFileEncoded != "" {
configFileJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(configFileEncoded))
if err := json.NewDecoder(configFileJson).Decode(configFile); err != nil {
// for a pull it is not an error if no auth was given
// to increase compatibility with the existing api it is defaulting
// to be empty.
// to increase compatibility with the existing api it is defaulting to be empty
configFile = &cliconfig.ConfigFile{}
}
}
@@ -1254,7 +1236,8 @@ func (s *Server) postBuild(version version.Version, w http.ResponseWriter, r *ht
buildConfig.SuppressOutput = boolValue(r, "q")
buildConfig.NoCache = boolValue(r, "nocache")
buildConfig.ForceRemove = boolValue(r, "forcerm")
buildConfig.AuthConfigs = authConfigs
buildConfig.AuthConfig = authConfig
buildConfig.ConfigFile = configFile
buildConfig.MemorySwap = int64ValueOrZero(r, "memswap")
buildConfig.Memory = int64ValueOrZero(r, "memory")
buildConfig.CpuShares = int64ValueOrZero(r, "cpushares")
@@ -1483,18 +1466,14 @@ func makeHttpHandler(logging bool, localMethod string, localRoute string, handle
}
version := version.Version(mux.Vars(r)["version"])
if version == "" {
version = api.Version
version = api.APIVERSION
}
if corsHeaders != "" {
writeCorsHeaders(w, r, corsHeaders)
}
if version.GreaterThan(api.Version) {
http.Error(w, fmt.Errorf("client is newer than server (client API version: %s, server API version: %s)", version, api.Version).Error(), http.StatusBadRequest)
return
}
if version.LessThan(api.MinVersion) {
http.Error(w, fmt.Errorf("client is too old, minimum supported API version is %s, please upgrade your client to a newer version", api.MinVersion).Error(), http.StatusBadRequest)
if version.GreaterThan(api.APIVERSION) {
http.Error(w, fmt.Errorf("client and server don't have same version (client API version: %s, server API version: %s)", version, api.APIVERSION).Error(), http.StatusBadRequest)
return
}
@@ -1597,3 +1576,30 @@ func createRouter(s *Server) *mux.Router {
return r
}
func allocateDaemonPort(addr string) error {
host, port, err := net.SplitHostPort(addr)
if err != nil {
return err
}
intPort, err := strconv.Atoi(port)
if err != nil {
return err
}
var hostIPs []net.IP
if parsedIP := net.ParseIP(host); parsedIP != nil {
hostIPs = append(hostIPs, parsedIP)
} else if hostIPs, err = net.LookupIP(host); err != nil {
return fmt.Errorf("failed to lookup %s address in host specification", host)
}
pa := portallocator.Get()
for _, hostIP := range hostIPs {
if _, err := pa.RequestPort(hostIP, "tcp", intPort); err != nil {
return fmt.Errorf("failed to allocate daemon listening port %d (err: %v)", intPort, err)
}
}
return nil
}
-53
View File
@@ -6,21 +6,10 @@ import (
"fmt"
"net"
"net/http"
"strconv"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon"
"github.com/docker/docker/pkg/sockets"
"github.com/docker/docker/pkg/systemd"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/runconfig"
"github.com/docker/libnetwork/portallocator"
)
const (
// See http://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/tree/kernel/sched/sched.h?id=8cd9234c64c584432f6992fe944ca9e46ca8ea76#n269
linuxMinCpuShares = 2
linuxMaxCpuShares = 262144
)
// newServer sets up the required serverClosers and does protocol specific checking.
@@ -78,45 +67,3 @@ func (s *Server) AcceptConnections(d *daemon.Daemon) {
close(s.start)
}
}
func allocateDaemonPort(addr string) error {
host, port, err := net.SplitHostPort(addr)
if err != nil {
return err
}
intPort, err := strconv.Atoi(port)
if err != nil {
return err
}
var hostIPs []net.IP
if parsedIP := net.ParseIP(host); parsedIP != nil {
hostIPs = append(hostIPs, parsedIP)
} else if hostIPs, err = net.LookupIP(host); err != nil {
return fmt.Errorf("failed to lookup %s address in host specification", host)
}
pa := portallocator.Get()
for _, hostIP := range hostIPs {
if _, err := pa.RequestPort(hostIP, "tcp", intPort); err != nil {
return fmt.Errorf("failed to allocate daemon listening port %d (err: %v)", intPort, err)
}
}
return nil
}
func adjustCpuShares(version version.Version, hostConfig *runconfig.HostConfig) {
if version.LessThan("1.19") {
if hostConfig.CpuShares > 0 {
// Handle unsupported CpuShares
if hostConfig.CpuShares < linuxMinCpuShares {
logrus.Warnf("Changing requested CpuShares of %d to minimum allowed of %d", hostConfig.CpuShares, linuxMinCpuShares)
hostConfig.CpuShares = linuxMinCpuShares
} else if hostConfig.CpuShares > linuxMaxCpuShares {
logrus.Warnf("Changing requested CpuShares of %d to maximum allowed of %d", hostConfig.CpuShares, linuxMaxCpuShares)
hostConfig.CpuShares = linuxMaxCpuShares
}
}
}
}
-68
View File
@@ -1,68 +0,0 @@
// +build linux
package server
import (
"testing"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/runconfig"
)
func TestAdjustCpuSharesOldApi(t *testing.T) {
apiVersion := version.Version("1.18")
hostConfig := &runconfig.HostConfig{
CpuShares: linuxMinCpuShares - 1,
}
adjustCpuShares(apiVersion, hostConfig)
if hostConfig.CpuShares != linuxMinCpuShares {
t.Errorf("Expected CpuShares to be %d", linuxMinCpuShares)
}
hostConfig.CpuShares = linuxMaxCpuShares + 1
adjustCpuShares(apiVersion, hostConfig)
if hostConfig.CpuShares != linuxMaxCpuShares {
t.Errorf("Expected CpuShares to be %d", linuxMaxCpuShares)
}
hostConfig.CpuShares = 0
adjustCpuShares(apiVersion, hostConfig)
if hostConfig.CpuShares != 0 {
t.Error("Expected CpuShares to be unchanged")
}
hostConfig.CpuShares = 1024
adjustCpuShares(apiVersion, hostConfig)
if hostConfig.CpuShares != 1024 {
t.Error("Expected CpuShares to be unchanged")
}
}
func TestAdjustCpuSharesNoAdjustment(t *testing.T) {
apiVersion := version.Version("1.19")
hostConfig := &runconfig.HostConfig{
CpuShares: linuxMinCpuShares - 1,
}
adjustCpuShares(apiVersion, hostConfig)
if hostConfig.CpuShares != linuxMinCpuShares-1 {
t.Errorf("Expected CpuShares to be %d", linuxMinCpuShares-1)
}
hostConfig.CpuShares = linuxMaxCpuShares + 1
adjustCpuShares(apiVersion, hostConfig)
if hostConfig.CpuShares != linuxMaxCpuShares+1 {
t.Errorf("Expected CpuShares to be %d", linuxMaxCpuShares+1)
}
hostConfig.CpuShares = 0
adjustCpuShares(apiVersion, hostConfig)
if hostConfig.CpuShares != 0 {
t.Error("Expected CpuShares to be unchanged")
}
hostConfig.CpuShares = 1024
adjustCpuShares(apiVersion, hostConfig)
if hostConfig.CpuShares != 1024 {
t.Error("Expected CpuShares to be unchanged")
}
}
+1 -9
View File
@@ -11,7 +11,7 @@ import (
)
// NewServer sets up the required Server and does protocol specific checking.
func (s *Server) newServer(proto, addr string) (serverCloser, error) {
func (s *Server) newServer(proto, addr string) (Server, error) {
var (
err error
l net.Listener
@@ -22,7 +22,6 @@ func (s *Server) newServer(proto, addr string) (serverCloser, error) {
if err != nil {
return nil, err
}
default:
return nil, errors.New("Invalid protocol format. Windows only supports tcp.")
}
@@ -44,10 +43,3 @@ func (s *Server) AcceptConnections(d *daemon.Daemon) {
close(s.start)
}
}
func allocateDaemonPort(addr string) error {
return nil
}
func adjustCpuShares(version version.Version, hostConfig *runconfig.HostConfig) {
}
+2 -2
View File
@@ -94,9 +94,9 @@ type ImageInspect struct {
// GET "/containers/json"
type Port struct {
IP string `json:",omitempty"`
IP string
PrivatePort int
PublicPort int `json:",omitempty"`
PublicPort int
Type string
}
+2 -2
View File
@@ -98,8 +98,8 @@ type Builder struct {
// the final configs of the Dockerfile but dont want the layers
disableCommit bool
// Registry server auth configs used to pull images when handling `FROM`.
AuthConfigs map[string]cliconfig.AuthConfig
AuthConfig *cliconfig.AuthConfig
ConfigFile *cliconfig.ConfigFile
// Deprecated, original writer used for ImagePull. To be removed.
OutOld io.Writer
+4 -9
View File
@@ -21,7 +21,6 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/builder/parser"
"github.com/docker/docker/cliconfig"
"github.com/docker/docker/daemon"
"github.com/docker/docker/graph"
imagepkg "github.com/docker/docker/image"
@@ -447,19 +446,15 @@ func (b *Builder) pullImage(name string) (*imagepkg.Image, error) {
tag = "latest"
}
pullRegistryAuth := &cliconfig.AuthConfig{}
if len(b.AuthConfigs) > 0 {
pullRegistryAuth := b.AuthConfig
if len(b.ConfigFile.AuthConfigs) > 0 {
// The request came with a full auth config file, we prefer to use that
repoInfo, err := b.Daemon.RegistryService.ResolveRepository(remote)
if err != nil {
return nil, err
}
resolvedConfig := registry.ResolveAuthConfig(
&cliconfig.ConfigFile{AuthConfigs: b.AuthConfigs},
repoInfo.Index,
)
pullRegistryAuth = &resolvedConfig
resolvedAuth := registry.ResolveAuthConfig(b.ConfigFile, repoInfo.Index)
pullRegistryAuth = &resolvedAuth
}
imagePullConfig := &graph.ImagePullConfig{
+7 -8
View File
@@ -53,7 +53,8 @@ type Config struct {
CpuSetCpus string
CpuSetMems string
CgroupParent string
AuthConfigs map[string]cliconfig.AuthConfig
AuthConfig *cliconfig.AuthConfig
ConfigFile *cliconfig.ConfigFile
Stdout io.Writer
Context io.ReadCloser
@@ -78,8 +79,9 @@ func (b *Config) WaitCancelled() <-chan struct{} {
func NewBuildConfig() *Config {
return &Config{
AuthConfigs: map[string]cliconfig.AuthConfig{},
cancelled: make(chan struct{}),
AuthConfig: &cliconfig.AuthConfig{},
ConfigFile: &cliconfig.ConfigFile{},
cancelled: make(chan struct{}),
}
}
@@ -158,7 +160,8 @@ func Build(d *daemon.Daemon, buildConfig *Config) error {
Pull: buildConfig.Pull,
OutOld: buildConfig.Stdout,
StreamFormatter: sf,
AuthConfigs: buildConfig.AuthConfigs,
AuthConfig: buildConfig.AuthConfig,
ConfigFile: buildConfig.ConfigFile,
dockerfileName: buildConfig.DockerfileName,
cpuShares: buildConfig.CpuShares,
cpuPeriod: buildConfig.CpuPeriod,
@@ -218,10 +221,6 @@ func Commit(d *daemon.Daemon, name string, c *daemon.ContainerCommitConfig) (str
return "", err
}
if c.Config == nil {
c.Config = &runconfig.Config{}
}
newConfig, err := BuildFromConfig(d, c.Config, c.Changes)
if err != nil {
return "", err
-1
View File
@@ -5,7 +5,6 @@
FROM centos:7
RUN yum groupinstall -y "Development Tools"
RUN yum -y swap -- remove systemd-container systemd-container-libs -- install systemd systemd-libs
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel sqlite-devel tar
ENV GO_VERSION 1.4.2
-4
View File
@@ -38,10 +38,6 @@ for version in "${versions[@]}"; do
centos:*)
# get "Development Tools" packages dependencies
echo 'RUN yum groupinstall -y "Development Tools"' >> "$version/Dockerfile"
if [[ "$version" == "centos-7" ]]; then
echo 'RUN yum -y swap -- remove systemd-container systemd-container-libs -- install systemd systemd-libs' >> "$version/Dockerfile"
fi
;;
*)
echo 'RUN yum install -y @development-tools fedora-packager' >> "$version/Dockerfile"
+4 -2
View File
@@ -7,6 +7,7 @@ DOCKER_LOGFILE=${DOCKER_LOGFILE:-/var/log/${SVCNAME}.log}
DOCKER_PIDFILE=${DOCKER_PIDFILE:-/run/${SVCNAME}.pid}
DOCKER_BINARY=${DOCKER_BINARY:-/usr/bin/docker}
DOCKER_OPTS=${DOCKER_OPTS:-}
UNSHARE_BINARY=${UNSHARE_BINARY:-/usr/bin/unshare}
start() {
checkpath -f -m 0644 -o root:docker "$DOCKER_LOGFILE"
@@ -16,11 +17,12 @@ start() {
ebegin "Starting docker daemon"
start-stop-daemon --start --background \
--exec "$DOCKER_BINARY" \
--exec "$UNSHARE_BINARY" \
--pidfile "$DOCKER_PIDFILE" \
--stdout "$DOCKER_LOGFILE" \
--stderr "$DOCKER_LOGFILE" \
-- -d -p "$DOCKER_PIDFILE" \
-- --mount \
-- "$DOCKER_BINARY" -d -p "$DOCKER_PIDFILE" \
$DOCKER_OPTS
eend $?
}
+1 -1
View File
@@ -1,6 +1,6 @@
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
Documentation=http://docs.docker.com
After=network.target docker.socket
Requires=docker.socket
+4 -3
View File
@@ -30,6 +30,7 @@ DOCKER_SSD_PIDFILE=/var/run/$BASE-ssd.pid
DOCKER_LOGFILE=/var/log/$BASE.log
DOCKER_OPTS=
DOCKER_DESC="Docker"
UNSHARE=${UNSHARE:-/usr/bin/unshare}
# Get lsb functions
. /lib/lsb/init-functions
@@ -99,11 +100,11 @@ case "$1" in
log_begin_msg "Starting $DOCKER_DESC: $BASE"
start-stop-daemon --start --background \
--no-close \
--exec "$DOCKER" \
--exec "$UNSHARE" \
--pidfile "$DOCKER_SSD_PIDFILE" \
--make-pidfile \
-- \
-d -p "$DOCKER_PIDFILE" \
-- --mount \
-- "$DOCKER" -d -p "$DOCKER_PIDFILE" \
$DOCKER_OPTS \
>> "$DOCKER_LOGFILE" 2>&1
log_end_msg $?
+1 -1
View File
@@ -39,7 +39,7 @@ script
if [ -f /etc/default/$UPSTART_JOB ]; then
. /etc/default/$UPSTART_JOB
fi
exec "$DOCKER" -d $DOCKER_OPTS
exec unshare -m -- "$DOCKER" -d $DOCKER_OPTS
end script
# Don't emit "started" event until docker.sock is ready.
+1 -1
View File
@@ -80,7 +80,7 @@ sudo mkdir -m 755 dev
# effectively: febootstrap-minimize --keep-zoneinfo --keep-rpmdb --keep-services "$target"
# locales
sudo rm -rf usr/{{lib,share}/locale,{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive}
# docs and man pages
# docs
sudo rm -rf usr/share/{man,doc,info,gnome/help}
# cracklib
sudo rm -rf usr/share/cracklib
+1 -1
View File
@@ -10,7 +10,7 @@ shift
# effectively: febootstrap-minimize --keep-zoneinfo --keep-rpmdb --keep-services "$target"
# locales
rm -rf usr/{{lib,share}/locale,{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive}
# docs and man pages
# docs
rm -rf usr/share/{man,doc,info,gnome/help}
# cracklib
rm -rf usr/share/cracklib
+12 -2
View File
@@ -14,7 +14,12 @@ type ContainerAttachWithLogsConfig struct {
Multiplex bool
}
func (daemon *Daemon) ContainerAttachWithLogs(container *Container, c *ContainerAttachWithLogsConfig) error {
func (daemon *Daemon) ContainerAttachWithLogs(name string, c *ContainerAttachWithLogsConfig) error {
container, err := daemon.Get(name)
if err != nil {
return err
}
var errStream io.Writer
if !container.Config.Tty && c.Multiplex {
@@ -46,6 +51,11 @@ type ContainerWsAttachWithLogsConfig struct {
Logs, Stream bool
}
func (daemon *Daemon) ContainerWsAttachWithLogs(container *Container, c *ContainerWsAttachWithLogsConfig) error {
func (daemon *Daemon) ContainerWsAttachWithLogs(name string, c *ContainerWsAttachWithLogsConfig) error {
container, err := daemon.Get(name)
if err != nil {
return err
}
return container.AttachWithLogs(c.InStream, c.OutStream, c.ErrStream, c.Logs, c.Stream)
}
+53 -20
View File
@@ -1,6 +1,8 @@
package daemon
import (
"net"
"github.com/docker/docker/opts"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/runconfig"
@@ -14,46 +16,77 @@ const (
// CommonConfig defines the configuration of a docker daemon which are
// common across platforms.
type CommonConfig struct {
AutoRestart bool
Context map[string][]string
CorsHeaders string
DisableBridge bool
Dns []string
DnsSearch []string
EnableCors bool
ExecDriver string
ExecOptions []string
ExecRoot string
GraphDriver string
GraphOptions []string
Labels []string
LogConfig runconfig.LogConfig
Mtu int
Pidfile string
Root string
TrustKeyPath string
AutoRestart bool
// Bridge holds bridge network specific configuration.
Bridge bridgeConfig
Context map[string][]string
CorsHeaders string
DisableNetwork bool
Dns []string
DnsSearch []string
EnableCors bool
ExecDriver string
ExecRoot string
GraphDriver string
Labels []string
LogConfig runconfig.LogConfig
Mtu int
Pidfile string
Root string
TrustKeyPath string
}
// bridgeConfig stores all the bridge driver specific
// configuration.
type bridgeConfig struct {
EnableIPv6 bool
EnableIPTables bool
EnableIPForward bool
EnableIPMasq bool
EnableUserlandProxy bool
DefaultIP net.IP
Iface string
IP string
FixedCIDR string
FixedCIDRv6 string
DefaultGatewayIPv4 string
DefaultGatewayIPv6 string
InterContainerCommunication bool
}
// InstallCommonFlags adds command-line options to the top-level flag parser for
// the current process.
// Subsequent calls to `flag.Parse` will populate config with values parsed
// from the command-line.
func (config *Config) InstallCommonFlags() {
opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options")
opts.ListVar(&config.ExecOptions, []string{"-exec-opt"}, "Set exec driver options")
flag.StringVar(&config.Pidfile, []string{"p", "-pidfile"}, defaultPidFile, "Path to use for daemon PID file")
flag.StringVar(&config.Root, []string{"g", "-graph"}, defaultGraph, "Root of the Docker runtime")
flag.StringVar(&config.ExecRoot, []string{"-exec-root"}, "/var/run/docker", "Root of the Docker execdriver")
flag.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run")
flag.BoolVar(&config.Bridge.EnableIPTables, []string{"#iptables", "-iptables"}, true, "Enable addition of iptables rules")
flag.BoolVar(&config.Bridge.EnableIPForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
flag.BoolVar(&config.Bridge.EnableIPMasq, []string{"-ip-masq"}, true, "Enable IP masquerading")
flag.BoolVar(&config.Bridge.EnableIPv6, []string{"-ipv6"}, false, "Enable IPv6 networking")
flag.StringVar(&config.Bridge.IP, []string{"#bip", "-bip"}, "", "Specify network bridge IP")
flag.StringVar(&config.Bridge.Iface, []string{"b", "-bridge"}, "", "Attach containers to a network bridge")
flag.StringVar(&config.Bridge.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs")
flag.StringVar(&config.Bridge.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", "IPv6 subnet for fixed IPs")
flag.StringVar(&config.Bridge.DefaultGatewayIPv4, []string{"-default-gateway"}, "", "Container default gateway IPv4 address")
flag.StringVar(&config.Bridge.DefaultGatewayIPv6, []string{"-default-gateway-v6"}, "", "Container default gateway IPv6 address")
flag.BoolVar(&config.Bridge.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
flag.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Storage driver to use")
flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, defaultExec, "Exec driver to use")
flag.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, "Set the containers network MTU")
flag.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "#-api-enable-cors"}, false, "Enable CORS headers in the remote API, this is deprecated by --api-cors-header")
flag.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", "Set CORS headers in the remote API")
opts.IPVar(&config.Bridge.DefaultIP, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports")
// FIXME: why the inconsistency between "hosts" and "sockets"?
opts.IPListVar(&config.Dns, []string{"#dns", "-dns"}, "DNS server to use")
opts.DnsSearchListVar(&config.DnsSearch, []string{"-dns-search"}, "DNS search domains to use")
opts.LabelListVar(&config.Labels, []string{"-label"}, "Set key=value labels to the daemon")
flag.StringVar(&config.LogConfig.Type, []string{"-log-driver"}, "json-file", "Default driver for container logs")
opts.LogOptsVar(config.LogConfig.Config, []string{"-log-opt"}, "Set log driver options")
flag.BoolVar(&config.Bridge.EnableUserlandProxy, []string{"-userland-proxy"}, true, "Use userland proxy for loopback traffic")
}
+4 -36
View File
@@ -1,8 +1,6 @@
package daemon
import (
"net"
"github.com/docker/docker/opts"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/ulimit"
@@ -21,32 +19,13 @@ type Config struct {
CommonConfig
// Fields below here are platform specific.
// Bridge holds bridge network specific configuration.
Bridge bridgeConfig
EnableSelinuxSupport bool
ExecOptions []string
GraphOptions []string
SocketGroup string
Ulimits map[string]*ulimit.Ulimit
}
// bridgeConfig stores all the bridge driver specific
// configuration.
type bridgeConfig struct {
EnableIPv6 bool
EnableIPTables bool
EnableIPForward bool
EnableIPMasq bool
EnableUserlandProxy bool
DefaultIP net.IP
Iface string
IP string
FixedCIDR string
FixedCIDRv6 string
DefaultGatewayIPv4 net.IP
DefaultGatewayIPv6 net.IP
InterContainerCommunication bool
}
// InstallFlags adds command-line options to the top-level flag parser for
// the current process.
// Subsequent calls to `flag.Parse` will populate config with values parsed
@@ -56,21 +35,10 @@ func (config *Config) InstallFlags() {
config.InstallCommonFlags()
// Then platform-specific install flags
opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options")
opts.ListVar(&config.ExecOptions, []string{"-exec-opt"}, "Set exec driver options")
flag.BoolVar(&config.EnableSelinuxSupport, []string{"-selinux-enabled"}, false, "Enable selinux support")
flag.StringVar(&config.SocketGroup, []string{"G", "-group"}, "docker", "Group for the unix socket")
config.Ulimits = make(map[string]*ulimit.Ulimit)
opts.UlimitMapVar(config.Ulimits, []string{"-default-ulimit"}, "Set default ulimits for containers")
flag.BoolVar(&config.Bridge.EnableIPTables, []string{"#iptables", "-iptables"}, true, "Enable addition of iptables rules")
flag.BoolVar(&config.Bridge.EnableIPForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
flag.BoolVar(&config.Bridge.EnableIPMasq, []string{"-ip-masq"}, true, "Enable IP masquerading")
flag.BoolVar(&config.Bridge.EnableIPv6, []string{"-ipv6"}, false, "Enable IPv6 networking")
flag.StringVar(&config.Bridge.IP, []string{"#bip", "-bip"}, "", "Specify network bridge IP")
flag.StringVar(&config.Bridge.Iface, []string{"b", "-bridge"}, "", "Attach containers to a network bridge")
flag.StringVar(&config.Bridge.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs")
flag.StringVar(&config.Bridge.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", "IPv6 subnet for fixed IPs")
opts.IPVar(&config.Bridge.DefaultGatewayIPv4, []string{"-default-gateway"}, "", "Container default gateway IPv4 address")
opts.IPVar(&config.Bridge.DefaultGatewayIPv6, []string{"-default-gateway-v6"}, "", "Container default gateway IPv6 address")
flag.BoolVar(&config.Bridge.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
opts.IPVar(&config.Bridge.DefaultIP, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports")
flag.BoolVar(&config.Bridge.EnableUserlandProxy, []string{"-userland-proxy"}, true, "Use userland proxy for loopback traffic")
}
+3 -16
View File
@@ -24,7 +24,6 @@ import (
"github.com/docker/docker/nat"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/broadcastwriter"
"github.com/docker/docker/pkg/fileutils"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/jsonlog"
"github.com/docker/docker/pkg/mount"
@@ -74,10 +73,7 @@ type CommonContainer struct {
MountLabel, ProcessLabel string
RestartCount int
UpdateDns bool
MountPoints map[string]*mountPoint
Volumes map[string]string // Deprecated since 1.7, kept for backwards compatibility
VolumesRW map[string]bool // Deprecated since 1.7, kept for backwards compatibility
MountPoints map[string]*mountPoint
hostConfig *runconfig.HostConfig
command *execdriver.Command
@@ -600,20 +596,11 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) {
return nil, err
}
for _, m := range mounts {
var dest string
dest, err = container.GetResourcePath(m.Destination)
dest, err := container.GetResourcePath(m.Destination)
if err != nil {
return nil, err
}
var stat os.FileInfo
stat, err = os.Stat(m.Source)
if err != nil {
return nil, err
}
if err = fileutils.CreateIfNotExists(dest, stat.IsDir()); err != nil {
return nil, err
}
if err = mount.Mount(m.Source, dest, "bind", "rbind,ro"); err != nil {
if err := mount.Mount(m.Source, dest, "bind", "rbind,ro"); err != nil {
return nil, err
}
}
+6 -7
View File
@@ -469,7 +469,7 @@ func (container *Container) buildJoinOptions() ([]libnetwork.EndpointOption, err
logrus.Error(err)
}
if c != nil && !container.daemon.config.DisableBridge && container.hostConfig.NetworkMode.IsPrivate() {
if c != nil && !container.daemon.config.DisableNetwork && container.hostConfig.NetworkMode.IsPrivate() {
logrus.Debugf("Update /etc/hosts of %s for alias %s with ip %s", c.ID, ref.Name, container.NetworkSettings.IPAddress)
joinOptions = append(joinOptions, libnetwork.JoinOptionParentUpdate(c.NetworkSettings.EndpointID, ref.Name, container.NetworkSettings.IPAddress))
if c.NetworkSettings.EndpointID != "" {
@@ -753,11 +753,6 @@ func (container *Container) AllocateNetwork() error {
return nil
}
if mode.IsBridge() && container.daemon.config.DisableBridge {
container.Config.NetworkDisabled = true
return nil
}
var err error
n, err := container.daemon.netController.NetworkByName(string(mode))
@@ -822,6 +817,10 @@ func (container *Container) initializeNetworking() error {
return nil
}
if container.daemon.config.DisableNetwork {
container.Config.NetworkDisabled = true
}
if container.hostConfig.NetworkMode.IsHost() {
container.Config.Hostname, err = os.Hostname()
if err != nil {
@@ -940,7 +939,7 @@ func (container *Container) getNetworkedContainer() (*Container, error) {
}
func (container *Container) ReleaseNetwork() {
if container.hostConfig.NetworkMode.IsContainer() || container.Config.NetworkDisabled {
if container.hostConfig.NetworkMode.IsContainer() || container.daemon.config.DisableNetwork {
return
}
-4
View File
@@ -15,10 +15,6 @@ import (
)
func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hostConfig *runconfig.HostConfig) (string, []string, error) {
if config == nil {
return "", nil, fmt.Errorf("Config cannot be empty in order to create a container")
}
warnings, err := daemon.verifyHostConfig(hostConfig)
if err != nil {
return "", warnings, err
+51 -113
View File
@@ -1,7 +1,6 @@
package daemon
import (
"errors"
"fmt"
"io"
"io/ioutil"
@@ -32,7 +31,6 @@ import (
"github.com/docker/docker/daemon/network"
"github.com/docker/docker/graph"
"github.com/docker/docker/image"
"github.com/docker/docker/nat"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/broadcastwriter"
"github.com/docker/docker/pkg/fileutils"
@@ -50,9 +48,10 @@ import (
"github.com/docker/docker/utils"
volumedrivers "github.com/docker/docker/volume/drivers"
"github.com/docker/docker/volume/local"
"github.com/docker/libcontainer/netlink"
)
const defaultVolumesPathName = "volumes"
var (
validContainerNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]`
validContainerNamePattern = regexp.MustCompile(`^/?` + validContainerNameChars + `+$`)
@@ -159,7 +158,12 @@ func (daemon *Daemon) containerRoot(id string) string {
// This is typically done at startup.
func (daemon *Daemon) load(id string) (*Container, error) {
container := &Container{
CommonContainer: daemon.newBaseContainer(id),
CommonContainer: CommonContainer{
State: NewState(),
root: daemon.containerRoot(id),
MountPoints: make(map[string]*mountPoint),
execCommands: newExecStore(),
},
}
if err := container.FromDisk(); err != nil {
@@ -522,21 +526,25 @@ func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID
daemon.generateHostname(id, config)
entrypoint, args := daemon.getEntrypointAndArgs(config.Entrypoint, config.Cmd)
base := daemon.newBaseContainer(id)
base.Created = time.Now().UTC()
base.Path = entrypoint
base.Args = args //FIXME: de-duplicate from config
base.Config = config
base.hostConfig = &runconfig.HostConfig{}
base.ImageID = imgID
base.NetworkSettings = &network.Settings{}
base.Name = name
base.Driver = daemon.driver.String()
base.ExecDriver = daemon.execDriver.Name()
container := &Container{
CommonContainer: base,
CommonContainer: CommonContainer{
ID: id, // FIXME: we should generate the ID here instead of receiving it as an argument
Created: time.Now().UTC(),
Path: entrypoint,
Args: args, //FIXME: de-duplicate from config
Config: config,
hostConfig: &runconfig.HostConfig{},
ImageID: imgID,
NetworkSettings: &network.Settings{},
Name: name,
Driver: daemon.driver.String(),
ExecDriver: daemon.execDriver.Name(),
State: NewState(),
execCommands: newExecStore(),
MountPoints: map[string]*mountPoint{},
},
}
container.root = daemon.containerRoot(container.ID)
return container, err
}
@@ -675,15 +683,13 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
if config.Bridge.Iface != "" && config.Bridge.IP != "" {
return nil, fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one.")
}
setDefaultMtu(config)
if !config.Bridge.EnableIPTables && !config.Bridge.InterContainerCommunication {
return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
}
if !config.Bridge.EnableIPTables && config.Bridge.EnableIPMasq {
config.Bridge.EnableIPMasq = false
}
config.DisableBridge = config.Bridge.Iface == disableNetworkBridge
config.DisableNetwork = config.Bridge.Iface == disableNetworkBridge
// Check that the system is supported and we have sufficient privileges
if runtime.GOOS != "linux" {
@@ -786,7 +792,7 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
return nil, err
}
volumesDriver, err := local.New(config.Root)
volumesDriver, err := local.New(filepath.Join(config.Root, defaultVolumesPathName))
if err != nil {
return nil, err
}
@@ -820,9 +826,11 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
return nil, fmt.Errorf("Couldn't create Tag store: %s", err)
}
d.netController, err = initNetworkController(config)
if err != nil {
return nil, fmt.Errorf("Error initializing network controller: %v", err)
if !config.DisableNetwork {
d.netController, err = initNetworkController(config)
if err != nil {
return nil, fmt.Errorf("Error initializing network controller: %v", err)
}
}
graphdbPath := path.Join(config.Root, "linkgraph.db")
@@ -910,22 +918,12 @@ func initNetworkController(config *Config) (libnetwork.NetworkController, error)
return nil, fmt.Errorf("Error creating default \"host\" network: %v", err)
}
if !config.DisableBridge {
// Initialize default driver "bridge"
if err := initBridgeDriver(controller, config); err != nil {
return nil, err
}
}
return controller, nil
}
func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error {
// Initialize default driver "bridge"
option := options.Generic{
"EnableIPForwarding": config.Bridge.EnableIPForward}
if err := controller.ConfigureNetworkDriver("bridge", options.Generic{netlabel.GenericData: option}); err != nil {
return fmt.Errorf("Error initializing bridge driver: %v", err)
return nil, fmt.Errorf("Error initializing bridge driver: %v", err)
}
netOption := options.Generic{
@@ -940,7 +938,7 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
if config.Bridge.IP != "" {
ip, bipNet, err := net.ParseCIDR(config.Bridge.IP)
if err != nil {
return err
return nil, err
}
bipNet.IP = ip
@@ -950,7 +948,7 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
if config.Bridge.FixedCIDR != "" {
_, fCIDR, err := net.ParseCIDR(config.Bridge.FixedCIDR)
if err != nil {
return err
return nil, err
}
netOption["FixedCIDR"] = fCIDR
@@ -959,38 +957,41 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
if config.Bridge.FixedCIDRv6 != "" {
_, fCIDRv6, err := net.ParseCIDR(config.Bridge.FixedCIDRv6)
if err != nil {
return err
return nil, err
}
netOption["FixedCIDRv6"] = fCIDRv6
}
if config.Bridge.DefaultGatewayIPv4 != nil {
netOption["DefaultGatewayIPv4"] = config.Bridge.DefaultGatewayIPv4
}
if config.Bridge.DefaultGatewayIPv6 != nil {
netOption["DefaultGatewayIPv6"] = config.Bridge.DefaultGatewayIPv6
}
// --ip processing
if config.Bridge.DefaultIP != nil {
netOption["DefaultBindingIP"] = config.Bridge.DefaultIP
}
// Initialize default network on "bridge" with the same name
_, err := controller.NewNetwork("bridge", "bridge",
_, err = controller.NewNetwork("bridge", "bridge",
libnetwork.NetworkOptionGeneric(options.Generic{
netlabel.GenericData: netOption,
netlabel.EnableIPv6: config.Bridge.EnableIPv6,
}))
if err != nil {
return fmt.Errorf("Error creating default \"bridge\" network: %v", err)
return nil, fmt.Errorf("Error creating default \"bridge\" network: %v", err)
}
return nil
return controller, nil
}
func (daemon *Daemon) Shutdown() error {
if daemon.containerGraph != nil {
if err := daemon.containerGraph.Close(); err != nil {
logrus.Errorf("Error during container graph.Close(): %v", err)
}
}
if daemon.driver != nil {
if err := daemon.driver.Cleanup(); err != nil {
logrus.Errorf("Error during graph storage driver.Cleanup(): %v", err)
}
}
if daemon.containers != nil {
group := sync.WaitGroup{}
logrus.Debug("starting clean shutdown of all containers...")
@@ -1012,23 +1013,6 @@ func (daemon *Daemon) Shutdown() error {
}
}
group.Wait()
// trigger libnetwork GC only if it's initialized
if daemon.netController != nil {
daemon.netController.GC()
}
}
if daemon.containerGraph != nil {
if err := daemon.containerGraph.Close(); err != nil {
logrus.Errorf("Error during container graph.Close(): %v", err)
}
}
if daemon.driver != nil {
if err := daemon.driver.Cleanup(); err != nil {
logrus.Errorf("Error during graph storage driver.Cleanup(): %v", err)
}
}
return nil
@@ -1198,13 +1182,6 @@ func (daemon *Daemon) verifyHostConfig(hostConfig *runconfig.HostConfig) ([]stri
return warnings, nil
}
for port := range hostConfig.PortBindings {
_, portStr := nat.SplitProtoPort(string(port))
if _, err := nat.ParsePort(portStr); err != nil {
return warnings, fmt.Errorf("Invalid port specification: %s", portStr)
}
}
if hostConfig.LxcConf.Len() > 0 && !strings.Contains(daemon.ExecutionDriver().Name(), "lxc") {
return warnings, fmt.Errorf("Cannot use --lxc-conf with execdriver: %s", daemon.ExecutionDriver().Name())
}
@@ -1269,42 +1246,3 @@ func (daemon *Daemon) setHostConfig(container *Container, hostConfig *runconfig.
container.toDisk()
return nil
}
func (daemon *Daemon) newBaseContainer(id string) CommonContainer {
return CommonContainer{
ID: id,
State: NewState(),
MountPoints: make(map[string]*mountPoint),
Volumes: make(map[string]string),
VolumesRW: make(map[string]bool),
execCommands: newExecStore(),
root: daemon.containerRoot(id),
}
}
func setDefaultMtu(config *Config) {
// do nothing if the config does not have the default 0 value.
if config.Mtu != 0 {
return
}
config.Mtu = defaultNetworkMtu
if routeMtu, err := getDefaultRouteMtu(); err == nil {
config.Mtu = routeMtu
}
}
var errNoDefaultRoute = errors.New("no default route was found")
// getDefaultRouteMtu returns the MTU for the default route's interface.
func getDefaultRouteMtu() (int, error) {
routes, err := netlink.NetworkGetRoutes()
if err != nil {
return 0, err
}
for _, r := range routes {
if r.Default {
return r.Iface.MTU, nil
}
}
return 0, errNoDefaultRoute
}
+7 -220
View File
@@ -12,8 +12,6 @@ import (
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/truncindex"
"github.com/docker/docker/volume"
"github.com/docker/docker/volume/drivers"
"github.com/docker/docker/volume/local"
)
//
@@ -180,11 +178,10 @@ func TestLoadWithVolume(t *testing.T) {
t.Fatal(err)
}
daemon, err := initDaemonForVolumesTest(tmp)
if err != nil {
t.Fatal(err)
daemon := &Daemon{
repository: tmp,
root: tmp,
}
defer volumedrivers.Unregister(volume.DefaultDriverName)
c, err := daemon.load(containerId)
if err != nil {
@@ -217,7 +214,7 @@ func TestLoadWithVolume(t *testing.T) {
t.Fatalf("Expected mount driver local, was %s\n", m.Driver)
}
newVolumeContent := filepath.Join(volumePath, local.VolumeDataPathName, "helo")
newVolumeContent := filepath.Join(volumePath, "helo")
b, err := ioutil.ReadFile(newVolumeContent)
if err != nil {
t.Fatal(err)
@@ -268,11 +265,10 @@ func TestLoadWithBindMount(t *testing.T) {
t.Fatal(err)
}
daemon, err := initDaemonForVolumesTest(tmp)
if err != nil {
t.Fatal(err)
daemon := &Daemon{
repository: tmp,
root: tmp,
}
defer volumedrivers.Unregister(volume.DefaultDriverName)
c, err := daemon.load(containerId)
if err != nil {
@@ -305,212 +301,3 @@ func TestLoadWithBindMount(t *testing.T) {
t.Fatalf("Expected mount point to be RW but it was not\n")
}
}
func TestLoadWithVolume17RC(t *testing.T) {
tmp, err := ioutil.TempDir("", "docker-daemon-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmp)
containerId := "d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e"
containerPath := filepath.Join(tmp, containerId)
if err := os.MkdirAll(containerPath, 0755); err != nil {
t.Fatal(err)
}
hostVolumeId := "6a3c03fc4a4e588561a543cc3bdd50089e27bd11bbb0e551e19bf735e2514101"
volumePath := filepath.Join(tmp, "volumes", hostVolumeId)
if err := os.MkdirAll(volumePath, 0755); err != nil {
t.Fatal(err)
}
content := filepath.Join(volumePath, "helo")
if err := ioutil.WriteFile(content, []byte("HELO"), 0644); err != nil {
t.Fatal(err)
}
config := `{"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":2464,"ExitCode":0,
"Error":"","StartedAt":"2015-05-26T16:48:53.869308965Z","FinishedAt":"0001-01-01T00:00:00Z"},
"ID":"d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e","Created":"2015-05-26T16:48:53.7987917Z","Path":"top",
"Args":[],"Config":{"Hostname":"d59df5276e7b","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"Cpuset":"",
"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":true,"OpenStdin":true,
"StdinOnce":false,"Env":null,"Cmd":["top"],"Image":"ubuntu:latest","Volumes":null,"WorkingDir":"","Entrypoint":null,
"NetworkDisabled":false,"MacAddress":"","OnBuild":null,"Labels":{}},"Image":"07f8e8c5e66084bef8f848877857537ffe1c47edd01a93af27e7161672ad0e95",
"NetworkSettings":{"IPAddress":"172.17.0.1","IPPrefixLen":16,"MacAddress":"02:42:ac:11:00:01","LinkLocalIPv6Address":"fe80::42:acff:fe11:1",
"LinkLocalIPv6PrefixLen":64,"GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"Gateway":"172.17.42.1","IPv6Gateway":"","Bridge":"docker0","PortMapping":null,"Ports":{}},
"ResolvConfPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/resolv.conf",
"HostnamePath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hostname",
"HostsPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hosts",
"LogPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e-json.log",
"Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0,
"UpdateDns":false,"MountPoints":{"/vol1":{"Name":"6a3c03fc4a4e588561a543cc3bdd50089e27bd11bbb0e551e19bf735e2514101","Destination":"/vol1","Driver":"local","RW":true,"Source":"","Relabel":""}},"AppliedVolumesFrom":null}`
if err = ioutil.WriteFile(filepath.Join(containerPath, "config.json"), []byte(config), 0644); err != nil {
t.Fatal(err)
}
hostConfig := `{"Binds":[],"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpusetCpus":"",
"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
"Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"no","MaximumRetryCount":0},
"SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"","Config":null},"CgroupParent":""}`
if err = ioutil.WriteFile(filepath.Join(containerPath, "hostconfig.json"), []byte(hostConfig), 0644); err != nil {
t.Fatal(err)
}
daemon, err := initDaemonForVolumesTest(tmp)
if err != nil {
t.Fatal(err)
}
defer volumedrivers.Unregister(volume.DefaultDriverName)
c, err := daemon.load(containerId)
if err != nil {
t.Fatal(err)
}
err = daemon.verifyVolumesInfo(c)
if err != nil {
t.Fatal(err)
}
if len(c.MountPoints) != 1 {
t.Fatalf("Expected 1 volume mounted, was 0\n")
}
m := c.MountPoints["/vol1"]
if m.Name != hostVolumeId {
t.Fatalf("Expected mount name to be %s, was %s\n", hostVolumeId, m.Name)
}
if m.Destination != "/vol1" {
t.Fatalf("Expected mount destination /vol1, was %s\n", m.Destination)
}
if !m.RW {
t.Fatalf("Expected mount point to be RW but it was not\n")
}
if m.Driver != volume.DefaultDriverName {
t.Fatalf("Expected mount driver local, was %s\n", m.Driver)
}
newVolumeContent := filepath.Join(volumePath, local.VolumeDataPathName, "helo")
b, err := ioutil.ReadFile(newVolumeContent)
if err != nil {
t.Fatal(err)
}
if string(b) != "HELO" {
t.Fatalf("Expected HELO, was %s\n", string(b))
}
}
func TestRemoveLocalVolumesFollowingSymlinks(t *testing.T) {
tmp, err := ioutil.TempDir("", "docker-daemon-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmp)
containerId := "d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e"
containerPath := filepath.Join(tmp, containerId)
if err := os.MkdirAll(containerPath, 0755); err != nil {
t.Fatal(err)
}
hostVolumeId := stringid.GenerateRandomID()
vfsPath := filepath.Join(tmp, "vfs", "dir", hostVolumeId)
volumePath := filepath.Join(tmp, "volumes", hostVolumeId)
if err := os.MkdirAll(vfsPath, 0755); err != nil {
t.Fatal(err)
}
if err := os.MkdirAll(volumePath, 0755); err != nil {
t.Fatal(err)
}
content := filepath.Join(vfsPath, "helo")
if err := ioutil.WriteFile(content, []byte("HELO"), 0644); err != nil {
t.Fatal(err)
}
config := `{"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":2464,"ExitCode":0,
"Error":"","StartedAt":"2015-05-26T16:48:53.869308965Z","FinishedAt":"0001-01-01T00:00:00Z"},
"ID":"d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e","Created":"2015-05-26T16:48:53.7987917Z","Path":"top",
"Args":[],"Config":{"Hostname":"d59df5276e7b","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"Cpuset":"",
"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":true,"OpenStdin":true,
"StdinOnce":false,"Env":null,"Cmd":["top"],"Image":"ubuntu:latest","Volumes":null,"WorkingDir":"","Entrypoint":null,
"NetworkDisabled":false,"MacAddress":"","OnBuild":null,"Labels":{}},"Image":"07f8e8c5e66084bef8f848877857537ffe1c47edd01a93af27e7161672ad0e95",
"NetworkSettings":{"IPAddress":"172.17.0.1","IPPrefixLen":16,"MacAddress":"02:42:ac:11:00:01","LinkLocalIPv6Address":"fe80::42:acff:fe11:1",
"LinkLocalIPv6PrefixLen":64,"GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"Gateway":"172.17.42.1","IPv6Gateway":"","Bridge":"docker0","PortMapping":null,"Ports":{}},
"ResolvConfPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/resolv.conf",
"HostnamePath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hostname",
"HostsPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hosts",
"LogPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e-json.log",
"Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0,
"UpdateDns":false,"Volumes":{"/vol1":"%s"},"VolumesRW":{"/vol1":true},"AppliedVolumesFrom":null}`
cfg := fmt.Sprintf(config, vfsPath)
if err = ioutil.WriteFile(filepath.Join(containerPath, "config.json"), []byte(cfg), 0644); err != nil {
t.Fatal(err)
}
hostConfig := `{"Binds":[],"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpusetCpus":"",
"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
"Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"no","MaximumRetryCount":0},
"SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"","Config":null},"CgroupParent":""}`
if err = ioutil.WriteFile(filepath.Join(containerPath, "hostconfig.json"), []byte(hostConfig), 0644); err != nil {
t.Fatal(err)
}
daemon, err := initDaemonForVolumesTest(tmp)
if err != nil {
t.Fatal(err)
}
defer volumedrivers.Unregister(volume.DefaultDriverName)
c, err := daemon.load(containerId)
if err != nil {
t.Fatal(err)
}
err = daemon.verifyVolumesInfo(c)
if err != nil {
t.Fatal(err)
}
if len(c.MountPoints) != 1 {
t.Fatalf("Expected 1 volume mounted, was 0\n")
}
m := c.MountPoints["/vol1"]
v, err := createVolume(m.Name, m.Driver)
if err != nil {
t.Fatal(err)
}
if err := removeVolume(v); err != nil {
t.Fatal(err)
}
fi, err := os.Stat(vfsPath)
if err == nil || !os.IsNotExist(err) {
t.Fatalf("Expected vfs path to not exist: %v - %v\n", fi, err)
}
}
func initDaemonForVolumesTest(tmp string) (*Daemon, error) {
daemon := &Daemon{
repository: tmp,
root: tmp,
}
volumesDriver, err := local.New(tmp)
if err != nil {
return nil, err
}
volumedrivers.Register(volumesDriver, volumesDriver.Name())
return daemon, nil
}
+2 -6
View File
@@ -109,6 +109,7 @@ func (d *Daemon) getActiveContainer(name string) (*Container, error) {
}
func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, error) {
// Not all drivers support Exec (LXC for example)
if err := checkExecSupport(d.execDriver.Name()); err != nil {
return "", err
@@ -122,16 +123,11 @@ func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, erro
cmd := runconfig.NewCommand(config.Cmd...)
entrypoint, args := d.getEntrypointAndArgs(runconfig.NewEntrypoint(), cmd)
user := config.User
if len(user) == 0 {
user = container.Config.User
}
processConfig := execdriver.ProcessConfig{
Tty: config.Tty,
Entrypoint: entrypoint,
Arguments: args,
User: user,
User: config.User,
}
execConfig := &execConfig{
-1
View File
@@ -24,7 +24,6 @@ func InitContainer(c *Command) *configs.Config {
container.Devices = c.AutoCreatedDevices
container.Rootfs = c.Rootfs
container.Readonlyfs = c.ReadonlyRootfs
container.Privatefs = true
// check to see if we are running in ramdisk to disable pivot root
container.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != ""
+1 -1
View File
@@ -124,7 +124,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
dataPath = d.containerDir(c.ID)
)
if c.Network == nil || (c.Network.NamespacePath == "" && c.Network.ContainerID == "") {
if c.Network.NamespacePath == "" && c.Network.ContainerID == "" {
return execdriver.ExitStatus{ExitCode: -1}, fmt.Errorf("empty namespace path for non-container network")
}
+5 -2
View File
@@ -104,8 +104,8 @@ type DeviceSet struct {
thinpBlockSize uint32
thinPoolDevice string
Transaction `json:"-"`
deferredRemove bool // use deferred removal
overrideUdevSyncCheck bool
deferredRemove bool // use deferred removal
}
type DiskUsage struct {
@@ -1033,7 +1033,10 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
// https://github.com/docker/docker/issues/4036
if supported := devicemapper.UdevSetSyncSupport(true); !supported {
logrus.Warn("Udev sync is not supported. This will lead to unexpected behavior, data loss and errors. For more information, see https://docs.docker.com/reference/commandline/cli/#daemon-storage-driver-option")
logrus.Errorf("Udev sync is not supported. This will lead to unexpected behavior, data loss and errors. For more information, see https://docs.docker.com/reference/commandline/cli/#daemon-storage-driver-option")
if !devices.overrideUdevSyncCheck {
return graphdriver.ErrNotSupported
}
}
if err := os.MkdirAll(devices.metadataDir(), 0700); err != nil && !os.IsExist(err) {
+1 -1
View File
@@ -168,7 +168,7 @@ func scanPriorDrivers(root string) []string {
priorDrivers := []string{}
for driver := range drivers {
p := filepath.Join(root, driver)
if _, err := os.Stat(p); err == nil && driver != "vfs" {
if _, err := os.Stat(p); err == nil {
priorDrivers = append(priorDrivers, driver)
}
}
+2 -4
View File
@@ -17,7 +17,6 @@ import (
"github.com/docker/docker/daemon/graphdriver"
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/libcontainer/label"
zfs "github.com/mistifyio/go-zfs"
)
@@ -282,15 +281,14 @@ func (d *Driver) Remove(id string) error {
func (d *Driver) Get(id, mountLabel string) (string, error) {
mountpoint := d.MountPath(id)
filesystem := d.ZfsPath(id)
options := label.FormatMountLabel("", mountLabel)
log.Debugf(`[zfs] mount("%s", "%s", "%s")`, filesystem, mountpoint, options)
log.Debugf(`[zfs] mount("%s", "%s", "%s")`, filesystem, mountpoint, mountLabel)
// Create the target directories if they don't exist
if err := os.MkdirAll(mountpoint, 0755); err != nil && !os.IsExist(err) {
return "", err
}
err := mount.Mount(filesystem, mountpoint, "zfs", options)
err := mount.Mount(filesystem, mountpoint, "zfs", mountLabel)
if err != nil {
return "", fmt.Errorf("error creating zfs mount of %s to %s: %v", filesystem, mountpoint, err)
}
+16 -72
View File
@@ -8,7 +8,6 @@ import (
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/libcontainer"
"github.com/docker/libcontainer/cgroups"
"github.com/docker/libnetwork/sandbox"
)
func (daemon *Daemon) ContainerStats(name string, stream bool, out io.Writer) error {
@@ -16,43 +15,31 @@ func (daemon *Daemon) ContainerStats(name string, stream bool, out io.Writer) er
if err != nil {
return err
}
var preCpuStats types.CpuStats
getStat := func(v interface{}) *types.Stats {
var pre_cpu_stats types.CpuStats
for first_v := range updates {
first_update := first_v.(*execdriver.ResourceStats)
first_stats := convertToAPITypes(first_update.Stats)
pre_cpu_stats = first_stats.CpuStats
pre_cpu_stats.SystemUsage = first_update.SystemUsage
break
}
enc := json.NewEncoder(out)
for v := range updates {
update := v.(*execdriver.ResourceStats)
// Retrieve the nw statistics from libnetwork and inject them in the Stats
if nwStats, err := daemon.getNetworkStats(name); err == nil {
update.Stats.Interfaces = nwStats
}
ss := convertToAPITypes(update.Stats)
ss.PreCpuStats = preCpuStats
ss.PreCpuStats = pre_cpu_stats
ss.MemoryStats.Limit = uint64(update.MemoryLimit)
ss.Read = update.Read
ss.CpuStats.SystemUsage = update.SystemUsage
preCpuStats = ss.CpuStats
return ss
}
enc := json.NewEncoder(out)
if !stream {
// prime the cpu stats so they aren't 0 in the final output
s := getStat(<-updates)
// now pull stats again with the cpu stats primed
s = getStat(<-updates)
err := enc.Encode(s)
daemon.UnsubscribeToContainerStats(name, updates)
return err
}
for v := range updates {
s := getStat(v)
if err := enc.Encode(s); err != nil {
pre_cpu_stats = ss.CpuStats
if err := enc.Encode(ss); err != nil {
// TODO: handle the specific broken pipe
daemon.UnsubscribeToContainerStats(name, updates)
return err
}
if !stream {
break
}
}
return nil
}
@@ -123,46 +110,3 @@ func copyBlkioEntry(entries []cgroups.BlkioStatEntry) []types.BlkioStatEntry {
}
return out
}
func (daemon *Daemon) getNetworkStats(name string) ([]*libcontainer.NetworkInterface, error) {
var list []*libcontainer.NetworkInterface
c, err := daemon.Get(name)
if err != nil {
return list, err
}
nw, err := daemon.netController.NetworkByID(c.NetworkSettings.NetworkID)
if err != nil {
return list, err
}
ep, err := nw.EndpointByID(c.NetworkSettings.EndpointID)
if err != nil {
return list, err
}
stats, err := ep.Statistics()
if err != nil {
return list, err
}
// Convert libnetwork nw stats into libcontainer nw stats
for ifName, ifStats := range stats {
list = append(list, convertLnNetworkStats(ifName, ifStats))
}
return list, nil
}
func convertLnNetworkStats(name string, stats *sandbox.InterfaceStatistics) *libcontainer.NetworkInterface {
n := &libcontainer.NetworkInterface{Name: name}
n.RxBytes = stats.RxBytes
n.RxPackets = stats.RxPackets
n.RxErrors = stats.RxErrors
n.RxDropped = stats.RxDropped
n.TxBytes = stats.TxBytes
n.TxPackets = stats.TxPackets
n.TxErrors = stats.TxErrors
n.TxDropped = stats.TxDropped
return n
}
+71 -88
View File
@@ -1,6 +1,7 @@
package daemon
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
@@ -11,7 +12,6 @@ import (
"github.com/docker/docker/pkg/chrootarchive"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/volume"
"github.com/docker/docker/volume/local"
"github.com/docker/libcontainer/label"
)
@@ -53,13 +53,6 @@ func (m *mountPoint) Path() string {
return m.Source
}
// BackwardsCompatible decides whether this mount point can be
// used in old versions of Docker or not.
// Only bind mounts and local volumes can be used in old versions of Docker.
func (m *mountPoint) BackwardsCompatible() bool {
return len(m.Source) > 0 || m.Driver == volume.DefaultDriverName
}
func parseBindMount(spec string, mountLabel string, config *runconfig.Config) (*mountPoint, error) {
bind := &mountPoint{
RW: true,
@@ -191,16 +184,11 @@ func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runc
}
for _, m := range c.MountPoints {
cp := &mountPoint{
Name: m.Name,
Source: m.Source,
RW: m.RW && mode != "ro",
Driver: m.Driver,
Destination: m.Destination,
}
cp := m
cp.RW = m.RW && mode != "ro"
if len(cp.Source) == 0 {
v, err := createVolume(cp.Name, cp.Driver)
if len(m.Source) == 0 {
v, err := createVolume(m.Name, m.Driver)
if err != nil {
return err
}
@@ -244,20 +232,8 @@ func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runc
mountPoints[bind.Destination] = bind
}
// Keep backwards compatible structures
bcVolumes := map[string]string{}
bcVolumesRW := map[string]bool{}
for _, m := range mountPoints {
if m.BackwardsCompatible() {
bcVolumes[m.Destination] = m.Path()
bcVolumesRW[m.Destination] = m.RW
}
}
container.Lock()
container.MountPoints = mountPoints
container.Volumes = bcVolumes
container.VolumesRW = bcVolumesRW
container.Unlock()
return nil
@@ -266,74 +242,81 @@ func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runc
// verifyVolumesInfo ports volumes configured for the containers pre docker 1.7.
// It reads the container configuration and creates valid mount points for the old volumes.
func (daemon *Daemon) verifyVolumesInfo(container *Container) error {
// Inspect old structures only when we're upgrading from old versions
// to versions >= 1.7 and the MountPoints has not been populated with volumes data.
if len(container.MountPoints) == 0 && len(container.Volumes) > 0 {
for destination, hostPath := range container.Volumes {
vfsPath := filepath.Join(daemon.root, "vfs", "dir")
rw := container.VolumesRW != nil && container.VolumesRW[destination]
if strings.HasPrefix(hostPath, vfsPath) {
id := filepath.Base(hostPath)
if err := migrateVolume(id, hostPath); err != nil {
return err
}
container.addLocalMountPoint(id, destination, rw)
} else { // Bind mount
id, source, err := parseVolumeSource(hostPath)
// We should not find an error here coming
// from the old configuration, but who knows.
if err != nil {
return err
}
container.addBindMountPoint(id, source, destination, rw)
}
}
} else if len(container.MountPoints) > 0 {
// Volumes created with a Docker version >= 1.7. We verify integrity in case of data created
// with Docker 1.7 RC versions that put the information in
// DOCKER_ROOT/volumes/VOLUME_ID rather than DOCKER_ROOT/volumes/VOLUME_ID/_container_data.
l, err := getVolumeDriver(volume.DefaultDriverName)
if err != nil {
return err
jsonPath, err := container.jsonPath()
if err != nil {
return err
}
f, err := os.Open(jsonPath)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
for _, m := range container.MountPoints {
if m.Driver != volume.DefaultDriverName {
continue
}
dataPath := l.(*local.Root).DataPath(m.Name)
volumePath := filepath.Dir(dataPath)
type oldContVolCfg struct {
Volumes map[string]string
VolumesRW map[string]bool
}
d, err := ioutil.ReadDir(volumePath)
if err != nil {
// If the volume directory doesn't exist yet it will be recreated,
// so we only return the error when there is a different issue.
if !os.IsNotExist(err) {
return err
}
// Do not check when the volume directory does not exist.
continue
}
if validVolumeLayout(d) {
continue
}
vols := oldContVolCfg{
Volumes: make(map[string]string),
VolumesRW: make(map[string]bool),
}
if err := json.NewDecoder(f).Decode(&vols); err != nil {
return err
}
if err := os.Mkdir(dataPath, 0755); err != nil {
for destination, hostPath := range vols.Volumes {
vfsPath := filepath.Join(daemon.root, "vfs", "dir")
rw := vols.VolumesRW != nil && vols.VolumesRW[destination]
if strings.HasPrefix(hostPath, vfsPath) {
id := filepath.Base(hostPath)
if err := daemon.migrateVolume(id, hostPath); err != nil {
return err
}
// Move data inside the data directory
for _, f := range d {
oldp := filepath.Join(volumePath, f.Name())
newp := filepath.Join(dataPath, f.Name())
if err := os.Rename(oldp, newp); err != nil {
logrus.Errorf("Unable to move %s to %s\n", oldp, newp)
}
container.addLocalMountPoint(id, destination, rw)
} else { // Bind mount
id, source, err := parseVolumeSource(hostPath)
// We should not find an error here coming
// from the old configuration, but who knows.
if err != nil {
return err
}
container.addBindMountPoint(id, source, destination, rw)
}
}
return container.ToDisk()
return container.ToDisk()
}
// migrateVolume moves the contents of a volume created pre Docker 1.7
// to the location expected by the local driver. Steps:
// 1. Save old directory that includes old volume's config json file.
// 2. Move virtual directory with content to where the local driver expects it to be.
// 3. Remove the backup of the old volume config.
func (daemon *Daemon) migrateVolume(id, vfs string) error {
volumeInfo := filepath.Join(daemon.root, defaultVolumesPathName, id)
backup := filepath.Join(daemon.root, defaultVolumesPathName, id+".back")
var err error
if err = os.Rename(volumeInfo, backup); err != nil {
return err
}
defer func() {
// Put old configuration back in place in case one of the next steps fails.
if err != nil {
os.Rename(backup, volumeInfo)
}
}()
if err = os.Rename(vfs, volumeInfo); err != nil {
return err
}
if err = os.RemoveAll(backup); err != nil {
logrus.Errorf("Unable to remove volume info backup directory %s: %v", backup, err)
}
return nil
-49
View File
@@ -10,8 +10,6 @@ import (
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/volume"
"github.com/docker/docker/volume/local"
)
// copyOwnership copies the permissions and uid:gid of the source file
@@ -70,50 +68,3 @@ func (m mounts) Swap(i, j int) {
func (m mounts) parts(i int) int {
return len(strings.Split(filepath.Clean(m[i].Destination), string(os.PathSeparator)))
}
// migrateVolume links the contents of a volume created pre Docker 1.7
// into the location expected by the local driver.
// It creates a symlink from DOCKER_ROOT/vfs/dir/VOLUME_ID to DOCKER_ROOT/volumes/VOLUME_ID/_container_data.
// It preserves the volume json configuration generated pre Docker 1.7 to be able to
// downgrade from Docker 1.7 to Docker 1.6 without losing volume compatibility.
func migrateVolume(id, vfs string) error {
l, err := getVolumeDriver(volume.DefaultDriverName)
if err != nil {
return err
}
newDataPath := l.(*local.Root).DataPath(id)
fi, err := os.Stat(newDataPath)
if err != nil && !os.IsNotExist(err) {
return err
}
if fi != nil && fi.IsDir() {
return nil
}
return os.Symlink(vfs, newDataPath)
}
// validVolumeLayout checks whether the volume directory layout
// is valid to work with Docker post 1.7 or not.
func validVolumeLayout(files []os.FileInfo) bool {
if len(files) == 1 && files[0].Name() == local.VolumeDataPathName && files[0].IsDir() {
return true
}
if len(files) != 2 {
return false
}
for _, f := range files {
if f.Name() == "config.json" ||
(f.Name() == local.VolumeDataPathName && f.Mode()&os.ModeSymlink == os.ModeSymlink) {
// Old volume configuration, we ignore it
continue
}
return false
}
return true
}
+1 -13
View File
@@ -2,11 +2,7 @@
package daemon
import (
"os"
"github.com/docker/docker/daemon/execdriver"
)
import "github.com/docker/docker/daemon/execdriver"
// Not supported on Windows
func copyOwnership(source, destination string) error {
@@ -16,11 +12,3 @@ func copyOwnership(source, destination string) error {
func (container *Container) setupMounts() ([]execdriver.Mount, error) {
return nil, nil
}
func migrateVolume(id, vfs string) error {
return nil
}
func validVolumeLayout(files []os.FileInfo) bool {
return true
}
+3
View File
@@ -1,2 +1,5 @@
# generated by man/man/md2man-all.sh
man1/
man5/
# avoid commiting the awsconfig file used for releases
awsconfig
+157 -7
View File
@@ -1,13 +1,163 @@
FROM docs/base:hugo
MAINTAINER Mary Anthony <mary@docker.com> (@moxiegirl)
#
# See the top level Makefile in https://github.com/docker/docker for usage.
#
FROM docs/base:latest
MAINTAINER Sven Dowideit <SvenDowideit@docker.com> (@SvenDowideit)
# To get the git info for this repo
# This section ensures we pull the correct version of each
# sub project
ENV COMPOSE_BRANCH release
ENV SWARM_BRANCH v0.2.0
ENV MACHINE_BRANCH docs
ENV DISTRIB_BRANCH docs
ENV KITEMATIC_BRANCH master
# TODO: need the full repo source to get the git version info
COPY . /src
COPY . /docs/content/
# Reset the /docs dir so we can replace the theme meta with the new repo's git info
# RUN git reset --hard
WORKDIR /docs/content
# Then copy the desired docs into the /docs/sources/ dir
COPY ./sources/ /docs/sources
RUN /docs/content/touch-up.sh
COPY ./VERSION VERSION
WORKDIR /docs
# adding the image spec will require Docker 1.5 and `docker build -f docs/Dockerfile .`
#COPY ./image/spec/v1.md /docs/sources/reference/image-spec-v1.md
# TODO: don't do this - look at merging the yml file in build.sh
COPY ./mkdocs.yml ./s3_website.json ./release.sh ./
#######################
# Docker Distribution
########################
#ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/mkdocs.yml /docs/mkdocs-distribution.yml
ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/images/notifications.png \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/images/registry.png \
/docs/sources/registry/images/
ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/index.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/deploying.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/configuration.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/storagedrivers.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/notifications.md \
/docs/sources/registry/
ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/spec/api.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/spec/json.md \
/docs/sources/registry/spec/
ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/storage-drivers/s3.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/storage-drivers/azure.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/storage-drivers/filesystem.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/storage-drivers/inmemory.md \
/docs/sources/registry/storage-drivers/
ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/spec/auth/token.md /docs/sources/registry/spec/auth/token.md
RUN sed -i.old '1s;^;no_version_dropdown: true;' \
/docs/sources/registry/*.md \
/docs/sources/registry/spec/*.md \
/docs/sources/registry/spec/auth/*.md \
/docs/sources/registry/storage-drivers/*.md
RUN sed -i.old -e '/^<!--GITHUB/g' -e '/^IGNORES-->/g'\
/docs/sources/registry/*.md \
/docs/sources/registry/spec/*.md \
/docs/sources/registry/spec/auth/*.md \
/docs/sources/registry/storage-drivers/*.md
#######################
# Docker Swarm
#######################
#ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/docs/mkdocs.yml /docs/mkdocs-swarm.yml
ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/docs/index.md /docs/sources/swarm/index.md
ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/discovery/README.md /docs/sources/swarm/discovery.md
ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/api/README.md /docs/sources/swarm/API.md
ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/scheduler/filter/README.md /docs/sources/swarm/scheduler/filter.md
ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/scheduler/strategy/README.md /docs/sources/swarm/scheduler/strategy.md
RUN sed -i.old '1s;^;no_version_dropdown: true;' /docs/sources/swarm/*.md /docs/sources/swarm/scheduler/*.md
#######################
# Docker Machine
#######################
#ADD https://raw.githubusercontent.com/docker/machine/${MACHINE_BRANCH}/docs/mkdocs.yml /docs/mkdocs-machine.yml
ADD https://raw.githubusercontent.com/docker/machine/${MACHINE_BRANCH}/docs/index.md /docs/sources/machine/index.md
RUN sed -i.old '1s;^;no_version_dropdown: true;' /docs/sources/machine/index.md
#######################
# Docker Compose
#######################
#ADD https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/mkdocs.yml /docs/mkdocs-compose.yml
ADD https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/index.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/install.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/cli.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/yml.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/env.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/completion.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/django.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/rails.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/wordpress.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/extends.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/production.md \
/docs/sources/compose/
RUN sed -i.old '1s;^;no_version_dropdown: true;' /docs/sources/compose/*.md
#######################
# Kitematic
#######################
ADD https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/faq.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/index.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/known-issues.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/minecraft-server.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/nginx-web-server.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/rethinkdb-dev-database.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/userguide.md \
/docs/sources/kitematic/
RUN sed -i.old '1s;^;no_version_dropdown: true;' /docs/sources/kitematic/*.md
ADD https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/browse-images.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/change-folder.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/cli-access-button.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/cli-redis-container.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/cli-terminal.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/containers.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/installing.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-add-server.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-create.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-data-volume.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-login.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-map.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-port.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-restart.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-server-address.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-2048-files.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-2048.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-create.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-data-folder.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-data-volume.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-hello-world.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-preview.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-serving-2048.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/rethink-container.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/rethink-create.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/rethink-ports.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/rethinkdb-preview.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/volumes-dir.png \
/docs/sources/kitematic/assets/
# Then build everything together, ready for mkdocs
RUN /docs/build.sh
-55
View File
@@ -1,55 +0,0 @@
.PHONY: all binary build cross default docs docs-build docs-shell shell test test-unit test-integration test-integration-cli test-docker-py validate
# env vars passed through directly to Docker's build scripts
# to allow things like `make DOCKER_CLIENTONLY=1 binary` easily
# `docs/sources/contributing/devenvironment.md ` and `project/PACKAGERS.md` have some limited documentation of some of these
DOCKER_ENVS := \
-e BUILDFLAGS \
-e DOCKER_CLIENTONLY \
-e DOCKER_EXECDRIVER \
-e DOCKER_GRAPHDRIVER \
-e TESTDIRS \
-e TESTFLAGS \
-e TIMEOUT
# note: we _cannot_ add "-e DOCKER_BUILDTAGS" here because even if it's unset in the shell, that would shadow the "ENV DOCKER_BUILDTAGS" set in our Dockerfile, which is very important for our official builds
# to allow `make DOCSDIR=docs docs-shell` (to create a bind mount in docs)
DOCS_MOUNT := $(if $(DOCSDIR),-v $(CURDIR)/$(DOCSDIR):/$(DOCSDIR))
# to allow `make DOCSPORT=9000 docs`
DOCSPORT := 8000
# Get the IP ADDRESS
DOCKER_IP=$(shell python -c "import urlparse ; print urlparse.urlparse('$(DOCKER_HOST)').hostname or ''")
HUGO_BASE_URL=$(shell test -z "$(DOCKER_IP)" && echo localhost || echo "$(DOCKER_IP)")
HUGO_BIND_IP=0.0.0.0
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)
DOCKER_IMAGE := docker$(if $(GIT_BRANCH),:$(GIT_BRANCH))
DOCKER_DOCS_IMAGE := docs-base$(if $(GIT_BRANCH),:$(GIT_BRANCH))
DOCKER_RUN_DOCS := docker run --rm -it $(DOCS_MOUNT) -e AWS_S3_BUCKET -e NOCACHE
# for some docs workarounds (see below in "docs-build" target)
GITCOMMIT := $(shell git rev-parse --short HEAD 2>/dev/null)
default: docs
docs: docs-build
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 -e DOCKERHOST "$(DOCKER_DOCS_IMAGE)" hugo server --port=$(DOCSPORT) --baseUrl=$(HUGO_BASE_URL) --bind=$(HUGO_BIND_IP)
docs-draft: docs-build
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 -e DOCKERHOST "$(DOCKER_DOCS_IMAGE)" hugo server --buildDrafts="true" --port=$(DOCSPORT) --baseUrl=$(HUGO_BASE_URL) --bind=$(HUGO_BIND_IP)
docs-shell: docs-build
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 "$(DOCKER_DOCS_IMAGE)" bash
docs-build:
# ( git remote | grep -v upstream ) || git diff --name-status upstream/release..upstream/docs ./ > ./changed-files
# echo "$(GIT_BRANCH)" > GIT_BRANCH
# echo "$(AWS_S3_BUCKET)" > AWS_S3_BUCKET
# echo "$(GITCOMMIT)" > GITCOMMIT
docker build -t "$(DOCKER_DOCS_IMAGE)" .
+20 -13
View File
@@ -1,12 +1,6 @@
<!--[metadata]>
+++
draft = true
+++
<![end-metadata]-->
# Docker Documentation
The source for Docker documentation is in this directory. Our
The source for Docker documentation is in this directory under `sources/`. Our
documentation uses extended Markdown, as implemented by
[MkDocs](http://mkdocs.org). The current release of the Docker documentation
resides on [https://docs.docker.com](https://docs.docker.com).
@@ -60,7 +54,7 @@ own.
release. It also allows docs maintainers to easily cherry-pick your changes
into the `docs` release branch.
4. Modify existing or add new `.md` files to the `docs` directory.
4. Modify existing or add new `.md` files to the `docs/sources` directory.
If you add a new document (`.md`) file, you must also add it to the
appropriate section of the `docs/mkdocs.yml` file in this repository.
@@ -113,7 +107,7 @@ links that are referenced in the documentation&mdash;there should be none.
## Style guide
If you have questions about how to write for Docker's documentation, please see
the [style guide](project/doc-style.md). The style guide provides
the [style guide](sources/project/doc-style.md). The style guide provides
guidance about grammar, syntax, formatting, styling, language, or tone. If
something isn't clear in the guide, please submit an issue to let us know or
submit a pull request to help us improve it.
@@ -286,11 +280,24 @@ aws cloudfront create-invalidation --profile docs.docker.com --distribution-id
aws cloudfront create-invalidation --profile docs.docker.com --distribution-id $DISTRIBUTION_ID --invalidation-batch '{"Paths":{"Quantity":1, "Items":["/v1.1/reference/api/docker_io_oauth_api/"]},"CallerReference":"6Mar2015sventest1"}'
```
### Generate the man pages
### Generate the man pages for Mac OSX
For information on generating man pages (short for manual page), see [the man
page directory](https://github.com/docker/docker/tree/master/docker) in this
project.
When using Docker on Mac OSX the man pages will be missing by default. You can manually generate them by following these steps:
1. Checkout the docker source. You must clone into your `/Users` directory because Boot2Docker can only share this path
with the docker containers.
$ git clone https://github.com/docker/docker.git
2. Build the docker image.
$ cd docker/docs/man
$ docker build -t docker/md2man .
3. Build the man pages.
$ docker run -v /Users/<path-to-git-dir>/docker/docs/man:/docs:rw -w /docs -i docker/md2man /docs/md2man-all.sh
4. Copy the generated man pages to `/usr/share/man`
$ cp -R man* /usr/share/man/
-196
View File
@@ -1,196 +0,0 @@
<!--[metadata]>
+++
title = "Installation on CentOS"
description = "Instructions for installing Docker on CentOS"
keywords = ["Docker, Docker documentation, requirements, linux, centos, epel, docker.io, docker-io"]
[menu.main]
parent = "smn_linux"
+++
<![end-metadata]-->
# CentOS
Docker is supported on the following versions of CentOS:
* CentOS 7.X
* CentOS 6.5 or higher
Installation on other binary compatible EL6/EL7 distributions such as Scientific
Linux might succeed, but Docker does not test or support Docker on these
distributions.
This page instructs you to install using Docker-managed release packages and
installation mechanisms. Using these packages ensures you get the latest release
of Docker. If you wish to install using CentOS-managed packages, consult your
CentOS documentation.
## Prerequisites
Docker requires a 64-bit installation regardless of your CentOS version. Also,
your kernel must be 3.10 at minimum. CentOS 7 runs the 3.10 kernel, 6.5 does
not. We make an exception for CentOS 6.5. To run Docker on
[CentOS-6.5](https://www.centos.org) or later, you need kernel 2.6.32-431 or
higher.
To check your current kernel version, open a terminal and use `uname -r` to
display your kernel version:
$ uname -r
2.6.32-431.el6.x86_64
Finally, is it recommended that you fully update your system. Please keep in
mind that CentOS 6 should be fully patched to fix any potential kernel bugs. Any
reported kernel bugs may have already been fixed on the latest kernel packages
## Install
You use the same installation procedure for all versions of CentOS,
only the package you install differs. There are two packages to choose from:
<table>
<tr>
<th>Version</th>
<th>Package name</th>
</tr>
<tr>
<td>6.5 and higher</td>
<td>
<p>
<a href="https://get.docker.com/rpm/1.7.0/centos-6/RPMS/x86_64/docker-engine-1.7.0-1.el6.x86_64.rpm">
https://get.docker.com/rpm/1.7.0/centos-6/RPMS/x86_64/docker-engine-1.7.0-1.el6.x86_64.rpm</a>
<p>
<a href="https://get.docker.com/rpm/1.7.0/centos-6/SRPMS/docker-engine-1.7.0-1.el6.src.rpm">
https://get.docker.com/rpm/1.7.0/centos-6/SRPMS/docker-engine-1.7.0-1.el6.src.rpm</a>
<p>
</p>
</td>
</tr>
<tr>
<td>7.X</td>
<td>
<p>
<a href="https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.centos.x86_64.rpm">
https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.centos.x86_64.rpm</a>
</p>
<p>
<a href="https://get.docker.com/rpm/1.7.0/centos-7/SRPMS/docker-engine-1.7.0-1.el7.centos.src.rpm">
https://get.docker.com/rpm/1.7.0/centos-7/SRPMS/docker-engine-1.7.0-1.el7.centos.src.rpm</a>
</p>
</td>
</tr>
</table>
This procedure depicts an installation on version 6.5. If you are installing on
7.X, substitute that package for your installation.
1. Log into your machine as a user with `sudo` or `root` privileges.
2. Make sure your existing packages are up-to-date.
$ sudo yum update
3. Download the Docker RPM to the current directory.
$ curl -O -sSL https://get.docker.com/rpm/1.7.0/centos-6/RPMS/x86_64/docker-engine-1.7.0-1.el6.x86_64.rpm
4. Use `yum` to install the package.
$ sudo yum localinstall --nogpgcheck docker-engine-1.7.0-1.el6.x86_64.rpm
5. Start the Docker daemon.
$ sudo service docker start
6. Verify `docker` is installed correctly by running a test image in a container.
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from hello-world
a8219747be10: Pull complete
91c95931e552: Already exists
hello-world:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:aa03e5d0d5553b4c3473e89c8619cf79df368babd1.7.0cf5daeb82aab55838d
Status: Downloaded newer image for hello-world:latest
Hello from Docker.
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(Assuming it was not already locally available.)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
For more examples and ideas, visit:
http://docs.docker.com/userguide/
## Create a docker group
The `docker` daemon binds to a Unix socket instead of a TCP port. By default
that Unix socket is owned by the user `root` and other users can access it with
`sudo`. For this reason, `docker` daemon always runs as the `root` user.
To avoid having to use `sudo` when you use the `docker` command, create a Unix
group called `docker` and add users to it. When the `docker` daemon starts, it
makes the ownership of the Unix socket read/writable by the `docker` group.
>**Warning**: The `docker` group is equivalent to the `root` user; For details
>on how this impacts security in your system, see [*Docker Daemon Attack
>Surface*](/articles/security/#docker-daemon-attack-surface) for details.
To create the `docker` group and add your user:
1. Log into Centos as a user with `sudo` privileges.
2. Create the `docker` group and add your user.
`sudo usermod -aG docker your_username`
3. Log out and log back in.
This ensures your user is running with the correct permissions.
4. Verify your work by running `docker` without `sudo`.
$ docker run hello-world
## Start the docker daemon at boot
To ensure Docker starts when you boot your system, do the following:
$ sudo chkconfig docker on
If you need to add an HTTP Proxy, set a different directory or partition for the
Docker runtime files, or make other customizations, read our Systemd article to
learn how to [customize your Systemd Docker daemon options](/articles/systemd/).
## Uninstall
You can uninstall the Docker software with `yum`.
1. List the package you have installed.
$ yum list installed | grep docker
yum list installed | grep docker
docker-engine.x86_64 1.7.0-1.el6
@/docker-engine-1.7.0-1.el6.x86_64.rpm
2. Remove the package.
$ sudo yum -y remove docker-engine.x86_64
This command does not remove images, containers, volumes, or user-created
configuration files on your host.
3. To delete all images, containers, and volumes, run the following command:
$ rm -rf /var/lib/docker
4. Locate and delete any user-created configuration files.
-232
View File
@@ -1,232 +0,0 @@
<!--[metadata]>
+++
title = "Installation on Fedora"
description = "Instructions for installing Docker on Fedora."
keywords = ["Docker, Docker documentation, Fedora, requirements, linux"]
[menu.main]
parent = "smn_linux"
+++
<![end-metadata]-->
# Fedora
Docker is supported on the following versions of Fedora:
- Fedora 20
- Fedora 21
- Fedora 22
This page instructs you to install using Docker-managed release packages and
installation mechanisms. Using these packages ensures you get the latest release
of Docker. If you wish to install using Fedora-managed packages, consult your
Fedora release documentation for information on Fedora's Docker support.
##Prerequisites
Docker requires a 64-bit installation regardless of your Fedora version. Also, your kernel must be 3.10 at minimum. To check your current kernel
version, open a terminal and use `uname -r` to display your kernel version:
$ uname -r
3.19.5-100.fc20.x86_64
If your kernel is at a older version, you must update it.
Finally, is it recommended that you fully update your system. Please keep in
mind that your system should be fully patched to fix any potential kernel bugs. Any
reported kernel bugs may have already been fixed on the latest kernel packages
## Install
You use the same installation procedure for all versions of Fedora,
only the package you install differs. There are two packages to choose from:
<table>
<tr>
<th>Version</th>
<th>Package name</th>
</tr>
<tr>
<td>Fedora 20</td>
<td>
<p>
<a href="https://get.docker.com/rpm/1.7.0/fedora-20/RPMS/x86_64/docker-engine-1.7.0-1.fc20.x86_64.rpm">
https://get.docker.com/rpm/1.7.0/fedora-20/RPMS/x86_64/docker-engine-1.7.0-1.fc20.x86_64.rpm</a>
</p>
</td>
<p>
<a href="https://get.docker.com/rpm/1.7.0/fedora-20/SRPMS/docker-engine-1.7.0-1.fc20.src.rpm">
https://get.docker.com/rpm/1.7.0/fedora-20/SRPMS/docker-engine-1.7.0-1.fc20.src.rpm/a>
</p>
</td>
</tr>
<tr>
<td>Fedora 21</td>
<td>
<p>
<a href="https://get.docker.com/rpm/1.7.0/fedora-21/RPMS/x86_64/docker-engine-1.7.0-1.fc21.x86_64.rpm">
https://get.docker.com/rpm/1.7.0/fedora-21/RPMS/x86_64/docker-engine-1.7.0-1.fc21.x86_64.rpm</a>
</p>
</td>
<p>
<a href="https://get.docker.com/rpm/1.7.0/fedora-21/SRPMS/docker-engine-1.7.0-1.fc21.src.rpm">
https://get.docker.com/rpm/1.7.0/fedora-21/SRPMS/docker-engine-1.7.0-1.fc21.src.rpm/a>
</p>
</td>
</tr>
<tr>
<td>Fedora 22</td>
<td>
<p>
<a href="https://get.docker.com/rpm/1.7.0/fedora-22/RPMS/x86_64/docker-engine-1.7.0-1.fc22.x86_64.rpm">
https://get.docker.com/rpm/1.7.0/fedora-22/RPMS/x86_64/docker-engine-1.7.0-1.fc22.x86_64.rpm</a>
</p>
</td>
<p>
<a href="https://get.docker.com/rpm/1.7.0/fedora-22/SRPMS/docker-engine-1.7.0-1.fc22.src.rpm">
https://get.docker.com/rpm/1.7.0/fedora-22/SRPMS/docker-engine-1.7.0-1.fc22.src.rpm/a>
</p>
</td>
</tr>
</table>
This procedure depicts an installation on version 21. If you are installing on
20 or 22, substitute that package for your installation.
1. Log into your machine as a user with `sudo` or `root` privileges.
2. Make sure you don't have an older version of Docker installed.
$ yum list installed | grep docker
If you have an older version, remove it using the `yum -y remove <packagename>` command.
3. Download the Docker RPM to the current directory.
$ curl -O -sSL https://url_to_package/docker-engine-1.7.0-0.1.fc21.x86_64.rpm
4. Use `yum` to install the package.
$ sudo yum localinstall --nogpgcheck docker-engine-1.7.0-0.1.fc21.x86_64.rpm
5. Start the Docker daemon.
$ sudo service docker start
6. Verify `docker` is installed correctly by running a test image in a container.
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from hello-world
a8219747be10: Pull complete
91c95931e552: Already exists
hello-world:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:aa03e5d0d5553b4c3473e89c8619cf79df368babd18681cf5daeb82aab55838d
Status: Downloaded newer image for hello-world:latest
Hello from Docker.
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(Assuming it was not already locally available.)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
For more examples and ideas, visit:
http://docs.docker.com/userguide/
## Create a docker group
The `docker` daemon binds to a Unix socket instead of a TCP port. By default
that Unix socket is owned by the user `root` and other users can access it with
`sudo`. For this reason, `docker` daemon always runs as the `root` user.
To avoid having to use `sudo` when you use the `docker` command, create a Unix
group called `docker` and add users to it. When the `docker` daemon starts, it
makes the ownership of the Unix socket read/writable by the `docker` group.
>**Warning**: The `docker` group is equivalent to the `root` user; For details
>on how this impacts security in your system, see [*Docker Daemon Attack
>Surface*](/articles/security/#docker-daemon-attack-surface) for details.
To create the `docker` group and add your user:
1. Log into your system as a user with `sudo` privileges.
2. Create the `docker` group and add your user.
`sudo usermod -aG docker your_username`
3. Log out and log back in.
This ensures your user is running with the correct permissions.
4. Verify your work by running `docker` without `sudo`.
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from hello-world
a8219747be10: Pull complete
91c95931e552: Already exists
hello-world:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:aa03e5d0d5553b4c3473e89c8619cf79df368babd18681cf5daeb82aab55838d
Status: Downloaded newer image for hello-world:latest
Hello from Docker.
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(Assuming it was not already locally available.)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
For more examples and ideas, visit:
http://docs.docker.com/userguide/
## Start the docker daemon at boot
To ensure Docker starts when you boot your system, do the following:
$ sudo chkconfig docker on
If you need to add an HTTP Proxy, set a different directory or partition for the
Docker runtime files, or make other customizations, read our Systemd article to
learn how to [customize your Systemd Docker daemon options](/articles/systemd/).
## Uninstall
You can uninstall the Docker software with `yum`.
1. List the package you have installed.
$ yum list installed | grep docker
yum list installed | grep docker
docker-engine.x86_64 1.7.0-0.1.fc20
@/docker-engine-1.7.0-0.1.fc20.el6.x86_64
2. Remove the package.
$ sudo yum -y remove docker-engine.x86_64
This command does not remove images, containers, volumes, or user-created
configuration files on your host.
3. To delete all images, containers, and volumes, run the following command:
$ rm -rf /var/lib/docker
4. Locate and delete any user-created configuration files.
-189
View File
@@ -1,189 +0,0 @@
<!--[metadata]>
+++
title = "Installation on Red Hat Enterprise Linux"
description = "Instructions for installing Docker on Red Hat Enterprise Linux."
keywords = ["Docker, Docker documentation, requirements, linux, rhel"]
[menu.main]
parent = "smn_linux"
+++
<![end-metadata]-->
# Red Hat Enterprise Linux
Docker is supported on the following versions of RHEL:
- Red Hat Enterprise Linux 7
- Red Hat Enterprise Linux 6.6 or later
This page instructs you to install using Docker-managed release packages and
installation mechanisms. Using these packages ensures you get the latest release
of Docker. If you wish to install using Red Hat-managed packages, consult your
Red Hat release documentation for information on Red Hat's Docker support.
## Prerequisites
Docker requires a 64-bit installation regardless of your Red Hat version. Docker
requires that your kernel must be 3.10 at minimum. Red Hat 7 runs the 3.10
kernel, 6.6 does not. We make an exception for Red Hat 6.6. To run Docker on
[Red Hat-6.6](http://www.centos.org) or later, you need kernel 2.6.32-431 or
higher.
To check your current kernel version, open a terminal and use `uname -r` to
display your kernel version:
$ uname -r
3.10.0-229.el7.x86_64
Finally, is it recommended that you fully update your system. Please keep in
mind that your system should be fully patched to fix any potential kernel bugs.
Any reported kernel bugs may have already been fixed on the latest kernel
packages
## Install
You use the same installation procedure for all versions of Red Hat Enterprise,
only the package you install differs. There are two packages to choose from:
<table>
<tr>
<th>Version</th>
<th>Package name</th>
</tr>
<tr>
<td>6.6 and higher</td>
<td>
<p>
<a href="https://get.docker.com/rpm/1.7.0/centos-6/RPMS/x86_64/docker-engine-1.7.0-1.el6.x86_64.rpm">
https://get.docker.com/rpm/1.7.0/centos-6/RPMS/x86_64/docker-engine-1.7.0-1.el6.x86_64.rpm</a>
<p>
<a href="https://get.docker.com/rpm/1.7.0/centos-6/SRPMS/docker-engine-1.7.0-1.el6.src.rpm">
https://get.docker.com/rpm/1.7.0/centos-6/SRPMS/docker-engine-1.7.0-1.el6.src.rpm</a>
<p>
</p>
</td>
</tr>
<tr>
<td>7.X</td>
<td>
<p>
<a href="https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.centos.x86_64.rpm">
https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.centos.x86_64.rpm</a>
</p>
<p>
<a href="https://get.docker.com/rpm/1.7.0/centos-7/SRPMS/docker-engine-1.7.0-1.el7.centos.src.rpm">
https://get.docker.com/rpm/1.7.0/centos-7/SRPMS/docker-engine-1.7.0-1.el7.centos.src.rpm</a>
</p>
</td>
</tr>
</table>
This procedure depicts an installation on version 6.6. If you are installing on
7.X, substitute that package for your installation.
1. Log into your machine as a user with `sudo` or `root` privileges.
2. Download the Docker RPM to the current directory.
$ curl -O -sSL http://get.docker.com/docker/1.7.0/rpms/centos-6/RPMS/x86_64/docker-engine-1.7.0-0.1.el6.x86_64.rpm
3. Use `yum` to install the package.
$ sudo yum localinstall --nogpgcheck docker-engine-1.7.0-0.1.el6.x86_64.rpm
5. Start the Docker daemon.
$ sudo service docker start
6. Verify `docker` is installed correctly.
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from hello-world
a8219747be10: Pull complete
91c95931e552: Already exists
hello-world:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:aa03e5d0d5553b4c3473e89c8619cf79df368babd18681cf5daeb82aab55838d
Status: Downloaded newer image for hello-world:latest
Hello from Docker.
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(Assuming it was not already locally available.)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
For more examples and ideas, visit:
http://docs.docker.com/userguide/
## Create a docker group
The `docker` daemon binds to a Unix socket instead of a TCP port. By default
that Unix socket is owned by the user `root` and other users can access it with
`sudo`. For this reason, `docker` daemon always runs as the `root` user.
To avoid having to use `sudo` when you use the `docker` command, create a Unix
group called `docker` and add users to it. When the `docker` daemon starts, it
makes the ownership of the Unix socket read/writable by the `docker` group.
>**Warning**: The `docker` group is equivalent to the `root` user; For details
>on how this impacts security in your system, see [*Docker Daemon Attack
>Surface*](/articles/security/#docker-daemon-attack-surface) for details.
To create the `docker` group and add your user:
1. Log into your machine as a user with `sudo` or `root` privileges.
2. Create the `docker` group and add your user.
`sudo usermod -aG docker your_username`
3. Log out and log back in.
This ensures your user is running with the correct permissions.
4. Verify your work by running `docker` without `sudo`.
$ docker run hello-world
## Start the docker daemon at boot
To ensure Docker starts when you boot your system, do the following:
$ sudo chkconfig docker on
If you need to add an HTTP Proxy, set a different directory or partition for the
Docker runtime files, or make other customizations, read our Systemd article to
learn how to [customize your Systemd Docker daemon options](/articles/systemd/).
## Uninstall
You can uninstall the Docker software with `yum`.
1. List the package you have installed.
$ yum list installed | grep docker
yum list installed | grep docker
docker-engine.x86_64 1.7.0-0.1.el6
@/docker-engine-1.7.0-0.1.el6.x86_64
2. Remove the package.
$ sudo yum -y remove docker-engine.x86_64
This command does not remove images, containers, volumes, or user created
configuration files on your host.
3. To delete all images, containers, and volumes run the following command:
$ rm -rf /var/lib/docker
4. Locate and delete any user-created configuration files.
+2 -2
View File
@@ -1,7 +1,7 @@
FROM golang:1.4
FROM golang:1.3
RUN mkdir -p /go/src/github.com/cpuguy83
RUN mkdir -p /go/src/github.com/cpuguy83 \
&& git clone -b v1.0.1 https://github.com/cpuguy83/go-md2man.git /go/src/github.com/cpuguy83/go-md2man \
&& git clone -b v1 https://github.com/cpuguy83/go-md2man.git /go/src/github.com/cpuguy83/go-md2man \
&& cd /go/src/github.com/cpuguy83/go-md2man \
&& go get -v ./...
CMD ["/go/bin/go-md2man", "--help"]
@@ -196,7 +196,7 @@ A Dockerfile is similar to a Makefile.
ADD <src> <dest>
# Required for paths with whitespace
ADD ["<src>",... "<dest>"]
ADD ["<src>", "<dest>"]
```
The **ADD** instruction copies new files, directories
@@ -215,7 +215,7 @@ A Dockerfile is similar to a Makefile.
COPY <src> <dest>
# Required for paths with whitespace
COPY ["<src>",... "<dest>"]
COPY ["<src>", "<dest>"]
```
The **COPY** instruction copies new files from `<src>` and
@@ -63,12 +63,7 @@ Again the output container IDs have been shortened for the purposes of this docu
2015-01-28T20:25:45.000000000-08:00 c21f6c22ba27: (from whenry/testimage:latest) die
2015-01-28T20:25:46.000000000-08:00 c21f6c22ba27: (from whenry/testimage:latest) stop
If you do not provide the --since option, the command returns only new and/or
live events.
# 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 <SvenDowideit@home.org.au>
June 2015, updated by Brian Goff <cpuguy83@gmail.com>
-39
View File
@@ -369,45 +369,6 @@ for data and metadata:
--storage-opt dm.metadatadev=/dev/vdc \
--storage-opt dm.basesize=20G
#### dm.override_udev_sync_check
By default, the devicemapper backend attempts to synchronize with the
`udev` device manager for the Linux kernel. This option allows
disabling that synchronization, to continue even though the
configuration may be buggy.
To view the `udev` sync support of a Docker daemon that is using the
`devicemapper` driver, run:
$ docker info
[...]
Udev Sync Supported: true
[...]
When `udev` sync support is `true`, then `devicemapper` and `udev` can
coordinate the activation and deactivation of devices for containers.
When `udev` sync support is `false`, a race condition occurs between
the`devicemapper` and `udev` during create and cleanup. The race
condition results in errors and failures. (For information on these
failures, see
[docker#4036](https://github.com/docker/docker/issues/4036))
To allow the `docker` daemon to start, regardless of whether `udev` sync is
`false`, set `dm.override_udev_sync_check` to true:
$ docker -d --storage-opt dm.override_udev_sync_check=true
When this value is `true`, the driver continues and simply warns you
the errors are happening.
**Note**: The ideal is to pursue a `docker` daemon and environment
that does support synchronizing with `udev`. For further discussion on
this topic, see
[docker#4036](https://github.com/docker/docker/issues/4036).
Otherwise, set this flag for migrating existing Docker daemons to a
daemon with a supported environment.
# EXEC DRIVER OPTIONS
Use the **--exec-opt** flags to specify options to the exec-driver. The only
+234
View File
@@ -0,0 +1,234 @@
site_name: Docker Documentation
#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
dev_addr: '0.0.0.0:8000'
repo_url: https://github.com/docker/docker/
docs_dir: sources
include_search: true
use_absolute_urls: true
# theme: docker
theme_dir: ./theme/mkdocs/
theme_center_lead: false
copyright: Copyright &copy; 2014-2015, Docker, Inc.
google_analytics: ['UA-6096819-11', 'docker.io']
pages:
# Introduction:
- ['index.md', 'About', 'Docker']
- ['introduction/understanding-docker.md', 'About', 'Understanding Docker']
- ['release-notes.md', 'About', 'Release notes']
# Experimental
- ['experimental/experimental.md', 'About', 'Experimental Features']
- ['experimental/plugin_api.md', '**HIDDEN**']
- ['experimental/plugins_volume.md', '**HIDDEN**']
- ['experimental/plugins.md', '**HIDDEN**']
- ['reference/glossary.md', 'About', 'Glossary']
- ['introduction/index.md', '**HIDDEN**']
# Installation:
- ['installation/index.md', '**HIDDEN**']
- ['installation/ubuntulinux.md', 'Installation', 'Ubuntu']
- ['installation/mac.md', 'Installation', 'Mac OS X']
- ['kitematic/index.md', 'Installation', 'Kitematic on OS X']
- ['installation/windows.md', 'Installation', 'Microsoft Windows']
- ['installation/testing-windows-docker-client.md', 'Installation', 'Building and testing the Windows Docker client']
- ['installation/amazon.md', 'Installation', 'Amazon EC2']
- ['installation/archlinux.md', 'Installation', 'Arch Linux']
- ['installation/binaries.md', 'Installation', 'Binaries']
- ['installation/centos.md', 'Installation', 'CentOS']
- ['installation/cruxlinux.md', 'Installation', 'CRUX Linux']
- ['installation/debian.md', 'Installation', 'Debian']
- ['installation/fedora.md', 'Installation', 'Fedora']
- ['installation/frugalware.md', 'Installation', 'FrugalWare']
- ['installation/google.md', 'Installation', 'Google Cloud Platform']
- ['installation/gentoolinux.md', 'Installation', 'Gentoo']
- ['installation/softlayer.md', 'Installation', 'IBM Softlayer']
- ['installation/joyent.md', 'Installation', 'Joyent Compute Service']
- ['installation/azure.md', 'Installation', 'Microsoft Azure']
- ['installation/rackspace.md', 'Installation', 'Rackspace Cloud']
- ['installation/rhel.md', 'Installation', 'Red Hat Enterprise Linux']
- ['installation/oracle.md', 'Installation', 'Oracle Linux']
- ['installation/SUSE.md', 'Installation', 'SUSE']
- ['compose/install.md', 'Installation', 'Docker Compose']
# User Guide:
- ['userguide/index.md', 'User Guide', 'The Docker user guide' ]
- ['userguide/dockerhub.md', 'User Guide', 'Getting started with Docker Hub' ]
- ['userguide/dockerizing.md', 'User Guide', 'Dockerizing applications' ]
- ['userguide/usingdocker.md', 'User Guide', 'Working with containers' ]
- ['userguide/dockerimages.md', 'User Guide', 'Working with Docker images' ]
- ['userguide/dockerlinks.md', 'User Guide', 'Linking containers together' ]
- ['userguide/dockervolumes.md', 'User Guide', 'Managing data in containers' ]
- ['userguide/labels-custom-metadata.md', 'User Guide', 'Apply custom metadata' ]
- ['userguide/dockerrepos.md', 'User Guide', 'Working with Docker Hub' ]
- ['userguide/level1.md', '**HIDDEN**' ]
- ['userguide/level2.md', '**HIDDEN**' ]
- ['compose/index.md', 'User Guide', 'Docker Compose' ]
- ['compose/production.md', 'User Guide', '&nbsp;&nbsp;&nbsp;&nbsp;&blacksquare;&nbsp; Use Compose in production' ]
- ['compose/extends.md', 'User Guide', '&nbsp;&nbsp;&nbsp;&nbsp;&blacksquare;&nbsp; Extend Compose services' ]
- ['machine/index.md', 'User Guide', 'Docker Machine' ]
- ['swarm/index.md', 'User Guide', 'Docker Swarm' ]
- ['kitematic/userguide.md', 'User Guide', 'Kitematic']
# Docker Hub docs:
- ['docker-hub/index.md', 'Docker Hub', 'Docker Hub' ]
- ['docker-hub/accounts.md', 'Docker Hub', 'Accounts']
- ['docker-hub/userguide.md', 'Docker Hub', 'User Guide']
- ['docker-hub/repos.md', 'Docker Hub', 'Your Repositories']
- ['docker-hub/builds.md', 'Docker Hub', 'Automated Builds']
- ['docker-hub/official_repos.md', 'Docker Hub', 'Official Repositories']
# Docker Hub Enterprise:
- ['docker-hub-enterprise/index.md', 'Docker Hub Enterprise', 'Overview' ]
- ['docker-hub-enterprise/quick-start.md', 'Docker Hub Enterprise', 'Quick Start: Basic Workflow' ]
- ['docker-hub-enterprise/userguide.md', 'Docker Hub Enterprise', 'User Guide' ]
- ['docker-hub-enterprise/adminguide.md', 'Docker Hub Enterprise', 'Admin Guide' ]
- ['docker-hub-enterprise/install.md', 'Docker Hub Enterprise', '&nbsp;&nbsp;Installation' ]
- ['docker-hub-enterprise/configuration.md', 'Docker Hub Enterprise', '&nbsp;&nbsp;Configuration options' ]
- ['docker-hub-enterprise/support.md', 'Docker Hub Enterprise', 'Support' ]
- ['docker-hub-enterprise/release-notes.md', 'Docker Hub Enterprise', 'Release notes' ]
# Examples:
- ['examples/index.md', '**HIDDEN**']
- ['examples/nodejs_web_app.md', 'Examples', 'Dockerizing a Node.js web application']
- ['examples/mongodb.md', 'Examples', 'Dockerizing MongoDB']
- ['examples/running_redis_service.md', 'Examples', 'Dockerizing a Redis service']
- ['examples/postgresql_service.md', 'Examples', 'Dockerizing a PostgreSQL service']
- ['examples/running_riak_service.md', 'Examples', 'Dockerizing a Riak service']
- ['examples/running_ssh_service.md', 'Examples', 'Dockerizing an SSH service']
- ['examples/couchdb_data_volumes.md', 'Examples', 'Dockerizing a CouchDB service']
- ['examples/apt-cacher-ng.md', 'Examples', 'Dockerizing an Apt-Cacher-ng service']
- ['compose/django.md', 'Examples', 'Getting started with Compose and Django']
- ['compose/rails.md', 'Examples', 'Getting started with Compose and Rails']
- ['compose/wordpress.md', 'Examples', 'Getting started with Compose and Wordpress']
- ['kitematic/minecraft-server.md', 'Examples', 'Kitematic: Minecraft server']
- ['kitematic/nginx-web-server.md', 'Examples', 'Kitematic: Ngnix web server']
- ['kitematic/rethinkdb-dev-database.md', 'Examples', 'Kitematic: RethinkDB development database']
# Articles
- ['articles/index.md', '**HIDDEN**']
- ['articles/basics.md', 'Articles', 'Docker basics']
- ['articles/networking.md', 'Articles', 'Advanced networking']
- ['articles/security.md', 'Articles', 'Security']
- ['articles/https.md', 'Articles', 'Running Docker with HTTPS']
- ['articles/registry_mirror.md', 'Articles', 'Run a local registry mirror']
- ['articles/host_integration.md', 'Articles', 'Automatically starting containers']
- ['articles/baseimages.md', 'Articles', 'Creating a base image']
- ['articles/dockerfile_best-practices.md', 'Articles', 'Best practices for writing Dockerfiles']
- ['articles/certificates.md', 'Articles', 'Using certificates for repository client verification']
- ['articles/using_supervisord.md', 'Articles', 'Using Supervisor']
- ['articles/configuring.md', 'Articles', 'Configuring Docker']
- ['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/b2d_volume_resize.md', 'Articles', 'Increasing a Boot2Docker volume']
- ['articles/systemd.md', 'Articles', 'Controlling and configuring Docker using Systemd']
# Reference
- ['reference/index.md', '**HIDDEN**']
- ['reference/commandline/index.md', '**HIDDEN**']
- ['reference/commandline/cli.md', 'Reference', 'Docker command line']
- ['reference/builder.md', 'Reference', 'Dockerfile']
- ['faq.md', 'Reference', 'FAQ']
- ['reference/run.md', 'Reference', 'Run reference']
- ['reference/logging/journald.md', '**HIDDEN**']
- ['compose/cli.md', 'Reference', 'Compose command line']
- ['compose/yml.md', 'Reference', 'Compose yml']
- ['compose/env.md', 'Reference', 'Compose ENV variables']
- ['compose/completion.md', 'Reference', 'Compose commandline completion']
- ['swarm/discovery.md', 'Reference', 'Swarm discovery']
- ['swarm/scheduler/strategy.md', 'Reference', 'Swarm strategies']
- ['swarm/scheduler/filter.md', 'Reference', 'Swarm filters']
- ['swarm/API.md', 'Reference', 'Swarm API']
- ['reference/api/index.md', '**HIDDEN**']
- ['registry/index.md', 'Reference', 'Docker Registry 2.0']
- ['registry/deploying.md', 'Reference', '&nbsp;&nbsp;&nbsp;&nbsp;&blacksquare;&nbsp; Deploy a registry' ]
- ['registry/configuration.md', 'Reference', '&nbsp;&nbsp;&nbsp;&nbsp;&blacksquare;&nbsp; Configure a registry' ]
- ['registry/storagedrivers.md', 'Reference', '&nbsp;&nbsp;&nbsp;&nbsp;&blacksquare;&nbsp; Storage driver model' ]
- ['registry/notifications.md', 'Reference', '&nbsp;&nbsp;&nbsp;&nbsp;&blacksquare;&nbsp; Work with notifications' ]
- ['registry/spec/api.md', 'Reference', '&nbsp;&nbsp;&nbsp;&nbsp;&blacksquare;&nbsp; Registry Service API v2' ]
- ['registry/spec/json.md', 'Reference', '&nbsp;&nbsp;&nbsp;&nbsp;&blacksquare;&nbsp; JSON format' ]
- ['registry/spec/auth/token.md', 'Reference', '&nbsp;&nbsp;&nbsp;&nbsp;&blacksquare;&nbsp; Authenticate via central service' ]
- ['reference/api/hub_registry_spec.md', 'Reference', 'Docker Hub and Registry 1.0']
- ['reference/api/registry_api.md', 'Reference', '&nbsp;&nbsp;&nbsp;&nbsp;&blacksquare;&nbsp;Docker Registry API v1']
- ['reference/api/registry_api_client_libraries.md', 'Reference', '&nbsp;&nbsp;&nbsp;&nbsp;&blacksquare;&nbsp;Docker Registry 1.0 API client libraries']
#- ['reference/image-spec-v1.md', 'Reference', 'Docker Image Specification v1.0.0']
- ['reference/api/docker-io_api.md', 'Reference', 'Docker Hub API']
#- ['reference/image-spec-v1.md', 'Reference', 'Docker Image Specification v1.0.0']
- ['reference/api/docker_remote_api.md', 'Reference', 'Docker Remote API']
- ['reference/api/docker_remote_api_v1.19.md', 'Reference', 'Docker Remote API v1.19']
- ['reference/api/docker_remote_api_v1.18.md', 'Reference', 'Docker Remote API v1.18']
- ['reference/api/docker_remote_api_v1.17.md', 'Reference', 'Docker Remote API v1.17']
- ['reference/api/docker_remote_api_v1.16.md', 'Reference', 'Docker Remote API v1.16']
- ['reference/api/docker_remote_api_v1.15.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.14.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.13.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.12.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.11.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.10.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.9.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.8.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.7.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.6.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.5.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.4.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.3.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.2.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.1.md', '**HIDDEN**']
- ['reference/api/docker_remote_api_v1.0.md', '**HIDDEN**']
- ['reference/api/remote_api_client_libraries.md', 'Reference', 'Docker Remote API client libraries']
- ['reference/api/docker_io_accounts_api.md', 'Reference', 'Docker Hub accounts API']
- ['kitematic/faq.md', 'Reference', 'Kitematic: FAQ']
- ['kitematic/known-issues.md', 'Reference', 'Kitematic: Known issues']
# Hidden registry files
- ['registry/storage-drivers/azure.md', '**HIDDEN**' ]
- ['registry/storage-drivers/filesystem.md', '**HIDDEN**' ]
- ['registry/storage-drivers/inmemory.md', '**HIDDEN**' ]
- ['registry/storage-drivers/s3.md', '**HIDDEN**' ]
- ['jsearch.md', '**HIDDEN**']
# - ['static_files/README.md', 'static_files', 'README']
- ['terms/index.md', '**HIDDEN**']
- ['terms/layer.md', '**HIDDEN**']
- ['terms/index.md', '**HIDDEN**']
- ['terms/registry.md', '**HIDDEN**']
- ['terms/container.md', '**HIDDEN**']
- ['terms/repository.md', '**HIDDEN**']
- ['terms/filesystem.md', '**HIDDEN**']
- ['terms/image.md', '**HIDDEN**']
# Project:
- ['project/index.md', '**HIDDEN**']
- ['project/who-written-for.md', 'Contributor', 'README first']
- ['project/software-required.md', 'Contributor', 'Get required software for Linux or OS X']
- ['project/software-req-win.md', 'Contributor', 'Get required software for Windows']
- ['project/set-up-git.md', 'Contributor', 'Configure Git for contributing']
- ['project/set-up-dev-env.md', 'Contributor', 'Work with a development container']
- ['project/test-and-docs.md', 'Contributor', 'Run tests and test documentation']
- ['project/make-a-contribution.md', 'Contributor', 'Understand contribution workflow']
- ['project/find-an-issue.md', 'Contributor', 'Find an issue']
- ['project/work-issue.md', 'Contributor', 'Work on an issue']
- ['project/create-pr.md', 'Contributor', 'Create a pull request']
- ['project/review-pr.md', 'Contributor', 'Participate in the PR review']
- ['project/advanced-contributing.md', 'Contributor', 'Advanced contributing']
- ['project/get-help.md', 'Contributor', 'Where to get help']
- ['project/coding-style.md', 'Contributor', 'Coding style guide']
- ['project/doc-style.md', 'Contributor', 'Documentation style guide']
-489
View File
@@ -1,489 +0,0 @@
<!--[metadata]>
+++
title = "daemon"
description = "The daemon command description and usage"
keywords = ["container, daemon, runtime"]
[menu.main]
parent = "smn_cli"
+++
<![end-metadata]-->
# daemon
Usage: docker [OPTIONS] COMMAND [arg...]
A self-sufficient runtime for linux containers.
Options:
--api-cors-header="" Set CORS headers in the remote API
-b, --bridge="" Attach containers to a network bridge
--bip="" Specify network bridge IP
-D, --debug=false Enable debug mode
-d, --daemon=false Enable daemon mode
--default-gateway="" Container default gateway IPv4 address
--default-gateway-v6="" Container default gateway IPv6 address
--dns=[] DNS server to use
--dns-search=[] DNS search domains to use
--default-ulimit=[] Set default ulimit settings for containers
-e, --exec-driver="native" Exec driver to use
--exec-opt=[] Set exec driver options
--exec-root="/var/run/docker" Root of the Docker execdriver
--fixed-cidr="" IPv4 subnet for fixed IPs
--fixed-cidr-v6="" IPv6 subnet for fixed IPs
-G, --group="docker" Group for the unix socket
-g, --graph="/var/lib/docker" Root of the Docker runtime
-H, --host=[] Daemon socket(s) to connect to
-h, --help=false Print usage
--icc=true Enable inter-container communication
--insecure-registry=[] Enable insecure registry communication
--ip=0.0.0.0 Default IP when binding container ports
--ip-forward=true Enable net.ipv4.ip_forward
--ip-masq=true Enable IP masquerading
--iptables=true Enable addition of iptables rules
--ipv6=false Enable IPv6 networking
-l, --log-level="info" Set the logging level
--label=[] Set key=value labels to the daemon
--log-driver="json-file" Default driver for container logs
--log-opt=[] Log driver specific options
--mtu=0 Set the containers network MTU
-p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file
--registry-mirror=[] Preferred Docker registry mirror
-s, --storage-driver="" Storage driver to use
--selinux-enabled=false Enable selinux support
--storage-opt=[] Set storage driver options
--tls=false Use TLS; implied by --tlsverify
--tlscacert="~/.docker/ca.pem" Trust certs signed only by this CA
--tlscert="~/.docker/cert.pem" Path to TLS certificate file
--tlskey="~/.docker/key.pem" Path to TLS key file
--tlsverify=false Use TLS and verify the remote
--userland-proxy=true Use userland proxy for loopback traffic
-v, --version=false Print version information and quit
Options with [] may be specified multiple times.
The Docker daemon is the persistent process that manages containers. Docker
uses the same binary for both the daemon and client. To run the daemon you
provide the `-d` flag.
To run the daemon with debug output, use `docker -d -D`.
## Daemon socket option
The Docker daemon can listen for [Docker Remote API](/reference/api/docker_remote_api/)
requests via three different types of Socket: `unix`, `tcp`, and `fd`.
By default, a `unix` domain socket (or IPC socket) is created at
`/var/run/docker.sock`, requiring either `root` permission, or `docker` group
membership.
If you need to access the Docker daemon remotely, you need to enable the `tcp`
Socket. Beware that the default setup provides un-encrypted and
un-authenticated direct access to the Docker daemon - and should be secured
either using the [built in HTTPS encrypted socket](/articles/https/), or by
putting a secure web proxy in front of it. You can listen on port `2375` on all
network interfaces with `-H tcp://0.0.0.0:2375`, or on a particular network
interface using its IP address: `-H tcp://192.168.59.103:2375`. It is
conventional to use port `2375` for un-encrypted, and port `2376` for encrypted
communication with the daemon.
> **Note:**
> If you're using an HTTPS encrypted socket, keep in mind that only
> TLS1.0 and greater are supported. Protocols SSLv3 and under are not
> supported anymore for security reasons.
On Systemd based systems, you can communicate with the daemon via
[Systemd socket activation](http://0pointer.de/blog/projects/socket-activation.html),
use `docker -d -H fd://`. Using `fd://` will work perfectly for most setups but
you can also specify individual sockets: `docker -d -H fd://3`. If the
specified socket activated files aren't found, then Docker will exit. You can
find examples of using Systemd socket activation with Docker and Systemd in the
[Docker source tree](https://github.com/docker/docker/tree/master/contrib/init/systemd/).
You can configure the Docker daemon to listen to multiple sockets at the same
time using multiple `-H` options:
# listen using the default unix socket, and on 2 specific IP addresses on this host.
docker -d -H unix:///var/run/docker.sock -H tcp://192.168.59.106 -H tcp://10.10.10.2
The Docker client will honor the `DOCKER_HOST` environment variable to set the
`-H` flag for the client.
$ docker -H tcp://0.0.0.0:2375 ps
# or
$ export DOCKER_HOST="tcp://0.0.0.0:2375"
$ docker ps
# both are equal
Setting the `DOCKER_TLS_VERIFY` environment variable to any value other than
the empty string is equivalent to setting the `--tlsverify` flag. The following
are equivalent:
$ docker --tlsverify ps
# or
$ export DOCKER_TLS_VERIFY=1
$ docker ps
The Docker client will honor the `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`
environment variables (or the lowercase versions thereof). `HTTPS_PROXY` takes
precedence over `HTTP_PROXY`.
### Daemon storage-driver option
The Docker daemon has support for several different image layer storage
drivers: `aufs`, `devicemapper`, `btrfs`, `zfs` and `overlay`.
The `aufs` driver is the oldest, but is based on a Linux kernel patch-set that
is unlikely to be merged into the main kernel. These are also known to cause
some serious kernel crashes. However, `aufs` is also the only storage driver
that allows containers to share executable and shared library memory, so is a
useful choice when running thousands of containers with the same program or
libraries.
The `devicemapper` driver uses thin provisioning and Copy on Write (CoW)
snapshots. For each devicemapper graph location typically
`/var/lib/docker/devicemapper` a thin pool is created based on two block
devices, one for data and one for metadata. By default, these block devices
are created automatically by using loopback mounts of automatically created
sparse files. Refer to [Storage driver options](#storage-driver-options) below
for a way how to customize this setup.
[~jpetazzo/Resizing Docker containers with the Device Mapper plugin](http://jpetazzo.github.io/2014/01/29/docker-device-mapper-resize/)
article explains how to tune your existing setup without the use of options.
The `btrfs` driver is very fast for `docker build` - but like `devicemapper`
does not share executable memory between devices. Use
`docker -d -s btrfs -g /mnt/btrfs_partition`.
The `zfs` driver is probably not fast as `btrfs` but has a longer track record
on stability. Thanks to `Single Copy ARC` shared blocks between clones will be
cached only once. Use `docker -d -s zfs`. To select a different zfs filesystem
set `zfs.fsname` option as described in [Storage driver options](#storage-driver-options).
The `overlay` is a very fast union filesystem. It is now merged in the main
Linux kernel as of [3.18.0](https://lkml.org/lkml/2014/10/26/137). Call
`docker -d -s overlay` to use it.
> **Note:**
> As promising as `overlay` is, the feature is still quite young and should not
> be used in production. Most notably, using `overlay` can cause excessive
> inode consumption (especially as the number of images grows), as well as
> being incompatible with the use of RPMs.
> **Note:**
> It is currently unsupported on `btrfs` or any Copy on Write filesystem
> and should only be used over `ext4` partitions.
### Storage driver options
Particular storage-driver can be configured with options specified with
`--storage-opt` flags. Options for `devicemapper` are prefixed with `dm` and
options for `zfs` start with `zfs`.
* `dm.thinpooldev`
Specifies a custom block storage device to use for the thin pool.
If using a block device for device mapper storage, it is best to use `lvm`
to create and manage the thin-pool volume. This volume is then handed to Docker
to exclusively create snapshot volumes needed for images and containers.
Managing the thin-pool outside of Docker makes for the most feature-rich
method of having Docker utilize device mapper thin provisioning as the
backing storage for Docker's containers. The highlights of the lvm-based
thin-pool management feature include: automatic or interactive thin-pool
resize support, dynamically changing thin-pool features, automatic thinp
metadata checking when lvm activates the thin-pool, etc.
Example use:
docker -d --storage-opt dm.thinpooldev=/dev/mapper/thin-pool
* `dm.basesize`
Specifies the size to use when creating the base device, which limits the
size of images and containers. The default value is 10G. Note, thin devices
are inherently "sparse", so a 10G device which is mostly empty doesn't use
10 GB of space on the pool. However, the filesystem will use more space for
the empty case the larger the device is.
This value affects the system-wide "base" empty filesystem
that may already be initialized and inherited by pulled images. Typically,
a change to this value requires additional steps to take effect:
$ sudo service docker stop
$ sudo rm -rf /var/lib/docker
$ sudo service docker start
Example use:
$ docker -d --storage-opt dm.basesize=20G
* `dm.loopdatasize`
>**Note**: This option configures devicemapper loopback, which should not be used in production.
Specifies the size to use when creating the loopback file for the
"data" device which is used for the thin pool. The default size is
100G. The file is sparse, so it will not initially take up this
much space.
Example use:
$ docker -d --storage-opt dm.loopdatasize=200G
* `dm.loopmetadatasize`
>**Note**: This option configures devicemapper loopback, which should not be used in production.
Specifies the size to use when creating the loopback file for the
"metadadata" device which is used for the thin pool. The default size
is 2G. The file is sparse, so it will not initially take up
this much space.
Example use:
$ docker -d --storage-opt dm.loopmetadatasize=4G
* `dm.fs`
Specifies the filesystem type to use for the base device. The supported
options are "ext4" and "xfs". The default is "ext4"
Example use:
$ docker -d --storage-opt dm.fs=xfs
* `dm.mkfsarg`
Specifies extra mkfs arguments to be used when creating the base device.
Example use:
$ docker -d --storage-opt "dm.mkfsarg=-O ^has_journal"
* `dm.mountopt`
Specifies extra mount options used when mounting the thin devices.
Example use:
$ docker -d --storage-opt dm.mountopt=nodiscard
* `dm.datadev`
(Deprecated, use `dm.thinpooldev`)
Specifies a custom blockdevice to use for data for the thin pool.
If using a block device for device mapper storage, ideally both datadev and
metadatadev should be specified to completely avoid using the loopback
device.
Example use:
$ docker -d --storage-opt dm.datadev=/dev/sdb1 --storage-opt dm.metadatadev=/dev/sdc1
* `dm.metadatadev`
(Deprecated, use `dm.thinpooldev`)
Specifies a custom blockdevice to use for metadata for the thin pool.
For best performance the metadata should be on a different spindle than the
data, or even better on an SSD.
If setting up a new metadata pool it is required to be valid. This can be
achieved by zeroing the first 4k to indicate empty metadata, like this:
$ dd if=/dev/zero of=$metadata_dev bs=4096 count=1
Example use:
$ docker -d --storage-opt dm.datadev=/dev/sdb1 --storage-opt dm.metadatadev=/dev/sdc1
* `dm.blocksize`
Specifies a custom blocksize to use for the thin pool. The default
blocksize is 64K.
Example use:
$ docker -d --storage-opt dm.blocksize=512K
* `dm.blkdiscard`
Enables or disables the use of blkdiscard when removing devicemapper
devices. This is enabled by default (only) if using loopback devices and is
required to resparsify the loopback file on image/container removal.
Disabling this on loopback can lead to *much* faster container removal
times, but will make the space used in `/var/lib/docker` directory not be
returned to the system for other use when containers are removed.
Example use:
$ docker -d --storage-opt dm.blkdiscard=false
* `dm.override_udev_sync_check`
Overrides the `udev` synchronization checks between `devicemapper` and `udev`.
`udev` is the device manager for the Linux kernel.
To view the `udev` sync support of a Docker daemon that is using the
`devicemapper` driver, run:
$ docker info
[...]
Udev Sync Supported: true
[...]
When `udev` sync support is `true`, then `devicemapper` and udev can
coordinate the activation and deactivation of devices for containers.
When `udev` sync support is `false`, a race condition occurs between
the`devicemapper` and `udev` during create and cleanup. The race condition
results in errors and failures. (For information on these failures, see
[docker#4036](https://github.com/docker/docker/issues/4036))
To allow the `docker` daemon to start, regardless of `udev` sync not being
supported, set `dm.override_udev_sync_check` to true:
$ docker -d --storage-opt dm.override_udev_sync_check=true
When this value is `true`, the `devicemapper` continues and simply warns
you the errors are happening.
> **Note:**
> The ideal is to pursue a `docker` daemon and environment that does
> support synchronizing with `udev`. For further discussion on this
> topic, see [docker#4036](https://github.com/docker/docker/issues/4036).
> Otherwise, set this flag for migrating existing Docker daemons to
> a daemon with a supported environment.
## Docker execdriver option
Currently supported options of `zfs`:
* `zfs.fsname`
Set zfs filesystem under which docker will create its own datasets.
By default docker will pick up the zfs filesystem where docker graph
(`/var/lib/docker`) is located.
Example use:
$ docker -d -s zfs --storage-opt zfs.fsname=zroot/docker
## Docker execdriver option
The Docker daemon uses a specifically built `libcontainer` execution driver as
its interface to the Linux kernel `namespaces`, `cgroups`, and `SELinux`.
There is still legacy support for the original [LXC userspace tools](
https://linuxcontainers.org/) via the `lxc` execution driver, however, this is
not where the primary development of new functionality is taking place.
Add `-e lxc` to the daemon flags to use the `lxc` execution driver.
## Options for the native execdriver
You can configure the `native` (libcontainer) execdriver using options specified
with the `--exec-opt` flag. All the flag's options have the `native` prefix. A
single `native.cgroupdriver` option is available.
The `native.cgroupdriver` option specifies the management of the container's
cgroups. You can specify `cgroupfs` or `systemd`. If you specify `systemd` and
it is not available, the system uses `cgroupfs`. By default, if no option is
specified, the execdriver first tries `systemd` and falls back to `cgroupfs`.
This example sets the execdriver to `cgroupfs`:
$ sudo docker -d --exec-opt native.cgroupdriver=cgroupfs
Setting this option applies to all containers the daemon launches.
## Daemon DNS options
To set the DNS server for all Docker containers, use
`docker -d --dns 8.8.8.8`.
To set the DNS search domain for all Docker containers, use
`docker -d --dns-search example.com`.
## Insecure registries
Docker considers a private registry either secure or insecure. In the rest of
this section, *registry* is used for *private registry*, and `myregistry:5000`
is a placeholder example for a private registry.
A secure registry uses TLS and a copy of its CA certificate is placed on the
Docker host at `/etc/docker/certs.d/myregistry:5000/ca.crt`. An insecure
registry is either not using TLS (i.e., listening on plain text HTTP), or is
using TLS with a CA certificate not known by the Docker daemon. The latter can
happen when the certificate was not found under
`/etc/docker/certs.d/myregistry:5000/`, or if the certificate verification
failed (i.e., wrong CA).
By default, Docker assumes all, but local (see local registries below),
registries are secure. Communicating with an insecure registry is not possible
if Docker assumes that registry is secure. In order to communicate with an
insecure registry, the Docker daemon requires `--insecure-registry` in one of
the following two forms:
* `--insecure-registry myregistry:5000` tells the Docker daemon that
myregistry:5000 should be considered insecure.
* `--insecure-registry 10.1.0.0/16` tells the Docker daemon that all registries
whose domain resolve to an IP address is part of the subnet described by the
CIDR syntax, should be considered insecure.
The flag can be used multiple times to allow multiple registries to be marked
as insecure.
If an insecure registry is not marked as insecure, `docker pull`,
`docker push`, and `docker search` will result in an error message prompting
the user to either secure or pass the `--insecure-registry` flag to the Docker
daemon as described above.
Local registries, whose IP address falls in the 127.0.0.0/8 range, are
automatically marked as insecure as of Docker 1.3.2. It is not recommended to
rely on this, as it may change in the future.
## Running a Docker daemon behind a HTTPS_PROXY
When running inside a LAN that uses a `HTTPS` proxy, the Docker Hub
certificates will be replaced by the proxy's certificates. These certificates
need to be added to your Docker host's configuration:
1. Install the `ca-certificates` package for your distribution
2. Ask your network admin for the proxy's CA certificate and append them to
`/etc/pki/tls/certs/ca-bundle.crt`
3. Then start your Docker daemon with `HTTPS_PROXY=http://username:password@proxy:port/ docker -d`.
The `username:` and `password@` are optional - and are only needed if your
proxy is set up to require authentication.
This will only add the proxy and authentication to the Docker daemon's requests -
your `docker build`s and running containers will need extra configuration to
use the proxy
## Default Ulimits
`--default-ulimit` allows you to set the default `ulimit` options to use for
all containers. It takes the same options as `--ulimit` for `docker run`. If
these defaults are not set, `ulimit` settings will be inherited, if not set on
`docker run`, from the Docker daemon. Any `--ulimit` options passed to
`docker run` will overwrite these defaults.
## Miscellaneous options
IP masquerading uses address translation to allow containers without a public
IP to talk to other machines on the Internet. This may interfere with some
network topologies and can be disabled with --ip-masq=false.
Docker supports softlinks for the Docker data directory (`/var/lib/docker`) and
for `/var/lib/docker/tmp`. The `DOCKER_TMPDIR` and the data directory can be
set like this:
DOCKER_TMPDIR=/mnt/disk2/tmp /usr/local/bin/docker -d -D -g /var/lib/docker -H unix:// > /var/lib/boot2docker/docker.log 2>&1
# or
export DOCKER_TMPDIR=/mnt/disk2/tmp
/usr/local/bin/docker -d -D -g /var/lib/docker -H unix:// > /var/lib/boot2docker/docker.log 2>&1
+176
View File
@@ -0,0 +1,176 @@
#!/bin/bash
set -e
set -o pipefail
usage() {
cat >&2 <<'EOF'
To publish the Docker documentation you need to set your access_key and secret_key in the docs/awsconfig file
(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.
If you're publishing the current release's documentation, also set `BUILD_ROOT=yes`
make AWS_S3_BUCKET=docs-stage.docker.com docs-release
will then push the documentation site to your s3 bucket.
Note: you can add `OPTIONS=--dryrun` to see what will be done without sending to the server
You can also add NOCACHE=1 to publish without a cache, which is what we do for the master docs.
EOF
exit 1
}
create_robots_txt() {
if [ "$AWS_S3_BUCKET" == "docs.docker.com" ]; then
cat > ./sources/robots.txt <<-'EOF'
User-agent: *
Allow: /
EOF
else
cat > ./sources/robots.txt <<-'EOF'
User-agent: *
Disallow: /
EOF
fi
}
setup_s3() {
# Try creating the bucket. Ignore errors (it might already exist).
echo "create $BUCKET if it does not exist"
aws s3 mb --profile $BUCKET s3://$BUCKET 2>/dev/null || true
# Check access to the bucket.
echo "test $BUCKET exists"
aws s3 --profile $BUCKET ls s3://$BUCKET
# Make the bucket accessible through website endpoints.
echo "make $BUCKET accessible as a website"
#aws s3 website s3://$BUCKET --index-document index.html --error-document jsearch/index.html
local s3conf=$(cat s3_website.json | envsubst)
aws s3api --profile $BUCKET put-bucket-website --bucket $BUCKET --website-configuration "$s3conf"
}
build_current_documentation() {
mkdocs build
cd site/
gzip -9k -f search_content.json
cd ..
}
upload_current_documentation() {
src=site/
dst=s3://$BUCKET$1
cache=max-age=3600
if [ "$NOCACHE" ]; then
cache=no-cache
fi
printf "\nUploading $src to $dst\n"
# 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
# versions.html_fragment
include="--recursive --include \"*.$i\" "
run="aws s3 cp $src $dst $OPTIONS --profile $BUCKET --cache-control $cache --acl public-read $include"
printf "\n=====\n$run\n=====\n"
$run
# Make sure the search_content.json.gz file has the right content-encoding
aws s3 cp --profile $BUCKET --cache-control $cache --content-encoding="gzip" --acl public-read "site/search_content.json.gz" "$dst"
}
invalidate_cache() {
if [[ -z "$DISTRIBUTION_ID" ]]; then
echo "Skipping Cloudfront cache invalidation"
return
fi
dst=$1
aws configure set preview.cloudfront true
# Get all the files
# not .md~ files
# replace spaces w %20 so urlencoded
files=( $(find site/ -not -name "*.md*" -type f | sed 's/site//g' | sed 's/ /%20/g') )
len=${#files[@]}
last_file=${files[$((len-1))]}
echo "aws cloudfront create-invalidation --profile $AWS_S3_BUCKET --distribution-id $DISTRIBUTION_ID --invalidation-batch '" > batchfile
echo "{\"Paths\":{\"Quantity\":$len," >> batchfile
echo "\"Items\": [" >> batchfile
for file in "${files[@]}" ; do
if [[ $file == $last_file ]]; then
comma=""
else
comma=","
fi
echo "\"$dst$file\"$comma" >> batchfile
done
echo "]}, \"CallerReference\":\"$(date)\"}'" >> batchfile
sh batchfile
}
main() {
[ "$AWS_S3_BUCKET" ] || usage
# Make sure there is an awsconfig file
export AWS_CONFIG_FILE=$(pwd)/awsconfig
[ -f "$AWS_CONFIG_FILE" ] || usage
# Get the version
VERSION=$(cat VERSION)
# Disallow pushing dev docs to master
if [ "$AWS_S3_BUCKET" == "docs.docker.com" ] && [ "${VERSION%-dev}" != "$VERSION" ]; then
echo "Please do not push '-dev' documentation to docs.docker.com ($VERSION)"
exit 1
fi
# Clean version - 1.0.2-dev -> 1.0
export MAJOR_MINOR="v${VERSION%.*}"
export BUCKET=$AWS_S3_BUCKET
export AWS_DEFAULT_PROFILE=$BUCKET
# debug variables
echo "bucket: $BUCKET, full version: $VERSION, major-minor: $MAJOR_MINOR"
echo "cfg file: $AWS_CONFIG_FILE ; profile: $AWS_DEFAULT_PROFILE"
# create the robots.txt
create_robots_txt
if [ "$OPTIONS" != "--dryrun" ]; then
setup_s3
fi
# Default to only building the version specific docs
# so we don't clober the latest by accident with old versions
if [ "$BUILD_ROOT" == "yes" ]; then
echo "Building root documentation"
build_current_documentation
echo "Uploading root documentation"
upload_current_documentation
[ "$NOCACHE" ] || invalidate_cache
fi
#build again with /v1.0/ prefix
sed -i "s/^site_url:.*/site_url: \/$MAJOR_MINOR\//" mkdocs.yml
echo "Building the /$MAJOR_MINOR/ documentation"
build_current_documentation
echo "Uploading the documentation"
upload_current_documentation "/$MAJOR_MINOR/"
# Invalidating cache
[ "$NOCACHE" ] || invalidate_cache "/$MAJOR_MINOR"
}
main
+50
View File
@@ -0,0 +1,50 @@
{
"ErrorDocument": {
"Key": "jsearch/index.html"
},
"IndexDocument": {
"Suffix": "index.html"
},
"RoutingRules": [
{ "Condition": { "KeyPrefixEquals": "en/latest/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "" } },
{ "Condition": { "KeyPrefixEquals": "en/master/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "" } },
{ "Condition": { "KeyPrefixEquals": "en/v0.6.3/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "" } },
{ "Condition": { "KeyPrefixEquals": "jsearch/index.html" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "jsearch/" } },
{ "Condition": { "KeyPrefixEquals": "index/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-io/" } },
{ "Condition": { "KeyPrefixEquals": "reference/api/index_api/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "reference/api/docker-io_api/" } },
{ "Condition": { "KeyPrefixEquals": "docker-hub/groups.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/hub-images/groups.png" } },
{ "Condition": { "KeyPrefixEquals": "docker-hub/hub.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/hub-images/hub.png" } },
{ "Condition": { "KeyPrefixEquals": "docker-hub/invite.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/hub-images/invite.png" } },
{ "Condition": { "KeyPrefixEquals": "docker-hub/orgs.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/hub-images/orgs.png" } },
{ "Condition": { "KeyPrefixEquals": "docker-hub/repos.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/hub-images/repos.png" } },
{ "Condition": { "KeyPrefixEquals": "installation/images/linux_docker_host.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "installation/images/linux_docker_host.svg" } },
{ "Condition": { "KeyPrefixEquals": "installation/images/osx_docker_host.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "installation/images/osx_docker_host.svg" } },
{ "Condition": { "KeyPrefixEquals": "installation/images/win_docker_host.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "installation/images/win_docker_host.svg" } },
{ "Condition": { "KeyPrefixEquals": "examples/hello_world/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockerizing/" } },
{ "Condition": { "KeyPrefixEquals": "examples/python_web_app/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockerizing/" } },
{ "Condition": { "KeyPrefixEquals": "use/working_with_volumes/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockervolumes/" } },
{ "Condition": { "KeyPrefixEquals": "use/working_with_links_names/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockerlinks/" } },
{ "Condition": { "KeyPrefixEquals": "use/workingwithrepository/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockerrepos/" } },
{ "Condition": { "KeyPrefixEquals": "use/port_redirection" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockerlinks/" } },
{ "Condition": { "KeyPrefixEquals": "use/networking/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/networking/" } },
{ "Condition": { "KeyPrefixEquals": "use/puppet/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/puppet/" } },
{ "Condition": { "KeyPrefixEquals": "use/ambassador_pattern_linking/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/ambassador_pattern_linking/" } },
{ "Condition": { "KeyPrefixEquals": "use/basics/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/basics/" } },
{ "Condition": { "KeyPrefixEquals": "use/chef/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/chef/" } },
{ "Condition": { "KeyPrefixEquals": "use/host_integration/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/host_integration/" } },
{ "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/" } },
{ "Condition": { "KeyPrefixEquals": "installation/openSUSE/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "installation/SUSE/" } },
{ "Condition": { "KeyPrefixEquals": "contributing/contributing/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "project/who-written-for/" } },
{ "Condition": { "KeyPrefixEquals": "contributing/devenvironment/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "project/set-up-prereqs/" } },
{ "Condition": { "KeyPrefixEquals": "contributing/docs_style-guide/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "project/doc-style/" } },
{ "Condition": { "KeyPrefixEquals": "registry/overview/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "registry/" } }
]
}

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 183 KiB

Some files were not shown because too many files have changed in this diff Show More