Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TLS support #147

Merged
merged 6 commits into from
Oct 30, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
```

Expand All @@ -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!**
65 changes: 56 additions & 9 deletions dclient/dclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package dclient

import (
"fmt"
"net"
"net/url"
"os"
"path"
"regexp"
"sort"

Expand All @@ -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,
Expand All @@ -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
}
Expand Down Expand Up @@ -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
}