Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ProxyPass with externalURL setting does not work for subfolders #94

Closed
azahnen opened this issue Mar 2, 2018 · 11 comments
Closed

ProxyPass with externalURL setting does not work for subfolders #94

azahnen opened this issue Mar 2, 2018 · 11 comments
Labels

Comments

@azahnen
Copy link
Collaborator

azahnen commented Mar 2, 2018

ldproxy needs to know the URL it will be accessed with, so if proxying it e.g. with apache httpd or nginx, the externalURL parameter has to be set. This works as long as ldproxy is still available in the root folder, but not when it is in a subfolder like http://localhost/ldproxy/.

@KathiSchleidt
Copy link

KathiSchleidt commented Mar 2, 2018 via email

@cportele
Copy link
Member

Code has been rewritten for the 2.0 release.

The external URL can be set in the configuration, we will document this in the documentation update for version 2.0.

@justb4
Copy link

justb4 commented May 28, 2021

We have a similar situation: ldproxy gives 404 behind a subpath, even with externalURL set, context:

The above setup works for other deployed services like pygeoapi. There we need to set SCRIPT_NAME to the subpath, but that is a Python-Flask-thing. IMHO all these settings should not be necessary (also in pygeoapi) when the front-end proxy adds X-Forwarded-For and/or X-Script-Name HTTP headers on which the backend service should act. I think GeoServer does something like that.

How can we solve this with the current versions of Traefik and ldproxy?

@justb4
Copy link

justb4 commented May 28, 2021

Working! Doing a similar thing in Traefik as classic Apache ProxyPass: using ReplacePath Traefik Middleware. Still need some ldproxy config+data to prove.

See our new config here. Maybe this is something for the ldproxy documentation, as Traefik is used extensively.

@cportele
Copy link
Member

Thanks @justb4. We are also using Traefik in the xyz.ldproxy.net deployments, but then always without a path.

We will have a look, how we can update/improve the documentation.

I think there might still an issue that we need to address, because the css link does not work.

@azahnen
Copy link
Collaborator Author

azahnen commented Jun 7, 2021

@justb4 ReplacePath is not the right tool for this case, it will replace any path with the static path /rest/services. Instead you should use the ReplacePathRegex middleware:

- traefik.http.middlewares.ldproxy-replace-restservices-path.replacepathregex.regex=(.*)
- traefik.http.middlewares.ldproxy-replace-restservices-path.replacepathregex.replacement=/rest/services/$$1

For simpler cases without subpath we use the AddPrefix middleware:

- traefik.http.middlewares.ldproxy-replace-restservices-path.addprefix.prefix=/rest/services

@justb4
Copy link

justb4 commented Jun 9, 2021

@azahnen thanks. I tried your suggestion within Geonovum/ogc-api-testbed#6, and several variants, but no success.

Aim is to run ldproxy on a subpath via Traefik as /rest/services, also disabling manager:
https://oapi.map5.nl/ldproxy/ (domain name will change next week)
or local:
http://localhost:8000/ldproxy/

When trying your suggestion, still /ldproxy is attached to /rest/services. Then I tried (current version) to use Traefik middleware that first strips the ldproxy prefix before adding the regex to render /rest/services$$1. Also /rest/services/$$1 gave double slashes, //. We are stuck here. Also leaving out the regex-replace and just strip the ldproxy prefix and call /ldproxy/rest/services did not work...

Our Docker compose file with the Traefik config. We did get services behind Traefik working for pygeoapi (using SCRIPT_NAME=pygeoapi , Python Flash-specific) and GeoServer. Maybe an HTTP header that should be set in Traefik?

@azahnen
Copy link
Collaborator Author

azahnen commented Jun 10, 2021

@justb4 Sorry, that was just a theoretical example and obviously it does not work. I set up the example in my environment, here is a minimal working docker-compose.yml to run ldproxy at http://localhost:8080/ldproxy:

version: "3.3"

