-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Expected Behavior
I'm trying to stand up a docker-compose based GeoNode and have it run on port 8002 rather than the usual port 80.
I have these relevant variables in my .env file:
SITEURL=http://localhost:8002/
GEONODE_LB_HOST_IP=django
GEONODE_LB_PORT=8000
GEOSERVER_LB_HOST_IP=geoserver
GEOSERVER_LB_PORT=8080
NGINX_BASE_URL=http://localhost
HTTP_HOST=localhost
HTTPS_HOST=
HTTP_PORT=8002
HTTPS_PORT=443
GEOSERVER_WEB_UI_LOCATION=http://localhost:8002/geoserver/
GEOSERVER_PUBLIC_LOCATION=http://localhost:8002/geoserver/
GEOSERVER_LOCATION=http://geoserver:8080/geoserver/As you can see, internally django is served on port 8000, as usual, and geoserver is served on port 8080, as usual. For the outside world (outside of the docker network), nginx serves django at htpp://localhost:8002 and geoserver at http://localhost:8002/geoserver
This seems related to #9041, but I'm guessing perhaps the new GeoNode UI was not default back then (I may be wrong on this assumption).
Actual Behavior
This does not work, as the GeoNode API reports its own links without any port, like this:
{
"categories": "http://localhost/api/v2/categories",
"datasets": "http://localhost/api/v2/datasets",
"documents": "http://localhost/api/v2/documents",
"executionrequest": "http://localhost/api/v2/executionrequest",
"geoapps": "http://localhost/api/v2/geoapps",
"groups": "http://localhost/api/v2/groups",
"keywords": "http://localhost/api/v2/keywords",
"maps": "http://localhost/api/v2/maps",
"owners": "http://localhost/api/v2/owners",
"regions": "http://localhost/api/v2/regions",
"resources": "http://localhost/api/v2/resources",
"tkeywords": "http://localhost/api/v2/tkeywords",
"upload-parallelism-limits": "http://localhost/api/v2/upload-parallelism-limits",
"upload-size-limits": "http://localhost/api/v2/upload-size-limits",
"uploads": "http://localhost/api/v2/uploads",
"users": "http://localhost/api/v2/users"
}As you can guess, having the API return wrong URLs meant that the GeoNode UI does not work OK - I was getting errors like the one depicted below:
And seeing this kind of output:
GET
[http://localhost:8082/](http://localhost:8082/proxy/?url=http://localhost/api/v2/resources?page=1&page_size=24&filter%7Bmetadata_only%7D=false&include=executions)[proxy/?url=http://localhost/api/v2/resources?page](http://localhost:8082/proxy/?url=http://localhost/api/v2/resources?page=1&page_size=24&filter%7Bmetadata_only%7D=false&include=executions)[=1&page_size=24&filter%7Bmetadata_only%7D=false&include=executions](http://localhost:8082/proxy/?url=http://localhost/api/v2/resources?page=1&page_size=24&filter%7Bmetadata_only%7D=false&include=executions)
[HTTP/1.1 500 HTTPConnectionPool(host= localhost', port=80): Max retries exceeded with url: /api/v2/resources?page=1&page_size=24&filter%7Bmetadata_only%7D=false&include=executions (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f591fe42d70>: Failed to establish a new connection: [Errno 111] Connection refused')) 225ms]
Steps to Reproduce the Problem
- Clone GeoNode repo
- Adjust
.envfile with variables as shown above - You'll likely need to change some other things related to database connection strings - Build the images
- Stand up the docker stack
- Try to access geonode at
http://localhost:8002
Specifications
- GeoNode version: master
- Installation type (vanilla, geonode-project): vanilla
- Installation method (manual, docker): docker
- Platform: ubuntu 22.04 LTS
- Additional details:
Solution
After much digging around for a possible cause, I found out that the way that the API URLs get generated is by eventually using django's request.build_absolute_uri() function, which should preserve the host and port of the current HTTP request - which led me to the realization that it was maybe NGINX which was not providing the port.
Upon verification of the nginx configuration in
https://github.com/GeoNode/geonode/blob/master/scripts/docker/nginx/geonode.conf.envsubst
it seems the culprit is here:
| proxy_set_header Host $host; |
It is not very explicit, but nginx docs on the $host variable mention that it only holds the name of the requesting host - this implies that the port is not included.
With this in mind, in the same NGINX doc page, I found $http_name variable, which can be used to get an arbitrary request field by replacing name with the relevant field name - in our case http_host - this includes both the host and the port.
So I did a change to set proxy_set_header host $http_host, in the mentioned nginx configuration filed, which fixed it.
I am willing to provide a PR with this change
