1 year ago

#381376

test-img

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

Accepted video resources