Docker RUN 安装在 ubuntu 中不存在

Docker RUN 安装在 ubuntu 中不存在

我有以下 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"]

尽管在第二个 RUN 命令中安装了 Java,但当我连接终端并运行时,which java却什么也没有得到。同样,$JAVA_HOME 也不存在等等。Java 去哪儿了?我需要在这个容器中做哪些更改才能使 Java 不消失?

答案1

这个 Dockerfile 存在很多问题,简直不知道从何说起。

首先,高层次的问题:你正试图使用​​ 启动守护进程RUN。这行不通。RUN构建时命令。它将运行一次,当图像被创建时。它将不是从此映像启动容器时运行。如果您希望容器运行某些内容,则它必须位于ENTRYPOINT或中CMD。它必须在前台运行。

接下来,关于分层。您应该在 Dockerfile 中对构建时命令进行排序,以便不经常更改的步骤和“基本”步骤首先出现。这意味着所有apt内容,基本配置(例如添加用户以及安装 Filebeat)。接下来应该做什么最后的是类似于 Filebeat 配置文件的东西。这样,当您更改配置文件时,只需重建单个层。

关于sudo:如果你允许用户使用做任何事情sudo,你不妨只使用直接。安全优势充其量只是微不足道的。对于您来说,根本不需要sudo:只需先进行系统操作,将 Filebeat 安装到用户无法写入的位置,也许还可以使配置文件仅可读。然后让 Docker 使用受限用户启动 Filebeat。

现在来看看实际问题:切勿在命令中使用nohup或。& 符号会影响&RUN整个命令前面的那个将不会运行完成,而是会立即被终止,因为构建步骤已经“完成”。

你也应该使用默认 jdk-headless顺便说一句,其他一切都是浪费空间。

你的 Dockerfile 可能如下所示:

FROM ubuntu:22.04
RUN apt update \
    && apt install -y curl default-jdk-headless vim \
    && adduser --disabled-password --gecos '' docker \
    && cd /opt \
    && curl -SL -o filebeat.tar.gz https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.3.3-linux-x86_64.tar.gz \
    && mkdir filebeat \
    && tar --strip-components 1 -xf filebeat.tar.gz -C filebeat/ \
    && rm filebeat.tar.gz \
    && rm -rf /var/lib/apt/lists/*

COPY filebeat.yml /etc/filebeat.yml
USER docker
ENTRYPOINT ["/opt/filebeat/filebeat", "-c", "/etc/filebeat.yml"]

另请查看编写 Dockerfile 的最佳实践

相关内容