
本文详解如何在 Azure Web App 的自定义 PHP/Apache 容器中安全启用 SSH 调试功能,重点解决因 CMD 与 ENTRYPOINT 冲突导致容器启动失败、SSH 无法连接的核心问题,并提供兼容 App Service 运行时的轻量级初始化脚本方案。
本文详解如何在 azure web app 的自定义 php/apache 容器中安全启用 ssh 调试功能,重点解决因 cmd 与 entrypoint 冲突导致容器启动失败、ssh 无法连接的核心问题,并提供兼容 app service 运行时的轻量级初始化脚本方案。
在 Azure App Service 中为自定义 Docker 容器(如基于 php:7.4-apache-bullseye 构建的 PHP 应用)启用 SSH,绝非简单安装 OpenSSH 并执行 service ssh start 即可成功。正如您所遭遇的——容器在 SSH 启动后立即退出并报错 Container didn't respond to HTTP pings on port: 80,其根本原因在于 App Service 强制要求容器主进程必须长期运行于前台(foreground),且唯一监听应用端口(默认 80/8080)的进程必须是健康检查的目标。而您原始 Dockerfile 中的 CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"] 在引入 ENTRYPOINT ["init.sh"] 后被覆盖,若 init.sh 执行完 service ssh start 后即退出(无持续前台进程),整个容器便会终止,导致应用启动失败。
✅ 正确解法:将 SSH 初始化与主服务(Supervisor)统一纳入单个前台入口点,确保容器生命周期由 Supervisor 全权管理。以下是经过生产验证的推荐方案:
✅ 步骤 1:精简并重写 init.sh(使用 /bin/sh,避免 Bash 依赖)
#!/bin/sh set -e # 生成 SSH 主机密钥(必需,否则 sshd 启动失败) ssh-keygen -A # 确保 /var/run/sshd 目录存在(sshd 运行时必需) mkdir -p /var/run/sshd echo "Starting SSH daemon..." # 启动 SSH 作为后台服务(由 Supervisor 统一管理更佳,此处为快速生效) /usr/sbin/sshd -D & echo "Starting Supervisor..." # 关键:以前台模式(-n)启动 supervisord,使其成为 PID 1 进程 exec /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
⚠️ 注意事项:
- 必须使用
#!/bin/sh(非#!/bin/bash),因 App Service 基础镜像可能不包含完整 Bash;ssh-keygen -A是强制步骤,缺失将导致sshd拒绝启动;exec启动supervisord确保其接管 PID 1,避免僵尸进程和信号转发问题;- 移除原 Dockerfile 中的
CMD指令,仅保留ENTRYPOINT ["init.sh"]。
✅ 步骤 2:更新 Dockerfile(移除冲突指令,精简配置)
# ... 其他构建步骤(RUN apt-get, COPY, ln -s 等)保持不变 ... # 移除原 CMD 行! # CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"] # 复制修正后的 init.sh(确保有执行权限) COPY init.sh /usr/local/bin/init.sh RUN chmod +x /usr/local/bin/init.sh # 设置 ENTRYPOINT(唯一入口) ENTRYPOINT ["init.sh"]
✅ 步骤 3:验证与连接 SSH
部署新镜像后,通过 Azure CLI 建立隧道并连接:
# 创建远程连接隧道(替换为您的实际参数)
az webapp create-remote-connection \
--subscription "your-sub-id" \
--resource-group "rg-name" \
--name "webapp-name" \
--port 2222
# 输出示例:
# Opening tunnel on addr: 127.0.0.1
# Opening tunnel on port: 2222
# SSH is available { username: root, password: Docker! }
# 新终端中连接(使用输出的端口)
ssh root@127.0.0.1 -p 2222 -o StrictHostKeyChecking=no
# 输入密码:Docker!
? 故障排查关键点
-
容器日志优先看:
az webapp log tail -n webapp-name,重点关注sshd启动失败或supervisord未启动的错误; -
禁止在 Portal 配置 Startup Command:App Service 会覆盖容器内
ENTRYPOINT,导致 SSH 初始化失效; -
存储挂载路径权限:
.png返回 400 错误大概率是 Apache 无权读取/var/www/data_persistent/maps,请在 SSH 中执行:ls -ld /var/www/data_persistent/maps ls -l /var/www/data_persistent/maps/ # 确保 apache 用户(www-data)有读取权限,必要时运行: chown -R www-data:www-data /var/www/data_persistent/maps chmod -R 755 /var/www/data_persistent/maps
通过以上配置,您将获得一个稳定运行、支持 SSH 调试且完全符合 Azure App Service 容器生命周期规范的自定义 PHP 应用环境。核心原则始终是:让 Supervisor 成为唯一的前台进程管理者,SSH 仅作为其托管的服务之一,而非独立竞争者。











