Docker中运行C++二进制文件无输出/输入且容器挂起问题
Docker中C++二进制容器挂起、stdout无输出问题解决
环境与配置
Dockerfile构建阶段
FROM ubuntu:focal as builder WORKDIR /var/lib/project RUN cmake ... && make ...
Dockerfile最终镜像阶段
WORKDIR /var/lib/project COPY --from=builder /usr/src/project/bin/binary ./binary EXPOSE 8080 CMD ["./binary"]
镜像构建命令
docker build . --platform=linux/amd64 --file docker/Dockerfile --progress=plain -c 32 -t mydocker:latest
问题现象
- 执行
docker run -d启动容器时,容器无任何输出且挂起,只能通过其他终端强制终止 - 用
docker exec进入容器shell后,手动运行二进制文件可正常工作 - 二进制进程作为PID1运行时,
std::printf无输出,仅当注释server->Serve()或输出内容填满缓冲区时才会显示内容
已尝试的无效配置
先后测试以下CMD/ENTRYPOINT组合,均无法解决问题:
CMD ["/bin/bash", "-c" , "./binary"] CMD ["/bin/bash", "-c" , "exec", "./binary"]
补充信息
- C++编译参数:
CXX_FLAGS= -fno-builtin-memcmp -fPIC -Wfatal-errors -w -msse -msse4.2 -mavx2 - 核心服务代码(基于Apache Arrow 10.0.1):
int main() { arf::Location srv_loc = arf::Location::ForGrpcTcp("127.0.01", 8080).ValueUnsafe(); arf::FlightServerOptions opt(srv_loc); auto server = std::make_unique<MyService>(); ARROW_RETURN_NOT_OK(server->Init(opt)); std::printf("Starting on port: %i\n", server->port()); return server->Serve().ok(); }
问题根因
当二进制进程作为容器的PID1运行时,会触发Linux系统的特殊行为:
- 信号处理异常:PID1不会自动转发
SIGTERM等终止信号,导致容器无法正常停止,表现为"挂起" - stdout缓冲模式异常:PID1的标准输出默认是全缓冲,而非交互式进程的行缓冲,因此
printf的内容不会立刻输出到主机终端,直到缓冲区填满或进程退出
解决方案
方案1:在Dockerfile中集成init进程(替代docker run --init)
通过安装tini工具(Docker官方--init参数的底层实现),让它作为容器的PID1进程,负责信号转发、缓冲修正和僵尸进程清理。修改后的最终镜像Dockerfile如下:
FROM ubuntu:focal WORKDIR /var/lib/project # 安装tini工具 RUN apt-get update && apt-get install -y --no-install-recommends tini \ && rm -rf /var/lib/apt/lists/* COPY --from=builder /usr/src/project/bin/binary ./binary EXPOSE 8080 # 用tini作为PID1,启动二进制程序 ENTRYPOINT ["tini", "--"] CMD ["./binary"]
方案2:修改C++代码强制刷新stdout(仅解决输出问题)
如果只需要解决stdout无输出的问题,可以在printf后手动刷新缓冲区:
std::printf("Starting on port: %i\n", server->port()); fflush(stdout); // 强制刷新标准输出
但此方案无法解决信号处理和容器正常停止的问题,仅作为临时输出调试手段。
验证
构建修改后的镜像并启动:
docker run -d mydocker:latest
此时容器会正常运行,docker logs可以看到Starting on port: 8080的输出,且容器能响应docker stop命令正常终止。
内容的提问来源于stack exchange,提问作者ishkhan23
相关产品推荐
相关产品推荐

