Setup FTP container with Traefik

Hi there. I'm trying to setup up stilliard/pure-ftpd:hardened image to be used through Traefik. I'd like to have also support for TLS inside image. Below I put my docker-compose.yml

FTP compose
services:
  pureftpd:
    image: stilliard/pure-ftpd:hardened
    tty: true
    environment:
      PUBLICHOST: "dev.domain.org"
      FTP_PASSIVE_PORTS: "30000:30009"
    #ports:
    #  - "2100:2100"
    #  - "30000-30009:30000-30009"
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=load_balancer"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd.entrypoints=ftp"
      #- "traefik.tcp.routers.${PROJECT_NAME}_ftpd.tls=false"
      #- "traefik.tcp.routers.${PROJECT_NAME}_ftpd.tls.passthrough=true"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd.service=${PROJECT_NAME}_ftp"
      - "traefik.tcp.services.${PROJECT_NAME}_ftp.loadbalancer.server.port=21"

      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-0.entrypoints=ftp-passive-0"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-0.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-0.service=${PROJECT_NAME}_ftpd-passive-0"
      - "traefik.tcp.services.${PROJECT_NAME}_ftpd-passive-0.loadbalancer.server.port=30000"

      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-1.entrypoints=ftp-passive-1"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-1.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-1.service=${PROJECT_NAME}_ftpd-passive-1"
      - "traefik.tcp.services.${PROJECT_NAME}_ftpd-passive-1.loadbalancer.server.port=30001"

      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-2.entrypoints=ftp-passive-2"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-2.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-2.service=${PROJECT_NAME}_ftpd-passive-2"
      - "traefik.tcp.services.${PROJECT_NAME}_ftpd-passive-2.loadbalancer.server.port=30002"

      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-3.entrypoints=ftp-passive-3"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-3.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-3.service=${PROJECT_NAME}_ftpd-passive-3"
      - "traefik.tcp.services.${PROJECT_NAME}_ftpd-passive-3.loadbalancer.server.port=30003"

      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-4.entrypoints=ftp-passive-4"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-4.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-4.service=${PROJECT_NAME}_ftpd-passive-4"
      - "traefik.tcp.services.${PROJECT_NAME}_ftpd-passive-4.loadbalancer.server.port=30004"

      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-5.entrypoints=ftp-passive-5"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-5.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-5.service=${PROJECT_NAME}_ftpd-passive-5"
      - "traefik.tcp.services.${PROJECT_NAME}_ftpd-passive-5.loadbalancer.server.port=30005"

      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-6.entrypoints=ftp-passive-6"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-6.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-6.service=${PROJECT_NAME}_ftpd-passive-6"
      - "traefik.tcp.services.${PROJECT_NAME}_ftpd-passive-6.loadbalancer.server.port=30006"

      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-7.entrypoints=ftp-passive-7"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-7.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-7.service=${PROJECT_NAME}_ftpd-passive-7"
      - "traefik.tcp.services.${PROJECT_NAME}_ftpd-passive-7.loadbalancer.server.port=30007"

      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-8.entrypoints=ftp-passive-8"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-8.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-8.service=${PROJECT_NAME}_ftpd-passive-8"
      - "traefik.tcp.services.${PROJECT_NAME}_ftpd-passive-8.loadbalancer.server.port=30008"

      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-9.entrypoints=ftp-passive-9"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-9.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.${PROJECT_NAME}_ftpd-ftp-passive-9.service=${PROJECT_NAME}_ftpd-passive-9"
      - "traefik.tcp.services.${PROJECT_NAME}_ftpd-passive-9.loadbalancer.server.port=30009"


    command: >
      bash -c "/run.sh -l puredb:/etc/pure-ftpd/pureftpd.pdb -E -j -R -P dev.domain.org -p 30000:30009"
    restart: unless-stopped
    networks:
      - default
      - load_balancer

networks:
  load_balancer:
    external: true
Traefik compose
services:
  lb:
    image: traefik:latest
    restart: always
    # Enables the web UI and tells Traefik to listen to docker                                                                                                                                                                                 
    command:
      - --api=true
      - --entrypoints.web.address=:80
      - --entrypoints.web-secure.address=:443 #Declares the web-secure entrypoint in Traefik                                                                                                                                                   
      - --entrypoints.ftp.address=:21
      - --entrypoints.ftp-passive-0.address=:30000
      - --entrypoints.ftp-passive-1.address=:30001
      - --entrypoints.ftp-passive-2.address=:30002
      - --entrypoints.ftp-passive-3.address=:30003
      - --entrypoints.ftp-passive-4.address=:30004
      - --entrypoints.ftp-passive-5.address=:30005
      - --entrypoints.ftp-passive-6.address=:30006
      - --entrypoints.ftp-passive-7.address=:30007
      - --entrypoints.ftp-passive-8.address=:30008
      - --entrypoints.ftp-passive-9.address=:30009
      - --providers.docker=true
      - --providers.docker.exposedByDefault=false
      - --providers.docker.network=load_balancer
      - --certificatesresolvers.le.acme.email=mail@domain.org
      - --certificatesresolvers.le.acme.storage=/acme.json
      - --certificatesresolvers.le.acme.tlschallenge=true
      # - --certificatesresolvers.le.acme.httpchallenge.entrypoint=web                                                                                                                                                                         
      - --serverstransport.insecureskipverify=true
      - --log.level=DEBUG
      - --log.filePath=/var/log/traefik.log
      - --accesslog=true
      - --accesslog.filepath=/var/log/access.log
      - --accesslog.bufferingsize=100
    ports:
      #- "21:21"                                                                                                                                                                                                                               
      #- "30000-30009:30000-30009"                                                                                                                                                                                                             
      - target: 21
        published: 21
        mode: host
      - target: 30000
        published: 30000
        mode: host
      - target: 30001
        published: 30001
        mode: host
      - target: 30002
        published: 30002
        mode: host
      - target: 30003
        published: 30003
        mode: host
      - target: 30004
        published: 30004
        mode: host
      - target: 30005
        published: 30005
        mode: host
      - target: 30006
        published: 30006
        mode: host
      - target: 30007
        published: 30007
        mode: host
      - target: 30008
        published: 30008
        mode: host
      - target: 30009
        published: 30009
        mode: host
      # The HTTP port
      - "80:80"
      - "443:443"
    labels:
      - "traefik.enable=true"
    volumes:
      # So that Traefik can listen to the Docker events
      - ./acme.json:/acme.json
      -  /var/run/docker.sock:/var/run/docker.sock
      - ./certs/:/certs/
      - ./logs/:/var/log/
    networks:
      - default
      - load_balancer
networks:
  load_balancer:
    name: load_balancer

Do you have any ideas what can be wrong?

The image is 3 years old, I would not recommend to use it, you don’t know how many security issues and bugs are included, even though it has tag hardened.

Most see FTP as a deprecated protocol nowadays.

Did you try the basic TLS example without Traefik?

Did you check Traefik dashboard and debug log?

Are you sure network load_balancer is shared between the two services?

Are you sure the command is executed the right way, as usually Dockerfile entrypoint is combined with it?

What’s the error message you get?

I found a problem with Traefik: It didn't correctly route traffic because not all services have set up entrypoints, so it pointed to default entrypoints, which were all available entrypoints. Coz of that request didn't point to the correct container.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.