Bugzilla容器以代码0无错退出,求排查方案及日志查看方法
首先,先解决你最关心的查看已退出容器日志的问题——这个操作很简单,Docker会保留所有容器的日志记录,哪怕容器已经停止,直接用docker logs命令就能调取:
# 查看bugzilla容器的完整日志 docker logs bugzilla # 只查看最后50行日志,适合日志内容较多的场景 docker logs --tail 50 bugzilla # 过滤包含错误关键词的行,快速定位问题 docker logs bugzilla | grep -i error
接下来分析你的Bugzilla容器为什么会以代码0退出:
核心原因:容器没有长期运行的进程
你的Bugzilla容器设置的CMD是perl ./checksetup.pl,ENTRYPOINT是perl ./testserver.pl http://localhost/bugzilla——这两个都是一次性执行的脚本,运行完成后就会自动退出,容器自然也跟着停止(退出代码0表示脚本执行成功,没有抛出错误)。
除此之外,你的架构设计和配置还存在几个关键问题:
1. Apache无法访问Bugzilla代码
你把Bugzilla的代码挂载到了Bugzilla容器的/var/www/html/目录,但Apache容器挂载的是自己的./apache/目录,这意味着Apache完全看不到Bugzilla的代码,根本无法提供Web服务。
2. 缺少MySQL就绪检查
depends_on只是保证MySQL容器启动了,但不代表MySQL服务已经可以接受连接。checksetup.pl需要连接数据库完成初始化配置,如果MySQL还没就绪,脚本可能会跳过关键步骤(这也是你看不到错误但容器退出的可能原因之一)。
3. 未传递数据库连接配置
Bugzilla需要知道MySQL的地址、用户名、密码等信息,你需要把mysql.env里的环境变量传递给Bugzilla容器,或者在checksetup.pl运行前配置好localconfig文件。
修正方案
方案一:调整架构,共享代码卷并添加初始化逻辑
修改docker-compose.yml,用命名卷共享Bugzilla代码给Apache,让Bugzilla容器只负责初始化配置,同时等待MySQL完全就绪:
version: "3.2" services: bugzilla: build: './bugzilla/' container_name: bugzilla networks: - bugzilla-network volumes: - bugzilla-code:/var/www/html/bugzilla # 用命名卷共享代码给Apache depends_on: mysql: condition: service_healthy # 等待MySQL服务完全就绪 environment: # 传递数据库连接信息,需和mysql.env里的内容保持一致 - DB_HOST=mysql - DB_NAME=bugzilla - DB_USER=bugzilla_user - DB_PASS=bugzilla_password # 先等待MySQL,再自动执行初始化脚本 command: > sh -c "until mysql -h$DB_HOST -u$DB_USER -p$DB_PASS -e 'SELECT 1'; do sleep 2; done; perl checksetup.pl --answer-accept-all --no-httpd-restart" restart: on-failure apache: build: './apache/' container_name: bugzilla-apache depends_on: - bugzilla networks: - bugzilla-network ports: - "8080:80" volumes: - bugzilla-code:/var/www/html/bugzilla # 共享Bugzilla代码 - ./apache/sites-available/:/etc/apache2/sites-available/ # 挂载Apache配置文件 restart: unless-stopped mysql: container_name: bugzilla-mysql env_file: - ./mysql/mysql.env networks: - bugzilla-network image: mysql command: --default-authentication-plugin=mysql_native_password restart: unless-stopped # 添加健康检查,确保MySQL服务就绪 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 5s timeout: 5s retries: 5 volumes: bugzilla-code: # 定义命名卷 networks: bugzilla-network: driver: bridge
同时修改Bugzilla的Dockerfile,去掉ENTRYPOINT和CMD,只负责安装依赖和复制代码:
FROM ubuntu:18.04 RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -q -y supervisor gcc \ apache2 mysql-client \ libapache2-mod-perl2 libmysqlclient-dev libmath-random-isaac-perl \ liblist-moreutils-perl libencode-detect-perl libdatetime-perl \ msmtp msmtp-mta libnet-ssleay-perl libcrypt-ssleay-perl \ libappconfig-perl libdate-calc-perl libtemplate-perl build-essential \ libdatetime-timezone-perl libdatetime-perl libemail-sender-perl libemail-mime-perl \ libemail-mime-modifier-perl libdbi-perl libdbd-mysql-perl libcgi-pm-perl \ libmath-random-isaac-perl libmath-random-isaac-xs-perl \ libapache2-mod-perl2 libapache2-mod-perl2-dev libchart-perl libxml-perl \ libxml-twig-perl perlmagick libgd-graph-perl libtemplate-plugin-gd-perl \ libsoap-lite-perl libhtml-scrubber-perl libjson-rpc-perl libdaemon-generic-perl \ libtheschwartz-perl libtest-taint-perl libauthen-radius-perl libfile-slurp-perl \ libencode-detect-perl libmodule-build-perl libnet-ldap-perl libauthen-sasl-perl \ libfile-mimeinfo-perl libhtml-formattext-withlinks-perl \ libgd-dev graphviz python-sphinx patch && \ rm -rf /var/lib/apt/lists/* WORKDIR /var/www/html/bugzilla COPY . .
最后在Apache的配置文件(比如000-default.conf)里添加Bugzilla的路由规则:
Alias /bugzilla /var/www/html/bugzilla <Directory /var/www/html/bugzilla> AddHandler cgi-script .cgi Options +Indexes +ExecCGI DirectoryIndex index.cgi AllowOverride All </Directory>
方案二:合并Bugzilla与Apache到同一个容器(更简单)
把Bugzilla和Apache放在同一个容器里是更常规的做法,能避免跨容器的代码共享问题。你可以修改Dockerfile,配置好Apache后,用一个初始化脚本先完成Bugzilla配置,再启动Apache:
Dockerfile:
FROM ubuntu:18.04 RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -q -y supervisor gcc \ apache2 mysql-client \ libapache2-mod-perl2 libmysqlclient-dev libmath-random-isaac-perl \ liblist-moreutils-perl libencode-detect-perl libdatetime-perl \ msmtp msmtp-mta libnet-ssleay-perl libcrypt-ssleay-perl \ libappconfig-perl libdate-calc-perl libtemplate-perl build-essential \ libdatetime-timezone-perl libdatetime-perl libemail-sender-perl libemail-mime-perl \ libemail-mime-modifier-perl libdbi-perl libdbd-mysql-perl libcgi-pm-perl \ libmath-random-isaac-perl libmath-random-isaac-xs-perl \ libapache2-mod-perl2 libapache2-mod-perl2-dev libchart-perl libxml-perl \ libxml-twig-perl perlmagick libgd-graph-perl libtemplate-plugin-gd-perl \ libsoap-lite-perl libhtml-scrubber-perl libjson-rpc-perl libdaemon-generic-perl \ libtheschwartz-perl libtest-taint-perl libauthen-radius-perl libfile-slurp-perl \ libencode-detect-perl libmodule-build-perl libnet-ldap-perl libauthen-sasl-perl \ libfile-mimeinfo-perl libhtml-formattext-withlinks-perl \ libgd-dev graphviz python-sphinx patch && \ rm -rf /var/lib/apt/lists/* # 启用Apache需要的模块 RUN a2enmod cgi rewrite perl # 复制Apache配置文件 COPY apache-config/000-default.conf /etc/apache2/sites-available/ # 复制Bugzilla代码 WORKDIR /var/www/html/bugzilla COPY bugzilla/ . # 复制初始化脚本并赋予执行权限 COPY init.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/init.sh ENTRYPOINT ["/usr/local/bin/init.sh"] CMD ["apache2-foreground"]
init.sh初始化脚本:
#!/bin/bash # 等待MySQL服务就绪 until mysql -h"$DB_HOST" -u"$DB_USER" -p"$DB_PASS" -e 'SELECT 1'; do echo "Waiting for MySQL to be ready..." sleep 2 done # 自动配置Bugzilla,跳过交互步骤 perl checksetup.pl --answer-accept-all --no-httpd-restart # 启动Apache,保持容器长期运行 exec "$@"
简化后的docker-compose.yml:
version: "3.2" services: bugzilla-apache: build: './' container_name: bugzilla-apache networks: - bugzilla-network ports: - "8080:80" environment: - DB_HOST=mysql - DB_NAME=bugzilla - DB_USER=bugzilla_user - DB_PASS=bugzilla_password depends_on: mysql: condition: service_healthy restart: unless-stopped mysql: container_name: bugzilla-mysql env_file: - ./mysql/mysql.env networks: - bugzilla-network image: mysql command: --default-authentication-plugin=mysql_native_password restart: unless-stopped healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 5s timeout: 5s retries: 5 networks: bugzilla-network: driver: bridge
这样调整后,容器会一直运行Apache服务,不会退出,同时自动完成Bugzilla的初始化配置。
内容的提问来源于stack exchange,提问作者Saurabh

