【发布时间】:2021-07-01 04:45:22
【问题描述】:
过去几天我试图找出我做错了什么,但我仍然无法弄清楚,因为我可以使用 flask run 在本地运行应用程序,也可以使用 docker-compose up --build 使用 Docker。 Source code is here
我的问题是我的 Cloud Run 部署成功,但单击 URL 时服务不可用。我检查了日志,似乎我的环境变量没有正确加载:
line 7, in <module> from web_messaging.blueprints.user import user File
"/web_messaging/web_messaging/blueprints/user/__init__.py", line 1, in <module> from
web_messaging.blueprints.user.views import user File
"/web_messaging/web_messaging/blueprints/user/views.py", line 3, in <module> from
web_messaging.extensions import mongo, login_manager, c, bc File
"/web_messaging/web_messaging/extensions.py", line 18, in <module> twilio_client = Client(TWILIO_SID,
TWILIO_TOKEN) File "/usr/local/lib/python3.9/site-packages/twilio/rest/__init__.py", line 54, in __init__
raise TwilioException("Credentials are required to create a TwilioClient")
twilio.base.exceptions.TwilioException: Credentials are required to create a TwilioClient
我有一个config/.env 文件和一个config/settings.py。我正在使用config/settings.py 上的load_dotenv() 从.env 加载环境变量。我决定在我的config/settings.py 中添加一些 print 和 try/expect 语句来查看变量的值。
settings.py
import os
from dotenv import load_dotenv
BASEDIR = os.path.abspath(os.path.dirname(__file__))
try:
load_dotenv(os.path.join(BASEDIR, '.env'))
print("OK")
print(BASEDIR)
except Exception as e:
print(str(e))
# Mongo Database
MONGO_URI = os.getenv('MONGO_URI')
TWILIO_SID = os.getenv('TWILIO_SID')
TWILIO_TOKEN = os.getenv('TWILIO_TOKEN')
print(MONGO_URI)
print(TWILIO_SID)
当我使用 flask run、docker-compose 或 cloud-run 运行时:
-
BASEDIR的值为/web_messaging/config -
load_dotenv()通话期间没有异常
但是,有一个主要区别,它是我的环境变量的值,例如MONGO_URI、TWILIO_SID。这些变量在使用 flask run 和 docker-compose 时具有正确的值,但在 Cloud Run 日志中却没有。在 Cloud Run 上,这些变量等于 None。
当我不使用 .env 并直接将我的变量值放入 /config/settings.py 时,没有问题,我的 Cloud Run 链接工作正常。我还尝试将 .env 移到配置文件之外和其他几个位置,但我仍然遇到同样的问题。
.
├── requirements.txt
├── Dockerfile
├── Docker-compose.yml
├── config
│ ├── .env
│ ├── settings.py
│ ├── gunicorn.py
│ └── __init__.py
├── web_messaging
│ ├── app.py # where I am calling create_app() - factory pattern
│ ├── blueprints
│ ├── static
│ └── ...
└── ...
Dockerfile
FROM python:3.9-slim
ENV INSTALL_PATH /web_messaging
RUN mkdir -p $INSTALL_PATH
WORKDIR $INSTALL_PATH
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD gunicorn -b 0.0.0.0:8080 --access-logfile - "web_messaging.app:create_app()"
docker-compose.yml
version: '2'
services:
website:
build: .
command: >
gunicorn -b 0.0.0.0:8080
--access-logfile -
--reload
"web_messaging.app:create_app()"
environment:
PYTHONUNBUFFERED: 'true'
volumes:
- '.:/web_messaging'
ports:
- '8080:8080'
config/.env
COMPOSE_PROJECT_NAME=web_messaging
FLASK_SECRET=xxx
MONGO_URI=mongodb+srv://xxx
MONGO_DB=xxx
TWILIO_SID=xxx
TWILIO_TOKEN=xxx
config/settings.py
import os
from dotenv import load_dotenv
BASEDIR = os.path.abspath(os.path.dirname(__file__))
load_dotenv(os.path.join(BASEDIR, '.env'))
DEBUG = True
PYTHONDONTWRITEBYTECODE=1
#SERVER_NAME = '127.0.0.1:5000'
# Mongo Database
MONGO_DBNAME = os.getenv('MONGO_DB')
MONGO_URI = os.getenv('MONGO_URI')
# Twilio API
FLASK_SECRET = os.getenv('FLASK_SECRET')
TWILIO_SID = os.getenv('TWILIO_SID')
TWILIO_TOKEN = os.getenv('TWILIO_TOKEN')
config/gunicorn.py
bind = '0.0.0.0:8080'
accesslog = '-'
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" in %(D)sµs'
【问题讨论】:
-
如果你在本地构建和运行容器,你有同样的问题吗?我说的是容器,而不是 docker-compose,执行 docker build 然后 docker run。
-
嗨 Guillaume,刚刚尝试使用
docker built -t然后docker run并且它有效。这是我的源代码:github.com/Pierre-Alexandre35/messaging-service-mousset -
为了更清楚,我做了
docker build -t helloworld .然后docker run -p 8080:8080 -it helloworld并且它起作用了 -
重现和缩小代码库的问题并不容易。就我而言,我不能将 dotenv 与 gunicorn run 一起使用。我不知道为什么(而且我不是 python 专家!)。但是为什么我在没有 gunicorn 的情况下在 Cloud Run 上使用 dotenv,效果很好。
标签: python docker docker-compose google-cloud-run python-dotenv