services:
  traefik:
    image: traefik:latest
    command:
      - --providers.docker=true
      - --providers.docker.exposedByDefault=false
      - --entrypoints.http.address=:8080
    ports:
      - 8080:8080
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  ldproxy:
    image: iide/ldproxy:master
    volumes:
      - ./data:/ldproxy/data
    labels:
      - "traefik.enable=true"

      - "traefik.http.services.ldproxy.loadbalancer.server.port=7080"

      - "traefik.http.middlewares.ldproxy-replace-restservices-path.replacepathregex.regex=/ldproxy(.*)"
      - "traefik.http.middlewares.ldproxy-replace-restservices-path.replacepathregex.replacement=/rest/services$$1"

      - "traefik.http.routers.ldproxy_http.rule=Host(`localhost`) && PathPrefix(`/ldproxy`)"
      - "traefik.http.routers.ldproxy_http.entrypoints=http"
      - "traefik.http.routers.ldproxy_http.middlewares=ldproxy-replace-restservices-path"

@justb4
Copy link

justb4 commented Jun 12, 2021

Thanks @azahnen , your suggestion works on localhost. A WFS provider has been configured, collections can be navigated, logs look good, ignoring some layer-errors:

DEBUG [2021-06-12 13:31:46,834]  RCE_Landschapsatlas_WFS - Creating http client for host: https://services.rce.geovoorziening.nl/landschapsatlas/wfs?service=WFS&request=GetCapabilities&version=2.0.0  
DEBUG [2021-06-12 13:31:47,195]  RCE_Landschapsatlas_WFS - HTTP GET request: https://services.rce.geovoorziening.nl/landschapsatlas/wfs?REQUEST=GetCapabilities&SERVICE=WFS&VERSION=2.0.0  
DEBUG [2021-06-12 13:31:49,888]  RCE_Landschapsatlas_WFS - warming up GeoTools Filter ...  
DEBUG [2021-06-12 13:31:51,147]  RCE_Landschapsatlas_WFS - BBOX geometry | EPSG:25833 | null  
DEBUG [2021-06-12 13:31:51,151]  RCE_Landschapsatlas_WFS - PROP geometry null  
DEBUG [2021-06-12 13:31:56,702]  RCE_Landschapsatlas_WFS - done  
ERROR [2021-06-12 13:31:57,169]  RCE_Landschapsatlas_WFS - Collection 'groenerfgoed' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,175]  RCE_Landschapsatlas_WFS - Collection 'begraafplaatsen' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,176]  RCE_Landschapsatlas_WFS - Collection 'bruinkoolgroeves' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,178]  RCE_Landschapsatlas_WFS - Collection 'droogmakerijen' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,178]  RCE_Landschapsatlas_WFS - Collection 'fabrieksschoorstenen' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,180]  RCE_Landschapsatlas_WFS - Collection 'gemalen' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,181]  RCE_Landschapsatlas_WFS - Collection 'gesloten_stations' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,183]  RCE_Landschapsatlas_WFS - Collection 'haltes_en_depots_museumspoorlijnen' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,185]  RCE_Landschapsatlas_WFS - Collection 'haltes_oorlogsspoorlijnen' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,187]  RCE_Landschapsatlas_WFS - Collection 'hertenkampen' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,192]  RCE_Landschapsatlas_WFS - Collection 'luchtwachttorens' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,194]  RCE_Landschapsatlas_WFS - Collection 'museumspoorlijnen' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,195]  RCE_Landschapsatlas_WFS - Collection 'stations_en_haltes' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,200]  RCE_Landschapsatlas_WFS - Collection 'turfwinning' has been disabled because its feature type has no property with role ID in the provider schema.  
ERROR [2021-06-12 13:31:57,205]  RCE_Landschapsatlas_WFS - Collection 'wielen' has been disabled because its feature type has no property with role ID in the provider schema.  
INFO  [2021-06-12 13:31:57,702]  RCE_Landschapsatlas_WFS - Feature provider with id 'RCE_Landschapsatlas_WFS' started successfully.  
DEBUG [2021-06-12 13:31:57,792]  RCE_Landschapsatlas_WFS - Generating API definition for EndpointConformance  
DEBUG [2021-06-12 13:31:57,944]  RCE_Landschapsatlas_WFS - Finished generating API definition for EndpointConformance  
DEBUG [2021-06-12 13:31:57,963]  RCE_Landschapsatlas_WFS - Generating API definition for EndpointDefinition  
DEBUG [2021-06-12 13:31:58,033]  RCE_Landschapsatlas_WFS - Finished generating API definition for EndpointDefinition  
DEBUG [2021-06-12 13:31:58,045]  RCE_Landschapsatlas_WFS - Generating API definition for EndpointLandingPage  
DEBUG [2021-06-12 13:31:58,095]  RCE_Landschapsatlas_WFS - Finished generating API definition for EndpointLandingPage  
DEBUG [2021-06-12 13:31:58,100]  RCE_Landschapsatlas_WFS - Generating API definition for EndpointCollection  
DEBUG [2021-06-12 13:31:58,181]  RCE_Landschapsatlas_WFS - Finished generating API definition for EndpointCollection  
DEBUG [2021-06-12 13:31:58,198]  RCE_Landschapsatlas_WFS - Generating API definition for EndpointFeatures  
DEBUG [2021-06-12 13:31:58,717]  RCE_Landschapsatlas_WFS - Finished generating API definition for EndpointFeatures  
DEBUG [2021-06-12 13:31:58,727]  RCE_Landschapsatlas_WFS - Generating API definition for EndpointCollections  
DEBUG [2021-06-12 13:31:58,741]  RCE_Landschapsatlas_WFS - Finished generating API definition for EndpointCollections  
INFO  [2021-06-12 13:31:58,779]  RCE_Landschapsatlas_WFS - Service with id 'RCE_Landschapsatlas_WFS' started successfully.  
DEBUG [2021-06-12 13:31:58,803]                          - Listening for events for [entities, overrides]  
DEBUG [2021-06-12 13:32:21,960]                          - Processing request: GET /rest/services/ [17b57355-77c4-4ae6-bb10-32e746b2e47c] 
DEBUG [2021-06-12 13:32:22,044]                          - Sending response: 200 OK [17b57355-77c4-4ae6-bb10-32e746b2e47c] 
DEBUG [2021-06-12 13:32:38,595]  RCE_Landschapsatlas_WFS - Processing request: GET / [13647036-4bea-43c8-b28a-081c619ec15c] 
DEBUG [2021-06-12 13:32:38,722]  RCE_Landschapsatlas_WFS - accept text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 [13647036-4bea-43c8-b28a-081c619ec15c] 
DEBUG [2021-06-12 13:32:38,802]  RCE_Landschapsatlas_WFS - content-type Optional[ApiMediaType{type=text/html, label=HTML, parameter=html, qs=1000}] [13647036-4bea-43c8-b28a-081c619ec15c] 
DEBUG [2021-06-12 13:32:38,806]  RCE_Landschapsatlas_WFS - accept-language en-GB,en-US;q=0.9,en;q=0.8 [13647036-4bea-43c8-b28a-081c619ec15c] 
DEBUG [2021-06-12 13:32:38,823]  RCE_Landschapsatlas_WFS - content-language Optional[en] [13647036-4bea-43c8-b28a-081c619ec15c] 
DEBUG [2021-06-12 13:32:38,967]  RCE_Landschapsatlas_WFS - Sending response: 200 OK [13647036-4bea-43c8-b28a-081c619ec15c] 
DEBUG [2021-06-12 13:32:51,211]  RCE_Landschapsatlas_WFS - Processing request: GET /collections [8c4bfe13-82e3-49de-b81f-c74c81540f7b] 
DEBUG [2021-06-12 13:32:51,231]  RCE_Landschapsatlas_WFS - accept text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 [8c4bfe13-82e3-49de-b81f-c74c81540f7b] 
DEBUG [2021-06-12 13:32:51,232]  RCE_Landschapsatlas_WFS - content-type Optional[ApiMediaType{type=text/html, label=HTML, parameter=html, qs=1000}] [8c4bfe13-82e3-49de-b81f-c74c81540f7b] 
DEBUG [2021-06-12 13:32:51,233]  RCE_Landschapsatlas_WFS - accept-language en-GB,en-US;q=0.9,en;q=0.8 [8c4bfe13-82e3-49de-b81f-c74c81540f7b] 
DEBUG [2021-06-12 13:32:51,233]  RCE_Landschapsatlas_WFS - content-language Optional[en] [8c4bfe13-82e3-49de-b81f-c74c81540f7b] 
DEBUG [2021-06-12 13:32:51,500]  RCE_Landschapsatlas_WFS - Sending response: 200 OK [8c4bfe13-82e3-49de-b81f-c74c81540f7b] 
DEBUG [2021-06-12 13:33:08,884]  RCE_Landschapsatlas_WFS - Processing request: GET /collections/molens/items [be9394fd-80f4-4f25-87bd-7c205f498567] 

