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

  • Apache Kafka in docker AND VirtualBox VM
  • How to set a docker container's iP?
  • How to Build a Dockerfile on RHEL7 and Oracle Java 8
  • Aldryn cloud on windows 10, using hyper-v, and docker 1.12 rc2 beta16
  • Can a Docker Task in a Swarm know which instance number or how many total instances there are?
  • Which DSpace Docker container is officially endorsed by the DSpace community?
  • How get I can the real client ip?

    Thanks,

  • How to build and start containers on multiple docker machines
  • deisctl list command raises a timeout error what am I doing wrong
  • Docker unsupported manifest mediatype
  • Docker ubuntu - elasticsearch
  • Share host timezone with docker container
  • Docker look at the log of an exited container
  • 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.