Python lança KeyError ao exportar variáveis ​​de ambiente

Python lança KeyError ao exportar variáveis ​​de ambiente

Eu tenho um caso estranho em que tenho um arquivo secret.env onde defino todas as minhas variáveis ​​de ambiente como tal:

segredo.env

export TWITTER_CONSUMER_KEY="something"
export TWITTER_CONSUMER_SECRET="something"

Então criei um arquivo docker para exportar todas as variáveis ​​e executar o aplicativo como tal:

FROM python:3.8-slim-buster

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install the dependencies
RUN pip install -r requirements.txt

RUN find . -name \*.pyc -delete

# Export all variables
RUN /bin/bash -c "source secret.env";

# tell the port number the container should expose
EXPOSE 8083

# run the command
ENTRYPOINT ["python", "run.py"]

No entanto, isso está gerando um erro importante:

$ docker run --name fortweet --rm -i -t fortweet:latest bash
Traceback (most recent call last):
  File "run.py", line 1, in <module>
    from app import socketio, app
  File "/app/app/__init__.py", line 65, in <module>
    app = create_app()
  File "/app/app/__init__.py", line 38, in create_app
    my_settings = settings.TwitterSettings.get_instance()
  File "/app/app/setup/settings.py", line 47, in get_instance
    TwitterSettings()
  File "/app/app/setup/settings.py", line 14, in __init__
    self.consumer_key = os.environ["TWITTER_CONSUMER_KEY"]
  File "/usr/local/lib/python3.8/os.py", line 675, in __getitem__
    raise KeyError(key) from None
KeyError: 'TWITTER_CONSUMER_KEY'

Quando executo isso no meu Windows, funciona bem!

Alguém pode me ajudar com isso ?

Responder1

Altere a linha final para:

ENTRYPOINT ["/bin/bash", "-c", "source secret.env ; python run.py"]

em vez disso, e remova o RUNlocal onde você está realizando a aquisição. Veja tambémhttps://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/para obter uma explicação da diferença RUNentre CMDe ENTRYPOINT.

Resumindo:

  • RUN executa comando(s) em uma nova camada e cria uma nova imagem. Por exemplo, é frequentemente usado para instalar pacotes de software.
  • O CMD define comandos e/ou parâmetros padrão, que podem ser substituídos na linha de comando quando o contêiner do docker é executado.
  • ENTRYPOINT configura um contêiner que será executado como executável.

Não sou um especialista em docker, mas já o usei em meu trabalho algumas vezes, portanto, tenho algum conhecimento básico sobre ele. Acho que a razão pela qual isso funciona é por causa das camadas e, mais importante, porque a ação de obter variáveis ​​de ambiente ocorre puramente apenas no domínio da memória, e não no armazenamento em disco. Portanto, o fornecimento sob um RUN na verdade não alcança nada. Você precisa obtê-los no ponto de execução do seu aplicativo real, e é por isso que a correção ENTRYPOINT acima funciona, porque estamos invocando o BASH, fornecendo as variáveis ​​no ambiente e, em seguida, bifurcando seu aplicativo python, tudo no mesmo shell, em tempo de execução.

No entanto, isso ainda não explica por que funciona no seu ambiente Windows - minha suspeita é que você tem as variáveis ​​de ambiente definidas em algum lugar do seu ambiente Windows, então isso tem funcionado para você, mas não pelo motivo que você acha que funcionou.

informação relacionada