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 RUN
local 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 RUN
entre CMD
e 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.