├── .env ├── .gitignore ├── README.md ├── common.env ├── configs └── caddy │ └── Caddyfile ├── docker-compose.yml ├── example-secrets.env └── images └── caddy-security └── Dockerfile /.env: -------------------------------------------------------------------------------- 1 | CONFIGS_DIR=./configs 2 | VOLUMES_DIR=./volumes 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | secrets.env 2 | volumes/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository contains a [docker-compose.yml](docker-compose.yml) file that can be used as a template for setting up automatic TLS and SSO with caddy. 2 | 3 | # Configuration 4 | ## .env 5 | [.env](.env) contains variables to be used in [docker-compose.yml](docker-compose.yml) 6 | 7 | | Variable | Description | 8 | | --- | --- | 9 | | CONFIGS_DIR | Where config files, such as [Caddyfile](configs/caddy/Caddyfile) are saved | 10 | | VOLUMES_DIR | Where mounted container volumes are saved | 11 | 12 | ## common.env 13 | [common.env](common.env) contains environment variables that can be applied to multiple containers. 14 | 15 | | Variable | Description | 16 | | --- | --- | 17 | | TZ | Timezone to use in the container | 18 | 19 | ## secrets.env 20 | secrets.env contains potentially sensistive data that you might not want to expose publicly. See [example-secrets.env](example-secrets.env) for an example. 21 | 22 | | Variable | Description | 23 | | --- | --- | 24 | | EMAIL | The email used to create the admin account (this should be your email) | 25 | | DOMAIN | Your domain name. This is used to create subdomains. For example `DOMAIN=example.com` results in the auth url being `https://auth.example.com` | 26 | | CODE | The registration code someone needs to register as a user | 27 | 28 | # Registration 29 | To register, simply go to `https://auth.$DOMAIN` and click on the register button. Once you register you will get a verification email sent to you. Be on the lookout for an email with the subject `User Registration for $DOMAIN` from `caddy@$DOMAIN` (it will likely go to your spam folder). Once you have gone through the verification flow, the container needs to be restarted. If you are the only person who will be registering you can delete the `mail` service from [docker-compose.yml](docker-compose.yml). 30 | 31 | # Adding Services 32 | To add additional services simply add the subdomain to the [Caddyfile](configs/caddy/Caddyfile): 33 | 34 | ``` 35 | additional_service.{$DOMAIN} { 36 | authorize with admin_policy 37 | reverse_proxy additional_service:80 38 | } 39 | ``` 40 | 41 | Here `additional_service` is the name of the service in your [docker-compose.yml](docker-compose.yml) file. If you want to add a service that doesn't require authorization, simply omit the `authorize with admin_policy` line. -------------------------------------------------------------------------------- /common.env: -------------------------------------------------------------------------------- 1 | TZ=America/New_York -------------------------------------------------------------------------------- /configs/caddy/Caddyfile: -------------------------------------------------------------------------------- 1 | { 2 | order authenticate before respond 3 | order authorize before reverse_proxy 4 | 5 | security { 6 | local identity store localdb { 7 | realm local 8 | path /data/auth/users.json 9 | } 10 | 11 | messaging email provider localhost-smtp-server { 12 | address mail:25 13 | protocol smtp 14 | passwordless 15 | sender caddy@{$DOMAIN} "User Registration for {$DOMAIN}" 16 | } 17 | 18 | user registration localdbRegistry { 19 | dropbox /data/auth/users.json 20 | title "User Registration" 21 | code {$CODE} 22 | admin email {$EMAIL} 23 | email provider localhost-smtp-server 24 | identity store localdb 25 | } 26 | 27 | authentication portal myportal { 28 | enable identity store localdb 29 | cookie domain mydomain.com 30 | cookie lifetime 3600 # 1 hour in seconds 31 | 32 | transform user { 33 | match email {$EMAIL} 34 | action add role authp/admin 35 | } 36 | } 37 | 38 | authorization policy admin_policy { 39 | set auth url https://auth.{$DOMAIN} 40 | allow roles authp/admin 41 | } 42 | } 43 | 44 | 45 | } 46 | 47 | auth.{$DOMAIN} { 48 | authenticate with myportal 49 | } 50 | 51 | whoami.{$DOMAIN} { 52 | authorize with admin_policy 53 | reverse_proxy whoami:80 54 | } -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3' 3 | services: 4 | caddy: 5 | build: ./images/caddy-security 6 | depends_on: 7 | - mail 8 | env_file: 9 | - common.env 10 | - secrets.env 11 | ports: 12 | - '80:80' 13 | - '443:443' 14 | restart: unless-stopped 15 | volumes: 16 | - ${CONFIGS_DIR}/caddy/Caddyfile:/etc/caddy/Caddyfile:ro 17 | - ${VOLUMES_DIR}/caddy/data:/data/ 18 | mail: 19 | expose: 20 | - 25 21 | image: bytemark/smtp 22 | restart: unless-stopped 23 | whoami: 24 | depends_on: 25 | - caddy 26 | expose: 27 | - 80 28 | image: containous/whoami 29 | restart: unless-stopped -------------------------------------------------------------------------------- /example-secrets.env: -------------------------------------------------------------------------------- 1 | EMAIL=example@mydomain.com 2 | DOMAIN=mydomain.com 3 | CODE=HELLO -------------------------------------------------------------------------------- /images/caddy-security/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM caddy:2-builder AS builder 2 | 3 | RUN xcaddy build --with github.com/greenpau/caddy-security 4 | 5 | FROM caddy:2 6 | 7 | COPY --from=builder /usr/bin/caddy /usr/bin/caddy --------------------------------------------------------------------------------