stack_options.go
129 lines1
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package platform
// This file gives Stack the same declarative With… Options API used across
// Congo, as an alternative to the struct literal. Both produce the same Stack:
//
// stack := platform.NewStack(
// platform.WithVolume("data"),
// platform.WithService("app",
// platform.WithImage("${APP_IMAGE}"),
// platform.WithPort(80, 5000),
// platform.WithMount("data", "/data"),
// platform.WithHealthcheck("curl -sf http://localhost:5000/health"),
// ),
// )
// StackOption configures a Stack.
type StackOption func(*Stack)
// NewStack builds a Stack from options.
func NewStack(opts ...StackOption) *Stack {
s := &Stack{}
for _, opt := range opts {
opt(s)
}
return s
}
// WithService adds a service built from service options.
func WithService(name string, opts ...ServiceOption) StackOption {
return func(s *Stack) {
svc := Service{Name: name}
for _, opt := range opts {
opt(&svc)
}
s.Services = append(s.Services, svc)
}
}
// WithVolume declares one or more named docker volumes.
func WithVolume(names ...string) StackOption {
return func(s *Stack) { s.Volumes = append(s.Volumes, names...) }
}
// WithNetwork declares one or more named docker networks.
func WithNetwork(names ...string) StackOption {
return func(s *Stack) { s.Networks = append(s.Networks, names...) }
}
// ServiceOption configures a Service within a Stack.
type ServiceOption func(*Service)
// WithImage sets the service image.
func WithImage(image string) ServiceOption {
return func(svc *Service) { svc.Image = image }
}
// WithContainerName fixes the container name (needed when another service targets
// it by name via docker exec).
func WithContainerName(name string) ServiceOption {
return func(svc *Service) { svc.ContainerName = name }
}
// WithCommand overrides the image's default command.
func WithCommand(cmd ...string) ServiceOption {
return func(svc *Service) { svc.Command = cmd }
}
// WithPort maps a host port to a container port.
func WithPort(host, container int) ServiceOption {
return func(svc *Service) { svc.Ports = append(svc.Ports, Port{Host: host, Container: container}) }
}
// WithBoundPort maps a host port on a specific bind address to a container port.
func WithBoundPort(bind string, host, container int) ServiceOption {
return func(svc *Service) {
svc.Ports = append(svc.Ports, Port{Bind: bind, Host: host, Container: container})
}
}
// WithEnv sets an environment variable on the service.
func WithEnv(key, value string) ServiceOption {
return func(svc *Service) {
if svc.Env == nil {
svc.Env = map[string]string{}
}
svc.Env[key] = value
}
}
// WithMount adds a volume or bind mount: a bare Source names a Stack volume, a
// Source with a slash is a host bind.
func WithMount(source, target string) ServiceOption {
return func(svc *Service) { svc.Volumes = append(svc.Volumes, Mount{Source: source, Target: target}) }
}
// WithDependsOn declares services that must start before this one.
func WithDependsOn(deps ...string) ServiceOption {
return func(svc *Service) { svc.DependsOn = append(svc.DependsOn, deps...) }
}
// WithServiceNetwork attaches the service to a named network.
func WithServiceNetwork(network string) ServiceOption {
return func(svc *Service) { svc.Network = network }
}
// WithRestart sets the restart policy (default "unless-stopped" at render time).
func WithRestart(policy string) ServiceOption {
return func(svc *Service) { svc.Restart = policy }
}
// WithPrivileged runs the container privileged.
func WithPrivileged() ServiceOption {
return func(svc *Service) { svc.Privileged = true }
}
// WithHealthcheck sets a shell health check command.
func WithHealthcheck(cmd string) ServiceOption {
return func(svc *Service) {
if svc.Healthcheck == nil {
svc.Healthcheck = &Healthcheck{}
}
svc.Healthcheck.Cmd = cmd
}
}
// WithResources sets CPU and memory limits (e.g. "0.5", "512m").
func WithResources(cpus, memory string) ServiceOption {
return func(svc *Service) { svc.Resources = &Resources{CPUs: cpus, Memory: memory} }
}