Skip to content
Closed
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
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,16 @@ Each caddy docker proxy instance can be executed in one of the following modes.

Acts as a proxy to your Docker resources. The server starts without any configuration, and will not serve anything until it is configured by a "controller".

In order to make a server discoverable and configurable by controllers, you need to mark it with label `caddy_controlled_server` and define the controller network via CLI option `controller-network` or environment variable `CADDY_CONTROLLER_NETWORK`.
In order to make a server discoverable and configurable by controllers, you need to mark it with label `caddy_controlled_server`.

Server instances doesn't need access to Docker host socket and you can run it in manager or worker nodes.

[Configuration example](examples/distributed.yaml#L5)

Optionally, you can do a more secure setup by restricting the server to only be configurable from a specific network. To do that you need to set the controller network via CLI option `controller-network` or environment variable `CADDY_CONTROLLER_NETWORK` on both server and controller instances.

[Configuration example](examples/distributed-controller-network.yaml#L5)

### Controller

Controller monitors your Docker cluster, generates Caddy configuration and pushes to all servers it finds in your Docker cluster.
Expand Down
8 changes: 5 additions & 3 deletions cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,19 @@ func getAdminListen(options *config.Options) string {
if options.ControllerNetwork.Contains(v.IP) {
return "tcp/" + v.IP.String() + ":2019"
}
break
case *net.IPNet:
if options.ControllerNetwork.Contains(v.IP) {
return "tcp/" + v.IP.String() + ":2019"
}
break
}
}
}
}
return "tcp/localhost:2019"
if options.Mode&config.Controller == config.Controller {
return "tcp/localhost:2019"
} else {
return "tcp/0.0.0.0:2019"
}
}

func createOptions(flags caddycmd.Flags) *config.Options {
Expand Down
106 changes: 106 additions & 0 deletions examples/distributed-controller-network.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
version: '3.7'

services:

caddy_server:
image: lucaslorentz/caddy-docker-proxy:ci-alpine
ports:
- 80:80
- 443:443
networks:
- caddy_controller
- caddy
environment:
- CADDY_DOCKER_MODE=server
- CADDY_CONTROLLER_NETWORK=10.200.200.0/24
volumes:
# this volume is needed to keep the certificates
# otherwise, new ones will be re-issued upon restart
- caddy_data:/data
deploy:
replicas: 3
labels:
caddy_controlled_server:

caddy_controller:
image: lucaslorentz/caddy-docker-proxy:ci-alpine
networks:
- caddy_controller
- caddy
environment:
- CADDY_DOCKER_MODE=controller
- CADDY_CONTROLLER_NETWORK=10.200.200.0/24
volumes:
- /var/run/docker.sock:/var/run/docker.sock

# Proxy to service
whoami0:
image: jwilder/whoami
networks:
- caddy
deploy:
labels:
caddy: whoami0.example.com
caddy.reverse_proxy: "{{upstreams 8000}}"
# remove the following line when you have verified your setup
# Otherwise you risk being rate limited by let's encrypt
caddy.tls.ca: https://acme-staging-v02.api.letsencrypt.org/directory

# Proxy to service
whoami1:
image: jwilder/whoami
networks:
- caddy
deploy:
labels:
caddy: whoami1.example.com
caddy.reverse_proxy: "{{upstreams 8000}}"
caddy.tls: "internal"

# Proxy to container
whoami2:
image: jwilder/whoami
networks:
- caddy
labels:
caddy: whoami2.example.com
caddy.reverse_proxy: "{{upstreams 8000}}"
caddy.tls: "internal"

# Proxy to container
whoami3:
image: jwilder/whoami
networks:
- caddy
labels:
caddy: whoami3.example.com
caddy.reverse_proxy: "{{upstreams 8000}}"
caddy.tls: "internal"

# Proxy with matches and route
echo_0:
image: brndnmtthws/nginx-echo-headers
networks:
- caddy
deploy:
labels:
caddy: echo0.example.com
[email protected]: "/sourcepath /sourcepath/*"
caddy.route: "@match"
caddy.route.0_uri: "strip_prefix /sourcepath"
caddy.route.1_rewrite: "* /targetpath{path}"
caddy.route.2_reverse_proxy: "{{upstreams 8080}}"
caddy.tls: "internal"

networks:
caddy:
driver: overlay
caddy_controller:
driver: overlay
ipam:
driver: default
config:
- subnet: "10.200.200.0/24"

volumes:
caddy_data: {}
10 changes: 0 additions & 10 deletions examples/distributed.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ services:
- 80:80
- 443:443
networks:
- caddy_controller
- caddy
environment:
- CADDY_DOCKER_MODE=server
- CADDY_CONTROLLER_NETWORK=10.200.200.0/24
volumes:
# this volume is needed to keep the certificates
# otherwise, new ones will be re-issued upon restart
Expand All @@ -25,11 +23,9 @@ services:
caddy_controller:
image: lucaslorentz/caddy-docker-proxy:ci-alpine
networks:
- caddy_controller
- caddy
environment:
- CADDY_DOCKER_MODE=controller
- CADDY_CONTROLLER_NETWORK=10.200.200.0/24
volumes:
- /var/run/docker.sock:/var/run/docker.sock

Expand Down Expand Up @@ -95,12 +91,6 @@ services:
networks:
caddy:
driver: overlay
caddy_controller:
driver: overlay
ipam:
driver: default
config:
- subnet: "10.200.200.0/24"

volumes:
caddy_data: {}
62 changes: 62 additions & 0 deletions tests/distributed-controller-network/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
version: '3.7'

services:

caddy_server:
image: caddy-docker-proxy:local
ports:
- 80:80
- 443:443
networks:
- caddy_controller
- caddy
environment:
- CADDY_DOCKER_MODE=server
- CADDY_CONTROLLER_NETWORK=10.200.200.0/24
deploy:
replicas: 3
labels:
caddy_controlled_server:

caddy_controller:
image: caddy-docker-proxy:local
networks:
- caddy_controller
- caddy
environment:
- CADDY_DOCKER_MODE=controller
- CADDY_CONTROLLER_NETWORK=10.200.200.0/24
volumes:
- source: "${DOCKER_SOCKET_PATH}"
target: "${DOCKER_SOCKET_PATH}"
type: ${DOCKER_SOCKET_TYPE}

whoami_service:
image: jwilder/whoami
networks:
- caddy
deploy:
labels:
caddy: whoami_service.example.com
caddy.reverse_proxy: "{{upstreams 8000}}"
caddy.tls: "internal"

whoami_container:
image: jwilder/whoami
networks:
- caddy
labels:
caddy: whoami_container.example.com
caddy.reverse_proxy: "{{upstreams 8000}}"
caddy.tls: "internal"

networks:
caddy:
name: caddy_test
external: true
caddy_controller:
driver: overlay
ipam:
driver: default
config:
- subnet: "10.200.200.0/24"
14 changes: 14 additions & 0 deletions tests/distributed-controller-network/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

set -e

. ../functions.sh

docker stack deploy -c compose.yaml --prune caddy_test

retry curl --show-error -s -k -f --resolve whoami_service.example.com:443:127.0.0.1 https://whoami_service.example.com &&
retry curl --show-error -s -k -f --resolve whoami_container.example.com:443:127.0.0.1 https://whoami_container.example.com || {
docker service logs caddy_test_caddy_controller
docker service logs caddy_test_caddy_server
exit 1
}
56 changes: 4 additions & 52 deletions tests/distributed/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ services:
- 80:80
- 443:443
networks:
- caddy_controller
- caddy
environment:
- CADDY_DOCKER_MODE=server
- CADDY_CONTROLLER_NETWORK=10.200.200.0/24
deploy:
replicas: 3
labels:
Expand All @@ -21,80 +19,34 @@ services:
caddy_controller:
image: caddy-docker-proxy:local
networks:
- caddy_controller
- caddy
environment:
- CADDY_DOCKER_MODE=controller
- CADDY_CONTROLLER_NETWORK=10.200.200.0/24
volumes:
- source: "${DOCKER_SOCKET_PATH}"
target: "${DOCKER_SOCKET_PATH}"
type: ${DOCKER_SOCKET_TYPE}

