Skip to content

Instantly share code, notes, and snippets.

@gesellix
Forked from Ocramius/Caddyfile
Created August 2, 2018 06:42
Show Gist options
  • Save gesellix/3c66f49d93da7898d32db32babe38c4a to your computer and use it in GitHub Desktop.
Save gesellix/3c66f49d93da7898d32db32babe38c4a to your computer and use it in GitHub Desktop.
Example docker + docker-compose + caddy + traefik setup that routes to multiple apps from one exposed HTTP port

Example docker-compose setup that routes to separate hosts while exposing one port

This example runs 4 different docker containers:

  • a traefik reverse proxy
  • 3 caddy instances (simple/modern web server with minimal config)

The 3 applications are completely isolated from the outside network, and are neither accessible nor can access the WAN.

The HTTP routing (and eventual SSL termination) is up to traefik or your reverse proxy of choice.

Running it

Careful: this CLI script will use sudo rights, please audit it before running it!

./run.sh
FROM abiosoft/caddy:0.11.0
ADD ./Caddyfile /etc/Caddyfile
ADD ./app1.html /serve/index.html
<title>app1</title>
FROM abiosoft/caddy:0.11.0
ADD ./Caddyfile /etc/Caddyfile
ADD ./app2.html /serve/index.html
<title>app2</title>
FROM abiosoft/caddy:0.11.0
ADD ./Caddyfile /etc/Caddyfile
ADD ./app3.html /serve/index.html
<title>app3</title>
:80 {
root /serve
}
version: '3.5'
services:
traefik:
image: traefik:1.7
command: --web --docker --docker.domain=app.test --logLevel=DEBUG
depends_on:
# our setup relies on the 3 apps running. Trying to spin up traefik will bring up those too
- "app1"
- "app2"
- "app3"
ports:
# access this with the correct Host header to access the respective container
- "80:80"
# management UI
- "8080:8080"
volumes:
# traefik does its magic by reading information about running containers from the docker socket
- /var/run/docker.sock:/var/run/docker.sock
- /dev/null:/traefik.toml
networks:
outside-world:
internal-network:
# app1, app2 and app3 are Caddy instances listening to port 80 and serving an index.html.
app1:
build:
context: .
dockerfile: app1-Dockerfile
networks:
internal-network:
# the aliases are not required, but are useful if the applications want to internally
# reference each other by host name
aliases:
- "app1.test"
labels:
- "traefik.port=80"
- "traefik.frontend.rule=Host:app1.test"
app2:
build:
context: .
dockerfile: app2-Dockerfile
networks:
internal-network:
aliases:
- "app2.test"
labels:
- "traefik.port=80"
- "traefik.frontend.rule=Host:app2.test"
app3:
build:
context: .
dockerfile: app3-Dockerfile
networks:
internal-network:
aliases:
- "app3.test"
labels:
- "traefik.port=80"
- "traefik.frontend.rule=Host:app3.test"
networks:
# everything that is *only* on "internal network" cannot talk to WAN
internal-network:
internal: true
# add this network to a container to make it talk to the rest of the world
outside-world:
#!/usr/bin/env bash
set -exuo pipefail
IFS=$'\n\t'
docker-compose up -d
echo "Will now ask for root access to add app1.test, app2.test and app3.test to /etc/hosts\n"
sudo bash -c 'echo "127.0.0.1 app1.test" >> /etc/hosts'
sudo bash -c 'echo "127.0.0.1 app2.test" >> /etc/hosts'
sudo bash -c 'echo "127.0.0.1 app3.test" >> /etc/hosts'
curl http://app1.test/
curl http://app2.test/
curl http://app3.test/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment