Eu tenho o seguinte Dockerfile:
FROM ubuntu:22.04
COPY filebeat.yml /home/docker/filebeat.yml
RUN apt update && \
apt install -y sudo curl vim && \
adduser --disabled-password --gecos '' docker && \
adduser docker sudo && \
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER docker
RUN sudo apt update && \
sudo apt install -y default-jdk && \
cd /home/docker/ && \
sudo curl -L -O --create-dirs https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.3.3-linux-x86_64.tar.gz && \
sudo tar xzvf filebeat-8.3.3-linux-x86_64.tar.gz && \
sudo nohup ./filebeat-8.3.3-linux-x86_64/filebeat -c ./filebeat.yml &
ENTRYPOINT ["tail", "-f", "/dev/null"]
Apesar do java estar instalado no segundo comando RUN, quando eu conecto um terminal e executo which java
não recebo nada. Da mesma forma $JAVA_HOME não existe etc. Para onde foi o java? O que preciso mudar neste container para que o java não desapareça?
Há tantos problemas com este Dockerfile, por onde começar.
Primeiro, o problema de alto nível: você está tentando iniciar um daemon usando
RUN
. Isso não funcionará.RUN
é um comando em tempo de construção . Ele será executado uma vez , quando a imagem for criada. Ele não será executado quando um contêiner for iniciado a partir desta imagem. Se você deseja que seu contêiner execute algo, ele deve estar emENTRYPOINT
ouCMD
. Ele deve ser executado em primeiro plano.Em seguida, sobre camadas. Você deve ordenar os comandos de tempo de compilação em seu Dockerfile de modo que as etapas de alteração esporádica e “base” venham primeiro. Isso significa todas as
apt
coisas, configuração básica como adicionar o usuário e também instalar o Filebeat. O que deve vir por último são coisas como o arquivo de configuração do Filebeat. Dessa forma, quando você altera o arquivo de configuração, apenas uma única camada precisa ser reconstruída.Sobre
sudo
: Se você permitir que seu usuário faça qualquer coisa usandosudo
, você pode usar root diretamente. Os benefícios de segurança serão marginais, na melhor das hipóteses. No seu caso, não há necessidade desudo
nada: apenas faça as coisas do sistema primeiro, instale o Filebeat em um local que não possa ser gravado pelo usuário e, talvez, também torne o arquivo de configuração apenas legível. Em seguida, faça o Docker iniciar o Filebeat com o usuário limitado.E agora para o problema real : nunca use
nohup
ou&
em umRUN
comando. O e comercial afetará todo o comando na frente, que não será executado até a conclusão e, em vez disso, será eliminado imediatamente porque a etapa de compilação está "concluída".A propósito, você também deve usar default-jdk-headless , todo o resto é um desperdício de espaço.
Seu Dockerfile pode ficar assim:
Confira também as práticas recomendadas para escrever Dockerfiles .