squ*_*ket 4 exec sh tee docker docker-compose
我正在尝试将应用程序的输出记录到文件和标准输出中。仅将输出记录到 stdout 并仅将输出记录到文件有效,但是两者的组合无法按预期工作。
以下是 docker-compose.yml 的简化版本和启动脚本。
docker-compose.yml:
version: "3.8"
services:
web:
image: node:14
command: sh "/app/scripts/init-app.sh"
init: true
volumes:
- ./:/app
Run Code Online (Sandbox Code Playgroud)
初始化应用程序.sh:
#!/usr/bin/env sh
# Exit script immediately if a command exits with a non-zero status.
set -e
# Install and configure app
[...]
# Start app
exec ./app
Run Code Online (Sandbox Code Playgroud)
上面的配置有效,但仅输出到标准输出。
修改#1(初始化脚本的最后一行):
# Start app and log output to file
exec ./app >> "/app/log.txt" 2>&1
Run Code Online (Sandbox Code Playgroud)
此配置也有效,将输出记录到文件,但不记录到标准输出。
修改#2(初始化脚本的最后一行):
# Start app and log output to both a file and stdout
exec ./app 2>&1 | tee -a "/app/log.txt"
Run Code Online (Sandbox Code Playgroud)
这可以正确输出到文件和标准输出,但它会破坏容器的启动/停止功能。
详细信息:尽管使用 调用exec,但./app在使用 调用时不会以 PID 1 运行tee。这是一个问题,因为当容器停止时(通过 CLI 或 GUI),docker 会向 PID 为 1 的进程发送停止信号。该./app进程不会收到该信号,因此./app不会停止。
如何在不破坏启动/停止功能的情况下将输出记录到文件和标准输出?
// 编辑:修复修改#1
// Edit2: 将“init: true”添加到 docker-compose.yml
我听说过一个最佳实践:
如果我应用这个,docker应该是唯一负责管理这个流的人。
如果您接受这个原则,您可以只使用启动脚本
exec ./app
Run Code Online (Sandbox Code Playgroud)
你可以通过运行来启动你的应用程序
docker-compose up web
Run Code Online (Sandbox Code Playgroud)
如果需要,可以使用 control-c。
您可以在另一个终端中访问日志并将其重定向到文件
docker-compose logs -f web > web.log
Run Code Online (Sandbox Code Playgroud)
我没有看到用例,但如果您想同时启动和记录到标准输出并始终记录到文件,那么
# run and detach
docker-compose up -d web
# save logs to a file in the background
docker-compose logs -f web > web.log 2>&1 &
# reattach to the container to be able to do control-c
# it will not rerun the container, just reattach
docker-compose up web
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13636 次 |
| 最近记录: |