在docker容器[multi-stage]中获取gunicorn和Python错误解释器错误

在docker容器[multi-stage]中获取gunicorn和Python错误解释器错误,python,docker,Python,Docker,我正在尝试为我的Flask应用程序开发一个多级Dockerfile。我使用Ubuntu作为构建模块的基础映像,然后在发布映像中使用较小的python映像 但是,当我尝试启动我的Flask服务器时,出现以下错误 /var/endpoint/run.sh:/opt/venv/bin/gunicorn:/opt/venv/bin/python3:错误的解释器:没有这样的文件或目录 我目前使用的方法是首先将所有必需的软件包安装到虚拟环境中,然后将虚拟环境从基本映像复制到发布映像。这似乎不管用 如有任何建

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

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

/var/endpoint/run.sh:/opt/venv/bin/gunicorn:/opt/venv/bin/python3:错误的解释器:没有这样的文件或目录

我目前使用的方法是首先将所有必需的软件包安装到虚拟环境中,然后将虚拟环境从基本映像复制到发布映像。这似乎不管用

如有任何建议/帮助,将不胜感激

这是我的文件

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


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

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

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

  • 从python:3.7-slim启动
    ,与运行时阶段相同。(请考虑,这样您就不需要键入两次。)
  • 不要安装python3.7或相关软件包,它们已经在基本映像中了

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

为什么要重新发明轮子?此外,您应该将Apache httpd移动到它自己的容器中。我还指出,使用Docker否定了对虚拟化的需求。这个问题有一个有用的例外:第一阶段安装一系列构建工具(
apt get install build essential
带来了很多东西),然后第二阶段复制虚拟环境,但不复制构建工具。您还可以在第一阶段将依赖项编译到控制盘,然后在第二阶段安装这些控制盘,但最终会得到
*.whl
文件的额外副本。