1

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.

0

1 Answer 1

2

The reason is that the compose yaml lacks spaces between the name and the value from the .env file and also take out the dashes:

environment:
  REDIS_HOST: $REDIS_HOST
  REDIS_PORT: $REDIS_PORT
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.