首页 > 解决方案 > 在 docker 容器中出现 gunicorn 和 Python 错误解释器错误 [多阶段]

问题描述

我正在尝试为我的 Flask 应用程序开发一个多阶段的 Dockerfile。我使用 Ubuntu 作为我的基础镜像来构建模块,然后在发布镜像中使用一个较小的 python 镜像。

但是,当我尝试启动 Flask 服务器时,出现以下错误

/var/endpoint/run.sh: /opt/venv/bin/gunicorn: /opt/venv/bin/python3: bad interpreter: No such file or directory

我目前使用的方法是先将所有需要的包安装到虚拟环境中,然后将虚拟环境从基础镜像复制到发布镜像。这似乎不起作用。

任何建议/帮助将不胜感激。

这是我的 Dockerfile

FROM ubuntu:18.04 as builder

WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    python3-venv cmake build-essential pkg-config libgoogle-perftools-dev git python3.7 python3-pip python3.7-dev python3-setuptools && \
    rm -rf /var/lib/apt/lists/*

# Setup the virtualenv
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
COPY requirements.txt ./
RUN pip install --upgrade pip==19.0 && python -m pip install sentencepiece==0.1.82 
RUN pip install -r requirements.txt



FROM python:3.7-slim as app

RUN apt-get update && apt-get install -y --no-install-recommends apache2

COPY --from=builder /opt/venv /opt/venv

WORKDIR /var/endpoint

COPY app.py /var/endpoint/

USER user

COPY scripts/* /var/endpoint/scripts/
COPY run.sh /var/endpoint/

RUN chmod +x /var/endpoint/run.sh

# Copy over the apache conf file and perform the required config
ADD model.conf /etc/apache2/sites-available/
RUN a2enmod proxy_http
RUN a2ensite model
RUN echo "Listen 5000" >> /etc/apache2/ports.conf

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PATH="/opt/venv/bin:$PATH"

# Run the script to start apache and gunicorn
CMD /var/endpoint/run.sh

我的run.sh文件如下:


#!/bin/bash

service apache2 start
gunicorn --workers 1 --threads 4 app:app --timeout 900

标签: pythondocker

解决方案


Python 虚拟环境非常特定于创建它们的单个 Python。如果有不同的安装路径或 Python 构建选项,虚拟环境将在不同的 Python 上失败。在 Docker 设置中,如果虚拟环境具有相同的基本映像,则可以将虚拟环境从一个构建阶段复制到另一个构建阶段,但在您的情况下,您是基于 Ubuntu 18.04 所具有的任何内容创建虚拟环境,然后在不同的构建阶段运行它Python 从python图像构建。

另一面是(正如您的第二阶段已经显示的那样)python:...-slim图像基于 Debian,几乎所有的安装机制和包名称在 Debian 和 Ubuntu 之间都是相同的。

因此,在您的第一个构建阶段:

  • Start FROM python:3.7-slim,与运行阶段相同。(考虑将确切的版本作为构建 ARG,这样您就不需要输入两次。)
  • 不要apt-get install python3.7或相关软件包,它们已经在基础映像中。

在最终图像中,您尝试运行两个程序,一个 Apache 反向代理和您的应用程序。我建议将它们作为两个单独的容器运行(您可以使用像 Docker Compose 这样的工具来编排它)。这简化了第二个构建阶段的设置;您可以使最后一行CMD gunicorn ...没有中间脚本。(您可能需要明确指定gunicorn --host 0.0.0.0 它可以从 Apache 容器访问。)


推荐阅读