-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathdocker-compose.yaml
277 lines (225 loc) · 9.06 KB
/
docker-compose.yaml
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
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
version: '3.5'
services:
# The best damn DNS filtering tool out there; please support them!
# See: https://pi-hole.net/donate/
pihole:
container_name: pihole
# See: https://hub.docker.com/r/pihole/pihole/
image: pihole/pihole:latest
# Always restart the container, unless operator has explicitly told us to stop
restart: unless-stopped
networks:
# Because it's backend, no ports to open!
backend:
ipv4_address: 172.16.241.8
domainname: your.domain.here
hostname: pihole
# TODO: get this implemented!
#depends_on:
# coredns:
# condition: service_healthy
labels:
# We want traefik to deal with this one
- "traefik.enable=true"
# and communicate with it over the backend network
- "traefik.docker.network=backend"
# HTTP host
# TODO: see docs here: https://docs.traefik.io/user-guide/docker-and-lets-encrypt/#exposing-web-services-to-the-outside-world
# it MAY be possible to only require http auth on /admin
# (meaning that you'd still get HTTPS pihole blocked page w/o having to auth!)
# TODO: add in the whitelist of IPs / if you only want to make the piHole webadmin available from your home...
- "traefik.basic.frontend.rule=Host:skyhole.your.domain.here"
- "traefik.basic.port=80"
- "traefik.basic.protocol=http"
volumes:
# piHole will create it's various config files in these directories on first run
#
# see the note.md file in the `pihole` dir for info
- /opt/skyhole/docker/vol/pihole/etc/:/etc/pihole/
- /opt/skyhole/docker/vol/pihole/dnsmasq.d/:/etc/dnsmasq.d/
dns:
# Sets your container's resolve settings to localhost to use the built-in dnsmasq
# TODO: does this even make it into resolv.conf?
- 127.0.0.1
# Sets a backup server of your choosing in case DNSMasq has problems starting
- 1.1.1.1
env_file:
# The IP address of core_dns instance
- env/pi.coredns_ip.env
# The PUBLIC IP of the instance must be set here
- env/pi.public_ip.env
# Actual Pihole server configuration vars
- env/pihole.env
# A wonderful little DNS server; used here to terminate DoT
coredns:
container_name: coredns
# See: https://hub.docker.com/r/coredns/coredns/
image: coredns/coredns:latest
# Always restart the container, unless operator has explicitly told us to stop
restart: unless-stopped
networks:
# TLS connections ingress over this guy
frontend:
ipv4_address: 172.16.240.9
# This is how we'll talk to the resolver in piHole
backend:
ipv4_address: 172.16.241.9
domainname: your.domain.here
hostname: coredns
ports:
# We use CoreDNS to "terminate" the DNS over TLS connections (tcp/853)
- target: 853
published: 853
protocol: tcp
mode: host
volumes:
# Config
- /opt/skyhole/docker/vol/coredns/config/Corefile:/Corefile:ro
- /opt/skyhole/docker/vol/coredns/config/plugin.cfg:/plugin.cfg:ro
# Certs for Dns over TLS
- /opt/skyhole/docker/vol/coredns/config/certs/fchain.pem:/fchain.pem:ro
- /opt/skyhole/docker/vol/coredns/config/certs/key.pem:/key.pem:ro
labels:
# We dont want to see this container as a front end in the traefik UX
- "traefik.enable=false"
##
# Core DNS does not allow the use of hostnames for query targets, so links: pihole is out
# This means that we either need to write the pihole IP address to a volume/file or an env var
#
# I chose env var
##
# The coredns docker image is TINY.
# This makes it difficult to do the "look up the IP of PiHole container and use it as the forward-to host"
# in the container
##
# So unfortunately, this is the best i could come up with:
# - Create the pihole container and get it running
# - THEN use docker inspect to get the IP
# - THEN write it into an env file
# - THEN create the coredns container with the env file
##
# NOW coredns will get the IP it should forward queries to dynamically
# Just not as seamless as i'd have liked
##
env_file:
- env/cdns.pihole_ip.env
domainname: your.domain.here
hostname: coredns
# A delightful frontend/reverse proxy with automatic LetsEncrypt support
traefik:
container_name: traefik
image: traefik:latest
# Always restart the container, unless operator has explicitly told us to stop
restart: unless-stopped
# Enables the web UI and tells Traefik to listen to docker
command: --api --docker
networks:
frontend:
ipv4_address: 172.16.240.10
backend:
ipv4_address: 172.16.241.10
ports:
# Traefik will take 80 and 443 and proxy to nodes on the back end
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
# And we'd also like the web UI; for now server firewal limits ingress here
# TODO: get traefik to do auth for it's own portal?
- target: 8080
published: 8080
protocol: tcp
mode: host
volumes:
# the main config file
- /opt/skyhole/docker/vol/traefik/traefik.toml:/traefik.toml:ro
# user / pass for pihole
- /opt/skyhole/docker/vol/traefik/.htpasswd:/.htpasswd:ro
# the ACME/Lets Encrypt cert data is stored here, i believe
# TODO: how to get the certs out / used in coreDNS (shared volume?)
- /opt/skyhole/docker/vol/traefik/acme.json:/acme.json
# This makes me nervous, as the container is now basically as powerful as root!
# but apparently, this is used to "listen" to events and configure new routes ... etc
- /var/run/docker.sock:/var/run/docker.sock
labels:
# We dont want to see this container as a front end in the traefik UX
- "traefik.enable=false"
# A helper container that does nothing but watch trafeik's Lets Encrypt storage and trigger the keys & coredns containers
inotify:
container_name: inotify
#image: alpine:latest
# It's so small, not worth actually setting up docker-hub crap...
build:
context: ./helpers/inotify
dockerfile: Dockerfile
networks:
# only expose this on the backend network; we don't care what IP address it gets
backend:
volumes:
# As with traefik, this makes me nervous. We're sleeping soundly at night because:
# - no ports on this container and socket is RO
- /var/run/docker.sock:/var/run/docker.sock:ro
# We need to mount the same dirs as the keys container
## read only access to keys json
- /opt/skyhole/docker/vol/traefik/acme.json:/etc/traefik/acme.json:ro
## read only access to the output of keys helper
# we expect a fchain.pem and key.pem to be written here by the keys helper
- /opt/skyhole/docker/vol/coredns/config/certs/:/etc/coredns:ro
environment:
# Which containers to restart
- 'CONTAINER1=keys'
- 'CONTAINER2=coredns'
# How long to wait (for restarting container2)
- 'COUNTDOWN=3'
# which vols we monitor
- 'VOLUMES=/etc/traefik/acme.json'
# curl SILENT mode; dont need to see the request / download stats in stdout / docker logs
- 'CURL_OPTIONS=-s'
restart: unless-stopped
labels:
# We dont want to see this container as a front end in the traefik UX
- "traefik.enable=false"
# A helper container that does nothing but extract the certificates from traefik for coredns
keys:
container_name: keys
# TODO: this is just for testing
# TODO: will need to introduce a BUILD section
# TODO: will need to make a dir...
#image: alpine:latest
# It's so small, not worth actually setting up docker-hub crap...
build:
context: ./helpers/keys
dockerfile: Dockerfile
# Always restart the container, unless operator has explicitly told us to stop
# TODO: this probably needs to be something else as this container is more of a 1 shot...
restart: on-failure
networks:
# only expose this on the backend network; we don't care what IP address it gets
backend:
volumes:
# the ACME/Lets Encrypt cert data is stored here; we only need READ access
- /opt/skyhole/docker/vol/traefik/acme.json:/etc/traefik/acme.json:ro
# we'll need to WRITE out the full chain and key file for coredns
- /opt/skyhole/docker/vol/coredns/config/certs/:/etc/coredns:rw
labels:
# We dont want to see this container as a front end in the traefik UX
- "traefik.enable=false"
# We create two networks; one for inbound and one for backend
networks:
frontend:
# use "pretty names" otherwise, docker-compose will generate pseudo random prefixes on the net names
name: frontend
# IPAM is IP Address Mgmt
ipam:
config:
- subnet: 172.16.240.0/24
backend:
name: backend
# IPAM is IP Address Mgmt
ipam:
config:
- subnet: 172.16.241.0/24