Google Cloud Run 不加载 .env 文件
Posted
技术标签:
【中文标题】Google Cloud Run 不加载 .env 文件【英文标题】:Google Cloud Run does not load .env file 【发布时间】: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,效果很好。
【参考方案1】:
已修复,我确实找到了问题所在,但我不知道为什么。
当我构建自己的图像之前,将图像推送到 GCP 容器注册表中时,它起作用了:
docker-compose up --build
docker tag 52e6159b6b13 gcr.io/mousset005/zoro
gcloud auth configure-docker
docker push gcr.io/mousset005/zoro
但是,我正在做的是使用 GCP API(这是他们在 Cloud Run Python 快速入门中推荐的)使用该命令构建我的图像:
gcloud run deploy --image gcr.io/mousset005/zoro --platform managed
【讨论】:
你能告诉我这里是如何使用 .env 文件的吗? gcloud run 是如何获取 .env 文件的以上是关于Google Cloud Run 不加载 .env 文件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React 中使用在 Google Cloud Run Dashboard 上声明的 ENV 变量
Docker 映像在本地部署,但在 Google Cloud Run 上失败
使用 GRPC 与 Google Cloud Run 通信的 Google App Engine 给出“错误:14 不可用:连接已断开”
Google Cloud Run(完全托管):无法自定义域映射
GCP - 无法在 Cloud Run 中使用 Google Secret Manager (@google-cloud/secret-manager)