# Proxy to service
whoami0:
whoami_service:
image: jwilder/whoami
networks:
- caddy
deploy:
labels:
caddy: whoami0.example.com
caddy: whoami_service.example.com
caddy.reverse_proxy: "{{upstreams 8000}}"
caddy.tls: "internal"

# Proxy to service
whoami1:
image: jwilder/whoami
networks:
- caddy
deploy:
labels:
caddy: whoami1.example.com
caddy.reverse_proxy: "{{upstreams 8000}}"
caddy.tls: "internal"

# Proxy to container
whoami2:
image: jwilder/whoami
networks:
- caddy
labels:
caddy: whoami2.example.com
caddy.reverse_proxy: "{{upstreams 8000}}"
caddy.tls: "internal"

# Proxy to container
whoami3:
whoami_container:
image: jwilder/whoami
networks:
- caddy
labels:
caddy: whoami3.example.com
caddy: whoami_container.example.com
caddy.reverse_proxy: "{{upstreams 8000}}"
caddy.tls: "internal"

# Proxy with matches and route
echo_0:
image: brndnmtthws/nginx-echo-headers
networks:
- caddy
deploy:
labels:
caddy: echo0.example.com
[email protected]: "/sourcepath /sourcepath/*"
caddy.route: "@match"
caddy.route.0_uri: "strip_prefix /sourcepath"
caddy.route.1_rewrite: "* /targetpath{path}"
caddy.route.2_reverse_proxy: "{{upstreams 8080}}"
caddy.tls: "internal"

networks:
caddy:
name: caddy_test
external: true
caddy_controller:
driver: overlay
ipam:
driver: default
config:
- subnet: "10.200.200.0/24"
7 changes: 2 additions & 5 deletions tests/distributed/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ set -e

docker stack deploy -c compose.yaml --prune caddy_test

retry curl --show-error -s -k -f --resolve whoami0.example.com:443:127.0.0.1 https://whoami0.example.com &&
retry curl --show-error -s -k -f --resolve whoami1.example.com:443:127.0.0.1 https://whoami1.example.com &&
retry curl --show-error -s -k -f --resolve whoami2.example.com:443:127.0.0.1 https://whoami2.example.com &&
retry curl --show-error -s -k -f --resolve whoami3.example.com:443:127.0.0.1 https://whoami3.example.com &&
retry curl --show-error -s -k -f --resolve echo0.example.com:443:127.0.0.1 https://echo0.example.com/sourcepath/something || {
retry curl --show-error -s -k -f --resolve whoami_service.example.com:443:127.0.0.1 https://whoami_service.example.com &&
retry curl --show-error -s -k -f --resolve whoami_container.example.com:443:127.0.0.1 https://whoami_container.example.com || {
docker service logs caddy_test_caddy_controller
docker service logs caddy_test_caddy_server
exit 1
Expand Down