I am currently struggling to persist environment variables through my DevOps deployment pipeline to Azure App Service.
I am deploying a Django app on Azure App Service with Docker containers and Azure's Container Registry. The containers are built on Azure DevOps and pushed to the registry via a release pipeline. I need to keep a few environment variables secret since the app will connect to our Azure Cosmos DB, and I'm doing so by using a tokenized .env file. The variables are kept secret and added to my '.env-prod' file with pipeline variables and the Replace Tokens DevOps task during the build.
Here is what my '.env-prod' file looks like:
PRODUCTION_KEY=#{{PRODUCTION_KEY}}#
AZURE_DB=#{{AZURE_DB}}#
AZURE_CONNECT=#{{AZURE_CONNECT}}#
...
The tokens are getting properly replaced during the build on DevOps, and the build executes without errors to push containers to our Azure container registry.
Now the problem arises when I launch the app on App Service via the docker compose script also used to build the containers. Here is the backend-service in my compose file which builds and runs the Django app:
backend-service:
env_file: backend_folder/.env-prod
build: backend_folder
# Container registry name in Azure
image: **.azurecr.io/**:0.1.1
volumes:
- static:/app/static
command: gunicorn django_proj.wsgi:application --chdir django_proj --bind 0.0.0.0:8001
expose:
- 8001
The static files are created via the CMD python manage.py collectstatic --no-input
command in my Docker file. There is also an nginx and a frontend service to serve our website, but they do not reference the .env file.
When I launch my App Service, the variables seem not to be loaded to the backend service when starting the app. I've also added the same variables to my Application Settings in the App Service, but I'm still encountering errors that indicate to me the variables were not set.
Here is a snapshot from my container log stream which describes the error:
2021-06-02 INFO - Container logs from backend-service = 2021-06-02 [2021-06-02] [INFO] Starting gunicorn 20.1.0 2021-06-02 [2021-06-02] [INFO] Listening at: http://0.0.0.0:8001 (1) 2021-06-02T2 [2021-06-02] [6] [ERROR] Exception in worker process 2021-06-02 Traceback (most recent call last):
...
2021-06-02 File "/app/django_proj/settings.py", line 116, in <module>
2021-06-02 connect(os.environ['AZURE_DB'], host=os.environ['AZURE_CONNECT'])
...
2021-06-02 pymongo.errors.InvalidURI: Invalid URI scheme: URI must begin with 'mongodb://' or 'mongodb+srv://'
It seems like my AZURE_CONNECT
variable is not being set in our running App Service backend container.
- How can I securely persist the secret environment variables in my compose script so they are present during both my build step in Azure DevOps and the run step in the Azure App Service?
- Is there another way to serve the static files via gunicorn so the environment variables are only referenced during the build step and not when launching the App Service?
Here is the closest related question I found to my issue, but we differ in that we are using multiple environment variables on Azure App Service and not Heroku. Also, I have no issues running the site on my local machine if I use my private .env file without tokens.