I have a python web app, a simple REST API implementing a blog CMS with web page dressing via html/css/js. (Note, use of bold below is to aid scanning. I'm not yelling.)
This is running as a docker container with a companion postgres database container at Digital Ocean. I've placed Traefik in front, Traefik handling TLS Termination to my web app.
The problem I am trying to solve is triggered by JavaScript use of the fetch() API only when performing PUT and DELETE requests.
JavaScript fetch() requests using GET or POST work fine, presumably sending https that Traefik decodes to http for the web app, and then the generated http API responses must be getting encoded as https for delivery to the web page.
The error is (I think) the JavaScript fetch() requests using PUT or DELETE occur in https while the response from the web API return as http, NOT getting encoded to https - hence the mixed active content browser error and the response being blocked.
My configuration uses a traefik.toml and a traefik_dynamic.toml files for Traefik's config. If anyone sees anything that ought to be changed, so the API's PUT & DELETE responses get encoded, so the https client does not complain about mixed active content, that'd be great.
traefik.toml file contents:
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web.http.redirections.entryPoint]
to = "websecure"
scheme = "https"
[entryPoints.websecure]
address = ":443"
[api]
dashboard = true
[certificatesResolvers.lets-encrypt.acme]
email = "blake@blakesenftner.com"
storage = "acme.json"
[certificatesResolvers.lets-encrypt.acme.tlsChallenge]
[providers.docker]
watch = true
network = "web"
[providers.file]
filename = "traefik_dynamic.toml"
traefik_dynamic.toml file contents:
[http.middlewares.simpleAuth.basicAuth]
users = [
"admin:$apr1$nzY1.zpG$xBsroABcqsyYj7EqmYM/10"
]
[http.routers.api]
rule = "Host(`monitor.blakesenftner.com`)"
entrypoints = ["websecure"]
middlewares = ["simpleAuth"]
service = "api@internal"
[http.routers.api.tls]
certResolver = "lets-encrypt"
I then launch Traefik with this command line:
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $PWD/traefik.toml:/traefik.toml \
-v $PWD/traefik_dynamic.toml:/traefik_dynamic.toml \
-v $PWD/acme.json:/acme.json \
-p 80:80 \
-p 443:443 \
--network web \
--name traefik \
traefik:v2.2
and finally, this is the docker-compose file that launches the web app:
version: '3.8'
networks:
web:
external: true
internal:
external: false
services:
blog:
build: ./src
command: |
bash -c 'while !</dev/tcp/db/5432; do sleep 1; done; uvicorn app.main:app --reload --workers 1 --host 0.0.0.0 --port 8000'
volumes:
- ./src/:/usr/src/app/
ports:
- 8000:8000
environment:
- DATABASE_URL=postgresql://basic_blog:basic_blog@db/basic_blog_dev
labels:
# next line is unecessary because the lines after it default to traefik.enable=true
# - traefik.enable=true
- traefik.http.routers.blog.rule=Host(`blog.blakesenftner.com`)
- traefik.http.routers.blog.tls=true
- traefik.http.routers.blog.tls.certresolver=lets-encrypt
- traefik.port=80
# middleware redirect
# - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
# global redirect to https
# - "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
# - "traefik.http.routers.redirs.entrypoints=web"
# - "traefik.http.routers.redirs.middlewares=redirect-to-https"
networks:
- internal
- web
db:
image: postgres:13-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
expose:
- 5432
environment:
- POSTGRES_USER=basic_blog
- POSTGRES_PASSWORD=basic_blog
- POSTGRES_DB=basic_blog_dev
networks:
- internal
labels:
- traefik.enable=false
volumes:
postgres_data: