Traefik and uwsgi sockets

Hi all,

For our new infra stack, I intend to make a switch from a combination of NGiNX and a with uWSGI deployed Django-app to Traefik (still with the same Django app). However, I can not seem to get the link between Traefik and uWSGI to work. Any help you guys (and girls) can provide here, is greatly appreciated.

New situation (Traefik - not working yet)

The intention for now is to get it working with a docker-compose.yaml file. The file itself is pretty much copied together from tutorials:

version: "3.3"

services:

  traefik:
    image: "traefik:v2.2"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  whoami:
    image: registry.gitlab.com/soffos/apiserver:dev
    container_name: "simple-service"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"
      - "traefik.http.routers.whoami.entrypoints=web"

  app:  # my app config. this will be different depending on your dockerfile
    image: {registry-name}/apiserver:dev
    container_name: app
    ports:
      - 8000:8000
    labels:  # redirecting http to https and defining routers and using tcl certresolver
      - "traefik.enable=true"
      - "traefik.http.routers.app-http.entrypoints=web"
      - "traefik.http.routers.app-http.rule=Host(`apiserver.localhost`)"

Current situation (NGiNX)

In the examples that I found so far, the applications used gunicorn, serving http trafic, but in our case, the process being run is served by a python uwsgi server, serving a socket on port 8000.

["uwsgi", "--ini", "/code/deploy/docker/uwsgi-api-server.ini"]
[uwsgi]
project = apiserver
base = /code

chdir = %(base)

mount = /api=%(project).wsgi:application
manage-script-name = true

master = true
processes = 5
socket = 0.0.0.0:8000
vacuum = true
stats = 127.0.0.1:9191

In the original setup we had with NGiNX, we had to install uwsgi-plugin-python3 and run the following code to serve the application:

upstream apirouter {
  server django:8000;
}

server {
  listen 80;
  listen [::]:80;
  server_name localhost;

  charset utf-8;
  client_max_body_size 75M;

  location /api {
    include             /etc/nginx/uwsgi_params;
    uwsgi_pass          apirouter;
  }
}

Question

Does any of you have an idea on how to replicate this behaviour with Traefik? This could mean that we need to switch to gunicorn, but I would very much like to give it a shot first to get it working with the uWSGI server that we currently have in place.

Many thanks for considering my request.

as far as I know, Traefik isn't able to forward to a socket and doesnt have the uwsgi integration found in nginx either. You should therefore do:

traefik --> nginx --> app

traefik would communicate via tcpip with nginx, which would int turn communicate via sockets with your app using the uwsgi support in nginx.

You could for example run nginx as a sidecar with each app instance and set it up so that nginx just does "dumb proxying", while Traefik would perform routing and all the other things it's so good at.

No need to keep nginx -- unless you have some good reason.

Change socket = 0.0.0.0:8000 to http-socket = :8000 in the uwsgi configuration.
No need for the ports entry in the app docker-compose configuration, services are supposed to find one another in the default network, created by docker-compose.