But on the server the Traefik path middelware works, but cannot get through the WFS Collection. Logs:

DEBUG [2021-06-12 13:49:41,985]                          - CAPABILITY CapabilityFoundation  
DEBUG [2021-06-12 13:49:42,543]  RCE_Landschapsatlas_WFS - warming up GeoTools Filter ...  
DEBUG [2021-06-12 13:49:43,321]  RCE_Landschapsatlas_WFS - BBOX geometry | EPSG:25833 | null  
DEBUG [2021-06-12 13:49:43,323]  RCE_Landschapsatlas_WFS - PROP geometry null  
DEBUG [2021-06-12 13:49:49,395]  RCE_Landschapsatlas_WFS - done  
INFO  [2021-06-12 13:49:49,801]  RCE_Landschapsatlas_WFS - Feature provider with id 'RCE_Landschapsatlas_WFS' started successfully.  
INFO  [2021-06-12 13:49:49,938]  RCE_Landschapsatlas_WFS - Service with id 'RCE_Landschapsatlas_WFS' started successfully.  
DEBUG [2021-06-12 13:49:49,983]                          - Listening for events for [entities, overrides]  
DEBUG [2021-06-12 13:50:07,569]                          - Processing request: GET /rest/services [c4d5df22-c7f5-40da-9876-efaa63cedc8f] 
DEBUG [2021-06-12 13:50:07,718]                          - Sending response: 200 OK [c4d5df22-c7f5-40da-9876-efaa63cedc8f] 
DEBUG [2021-06-12 13:50:13,096]  RCE_Landschapsatlas_WFS - Processing request: GET / [0dd44114-5f6a-47ba-be99-cb98fbe57f9b] 
DEBUG [2021-06-12 13:50:13,202]  RCE_Landschapsatlas_WFS - accept text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 [0dd44114-5f6a-47ba-be99-cb98fbe57f9b] 
DEBUG [2021-06-12 13:50:13,217]  RCE_Landschapsatlas_WFS - content-type Optional[ApiMediaType{type=text/html, label=HTML, parameter=html, qs=1000}] [0dd44114-5f6a-47ba-be99-cb98fbe57f9b] 
DEBUG [2021-06-12 13:50:13,225]  RCE_Landschapsatlas_WFS - Client error, HTTP status 404, Request path /RCE_Landschapsatlas_WFS: The requested path is not a resource in this API. [0dd44114-5f6a-47ba-be99-cb98fbe57f9b] 
DEBUG [2021-06-12 13:50:13,228]  RCE_Landschapsatlas_WFS - Sending response: 404 Not Found [0dd44114-5f6a-47ba-be99-cb98fbe57f9b] 

