-
Notifications
You must be signed in to change notification settings - Fork 7
/
docker.go
89 lines (80 loc) · 2.49 KB
/
docker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package main
import (
"context"
"fmt"
"os/exec"
"strings"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
log "github.com/sirupsen/logrus"
)
var portPriority = map[uint16]int{
80: 1, // HTTP
81: 2, // HTTP
8080: 3, // HTTP
3000: 4, // HTTP
5000: 5, // HTTP
}
// ContainerWatch checks for new containers and if they exist, add the sites and it's endpoints
func ContainerWatch(containerized, healthchecks bool, healthCheckURL string, myPort int) {
myPort64 := uint16(myPort)
address := "localhost"
if containerized {
address = containerizedIP()
}
cli, err := client.NewEnvClient()
if err != nil {
log.Error(err.Error())
return
}
for {
if containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{}); err == nil {
for _, container := range containers {
name := container.Names[0][1:]
var svcPort types.Port
for _, port := range container.Ports {
// Prioritize port selection
if port.PublicPort != myPort64 && port.PublicPort != 443 && port.Type == "tcp" && port.PrivatePort >= 80 {
if 0 == svcPort.PrivatePort {
log.WithFields(log.Fields{
"Container": name,
"Public": port.PublicPort,
"Private": port.PrivatePort,
}).Debug("initial port selected")
svcPort = port
}
priority1, ok := portPriority[port.PrivatePort]
priority2, _ := portPriority[svcPort.PrivatePort]
if ok && priority1 > 0 && (0 == priority2 || priority1 < priority2) {
log.WithFields(log.Fields{
"Container": name,
"Public": port.PublicPort,
"Private": port.PrivatePort,
}).Debug("prioritized port selected")
svcPort = port
}
}
}
AddSite(name, fmt.Sprintf("http://%s:%d", address, svcPort.PublicPort), healthchecks, healthCheckURL)
}
} else {
log.Error("Unable to connect to docker")
log.Error(err.Error())
}
// Every 5 seconds, check for new containers
<-time.After(5 * time.Second)
}
}
// containerizedIP returns a string with the ip address of the docker host. Localhost else ...
func containerizedIP() string {
// Do we need to start our docker service?
cmd := exec.Command("bash", "-c", "/sbin/ip route|awk '/default/ { print $3 }'")
if output, err := cmd.Output(); err == nil {
log.WithFields(log.Fields{
"IP": strings.TrimSpace(string(output)),
}).Info("Auto detecting docker host IP Address")
return fmt.Sprintf("%s", strings.TrimSpace(string(output)))
}
return "localhost"
}