Api Container returns 404 page when trying to access Swagger UI

Hey everybody,
I’m having issues connecting to Swagger.
I have the installation setup on a dedicated Debian server with docker-compose running behind Traefik 2 reverse proxy. here is my docker-compose.yml.

version: "2"

networks:
  web:
    external: true
  erp-network:
    driver: bridge

volumes:
  db-data:
  db-log:
  app-heapdump:
  app-log:
  rabbitmq-log:
  webapi-log:
  webapi-heapdump:
  search-data:

services:
  webapi:
    build: webapi
    links:
      - app:app
      - db:db
      - rabbitmq:rabbitmq
      - search:search
    restart: always
    volumes:
      - webapi-log:/opt/metasfresh-webui-api/log:rw
      - webapi-heapdump:/opt/metasfresh-webui-api/heapdump:rw
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    # to access the webui-api directly
    # (eg. for debugging or connecting your app to the metasfresh api)
    # uncomment following port:
    expose: 
     - 8080
    ports:
      - 8080:8080
    networks:
      erp-network:
        aliases:
          - webapi
      web:
        aliases:
          - erp-api.${DOMAIN}
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.erp-api.entrypoints=websecure"
      - "traefik.http.routers.erp-api.rule=Host(`commerce-api.${DOMAIN}`)"
      - "traefik.http.routers.erp-api.tls.certresolver=lets-encrypt"
      - "traefik.http.routers.erp-api.tls=true"
      - "traefik.docker.network=web"
      - "traefik.http.routers.erp-api.service=erp-api"
      - "traefik.http.services.erp-api.loadbalancer.server.port=8080"
  db:
    build: db
    restart: always
    volumes:
      - db-data:/var/lib/postgresql/data
      - db-log:/var/log/postgresql
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    environment:
      - METASFRESH_USERNAME=metasfresh
      - METASFRESH_PASSWORD=metasfresh
      - METASFRESH_DBNAME=metasfresh
      - DB_SYSPASS=System
      - POSTGRES_PASSWORD=*******
    networks:
      erp-network:
        aliases:
          - db

  app:
    build: app
    mem_limit: 8192m
    hostname: app
    ports:
      - 8282:8282
      - 61616:61616
    links:
      - db:db
      - rabbitmq:rabbitmq
      - search:search
    restart: always
    volumes:
      - app-log:/opt/metasfresh/log:rw
      - app-heapdump:/opt/metasfresh/heapdump:rw
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    environment:
      - METASFRESH_HOME=/opt/metasfresh
    networks:
      erp-network:
        aliases:
          - app
      web:
        aliases:
          - swagger.${DOMAIN}
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.swagger.entrypoints=websecure"
      - "traefik.http.routers.swagger.rule=Host(`erp-app.${DOMAIN}`)"
      - "traefik.http.routers.swagger.tls.certresolver=lets-encrypt"
      - "traefik.http.routers.swagger.tls=true"
      - "traefik.docker.network=web"
      - "traefik.http.routers.swagger.service=swagger"
      - "traefik.http.services.swagger.loadbalancer.server.port=8282"

  webui:
    build: webui
    links:
      - webapi:webapi
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - ./webui/sources/configs/config.js:/opt/metasfresh-webui-frontend/dist/config.js
    #uncomment and set to URL where metasfresh will be available from browsers
    environment:
      - WEBAPI_URL=https://erp.${DOMAIN}/
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.erp.entrypoints=websecure"
      - "traefik.http.routers.erp.rule=Host(`erp.${DOMAIN}`)"
      - "traefik.http.routers.erp.tls.certresolver=lets-encrypt"
      - "traefik.http.routers.erp.tls=true"
      - "traefik.docker.network=web"
      - "traefik.http.routers.erp.service=erp"
      - "traefik.http.services.erp.loadbalancer.server.port=80"
    networks:
      web:
        aliases:
          - erp.${DOMAIN}
      erp-network:
        aliases:
          - webui

  rabbitmq:
    build: rabbitmq
     expose:
       - "5672"
    restart: always
    volumes:
      - rabbitmq-log:/var/log/rabbitmq/log
      #    - ./volumes/rabbitmq/log:/var/log/rabbitmq/log
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    environment:
      RABBITMQ_DEFAULT_USER: "metasfresh"
      RABBITMQ_DEFAULT_PASS: "metasfresh"
      RABBITMQ_DEFAULT_VHOST: "/"
    networks:
      erp-network:
        aliases:
          - rabbitmq

  search:
    build: search
    ports:
      - 9200:9200
      - 9300:9300
    expose: 
      - 9300
      - 9200
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    cap_add:
      - IPC_LOCK
    # to access the search api directly
    # (e.g. if you did docker-compose up search to have the dashboard with your locally running metasfresh services)
    # uncomment following ports:
    volumes:
      - search-data:/usr/share/elasticsearch/data
      #    - ./volumes/search/data/:/usr/share/elasticsearch/data
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    environment:
      - "ES_JAVA_OPTS=-Xms512M -Xmx2048m"
    restart: always
    networks:
      erp-network:
        aliases:
          - search

I think I set all the URLs in docker-compose.yml and config.js of webui.

const config = {
        API_URL: 'https://erp.my-domain.de/rest/api',
        WS_URL: 'https://erp.my-domain.de/stomp'

Set the frontend url in the database with UPDATE AD_SysConfig SET Value='https://erp.my-domain.de' WHERE Name='webui.frontend.url';

I can visit the domain without CORS errors. I am able login and start using the software as intended. So far so good, although the logs of both app and api container show, that they cannot find the elastic search instance, despite it having both ports 9200 and 9300 exposed in the docker.compose.yml file.

app_1         | Caused by: org.springframework.data.elasticsearch.client.NoReachableHostException: Host 'localhost:9200' not reachable. Cluster state is offline.
webapi_1      | reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.data.elasticsearch.client.NoReachableHostException: Host 'localhost:9200' not reachable. Cluster state is offline.

I tried restarting the stack or just the search container, deleting volume and restarting search container, but the error message kept appearing. Although application.properties files state differently:

...
# --------------------------------------------------------------------------------
# Elasticsearch
# for more properties, see https://github.com/spring-projects/spring-boot/blob/v1.4.1.RELEASE/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchProperties.java
# --------------------------------------------------------------------------------
# Elasticsearch cluster name.
spring.data.elasticsearch.cluster-name=metasfresh
spring.data.elasticsearch.cluster-nodes=search:9300

So when I call https://erp.my-domain.de/swagger-ui.html#/ I get a 404 whitepage .
The docker logs show, that the call is correctly redirected to the api-container.

webapi_1      | 2022-04-17 15:09:14.164  WARN 19 --- [io-8080-exec-10] o.s.web.servlet.PageNotFound             : No mapping for GET /swagger-ui.html

Same when I call the api domain directly with https://commerce-api.mydomain.de/swagger-ui.html#/.
Same with https://erp.my-domain.de/app/swagger-ui.html#/
Same when I try to connect to the app container on port 8282. With https://erp-app.my-domain.de/app/swagger-ui.html#/
And same with http://host-ip:8080/swagger-ui.html#/ and http://host-ip:8282/swagger-ui.html#/

So I guess Swagger is simply not runnning or something else is wrong with the api container… But why and what? xD

I found this github issue suggesting the apache redirect configs may couse swagger to return a 404 page. But simply removing the / from the redirect URL did not help.

Does someone have a solution for my problem or point me in the right direction?

Help would be highly appreciated :slight_smile:

Greetings
Luke

hi,

there was a change in the URL. So it depends on your version.
What version precisely of metasfresh do you use for the app container?

cheers,
Norbert