You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Pipeline SSH部署Docker容器后自动退出的问题咨询

容器通过Azure Pipeline SSH部署后自动退出的问题排查与优化方案

问题概述

通过Azure Pipeline完成应用容器镜像构建并推送到私有镜像仓库后,使用SSH任务连接目标VM执行docker run -d启动容器。容器能正常启动并监听端口,但运行一段时间后自动退出,容器日志显示gunicorn主进程收到SIGTERM信号后主动关闭。

排查分析

从日志和部署配置来看,docker run -d已指定后台运行容器,容器退出与SSH会话无关。核心原因是容器进程收到终止信号,可能的触发点包括:

  • 容器内主进程未正确处理系统信号(比如PID 1进程的信号转发问题)
  • 目标VM的系统进程管理工具(如systemd)或定时任务误杀容器进程
  • 容器资源耗尽(但日志未体现OOM等相关信息)

解决方案

1. 确保容器进程以正确方式运行

检查Dockerfile的CMD/ENTRYPOINT配置,确保gunicorn以前台方式启动,避免使用&将进程放入后台(Docker需要主进程保持前台运行,否则会认为容器任务完成而退出)。示例正确配置:

# Dockerfile示例
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]

2. 配置Docker自动重启容器

在docker run命令中添加--restart always参数,让Docker在容器意外退出时自动重启:

docker run -d --restart always --name $(APPLICATION_NAME) -p 5000:5000 "$DOCKER_IMAGE"

3. 使用systemd管理容器生命周期

如果目标VM基于systemd(大多数Linux发行版默认),将容器注册为systemd服务,由系统负责监控和自动恢复,彻底避免进程被误杀或意外退出的问题:
修改Azure Pipeline的SSH任务命令如下:

echo "started executing commands"
export DOCKER_IMAGE="$(DOCKER_CONTAINER_REGISTRY)/$(APPLICATION_NAME):$(APP_VERSION)"
docker login -u $(azure_username) -p $(azure_password) $(DOCKER_CONTAINER_REGISTRY)
docker pull $DOCKER_IMAGE

# 停止并清理旧容器(如果存在)
PREVIOUS_CONTAINER=$(docker ps -aq --filter "name=$APPLICATION_NAME")
if [ ! -z "$PREVIOUS_CONTAINER" ]; then
  docker stop "$PREVIOUS_CONTAINER" || true
  docker rm "$PREVIOUS_CONTAINER" || true
fi

# 生成systemd服务文件
cat > /etc/systemd/system/$(APPLICATION_NAME).service << EOF
[Unit]
Description=$(APPLICATION_NAME) Container Service
After=docker.service
Requires=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker run --name $(APPLICATION_NAME) -p 5000:5000 "$DOCKER_IMAGE"
ExecStop=/usr/bin/docker stop -t 10 $(APPLICATION_NAME)
ExecStopPost=/usr/bin/docker rm -f $(APPLICATION_NAME)

[Install]
WantedBy=multi-user.target
EOF

# 重新加载systemd配置并启动服务
systemctl daemon-reload
systemctl restart $(APPLICATION_NAME).service
systemctl enable $(APPLICATION_NAME).service

4. 优化镜像的信号处理

使用tini作为容器的init进程,解决PID 1进程无法正确转发信号的问题。在Dockerfile中添加以下内容:

RUN apt-get update && apt-get install -y --no-install-recommends tini
ENTRYPOINT ["tini", "--"]
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]

更优实现方式

  1. 使用Docker Compose管理部署:将容器配置写入docker-compose.yml,简化部署命令,同时便于扩展服务:
# docker-compose.yml
version: '3.8'
services:
  myapp:
    image: ${DOCKER_IMAGE}
    ports:
      - "5000:5000"
    restart: always

在SSH任务中执行docker-compose up -d完成部署。

  1. 替换SSH任务为专用部署工具:如果目标VM是Azure VM,可使用Azure Pipeline的Azure VM Deployment任务,或者借助Ansible等配置管理工具实现更可靠的部署流程,避免直接执行SSH命令的维护成本。

内容的提问来源于stack exchange,提问作者Manish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:05:15