Somehow the WFS Resource is not processed and https://oapi.map5.nl/ldproxy/RCE_Landschapsatlas_WFS gives 404 (the localhost version works). Configuration is identical, in GitHub. Could it be permission problems ? We had permission problems, container changing file-ownership, with GeoServer.

Also I tried the same convention to access the manager on localhost via /manager_ldproxy (we like to run Manager only on localhost, checking-in the result config). But when trying the login form cannot login, error: manager.404 page not found ._label.
Relevant config is:


  ldproxy:
    # Seems 'latest' is another version
    image: iide/ldproxy:master

    container_name: ldproxy

    expose:
      - "7080"

#    ports:
#      - "7080:7080"
    
    volumes:
      - ./data:/ldproxy/data
    
    labels:
      # Enable Traefik routing on overlay service network
      - "traefik.enable=true"
      - "traefik.docker.network=service-network"

      # This will replace any /ldproxy/* with /rest/services/* when calling the ldproxy container
      - "traefik.http.middlewares.ldproxy-replace-restservices-path.replacepathregex.regex=/ldproxy(.*)"
      - "traefik.http.middlewares.ldproxy-replace-restservices-path.replacepathregex.replacement=/rest/services$$1"

      - "traefik.http.middlewares.ldproxy-replace-manager-path.replacepathregex.regex=/manager_ldproxy(.*)"
      - "traefik.http.middlewares.ldproxy-replace-manager-path.replacepathregex.replacement=/manager$$1"

      # SSL/https router
      - "traefik.http.routers.ldproxy_https.rule=Host(`${TRAEFIK_SSL_DOMAIN}`) && PathPrefix(`/ldproxy`)"
      - "traefik.http.routers.ldproxy_https.entrypoints=https"
      - "traefik.http.routers.ldproxy_https.tls=${TRAEFIK_USE_TLS}"
      - "traefik.http.routers.ldproxy_https.tls.certresolver=${TRAEFIK_SSL_CERT_RESOLVER}"
      - "traefik.http.routers.ldproxy_https.tls.options=my_default@file"
      - "traefik.http.routers.ldproxy_https.middlewares=secure-headers@file,ldproxy-replace-restservices-path"

      # local http router - REST services
      - "traefik.http.routers.ldproxy_http.rule=Host(`localhost`) && PathPrefix(`/ldproxy`)"
      - "traefik.http.routers.ldproxy_http.entrypoints=http"
      - "traefik.http.routers.ldproxy_http.middlewares=ldproxy-replace-restservices-path"

      # local http router - for ldproxy Manager
      - "traefik.http.routers.ldproxy_manager_http.rule=Host(`localhost`) && PathPrefix(`/manager_ldproxy`)"
      - "traefik.http.routers.ldproxy_manager_http.entrypoints=http"
      - "traefik.http.routers.ldproxy_manager_http.middlewares=ldproxy-replace-manager-path"

