zappa / Zappa

Serverless Python
https://zappa.ws/zappa
MIT License
3.25k stars 363 forks source link

[Migrated] Getting GeoDjango Working #392

Closed jneves closed 5 months ago

jneves commented 3 years ago

Originally from: https://github.com/Miserlou/Zappa/issues/985 by bahoo

Update September 2019: This issue + comment originally laid out a proposal to make project directory a configurable setting in Zappa, as a way of getting GeoDjango to work more seamlessly in Zappa across different projects. I've found a better solution to my original problem, laid out in a comment below, but I'm going to leave this issue as-is in case it offers guidance for someone else with a similar issue. Mods / maintainer folks, if you've got better solutions for next steps / what to do with this ticket, I'm all ears. 👍


A suggestion: make the project directory a configurable option within a stage.

Context

Following davepretty's comment on Slack for getting GeoDjango working, I hardcoded the rpath in one of my libraries I needed.

To make this approach more re-usable for future GeoDjango / Zappa projects, I thought that having the option for a consistent path for the project directory would be helpful. Then, future projects can use the same library files, specify the same path (something generic like /tmp/code/ in my case) and Bob's your uncle.

Currently, Zappa uses /tmp/{0!s}'.format(self.settings.PROJECT_NAME) which a good and fine default for most cases, but being able to use the same directory across different projects would be more portable.

Possible Fix

I've made this change in a branch, here: https://github.com/bahoo/Zappa/commits/specify_project_directory

Your Environment

Alex-Mackie commented 3 years ago

Update for 2021. The neatest, lightest way I could find was to use these layers (these are minimalist and conveniently supplied in all aws regions which is not the case for geolambda).

Concretely:

zappa_settings.json

        "layers": ["arn:aws:lambda:eu-west-2:524387336408:layer:gdal32:4"],
       ...
        "environment_variables": {
            "GDAL_LIBRARY_PATH": "/opt/lib/libgdal.so.3.2.1",
            "GEOS_LIBRARY_PATH": "/opt/lib/libgeos_c.so.1.16.2",
            "GDAL_DATA": "/var/task/share/gdal" 
        },

settings.py:

    GDAL_LIBRARY_PATH = os.environ['GDAL_LIBRARY_PATH']
    GEOS_LIBRARY_PATH = os.environ['GEOS_LIBRARY_PATH']

To find where the library paths to put in zappa_settings.json actually are:

    # zappa invoke dev "import subprocess; print(subprocess.getoutput(['find / -name *libgdal*']))" --raw
    # zappa invoke dev "import subprocess; print(subprocess.getoutput(['find / -name *libgeos*']))" --raw
Django==3.2
zappa==0.52.0
pfcodes commented 1 year ago

Update for 2021. The neatest, lightest way I could find was to use these layers (these are minimalist and conveniently supplied in all aws regions which is not the case for geolambda).

Concretely:

zappa_settings.json

        "layers": ["arn:aws:lambda:eu-west-2:524387336408:layer:gdal32:4"],
       ...
        "environment_variables": {
            "GDAL_LIBRARY_PATH": "/opt/lib/libgdal.so.3.2.1",
            "GEOS_LIBRARY_PATH": "/opt/lib/libgeos_c.so.1.16.2",
            "GDAL_DATA": "/var/task/share/gdal" 
        },

settings.py:

    GDAL_LIBRARY_PATH = os.environ['GDAL_LIBRARY_PATH']
    GEOS_LIBRARY_PATH = os.environ['GEOS_LIBRARY_PATH']

To find where the library paths to put in zappa_settings.json actually are:

    # zappa invoke dev "import subprocess; print(subprocess.getoutput(['find / -name *libgdal*']))" --raw
    # zappa invoke dev "import subprocess; print(subprocess.getoutput(['find / -name *libgeos*']))" --raw
Django==3.2
zappa==0.52.0

thanks for this, only difference for me was that I had to set GDAL_DATA to /opt/share/gdal

Alex-Mackie commented 1 year ago

Update for 2023 - IMO the best way to deploy GeoDjango with Zappa is via a custom Docker image. This knocks the socks off previous solutions. See #967 and https://ianwhitestone.work/zappa-serverless-docker/.

For example (there are lots of ways to do this but this worked for me):

Dockerfile

FROM python:3.8-slim-buster

RUN apt-get update && \
  apt-get install -y \
  g++ \
  make \
  cmake \
  unzip \
  libcurl4-openssl-dev \
  binutils \
  libproj-dev  \
  gdal-bin

ARG FUNCTION_DIR="/var/task/"
RUN mkdir -p ${FUNCTION_DIR}
WORKDIR ${FUNCTION_DIR}

RUN pip install --target ${FUNCTION_DIR} awslambdaric

ENTRYPOINT ["/usr/local/bin/python", "-m", "awslambdaric"]

COPY ./ ${FUNCTION_DIR}

RUN pip install poetry
RUN POETRY_VIRTUALENVS_CREATE=false poetry install --no-root

RUN ZAPPA_HANDLER_PATH=$( \
    python -c "from zappa import handler; print (handler.__file__)" \
    ) \
    && echo $ZAPPA_HANDLER_PATH \
    && cp $ZAPPA_HANDLER_PATH ${FUNCTION_DIR}

CMD ["handler.lambda_handler"]

settings.py (in this exact case)

GDAL_LIBRARY_PATH = '/usr/lib/libgdal.so.20.5.0'
GEOS_LIBRARY_PATH = '/usr/lib/x86_64-linux-gnu/libgeos_c.so.1'
github-actions[bot] commented 5 months ago

Hi there! Unfortunately, this Issue has not seen any activity for at least 90 days. If the Issue is still relevant to the latest version of Zappa, please comment within the next 10 days if you wish to keep it open. Otherwise, it will be automatically closed.

github-actions[bot] commented 5 months ago

Hi there! Unfortunately, this Issue was automatically closed as it had not seen any activity in at least 100 days. If the Issue is still relevant to the latest version of Zappa, please open a new Issue.