I have a containerised app
|-- project
|-- app
|-- main.py
|-- settings.py
|-- Dockerfile
|-- requirements.txt
|-- .env
|-- docker-compose-dev.yaml
I have set environment variables in .env. I use the 'environment:' section in docker-compose-dev.yaml to pass them to the app container, I access them in settings.py and then import them into main.py. They do not seem to be being picked up by the app, but docker-compose docker-compose-dev.yaml config shows them being pulled from .env.
.env
REDIS_HOST=redis
REDIS_PORT=6379
docker-compose-dev.yaml
version: "3.2"
services:
app:
build: ./app
container_name: app
environment:
- REDIS_HOST:$REDIS_HOST
- REDIS_PORT:$REDIS_PORT
Running docker-compose -f docker-compose-dev.yaml config gives:
services:
collector:
build:
context: /project/app
container_name: app
environment:
REDIS_HOST:redis: null
REDIS_PORT:6379: null
app/Dockerfile
FROM python:3.8.7-buster
WORKDIR /app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV USE_DOCKER=true
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
CMD ["python", "main.py"]
app/settings.py
import os
import dotenv
BASE_DIR = os.path.dirname(
os.path.dirname(
os.path.abspath(__file__)
)
)
dotenv_file = os.path.join(BASE_DIR, ".env")
if os.path.isfile(dotenv_file):
print(dotenv_file)
dotenv.load_dotenv(dotenv_file)
#load_dotenv()
REDIS_HOST = os.environ.get('REDIS_HOST', None)
REDIS_PORT = os.getenv('REDIS_PORT', None)
print(REDIS_HOST)
print(REDIS_PORT)
app/main.py
import logging
import settings
import redis
def main():
logging.info("redis host: %s", settings.REDIS_HOST)
logging.info("redis port: %s", settings.REDIS_PORT)
r = redis.Redis(host=settings.REDIS_HOST,
port=settings.REDIS_PORT,
db=0,
)
if __name__ == "__main__":
main()
If I run this locally, outside of Docker, then main.py does what I expect: print() and logging.info() both show REDIS_HOST = redis, REDIS_PORT = 6379.
If I run this using docker-compose -f docker-compose-dev.yaml up --build then main.py logs REDIS_HOST and REDIS_PORT as None.
If I include print(os.environ) in main.py and then spin it up with docker-compose, it shows the environment variables declared in the Dockerfile (PYTHONBUFFERED, USE_DOCKER), but not those referenced in docker-compose-dev.yaml (REDIS_HOST, REDIS_PORT).
The 'null's after the variables in the config output give me pause for thought, but I cannot find an explanation for them anywhere.
Any suggestions for what I'm overlooking would be welcome. I have a very similar set-up on another project which works smoothly, so I'm stumped about what's causing this.