Nginx behind Traefik Docker Swarm mode real ip

I’m using Traefik as a reverse proxy in front of nginx service on a docker swarm environment. Here’s my docker-stack.yml:

traefik:
    image: traefik
    command: -c /dev/null --web --docker --docker.swarmmode --docker.watch --docker.domain=domain --logLevel=DEBUG
    ports:
      - "8080:8080"
      - "80:80"
      - "443:443"
    networks:
       - app
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    deploy:
      placement:
        constraints: [node.role == manager]

nginx:
    image: nginx
    networks:
      - app
    deploy:
      labels:
        traefik.port: 80
        traefik.docker.network: app
        traefik.frontend.rule: "Host:app.domain"

Everything works fine but I need the real client IP in my Nginx access log, instead I get something like 10.0.1.37

  • Docker webpack dev server
  • Can I run JetBrains dotCover in a Linux Docker container?
  • Service 'web' failed to build: lstat apache/sites-enabled/000-default.conf: no such file or directory
  • creating /tmp directory inside docker
  • How to run Eclipse with Docker on Windows using Boot2Docker?
  • AWS ECS - how to log to cloudwatch from ECS container?
  • How get I can the real client ip?

    Thanks,

  • Parse a variable with the result of a command in DockerFile
  • how to build and run android apk on emulator using dockerfile
  • Docker and Neo4J
  • Use fig and docker-machine to deploy remotely
  • Docker Machine + Docker Compose + Volumes on Ubuntu
  • Can't resolve docker related sbt tags
  • One Solution collect form web for “Nginx behind Traefik Docker Swarm mode real ip”

    This issue was discussed on github #614.

    When the upstream service receives requests forwarded from Traefik, the X-Forwarded-For header contains an IP address from the overlay network, not the actual client address.

    To overcome this, you can use the new way of declaring service ports in docker-compose >=3.2 (LONG SYNTAX).

    Then you ensure that traefik is attached to host network and will send the right X-Forwarded-For header (see below mode: host for the 80 port):

    version: "3.2"
    services:
      traefik:
        ...
        ports:
          - "8080:8080"
          - target: 80
            published: 80
            protocol: tcp
            mode: host
          - "443:443"
        ...
    

    Finally, you have to change the nginx log_format in the http {} section. That can be done through volume binding of a nginx.conf configuration file:

    nginx:
      ..
      volumes:
        - /data/nginx/nginx.conf:/etc/nginx/nginx.conf
    

    you’d have nginx.conf with this:

    http {
      ...
      log_format main '$http_x_forwarded_for - $remote_user [$time_local] '
      '"$request" $status $body_bytes_sent "$http_referer" '
      '"$http_user_agent"' ;
    

    Tested on an AWS ec2, the traefik_nginx service (I called my stack traefik) logs like this:

    $ docker service logs -f traefik_nginx
    ...
    traefik_nginx.1.qpxyjheql5uk@xxx    | 82.253.xxx.xxx - - [20/Jun/2017:08:46:51 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36"
    
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.