diff --git a/README.md b/README.md index 7a884ba..b65a454 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ $GOPATH/bin/docker-builder --help 0. Run`docker-builder --help` 0. Run `docker-builder help build` -### First, Install `docker-builder` +### Installing `docker-builder` #### Easiest @@ -41,11 +41,11 @@ go get github.com/rafecolton/docker-builder ```bash # on Mac OS X -curl -sL https://github.com/rafecolton/docker-builder/releases/download/v0.9.1/docker-builder-v0.9.1-darwin-amd64 \ +curl -sL https://github.com/rafecolton/docker-builder/releases/download/v0.9.2/docker-builder-v0.9.2-darwin-amd64 \ -o /usr/local/bin/docker-builder && chmod +x /usr/local/bin/docker-builder # on Linux, note: you may need sudo -curl -sL https://github.com/rafecolton/docker-builder/releases/download/v0.9.1/docker-builder-v0.9.1-linux-amd64 \ +curl -sL https://github.com/rafecolton/docker-builder/releases/download/v0.9.2/docker-builder-v0.9.2-linux-amd64 \ -o /usr/local/bin/docker-builder && chmod +x /usr/local/bin/docker-builder ``` @@ -56,6 +56,30 @@ curl -sL https://github.com/rafecolton/docker-builder/releases/download/v0.9.1/d To build from source, run `make build`. You may have to install some things first, such as `go` +### Using with TLS + +If you are using a version of `docker` with TLS enabled (supported in +`docker` `v1.3.0` and up, enabled by default with `boot2docker`), you +will need to use `docker-builder` `v0.9.2` or greater. + +Additionally, you must set the following environment variables: + +```bash +# all values are the boot2docker defaults +export DOCKER_CERT_PATH="$HOME/.boot2docker/certs/boot2docker-vm" +export DOCKER_TLS_VERIFY=1 +export DOCKER_HOST="tcp://127.0.0.1:2376" +``` + +**NOTE:** `docker-builder` will automatically set the correct url scheme +for TLS if you are using port 2376. If you are using another port and +wish to enable TLS, you must set the following additional environment +variable: + +```bash +export DOCKER_HOST_SCHEME="https" +``` + ## Contributing **Pull requests welcome!** diff --git a/dclient/dclient.go b/dclient/dclient.go index 919e35d..f3e2ade 100644 --- a/dclient/dclient.go +++ b/dclient/dclient.go @@ -2,7 +2,10 @@ package dclient import ( "fmt" + "net" + "net/url" "os" + "path" "regexp" "sort" @@ -25,19 +28,31 @@ func NewDockerClient(logger *logrus.Logger, shouldBeReal bool) (DockerClient, er }, nil } - var endpoint string + endpoint, err := getEndpoint() + if err != nil { + return nil, err + } + tlsVerify := os.Getenv("DOCKER_TLS_VERIFY") != "" + certPath := os.Getenv("DOCKER_CERT_PATH") - defaultHost := os.Getenv("DOCKER_HOST") + var dclient *docker.Client + if endpoint.Scheme == "https" { + if certPath == "" { + return nil, fmt.Errorf("Using TLS, but DOCKER_CERT_PATH is empty") + } - if defaultHost == "" { - endpoint = "unix:///var/run/docker.sock" + cert := path.Join(certPath, "cert.pem") + key := path.Join(certPath, "key.pem") + ca := "" + if tlsVerify { + ca = path.Join(certPath, "ca.pem") + } + + dclient, err = docker.NewTLSClient(endpoint.String(), cert, key, ca) } else { - // tcp endpoints cause a panic with this version of the go/docker library - endpoint = defaultHost + dclient, err = docker.NewClient(endpoint.String()) } - dclient, err := docker.NewClient(endpoint) - if err != nil { logger.WithFields(logrus.Fields{ "docker_host": endpoint, @@ -49,7 +64,7 @@ func NewDockerClient(logger *logrus.Logger, shouldBeReal bool) (DockerClient, er return &realDockerClient{ client: dclient, - host: endpoint, + host: endpoint.String(), Logger: logger, }, nil } @@ -139,3 +154,35 @@ func (rtoo *realDockerClient) PushImage(opts docker.PushImageOptions, auth docke func (rtoo *realDockerClient) BuildImage(opts docker.BuildImageOptions) error { return rtoo.client.BuildImage(opts) } + +// Workaround since DOCKER_HOST typically is tcp:// but we need to vary whether +// we use HTTP/HTTPS when interacting with the API +// Can be removed if https://github.com/fsouza/go-dockerclient/issues/173 is +// resolved +func getEndpoint() (*url.URL, error) { + endpoint := os.Getenv("DOCKER_HOST") + if endpoint == "" { + endpoint = "unix:///var/run/docker.sock" + } + + u, err := url.Parse(endpoint) + if err != nil { + return nil, fmt.Errorf("couldn't parse endpoint %s as URL", endpoint) + } + if u.Scheme == "tcp" { + _, port, err := net.SplitHostPort(u.Host) + if err != nil { + return nil, fmt.Errorf("error parsing %s for port", u.Host) + } + + // Only reliable way to determine if we should be using HTTPS appears to be via port + if os.Getenv("DOCKER_HOST_SCHEME") != "" { + u.Scheme = os.Getenv("DOCKER_HOST_SCHEME") + } else if port == "2376" { + u.Scheme = "https" + } else { + u.Scheme = "http" + } + } + return u, nil +}