1 year ago
#381376
Micheal J. Roberts
Local traefik https proxy setup issue with uvicorn and FastAPI
I'm currently attempting to setup a traefik proxy to serve a Fast API app up on https locally, but I am encountering the following error that I have been unable to debug further, notably:
perseus_api | WARNING: Invalid HTTP request received.
perseus_api | Traceback (most recent call last):
perseus_api | File "/usr/local/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py", line 124, in data_received
perseus_api | self.parser.feed_data(data)
perseus_api | File "httptools/parser/parser.pyx", line 212, in httptools.parser.parser.HttpParser.feed_data
perseus_api | httptools.parser.errors.HttpParserInvalidMethodError: Invalid method encountered
I believe this may be a termination issue, but I'm not 100% sure. My hunch says it could be an issue with my traefik setup or with the uvicorn server that is serving my app...
My docker-compose.yml
with traefik setup is as follows:
version: '3.8'
services:
api:
build: .
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
container_name: perseus_api
volumes:
- .:/app
ports:
- 8008:8000
depends_on:
- db
env_file:
- .env
labels:
# Enable this container to be mapped by traefik
# For more information, see: https://docs.traefik.io/providers/docker/#exposedbydefault
- traefik.enable=true
- traefik.http.routers.perseus_api.tls=true
# URL to reach this container
- traefik.http.routers.perseus_api.rule=Host("perseus.docker.localhost")
# If port is different than 80, use the following service:
# - traefik.http.services.api@internal.loadbalancer.server.port=8000"
db:
image: postgres:14-alpine
container_name: postgres
volumes:
- postgres_data:/var/lib/postgresql/data/
ports:
- 5432:5432
env_file:
- .env
traefik:
image: traefik:latest
container_name: traefik_proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik=true"
ports:
# HTTPS / SSL port
- "443:443"
# The Traefik Web UI port (enabled by api:insecure: true in traefik.yml)
- "8888:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
# Map the static configuration into the container
- ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
# Map the configuration into the container
- ./traefik/config.yml:/etc/traefik/config.yml:ro
# Map the certificats into the container
- ./certs:/etc/certs:ro
volumes:
postgres_data:
My traefik.yml
file is as follows:
global:
sendAnonymousUsage: false
api:
dashboard: true
insecure: true
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
watch: true
exposedByDefault: false
file:
filename: /etc/traefik/config.yml
watch: true
log:
level: INFO
format: common
entryPoints:
http:
address: ":80"
http:
redirections:
entryPoint:
to: https
scheme: https
https:
address: ":443"
And my config.yml
is as follows:
http:
routers:
traefik:
rule: "Host(`traefik.docker.localhost`)"
service: "api@internal"
tls:
domains:
- main: "docker.localhost"
sans:
- "*.docker.localhost"
- main: "domain.local"
sans:
- "*.domain.local"
tls:
certificates:
- certFile: "/etc/certs/local-cert.pem"
keyFile: "/etc/certs/local-key.pem"
I have also setup certs locally using mkcert as follows:
$ mkcert -install
and then:
$ mkcert -cert-file certs/local-cert.pem -key-file certs/local-key.pem "docker.localhost" "*.docker.localhost" "domain.local" "*.domain.local"
And they're all mapped in correctly as far as I can tell.
So my question, is this a traefik configuration issue, is this an issue with the certs, or is this an issue with uvicorn?
Perhaps something like this:
$ uvicorn example:app --port 5000 --ssl-keyfile=./key.pem --ssl-certfile=./cert.pem
If anyone can advise and point me in the right direction I'd be very, very grateful.
Thank you for reading!
fastapi
traefik
uvicorn
0 Answers
Your Answer