diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 28f0592d2..baaa67aa8 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -2,8 +2,10 @@ # ================================================================= # # Authors: Just van den Broecke +# Benjamin Webb # # Copyright (c) 2019 Just van den Broecke +# Copyright (c) 2024 Benjamin Webb # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation @@ -43,6 +45,7 @@ SCRIPT_NAME=${SCRIPT_NAME:=/} CONTAINER_NAME=${CONTAINER_NAME:=pygeoapi} CONTAINER_HOST=${CONTAINER_HOST:=0.0.0.0} CONTAINER_PORT=${CONTAINER_PORT:=80} +WSGI_APP=${WSGI_APP:=pygeoapi.flask_app:APP} WSGI_WORKERS=${WSGI_WORKERS:=4} WSGI_WORKER_TIMEOUT=${WSGI_WORKER_TIMEOUT:=6000} WSGI_WORKER_CLASS=${WSGI_WORKER_CLASS:=gevent} @@ -66,6 +69,20 @@ pygeoapi openapi generate ${PYGEOAPI_CONFIG} --output-file ${PYGEOAPI_OPENAPI} echo "openapi.yml generated continue to pygeoapi" +start_gunicorn() { + # SCRIPT_NAME should not have value '/' + [[ "${SCRIPT_NAME}" = '/' ]] && export SCRIPT_NAME="" && echo "make SCRIPT_NAME empty from /" + + echo "Starting gunicorn name=${CONTAINER_NAME} on ${CONTAINER_HOST}:${CONTAINER_PORT} with ${WSGI_WORKERS} workers and SCRIPT_NAME=${SCRIPT_NAME}" + exec gunicorn --workers ${WSGI_WORKERS} \ + --worker-class=${WSGI_WORKER_CLASS} \ + --timeout ${WSGI_WORKER_TIMEOUT} \ + --name=${CONTAINER_NAME} \ + --bind ${CONTAINER_HOST}:${CONTAINER_PORT} \ + ${@} \ + ${WSGI_APP} +} + case ${entry_cmd} in # Run Unit tests test) @@ -91,19 +108,21 @@ case ${entry_cmd} in # Run pygeoapi server run) - # SCRIPT_NAME should not have value '/' - [[ "${SCRIPT_NAME}" = '/' ]] && export SCRIPT_NAME="" && echo "make SCRIPT_NAME empty from /" - - echo "Start gunicorn name=${CONTAINER_NAME} on ${CONTAINER_HOST}:${CONTAINER_PORT} with ${WSGI_WORKERS} workers and SCRIPT_NAME=${SCRIPT_NAME}" - exec gunicorn --workers ${WSGI_WORKERS} \ - --worker-class=${WSGI_WORKER_CLASS} \ - --timeout ${WSGI_WORKER_TIMEOUT} \ - --name=${CONTAINER_NAME} \ - --bind ${CONTAINER_HOST}:${CONTAINER_PORT} \ - pygeoapi.flask_app:APP - ;; + # Start + start_gunicorn + ;; + + # Run pygeoapi server with hot reload + run-with-hot-reload) + # Lock all Python files (for gunicorn hot reload) + find . -type f -name "*.py" | xargs chmod 0444 + + # Start with hot reload options + start_gunicorn --reload --reload-extra-file ${PYGEOAPI_CONFIG} + ;; + *) - error "unknown command arg: must be run (default) or test" + error "unknown command arg: must be run (default), run-with-hot-reload, or test" ;; esac diff --git a/docs/source/running-with-docker.rst b/docs/source/running-with-docker.rst index 7acf98b82..a1094fef4 100644 --- a/docs/source/running-with-docker.rst +++ b/docs/source/running-with-docker.rst @@ -29,6 +29,12 @@ To run with the default built-in configuration and data: ...then browse to http://localhost:5000 +You can also run pygeoapi with run-with-hot-reload of the configuration enabled + +.. code-block:: bash + + docker run -p 5000:80 -it geopython/pygeoapi run-with-hot-reload + You can also run all unit tests to verify: .. code-block:: bash @@ -91,8 +97,10 @@ The base Docker image supports two additional environment variables for configur .. code-block:: bash docker run -p 5000:80 -e PYGEOAPI_SERVER_ADMIN=true -it geopython/pygeoapi + # run with hot reload + docker run -p 5000:80 -e PYGEOAPI_SERVER_ADMIN=true -it geopython/pygeoapi run-with-hot-reload - This does not enable hot reloading of the `pygeoapi` configuration. To learn more about the Admin API see :ref:`admin-api`. + To learn more about the Admin API see :ref:`admin-api`. Deploying on a sub-path