无法使用 Flask 和 Flask Migrate 在 Docker 中 运行 入口点脚本,即使它在终端中工作
Cannot run entrypoint script in Docker with Flask and Flask Migrate, even though it works in Terminal
我有一个连接到 Azure SQL 数据库的 Flask API,部署在 Docker 映像中的 Azure 应用服务上。
它工作正常,但我正在尝试使用 Alembic/Flask-Migrate 应用数据库升级来保持我的开发、暂存和生产环境之间的一致性。
我在 Miguel Grinberg's Docker Deployment Tutorial 上看到,这可以通过将 flask db upgrade
命令添加到 boot.sh
脚本来实现,如下所示:
#!/bin/sh
flask db upgrade
exec gunicorn -w 4 -b :5000 --access-logfile - --error-logfile - app:app
我的问题是,当 运行 运行 boot.sh
脚本时,我收到错误消息:
Usage: flask db [OPTIONS] COMMAND [ARGS]...
Try 'flask db --help' for help.
'.ror: No such command 'upgrade
这表示脚本找不到 Flask-Migrate
库。如果我尝试其他站点包,例如只是尝试 运行 flask
命令,这实际上会发生。
奇怪的是:
- gunicorn 工作正常
- API 工作正常
- 如果我启动容器并使用
docker exec -i -t api /bin/sh
打开终端会话,我可以 运行 flask db upgrade
没有问题
显然,我的 Docker 文件有问题。我非常感谢这里的任何帮助,因为我对 Docker 和 Linux 比较陌生,所以我确定我遗漏了一些明显的东西:
编辑:如果我将以下行添加到我的 Docker 文件中,就在入口点 CMD 之前,它也可以正常工作:
RUN flask db upgrade
Docker文件
FROM python:3.8-alpine
# Dependencies for pyodbc on Linux
RUN apk update
RUN apk add curl sudo build-base unixodbc-dev unixodbc freetds-dev
RUN apk add gcc musl-dev libffi-dev openssl-dev
RUN apk add --no-cache tzdata
RUN rm -rf /var/cache/apk/*
RUN curl -O https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/msodbcsql17_17.5.2.2-1_amd64.apk
RUN sudo sudo apk add --allow-untrusted msodbcsql17_17.5.2.2-1_amd64.apk
RUN mkdir /code
WORKDIR /code
COPY requirements.txt requirements.txt
RUN python -m pip install --default-timeout=100 -r requirements.txt
RUN python -m pip install gunicorn
ADD . /code/
COPY boot.sh /usr/local/bin/
RUN chmod u+x /usr/local/bin/boot.sh
EXPOSE 5000
ENTRYPOINT ["sh", "boot.sh"]
我认为这是关键信息。
Which indicates the script cannot find the Flask-Migrate library. This actually happens if I try other site-packages, such as just trying to run flask commands.
对我来说,这可能表明问题并非特定于 Flask-Migrate
,而是针对所有包 - 如您所写。这可能意味着以下两个中的一个。
首先,这可能意味着软件包没有正确安装。但是,这不太可能,因为您写道它在您 手动 启动容器时有效。
其次,您执行 boot.sh
脚本的方式有问题。例如,尝试更改
ENTRYPOINT ["sh", "boot.sh"]
到
ENTRYPOINT ["/bin/sh", "boot.sh"]
HTH!
我最终对 Docker 文件和 boot.sh
脚本进行了一些重大更改。我将尽我所能在下面分享这些内容:
问题 1:入口点脚本无法访问目录
我的主要问题是我的目录中的文件夹结构不一致。有 2 个 boot.sh
脚本,入口点上的 运行 要么权限错误,要么在错误的位置找到我的网站包。
我简化了将文件从本地计算机复制到 Docker 映像的过程,如下所示:
RUN mkdir /code
WORKDIR /code
COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install --default-timeout=100 -r requirements.txt
RUN venv/bin/pip install gunicorn
COPY app app
COPY migrations migrations
COPY api.py config.py boot.sh ./
RUN chmod u+x boot.sh
EXPOSE 5000
ENTRYPOINT ["./boot.sh"]
涉及的变化:
- 正在设置 virtualenv 并在其中安装所有站点包
- 确保
config.py
、boot.sh
和 api.py
文件位于应用程序文件夹的根目录中 (./
)
- 将入口点命令从
["bin/sh", "boot.sh"]
更改为仅 ["./boot.sh"]
- 将迁移文件移动到升级脚本的相关文件夹中
然后我能够在入口点文件中激活虚拟环境,并且 运行 flask 升级命令(注意:我在 boot.sh
中行结尾是 CRLF 而不是 LF 时遇到问题, 因此请确保在 Windows):
上更改它
#!/bin/bash
source venv/bin/activate
flask db upgrade
exec gunicorn -w 4 -b :5000 --access-logfile - --error-logfile - api:app
问题 2:Alpine Linux 太慢
我的另一个问题是我的图像在 Alpine Linux 上需要很长时间才能构建(超过 45 分钟)。在我的 API (Pandas, Numpy) 中使用一些库时发现这是 pretty well-established issue。
我切换到 Debian 版本以便我可以更快地更改我的 Docker 图像。
包括安装 pyodbc 以连接到 Azure SQL 服务器,我的 Docker 文件的前半部分现在看起来像:
FROM python:3.8-slim-buster
RUN apt-get update
RUN apt-get install -y apt-utils curl sudo gcc g++ gnupg2
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN apt-get install -y libffi-dev libgssapi-krb5-2 unixodbc-dev unixodbc freetds-dev
RUN sudo apt-get update
RUN sudo ACCEPT_EULA=Y apt-get install msodbcsql17
RUN apt-get clean -y
curl
命令及以下来自 the official MS docs on installing pyodbc on Debian
完整的 dockerfile:
FROM python:3.8-slim-buster
RUN apt-get update
RUN apt-get install -y apt-utils curl sudo gcc g++ gnupg2
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN apt-get install -y libffi-dev libgssapi-krb5-2 unixodbc-dev unixodbc freetds-dev
RUN sudo apt-get update
RUN sudo ACCEPT_EULA=Y apt-get install msodbcsql17
RUN apt-get clean -y
RUN mkdir /code
WORKDIR /code
COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install --default-timeout=100 -r requirements.txt
RUN venv/bin/pip install gunicorn
COPY app app
COPY migrations migrations
COPY api.py config.py boot.sh ./
RUN chmod u+x boot.sh
EXPOSE 5000
ENTRYPOINT ["./boot.sh"]
我有一个连接到 Azure SQL 数据库的 Flask API,部署在 Docker 映像中的 Azure 应用服务上。
它工作正常,但我正在尝试使用 Alembic/Flask-Migrate 应用数据库升级来保持我的开发、暂存和生产环境之间的一致性。
我在 Miguel Grinberg's Docker Deployment Tutorial 上看到,这可以通过将 flask db upgrade
命令添加到 boot.sh
脚本来实现,如下所示:
#!/bin/sh
flask db upgrade
exec gunicorn -w 4 -b :5000 --access-logfile - --error-logfile - app:app
我的问题是,当 运行 运行 boot.sh
脚本时,我收到错误消息:
Usage: flask db [OPTIONS] COMMAND [ARGS]...
Try 'flask db --help' for help.
'.ror: No such command 'upgrade
这表示脚本找不到 Flask-Migrate
库。如果我尝试其他站点包,例如只是尝试 运行 flask
命令,这实际上会发生。
奇怪的是:
- gunicorn 工作正常
- API 工作正常
- 如果我启动容器并使用
docker exec -i -t api /bin/sh
打开终端会话,我可以 运行
flask db upgrade
没有问题
显然,我的 Docker 文件有问题。我非常感谢这里的任何帮助,因为我对 Docker 和 Linux 比较陌生,所以我确定我遗漏了一些明显的东西:
编辑:如果我将以下行添加到我的 Docker 文件中,就在入口点 CMD 之前,它也可以正常工作:
RUN flask db upgrade
Docker文件
FROM python:3.8-alpine
# Dependencies for pyodbc on Linux
RUN apk update
RUN apk add curl sudo build-base unixodbc-dev unixodbc freetds-dev
RUN apk add gcc musl-dev libffi-dev openssl-dev
RUN apk add --no-cache tzdata
RUN rm -rf /var/cache/apk/*
RUN curl -O https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/msodbcsql17_17.5.2.2-1_amd64.apk
RUN sudo sudo apk add --allow-untrusted msodbcsql17_17.5.2.2-1_amd64.apk
RUN mkdir /code
WORKDIR /code
COPY requirements.txt requirements.txt
RUN python -m pip install --default-timeout=100 -r requirements.txt
RUN python -m pip install gunicorn
ADD . /code/
COPY boot.sh /usr/local/bin/
RUN chmod u+x /usr/local/bin/boot.sh
EXPOSE 5000
ENTRYPOINT ["sh", "boot.sh"]
我认为这是关键信息。
Which indicates the script cannot find the Flask-Migrate library. This actually happens if I try other site-packages, such as just trying to run flask commands.
对我来说,这可能表明问题并非特定于 Flask-Migrate
,而是针对所有包 - 如您所写。这可能意味着以下两个中的一个。
首先,这可能意味着软件包没有正确安装。但是,这不太可能,因为您写道它在您 手动 启动容器时有效。
其次,您执行 boot.sh
脚本的方式有问题。例如,尝试更改
ENTRYPOINT ["sh", "boot.sh"]
到
ENTRYPOINT ["/bin/sh", "boot.sh"]
HTH!
我最终对 Docker 文件和 boot.sh
脚本进行了一些重大更改。我将尽我所能在下面分享这些内容:
问题 1:入口点脚本无法访问目录
我的主要问题是我的目录中的文件夹结构不一致。有 2 个 boot.sh
脚本,入口点上的 运行 要么权限错误,要么在错误的位置找到我的网站包。
我简化了将文件从本地计算机复制到 Docker 映像的过程,如下所示:
RUN mkdir /code
WORKDIR /code
COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install --default-timeout=100 -r requirements.txt
RUN venv/bin/pip install gunicorn
COPY app app
COPY migrations migrations
COPY api.py config.py boot.sh ./
RUN chmod u+x boot.sh
EXPOSE 5000
ENTRYPOINT ["./boot.sh"]
涉及的变化:
- 正在设置 virtualenv 并在其中安装所有站点包
- 确保
config.py
、boot.sh
和api.py
文件位于应用程序文件夹的根目录中 (./
) - 将入口点命令从
["bin/sh", "boot.sh"]
更改为仅["./boot.sh"]
- 将迁移文件移动到升级脚本的相关文件夹中
然后我能够在入口点文件中激活虚拟环境,并且 运行 flask 升级命令(注意:我在 boot.sh
中行结尾是 CRLF 而不是 LF 时遇到问题, 因此请确保在 Windows):
#!/bin/bash
source venv/bin/activate
flask db upgrade
exec gunicorn -w 4 -b :5000 --access-logfile - --error-logfile - api:app
问题 2:Alpine Linux 太慢
我的另一个问题是我的图像在 Alpine Linux 上需要很长时间才能构建(超过 45 分钟)。在我的 API (Pandas, Numpy) 中使用一些库时发现这是 pretty well-established issue。
我切换到 Debian 版本以便我可以更快地更改我的 Docker 图像。
包括安装 pyodbc 以连接到 Azure SQL 服务器,我的 Docker 文件的前半部分现在看起来像:
FROM python:3.8-slim-buster
RUN apt-get update
RUN apt-get install -y apt-utils curl sudo gcc g++ gnupg2
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN apt-get install -y libffi-dev libgssapi-krb5-2 unixodbc-dev unixodbc freetds-dev
RUN sudo apt-get update
RUN sudo ACCEPT_EULA=Y apt-get install msodbcsql17
RUN apt-get clean -y
curl
命令及以下来自 the official MS docs on installing pyodbc on Debian
完整的 dockerfile:
FROM python:3.8-slim-buster
RUN apt-get update
RUN apt-get install -y apt-utils curl sudo gcc g++ gnupg2
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN apt-get install -y libffi-dev libgssapi-krb5-2 unixodbc-dev unixodbc freetds-dev
RUN sudo apt-get update
RUN sudo ACCEPT_EULA=Y apt-get install msodbcsql17
RUN apt-get clean -y
RUN mkdir /code
WORKDIR /code
COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install --default-timeout=100 -r requirements.txt
RUN venv/bin/pip install gunicorn
COPY app app
COPY migrations migrations
COPY api.py config.py boot.sh ./
RUN chmod u+x boot.sh
EXPOSE 5000
ENTRYPOINT ["./boot.sh"]