简体   繁体   中英

Traefik different ports for different Docker containers

I'm new to Traefik and I want to expose two containers to two different ports via Traefik.

  • The first container is a ckan service which run on port 5000
  • The second container is a jupyter notebook running on port 8000

I mapped the first container to web and secureweb entrypoints via traefik (using port 80 and 443) and it's working fine.

However, the second container is not exposed even though I mapped it to port 9090 as I did with the previous container. So when I try to open the domain with port 8443 i get (404 page not found).

What I want to achieve is to access both containers' services via HTTPS:

  1. https://example.com
  2. https://example.com:9090

Here is my docker-compose file:

version: "3"

volumes:
  ckan_config:
  ckan_home:
  ckan_storage:
  pg_data:
  solr_data:
  jn_config:

services:
  ckan:
    container_name: ckan
    image: ckan
    build:
      context: ./
      args:
          - CKAN_SITE_URL=${CKAN_SITE_URL}
          - CKAN_JUPYTERNOTEBOOK_URL=${CKAN_JUPYTERNOTEBOOK_URL}
          - CKAN_CONFIG_L=${CKAN_CONFIG}
          - CKAN_HOME_L=${CKAN_HOME}
          - CKAN_STORAGE_PATH_L=${CKAN_STORAGE_PATH}
          - CKAN_VER=${CKAN_VERSION}

    links:
      - jupyternotebook
      
    depends_on:
      - jupyternotebook
    ports:
      - "5000:5000"
    env_file:
      - .env

    volumes:
      - ckan_config:${CKAN_CONFIG}
      - ckan_home:${CKAN_HOME}
      - ckan_storage:${CKAN_STORAGE_PATH}
    networks:
      - ldmnetwork
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ckan.rule=Host(`example.com`)"
      - "traefik.http.routers.ckan.entrypoints=websecure"
      - "traefik.http.routers.ckan.tls.certresolver=myresolver"
      - "traefik.http.services.ckan.loadbalancer.server.port=5000"


  jupyternotebook:
    build: 
      context: ./jupyternotebook/
      args:
          - CKAN_JUPYTERNOTEBOOK_URL=${CKAN_JUPYTERNOTEBOOK_URL}
          - CKAN_SITE_URL=${CKAN_SITE_URL}
          - CKAN_STORAGE_PATH=${CKAN_STORAGE_PATH}
    image: jupyter/datascience-notebook
    container_name: jupyternotebook
    ports:
      - "8000:8000"
    env_file:
      - .env  
    volumes:
      - ckan_storage:${CKAN_STORAGE_PATH}:ro
      - jn_config:/home/jovyan/.jupyter
    networks:
      - ldmnetwork
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.jupyternotebook.rule=Host(`example.com`)"
      - "traefik.http.routers.jupyternotebook.entrypoints=other"
      - "traefik.http.routers.jupyternotebook.tls.certresolver=myresolver"
      - "traefik.http.services.jupyternotebook.loadbalancer.server.port=8000"
      
      
  traefik:
    # The official v2 Traefik docker image
    image: "traefik:latest"
    container_name: "traefik"
    # Enables the web UI and tells Traefik to listen to docker
    command:
      - "--api=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=ldmnetwork"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.other.address=:9090"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
      - "--entrypoints.other.http.redirections.entryPoint.scheme=https"
    
      
      - "--certificatesresolvers.myresolver.acme.httpchallenge=true"
      - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
    
      - "--certificatesresolvers.myresolver.acme.email=XXXX"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
      - "9090:9090"
    volumes:
      - "./letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.api.service=api@internal"
      - "traefik.http.routers.api.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=XXXXX"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.routers.api.tls.certresolver=myresolver"
    networks:
      - "ldmnetwork"
  
networks:
  ldmnetwork:      

Here's a simple example that does what you want:

version: "3"

services:

  # The `proxy` service set up two entrypoints (read that as
  # "listeners") for traefik, one on port 80 and one on port 9090.
  proxy:
    image: traefik:latest
    command:
      - --api.insecure=true
      - --providers.docker
      - --entrypoints.ep1.address=:80
      - --entrypoints.ep2.address=:9090

    # We need to publish ports 80 and 9090. Here I'm also
    # publishing port 8080, which is the Traefik dashboard, but
    # that's not necessary.
    ports:
      - "80:80"
      - "8080:8080"
      - "9090:9090"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  # We bind container `app1` to entrypoint `ep1`, with a `Host`
  # rule matching `example.com`. I'm setting `...server.port` here
  # because the `darkhttpd` container listens on port 8080.
  app1:
    image: docker.io/alpinelinux/darkhttpd:latest
    labels:
      - traefik.enable=true
      - traefik.http.services.app1.loadbalancer.server.port=8080
      - traefik.http.routers.app1.rule=Host(`example.com`)
      - traefik.http.routers.app1.entrypoints=ep1

  # We bind container `app2` to entrypoint `ep2`, with a `Host`
  # rule matching `example.com`.
  app2:
    image: docker.io/alpinelinux/darkhttpd:latest
    labels:
      - traefik.enable=true
      - traefik.http.services.app2.loadbalancer.server.port=8080
      - traefik.http.routers.app2.rule=Host(`example.com`)
      - traefik.http.routers.app2.entrypoints=ep2

With this configuration in place, we can watch the logs from docker-compose and see that a request like this:

curl -H 'host: example.com' http://localhost/

Is serviced by app1 :

app1_1   | 172.20.0.2 - - [21/Jun/2022:02:14:52 +0000] "GET / HTTP/1.1" 200 354 "" "curl/7.76.1"

And that a request like this:

curl -H 'host: example.com' http://localhost:9090/

Is serviced by app2 :

app2_1   | 172.20.0.2 - - [21/Jun/2022:02:16:47 +0000] "GET / HTTP/1.1" 200 354 "" "curl/7.76.1"

And I think that is what you were asking for.

I found out what's the problem. The traefik configurations were correct. However, after having a look at the logs of traefik, the jupyter notebook container was filtered out because it has an unhealthy status. I put a valid Health Check command in the docker file of the container and now everything is working fine.

So to summarize the problem is that traefik filter out unhealthy docker containers and don't pass traffic unless the status of the docker container is healthy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM