Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Cloud Run does not load .env file

I spend the last couple of days trying to find what I have done wrong but I am still not able to figure out because I am able to run the app locally using flask run and also using Docker using docker-compose up --build. Source code is here

My issue is my Cloud Run deployment is successful but Service Unavailable when I am clicking on the URL. I checked the logs and seems my environment variables are not correctly loaded:

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    

I have a config/.env file and a config/settings.py. I am loading the env variables from .env using load_dotenv() on my config/settings.py. I decided to add some print and try/expect statements in my config/settings.py to see the value of variables.

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)

When I am running with flask run, docker-compose or on cloud-run:

  • The BASEDIR value is /web_messaging/config
  • There is no exceptions during the load_dotenv() call

However, there is one major difference, it is the value of my env variables such as MONGO_URI, TWILIO_SID. Those variables have correct values when using flask run and docker-compose but not on the Cloud Run logs. On Cloud Run, those variables are equal to None.

When I don't use a .env and directly put the value of my variables inside /config/settings.py, there is no issues and my Cloud Run link is working correctly. I also tried to moved .env outside of the config file and in few other locations but I still got the same issue.

.
├── 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'
                              
like image 992
Pierre-Alexandre Avatar asked Apr 05 '21 09:04

Pierre-Alexandre


People also ask

Where do I put the .env file?

env file is placed at the base of the project directory. Project directory can be explicitly defined with the --file option or COMPOSE_FILE environment variable.


1 Answers

Fixed, I found exactly what went wrong but I do not know why.

  • It worked when I build my own image before to push the image on GCP container registry following those steeps:

      docker-compose up --build
      docker tag 52e6159b6b13 gcr.io/mousset005/zoro
      gcloud auth configure-docker
      docker push gcr.io/mousset005/zoro
    

However, what I was doing is building my Image using GCP API (which is what they recommend in the Cloud Run Python quickstart) using that command:

gcloud run deploy --image gcr.io/mousset005/zoro --platform managed
like image 186
Pierre-Alexandre Avatar answered Oct 31 '22 20:10

Pierre-Alexandre