2025-05-13 11:09:35 +02:00
2025-05-12 14:45:37 +02:00
2025-05-12 13:09:43 +02:00
2025-05-12 13:09:43 +02:00
2025-05-12 13:09:43 +02:00
2025-05-13 11:09:35 +02:00

LocalCerts

Automatic HTTPS and local domain routing for Docker Compose services using Traefik, DPS and Step-CA.

Created by @Sajito

Setup

  1. Clone this repository and navigate into the directory.

  2. Start the services:

docker compose up -d
  1. Trust the Step-CA root certificate:
# Linux
curl -k https://localhost:9000/roots.pem -o roots.pem
sudo trust anchor --store roots.pem
rm roots.pem

Linux

curl -k https://localhost:9000/roots.pem -o roots.pem
sudo trust anchor --store roots.pem
rm roots.pem

Windows

Invoke-WebRequest -Uri "https://localhost:9000/roots.pem" -OutFile "roots.pem"
Import-Certificate -FilePath "roots.pem" -CertStoreLocation "Cert:\LocalMachine\Root"
Remove-Item "roots.pem"

macOS

curl -k https://localhost:9000/roots.pem -o roots.pem
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain roots.pem
rm roots.pem

How to Use

  1. Add a label to your docker compose service:
labels:
  serviceName: my-app
  1. Your service will be accessible at https://my-app.dev.local.

Troubleshooting

  • If routes do not work you can open the traefik dashboard under https://traefik.vm and check if the service and route exist.

  • If your service is not reachable it could mean that traefik did not detect the correct port. You can set the port manually in your docker compose file:

labels:
  traefik.http.services.my-app.loadbalancer.server.port: 8080

Important

For each overwritten port you need to specify a custom service-label traefik.http.services.[service-label]. Otherwise the custom port will not be detected.

  • If certificates are not renewed or have expired
docker compose up -d --force-recreate traefik

Tipps

Custom Domain Suffix

For example dev.cool 😎

Replace .dev.local with your custom domain suffix in the config/traefik/traefik.yml file:

   docker:
     defaultRule: |
-      Host(`{{ trim (index .Labels "serviceName") }}.dev.local`) {{range $i, $domain := splitList "," (index .Labels "serviceDomains")}}{{if ne $domain ""}}|| Host(`{{$domain}}`){{end}}{{end}}
+      Host(`{{ trim (index .Labels "serviceName") }}.dev.cool`) {{range $i, $domain := splitList "," (index .Labels "serviceDomains")}}{{if ne $domain ""}}|| Host(`{{$domain}}`){{end}}{{end}}
     constraints: LabelRegex(`serviceName`, `.+`) && !Label(`com.docker.compose.oneoff`, `True`)

Replace .dev.local with your custom domain suffix in the config/dns/config.sample.json file:

         {
           "id": 2,
-          "hostname": ".dev.local",
+          "hostname": ".dev.cool",
           "ip": "",

Remove the dns_config volume

docker compose down
docker compose up -d --force-recreate

Custom Domain Per Service

If you want a single service to have a custom domain you can use the serviceDomains label. This will override the default domain suffix:

labels:
  serviceName: my-app
  serviceDomains: my-app.very.cool

The service would now be reachable at https://my-app.very.cool and https://my-app.dev.local.

Certificate Lifetime

To ensure Traefik has enough time to renew certificates, increase their duration:

docker compose exec step step ca provisioner update acme \
  --x509-min-dur=20m \
  --x509-max-dur=8760h \
  --x509-default-dur=2160h

Use the preconfigured services

If you use the preconfigured services, you can add the following snippet to you .bashrc/.zshrc to easily start, stop, and manage the services.

dev () {
  PROJECT_DIR="$HOME/Projects/dev/services"
  case "$1" in
    (start) shift
      docker compose -f "$PROJECT_DIR/docker-compose.yml" --profile "$@" up -d ;;
    (restart) shift
      docker compose -f "$PROJECT_DIR/docker-compose.yml" --profile "$@" restart ;;
    (stop) shift
      docker compose -f "$PROJECT_DIR/docker-compose.yml" --profile "$@" down --remove-orphans ;;
    (logs) shift
      docker compose -f "$PROJECT_DIR/docker-compose.yml" --profile "$@" logs -f ;;
    (*) echo "Usage: dev {start|restart|stop|logs} [services...]" ;;
  esac
}
Description
No description provided
Readme 80 KiB
Languages
Shell 100%