Docker

在 Alpine docker 上安裝 Shapely

  • March 4, 2020

我正在嘗試將我的項目移動到 docker 並且我一直在使用 alpine 變體。這是一個帶有 postgres 數據庫的 django 項目

這是我安裝依賴項的方法:

...
ADD ./requirements.txt /srv/sites/mysite/requirements.txt

RUN echo "http://mirror.leaseweb.com/alpine/edge/testing" >> 
/etc/apk/repositories

RUN apk add --no-cache --virtual .build-deps \
build-base postgresql-dev libffi-dev gcc libc-dev linux-headers bash \
geos geos-dev jpeg-dev zlib-dev \
&& pip install -r requirements.txt \
&& find /usr/local \
   \( -type d -a -name test -o -name tests \) \
   -o \( -type f -a -name '*.pyc' -o -name '*.pyo' \) \
   -exec rm -rf '{}' + \
&& runDeps="$( \
   scanelf --needed --nobanner --recursive /usr/local \
           | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
           | sort -u \
           | xargs -r apk info --installed \
           | sort -u \
)" \
&& apk add --virtual .rundeps $runDeps \
&& apk del .build-deps
...

geos geos-dev是夏普利的依賴。一切都很好,直到我嘗試啟動 Web 伺服器,因為我正在測試我只是使用runserver命令docker-compose,它導致

web_1_ba4690531efe | Traceback (most recent call last):
web_1_ba4690531efe |   File "/srv/sites/mysite/manage.py", line 10, in <module>
web_1_ba4690531efe |     execute_from_command_line(sys.argv)
web_1_ba4690531efe |   File "/usr/local/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
web_1_ba4690531efe |     utility.execute()
web_1_ba4690531efe |   File "/usr/local/lib/python3.6/site-packages/django/core/management/__init__.py", line 338, in execute
web_1_ba4690531efe |     django.setup()
web_1_ba4690531efe |   File "/usr/local/lib/python3.6/site-packages/django/__init__.py", line 27, in setup
web_1_ba4690531efe |     apps.populate(settings.INSTALLED_APPS)
web_1_ba4690531efe |   File "/usr/local/lib/python3.6/site-packages/django/apps/registry.py", line 108, in populate
web_1_ba4690531efe |     app_config.import_models()
web_1_ba4690531efe |   File "/usr/local/lib/python3.6/site-packages/django/apps/config.py", line 202, in import_models
web_1_ba4690531efe |     self.models_module = import_module(models_module_name)
web_1_ba4690531efe |   File "/usr/local/lib/python3.6/importlib/__init__.py", line 126, in import_module
web_1_ba4690531efe |     return _bootstrap._gcd_import(name[level:], package, level)
web_1_ba4690531efe |   File "<frozen importlib._bootstrap>", line 994, in _gcd_import
web_1_ba4690531efe |   File "<frozen importlib._bootstrap>", line 971, in _find_and_load
web_1_ba4690531efe |   File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
web_1_ba4690531efe |   File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
web_1_ba4690531efe |   File "<frozen importlib._bootstrap_external>", line 678, in exec_module
web_1_ba4690531efe |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
web_1_ba4690531efe |   File "/srv/sites/mysite/utils/models.py", line 5, in <module>
web_1_ba4690531efe |     from utils.common_models import AbstractDetailedPerson, AbstractTimeStamped
web_1_ba4690531efe |   File "/srv/sites/mysite/utils/common_models.py", line 5, in <module>
web_1_ba4690531efe |     from utils.functions import national_id_validator
web_1_ba4690531efe |   File "/srv/sites/mysite/utils/functions.py", line 16, in <module>
web_1_ba4690531efe |     from shapely.geometry import Polygon, Point
web_1_ba4690531efe |   File "/usr/local/lib/python3.6/site-packages/shapely/geometry/__init__.py", line 4, in <module>
web_1_ba4690531efe |     from .base import CAP_STYLE, JOIN_STYLE
web_1_ba4690531efe |   File "/usr/local/lib/python3.6/site-packages/shapely/geometry/base.py", line 17, in <module>
web_1_ba4690531efe |     from shapely.coords import CoordinateSequence
web_1_ba4690531efe |   File "/usr/local/lib/python3.6/site-packages/shapely/coords.py", line 8, in <module>
web_1_ba4690531efe |     from shapely.geos import lgeos
web_1_ba4690531efe |   File "/usr/local/lib/python3.6/site-packages/shapely/geos.py", line 76, in <module>
web_1_ba4690531efe |     free = load_dll('c').free
web_1_ba4690531efe |   File "/usr/local/lib/python3.6/site-packages/shapely/geos.py", line 56, in load_dll
web_1_ba4690531efe |     libname, fallbacks or []))
web_1_ba4690531efe | OSError: Could not find lib c or load any of its variants [].

現在我猜要麼我已經刪除了一些依賴項,要麼我需要安裝一些其他庫。做了一些Google搜尋,顯然我需要安裝sudo apt-get install libgeos-c1,但我找不到alpine/apk等效的

我在同樣的問題上苦苦掙扎(雖然沒有使用 Django 和 PostGres 數據庫)。

最後,我設法用 Amir 的解決方案解決了這個問題。我根據https://github.com/appropriate/docker-postgis/blob/master/Dockerfile.alpine.template添加了來自 dl-cdn.alpinelinux.org 的儲存庫。至關重要的部分是在實施 geos-dev 和 geos 之後執行 geos-config。在此之後,我安裝了 python 模組,包括 pandas。如前所述,在清理部分 .build-deps 被跳過。

這是我的 Dockerfile 中起到作用的部分:

...
執行 apk --update 添加建構庫 libxslt-dev

執行 apk 添加 --virtual .build-deps \
--repository http://dl-cdn.alpinelinux.org/alpine/edge/testing \
--repository http://dl-cdn.alpinelinux.org/alpine/edge/main \
gcc libc-dev geos-dev geos && \
runDeps="$(scanelf --needed --nobanner --recursive /usr/local \
| awk '{ gsub(/,/, "\nso:", $2); 列印 "so:" $2 }' \
| xargs -r apk 資訊--已安裝 \
| 排序 -u)" && \
apk add --virtual .rundeps $runDeps

執行地理配置--cflags

執行 pip install --disable-pip-version-check -r requirements.txt

執行 apk del build-base python3-dev && \
rm -rf /var/cache/apk/*
...

順便說一句,我還嘗試了https://github.com/calendar42/docker-python-geos/blob/master/Dockerfile上提供的解決方案。但這對我沒有用。

引用自:https://serverfault.com/questions/947044