我的应用在 Docker 中启动时无法创建日志文件

My app can't create log files when it starts up inside Docker

我整个周末都在阅读 Docker 文档,玩弄玩具应用程序和示例项目。我现在正在尝试自己编写一个超级简单的 Web 服务,并 运行 从容器内部编写它。在容器中,我希望我的应用程序(一个 Spring 引擎盖下的引导应用程序)——称为 bootup —— 具有以下目录结构:

/opt/
    bootup/
        bin/
            bootup.jar        ==> the app
        logs/
            bootup.log        ==> log file; GETS CREATED BY THE APP @ STARTUP
        config/
            application.yml   ==> app config file
            logback.groovy    ==> log config file

非常重要的是要注意,当我 运行 我的应用程序本地在我的主机上时 - 在 Docker 之外 - 一切正常,包括创建日志文件到我的主机的 /opt/bootup/logs 目录。 应用程序端点提供正确的内容等。一切都很好,花花公子。

所以我创建了以下 Dockerfile:

FROM openjdk:8

RUN mkdir /opt/bootup
RUN mkdir /opt/bootup/logs
RUN mkdir /opt/bootup/config
RUN mkdir /opt/bootup/bin

ADD build/libs/bootup.jar /opt/bootup/bin
ADD application.yml /opt/bootup/config
ADD logback.groovy /opt/bootup/config

WORKDIR /opt/bootup/bin

EXPOSE 9200

ENTRYPOINT java -Dspring.config=/opt/bootup/config -jar bootup.jar

然后我通过以下方式构建我的图像:

docker build -t bootup .

然后我运行我的容器:

docker run -it -p 9200:9200 -d --name bootup bootup

我运行docker ps:

CONTAINER ID        IMAGE               COMMAND ...
3f1492790397        bootup              "/bin/sh -c 'java ..."

到目前为止,一切顺利!

然后我的应用程序应该在 localhost:9200 提供一个简单的网页,所以我打开浏览器 http://localhost:9200 但我什么也没得到。

当我在我的容器中使用 docker exec -it 3f1492790397 bash 到 "ssh" 时,我发现一切正常, 除了 /opt/bootup/logs 目录,它应该其中有一个 bootup.log 文件——在启动时创建——而是空的。

我尝试使用 docker attach 3f1492790397,然后在我的浏览器中点击 http://localhost:9200,看看是否会生成一些标准输出(我的应用程序同时记录到 /opt/bootup/logs/bootup.log 以及控制台) 但这不会产生任何输出。

所以我认为发生的事情是我的应用程序(出于某种原因)没有权限在容器启动时创建自己的日志文件,并将应用程序处于奇怪的状态,甚至完全无法启动。

所以我问:

提前致谢!

我不知道为什么你的应用不能运行,但可以回答你的问题-

Is there a way to see what user my app is starting up as?; or

A:Docker 个容器 运行 作为 root 除非另有说明。

Is there a way to tail standard output while the container is starting? Attaching after startup doesn't help me because I think by the time I run the docker attach command the app has already choked

A:Docker 容器默认将 stdout/stderr 转储到 Docker 日志。有两种方法可以查看这些 - 1 是 运行 带有标志 -it 而不是 -d 的容器,以获得一个交互式会话,该会话将列出容器中的标准输出。另一种是在 运行ning 或停止的容器上使用 docker logs *container_name* 命令。

docker attach 3f1492790397

这不符合您的期望。你想要的是docker exec(可能是docker exec -it bootup bash),这会给你一个容器范围内的shell,让你检查你的日志文件或尝试使用从容器内部卷曲。

Why do I get no output?

如果没有来自早期命令的信息,很难说。您的应用程序是在 0.0.0.0 上侦听还是在本地主机上侦听(您的笔记本电脑浏览器看起来就像容器的外部机器)?您的应用程序是否需要不 运行ning 的主管进程?它是否需要在您笔记本电脑的 CLASSPATH 中但不在容器中的其他一些 JAR 文件?您是否 运行ning docker 使用 Docker-Machine(在这种情况下 localhost 可能不是容器的名称)?