@azahnen
Copy link
Collaborator Author

azahnen commented Jun 16, 2021

@justb4 It looks like you figured out the 404 issue, as I can access https://apitestbed.geonovum.nl/ldproxy/RCE_Landschapsatlas_WFS.

The manager needs some rest endpoints relative to the manager path, so one more RegexReplace is needed. For example this works for me, manager runs at http://localhost:8080/ldproxy/manager/:

- "traefik.http.middlewares.ldproxy-replace-manager-path.replacepathregex.regex=/ldproxy/manager(.*)"
- "traefik.http.middlewares.ldproxy-replace-manager-path.replacepathregex.replacement=/manager$$1"

- "traefik.http.middlewares.ldproxy-replace-rest-path.replacepathregex.regex=/ldproxy/rest(.*)"
- "traefik.http.middlewares.ldproxy-replace-rest-path.replacepathregex.replacement=/rest$$1"

- "traefik.http.middlewares.ldproxy-replace-restservices-path.replacepathregex.regex=/ldproxy(.*)"
- "traefik.http.middlewares.ldproxy-replace-restservices-path.replacepathregex.replacement=/rest/services$$1"

- "traefik.http.routers.ldproxy_http.rule=Host(`localhost`) && PathPrefix(`/ldproxy`)"
- "traefik.http.routers.ldproxy_http.entrypoints=http"
- "traefik.http.routers.ldproxy_http.middlewares=ldproxy-replace-manager-path,ldproxy-replace-rest-path,ldproxy-replace-restservices-path"

@justb4
Copy link

justb4 commented Jun 16, 2021

@azahnen thanks again. Yes, somehow the endpoint https://apitestbed.geonovum.nl/ldproxy/RCE_Landschapsatlas_WFS suddenly worked. Ok, took the latest master DockerHub version, but I also suspect some "dangling" data in the Docker-mounted dirs. Or maybe a permission issue? Is there a way that the ldproxy container main user runs with the Docker host uid and guid ? We had to do a similar config with GeoServer, otherwise the Container runs with user tomcat causing permission issues for non-matching uid/guid.

We found another issue when opening the OAS Swagger page, see:
Geonovum/ogc-api-testbed#27 . Maybe it is a thing we can solve in our config, before opening an issue here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants