Docker部署含facebook_scraper的Django项目遇依赖错误求解决
问题原因与解决方案
错误原因分析
第一个错误(libxml2/libxslt缺失):
你在builder阶段先安装了编译lxml的依赖,安装完lxml后立刻删除了.build-deps(包含libxml2-dev、libxslt-dev),但后续执行pip wheel -r requirements.txt时,facebook_scraper依赖的lxml需要重新编译(因为wheel阶段要处理整个requirements,而非提前安装好),此时编译依赖已被删除,导致报错。第二个错误(wheel不兼容):
Alpine使用musl C库,lxml==4.9.2的musllinux wheel与Python 3.8.3的Alpine版本不兼容,预编译wheel无法被识别,而此时缺少编译依赖,无法从源码编译。切换到slim镜像后仍有问题:
slim镜像基于Debian,默认缺少lxml的编译依赖(libxml2-dev、libxslt1-dev等),同样会导致编译失败。
解决方案一:修复Alpine镜像的Dockerfile
调整builder阶段的依赖安装顺序,确保pip wheel执行时编译依赖仍存在,完成wheel构建后再删除临时依赖:
########### # BUILDER # ########### FROM python:3.8.3-alpine as builder WORKDIR /usr/src/app ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 # 安装所有编译依赖(psycopg2 + lxml) RUN apk update \ && apk add postgresql-dev gcc python3-dev musl-dev \ && apk add --update --no-cache --virtual .build-deps g++ libxml2-dev libxslt-dev # 升级pip、安装flake8并检查代码 RUN pip install --upgrade pip RUN pip install flake8 COPY . . RUN flake8 --ignore=E501,F401 . # 安装依赖并构建wheel(此时编译依赖还在,能正常编译lxml) COPY ./requirements.txt . RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt # 删除临时编译依赖 RUN apk del .build-deps ######### # FINAL # ######### FROM python:3.8.3-alpine RUN mkdir -p /home/app RUN addgroup -S app && adduser -S app -G app ENV HOME=/home/app ENV APP_HOME=/home/app/web RUN mkdir $APP_HOME WORKDIR $APP_HOME # 安装运行时依赖(psycopg2需要libpq,lxml需要libxslt) RUN apk update && apk add --no-cache libpq libxslt # 复制builder阶段的wheel和requirements COPY --from=builder /usr/src/app/wheels /wheels COPY --from=builder /usr/src/app/requirements.txt . RUN pip install --no-cache /wheels/* # 复制项目文件和entrypoint COPY ./entrypoint.prod.sh $APP_HOME COPY . $APP_HOME RUN chown -R app:app $APP_HOME USER app ENTRYPOINT ["/home/app/web/entrypoint.prod.sh"]
说明:
- 将编译依赖的安装统一放到
pip wheel之前,确保构建wheel时能编译lxml - final阶段只保留运行时依赖(
libxslt),不需要开发包 - 无需单独提前安装lxml,让
pip wheel自动处理requirements.txt中的依赖
解决方案二:使用Python Slim(Debian)镜像(更适合新手,减少依赖问题)
Slim镜像基于Debian,glibc生态更完善,预编译wheel兼容性更好,调整Dockerfile如下:
########### # BUILDER # ########### FROM python:3.8.3-slim as builder WORKDIR /usr/src/app ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 # 安装编译依赖(psycopg2 + lxml) RUN apt-get update \ && apt-get install -y --no-install-recommends gcc python3-dev libpq-dev libxml2-dev libxslt1-dev # 升级pip、安装flake8并检查代码 RUN pip install --upgrade pip RUN pip install flake8 COPY . . RUN flake8 --ignore=E501,F401 . # 构建wheel COPY ./requirements.txt . RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt ######### # FINAL # ######### FROM python:3.8.3-slim RUN mkdir -p /home/app RUN groupadd -r app && useradd -r -g app app ENV HOME=/home/app ENV APP_HOME=/home/app/web RUN mkdir $APP_HOME WORKDIR $APP_HOME # 安装运行时依赖 RUN apt-get update \ && apt-get install -y --no-install-recommends libpq5 libxslt1.1 \ && rm -rf /var/lib/apt/lists/* # 复制wheel和requirements COPY --from=builder /usr/src/app/wheels /wheels COPY --from=builder /usr/src/app/requirements.txt . RUN pip install --no-cache /wheels/* # 复制项目文件和entrypoint COPY ./entrypoint.prod.sh $APP_HOME COPY . $APP_HOME RUN chown -R app:app $APP_HOME USER app ENTRYPOINT ["/home/app/web/entrypoint.prod.sh"]
说明:
- Debian下的lxml编译依赖是
libxml2-dev、libxslt1-dev,运行时依赖是libxslt1.1 - 安装依赖后清理apt缓存,减小镜像体积
- 让
pip wheel自动处理requirements中的lxml,无需强行指定版本(除非有特殊需求)
额外注意事项
- 确保
requirements.txt中只保留必要依赖,facebook_scraper会自动拉取lxml的合适版本,无需强行指定lxml==4.9.2 - 使用docker-compose时,确保数据库服务(如PostgreSQL)配置正确,Django能正常连接
- entrypoint脚本需包含必要的初始化步骤(如迁移数据库、收集静态文件等)
内容的提问来源于stack exchange,提问作者Александр Хипхопов
相关产品推荐
相关产品推荐

