资讯详情

资讯详情

手把手教你用Dockerfile构建MySQL 8.4自定义镜像

说实话用Dockerfile自己构建MySQL镜像这件事听起来像是“官方镜像都现成的何必重复造轮子”但真做过的朋友都知道官方镜像在某些场景下就是不够用。比如公司要求统一走内部镜像仓库比如CentOS环境里需要特定glibc版本兜底比如你希望镜像里默认就带上初始化脚本和自定义配置再比如你的应用需要一个内置了指定插件和参数的MySQL 8.4环境——这些时候手写Dockerfile就是刚需。这篇文章就以“基于Ubuntu/CentOS基础镜像手动构建MySQL 8.4自定义镜像”为主线把Dockerfile的设计思路、关键指令、初始化机制和坑点一次说清楚。我会贴出可以直接抄作业的完整Dockerfile和构建指令也会把为什么这样写、为什么踩坑的底层逻辑掰开揉碎讲。适合刚接触容器化但已经能看懂Dockerfile基本语法的读者也适合想摆脱官方镜像束缚、自己做基础镜像运维的同行。1. 这次折腾的基本盘为什么要自己构建MySQL 8.4镜像1.1 官方镜像确实香但自定义镜像解决的是“最后一公里”mysql/mysql-server:8.4这类官方镜像本身质量很高开箱即用。它的默认配置、目录结构、入口脚本都经过大量验证Pull下来就能跑。可实际情况往往是我要的不是“一个能跑的MySQL”而是“一个符合我团队规范的MySQL”。举个例子官方镜像默认的mysqld参数很多是“能用但性能平庸”的取值生产环境肯定要调innodb_buffer_pool_size、max_connections。这些参数你可以在运行时挂载配置文件进去但如果是几十台机器、成百上千个环境通过-v挂载配置文件的方式就显得很散。把配置直接烤进镜像或者通过环境变量驱动启动脚本去生成配置这才是镜像该有的“自包含”姿态。另一个常见诉求是基础镜像的统一管理。很多企业现在都要求基础镜像必须统一全用Ubuntu就全用Ubuntu全用CentOS就全用CentOS。这时候你直接拿官方MySQL镜像它底层是什么发行版、什么版本、带什么依赖你无法把控。自己构建从基础镜像开始就是可控的。1.2 Ubuntu路线和CentOS路线的选择逻辑标题把Ubuntu和CentOS都点了出来不是没有原因的。这两条路线的差异比想象中大主要集中在几个地方包管理器的差异直接影响Dockerfile写法。Ubuntu用aptCentOS用yum安装MySQL官方仓库的步骤完全两套。这不光是命令不同还涉及仓库配置文件的路径、GPG密钥的导入方式、依赖包名称的差异。比如Ubuntu上安装mysql-community-server会自动拉起libaio1等依赖CentOS 7上可能还需要手动补libaio和numactl-libs。glibc版本的差异也很关键。CentOS 7的glibc是2.17Ubuntu 22.04的glibc是2.35。MySQL 8.4的官方二进制包对glibc版本有要求更老的CentOS 7在安装新版MySQL时偶尔会遇到“版本过旧”的警告或运行时的莫名崩溃这就是glibc说事。所以选CentOS路线我一般建议直接用CentOS 7的官方仓库包不要自己去编译源码否则会被依赖问题折腾到怀疑人生。维护状态的差异是2025年绕不开的现实。CentOS 7的生命周期已经走到了尽头各软件源也在逐步清退旧包。如果新项目还在坚持CentOS 7我会诚实地劝一句尽量迁移到Rocky Linux或AlmaLinux。本文里CentOS路线的Dockerfile我依然给出因为存量场景确实还有但你的新环境建议看Ubuntu路线或者把基础镜像换成Rocky Linux 9。1.3 MySQL 8.4和之前版本的关键差异Docker化时要知道MySQL 8.4是LTS版本注意它不是8.0的简单升级而是“当前创新版精简后再固化”的产物所以有几个点直接影响到Docker镜像的构建方式默认认证插件是caching_sha2_password如果你有老应用用mysql_native_password连库镜像里就需要显式兼容配置或者应用端升级驱动。部分旧参数被移除或改名比如innodb_file_format这类早期参数在8.4里已经没了。Dockerfile里如果残留了这些参数mysqld会直接启动失败。官方包仓库的命名从mysql80-community变成了mysql84-community安装时注意仓库名别搞混yum repolist看到的名字就是mysql84-community。8.4版本对系统表空间、redo log容量等默认值做了调整你自定义my.cnf时最好基于8.4的默认值去微调别拿8.0的模板硬套。2. Dockerfile设计构建“能跑”的MySQL镜像要把握的关键点2.1 基础层环境变量、系统依赖和目录规划写Dockerfile跟写shell脚本很像先把环境捋顺了再谈安装。第一步是明确基础镜像的tag。Ubuntu路线我推荐ubuntu:22.04原因很朴素22.04的glibc版本、openssl版本和MySQL 8.4官方bin的兼容性已经经过大量验证24.04虽更新但不少依赖包在24.04下需要额外处理。CentOS路线就直接用centos:7官方bin就是对着它编的用别的版本反而别扭。第二步是环境变量。这些变量会在构建时被RUN指令引用也会在运行时被入口脚本读取。我习惯把MYSQL_ROOT_HOST、MYSQL_DATABASE、MYSQL_USER这些变量统一放在ENV段里给后续初始化脚本用。同时把PATH里加上MySQL的bin目录省得后面一堆绝对路径看着心烦。第三步是创建目录并规划权限。容器里跑MySQL目录结构要和官方一致省得自己在配置里猜来猜去ENV MYSQL_DATA_DIR/var/lib/mysql \ MYSQL_RUN_DIR/var/run/mysqld \ MYSQL_LOG_DIR/var/log/mysql RUN mkdir -p ${MYSQL_DATA_DIR} ${MYSQL_RUN_DIR} ${MYSQL_LOG_DIR} \ chown -R mysql:mysql ${MYSQL_DATA_DIR} ${MYSQL_RUN_DIR} ${MYSQL_LOG_DIR}别小看这一步。MySQL的mysqld进程在启动时要对datadir、socket目录、日志目录有写权限而这些目录的属主必须是执行mysqld的用户。如果你用mysql用户启动结果目录却是root的启动会报“Permission denied”。这个属于可预见的坑写进Dockerfile比事后排查省事多了。注意MySQL官方rpm/deb包装完以后会生成mysql系统用户所以基础层不需要自己useradd除非你的基础镜像特别精简。2.2 安装层MySQL官方仓库的配置技巧安装MySQL 8.4核心是要先把官方仓库装进去。Ubuntu和CentOS的仓库配置差异很明显分开看。Ubuntu 22.04安装官方仓库RUN apt-get update apt-get install -y --no-install-recommends \ wget ca-certificates lsb-release gnupg \ wget https://dev.mysql.com/get/mysql-apt-config_0.8.33-1_all.deb \ echo mysql-apt-config mysql-apt-config/select-server select mysql-8.4-lts | debconf-set-selections \ dpkg -i mysql-apt-config_0.8.33-1_all.deb \ apt-get update \ DEBIAN_FRONTENDnoninteractive apt-get install -y mysql-server \ rm -rf /var/lib/apt/lists/*这里有两个细节很容易翻车。第一debconf-set-selections这一步是必须的否则安装过程中会弹出交互式界面让你选MySQL版本容器构建遇到交互就是死等。第二如果基础镜像里没装lsb-releasemysql-apt-config脚本可能找不到系统版本信息而报错所以基础包要装齐。CentOS 7安装官方仓库RUN yum install -y https://dev.mysql.com/get/mysql84-community-release-el7-1.noarch.rpm \ yum install -y mysql-community-server \ yum clean all这条命令看起来简单但现实中会遇到GPG key验证失败这是因为官方仓库的GPG密钥在2023年换过。解决办法是导入新密钥或者临时加--nogpgcheck。但我不建议裸奔--nogpgcheck正确做法是RUN rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023然后yum install时如果还报key不匹配就把密钥文件和仓库配置里的GPG路径对齐一下。安装完成后还要顺手清理。Ubuntu的apt-get cleanCentOS的yum clean all都是为了砍掉镜像里的缓存文件。别小看这几MB积少成多最后镜像体积能差出几百MB。MySQL这种重组件构建完的镜像体积分分钟上1GB容量控制要从小处抠。2.3 初始化层入口脚本设计的核心思路官方镜像之所以好用很大程度是因为它的入口脚本帮你做了初始化首次启动时检测datadir是否为空为空就执行mysqld --initialize-insecure然后启动服务再根据环境变量创建用户和数据库。我们自定义Dockerfile也要复刻这套逻辑否则镜像只能算“装了MySQL的容器”不能算“能开箱即用的MySQL服务”。入口脚本我习惯命名为docker-entrypoint.sh功能拆成四步#!/bin/bash set -euo pipefail # 1. 配置文件生成根据环境变量动态写入 /etc/my.cnf if [ -n ${MYSQL_PASSWORDx} ]; then sed -i s/^#max_connections.*/max_connections${MYSQL_MAX_CONNECTIONS:-200}/ /etc/my.cnf fi # 2. 数据目录初始化判断是否首次启动 if [ ! -d ${MYSQL_DATA_DIR}/mysql ]; then echo Initializing MySQL data directory... mysqld --initialize-insecure --usermysql --datadir${MYSQL_DATA_DIR} fi # 3. 服务启动用 mysqld 直接前台运行 exec mysqld --usermysql --datadir${MYSQL_DATA_DIR}这段脚本有一个很关键的判断——[ ! -d ${MYSQL_DATA_DIR}/mysql ]。MySQL初始化成功后datadir下会出现名为mysql的系统库目录所以这个判断能准确区分“空数据目录”和“已初始化数据目录”。容器重启时如果datadir已经存在就跳过初始化直接启动这个机制保证了数据不会在每次重启时被清掉。初始化用的--initialize-insecure表示生成一个空的root密码然后在启动前通过SQL去设置用户。也可以直接用--initialize生成随机密码再日志里找但自动化的场景下随机密码反而增加复杂度我倾向用insecure模式然后自己在脚本里改密码。注意set -euo pipefail是必须的。-e保证任何一个命令失败都会让容器启动失败退出避免MySQL没起来容器却“活”着的假象-u防止变量未定义时静默通过pipefail让管道命令的真实错误能暴露出来。少了这个排查问题时你看到的现象会非常诡异。2.4 数据持久化VOLUME和目录权限的平衡MySQL天生是有状态服务镜像里无论如何都要把数据目录做成持久化。Dockerfile里直接声明VOLUMEVOLUME [/var/lib/mysql]声明VOLUME后docker run时不加-v数据也会落在容器可写层但无法被外部直接管理。真正要持久化还得在docker run时挂载docker run -d --name mysql84 \ -v /data/mysql:/var/lib/mysql \ -p 3306:3306 \ my-mysql:8.4这里有个权限细节宿主机上的/data/mysql目录属主默认是root而容器里的mysqld要用mysql用户写于是启动时报“cant create/write to file”。解决方法是把宿主机目录的属主改成和容器内MySQL的UID一致。MySQL官方用户的UID通常是999CentOS系或999Ubuntu系但不同发行版也可能不同。保险做法是宿主机上执行mkdir -p /data/mysql chown 999:999 /data/mysql这样容器内用户和宿主机目录权限就对齐了。如果基础镜像不同导致UID不一致在Dockerfile里显式useradd -u 1001并让数据目录属主为1001然后宿主机上chown 1001:1001 -R /data/mysql道理一样。2.5 健康检查HEALTHCHECK的实用写法镜像不能用起来就完事还要告诉编排系统“什么时候算健康”。Dockerfile里的HEALTHCHECK指令可以定时探测HEALTHCHECK --interval30s --timeout5s --start-period60s --retries3 \ CMD mysqladmin ping -h 127.0.0.1 -u$$MYSQL_USER -p$$MYSQL_PASSWORD || exit 1这里有个小坑——$$是对环境变量的转义$MYSQL_USER会留到运行时才被替换而不是在构建期就被展开。如果你写成单$构建阶段就会被当成空变量替换掉镜像里的健康检查命令就变成mysqladmin ping -h ... -u -p语法直接报错。--start-period60s很重要。MySQL首次初始化启动在性能一般的机器上可能要三十秒到一分钟如果没给足启动宽限期健康检查会一直失败然后容器被判定unhealthy。你可以在运行时用docker inspect观察状态如果反复出现unhealthy第一件事就是看启动耗时是不是超过了start-period。3. 两个可以抄作业的Dockerfile3.1 Ubuntu 22.04路线完整实现下面这个Dockerfile我实测过构建产物可以直接拉到生产跑字符集、时区、密码策略都做了合理的默认设置。FROM ubuntu:22.04 MAINTAINER devopsexample.com ENV DEBIAN_FRONTENDnoninteractive \ TZAsia/Shanghai \ MYSQL_DATA_DIR/var/lib/mysql \ MYSQL_RUN_DIR/var/run/mysqld \ MYSQL_LOG_DIR/var/log/mysql \ MYSQL_ROOT_PASSWORDroot123 \ MYSQL_DATABASEappdb \ MYSQL_USERappuser \ MYSQL_PASSWORDapp123 RUN sed -i shttp://.*archive.ubuntu.comhttp://mirrors.aliyun.comg; shttp://.*security.ubuntu.comhttp://mirrors.aliyun.comg /etc/apt/sources.list \ apt-get update \ apt-get install -y --no-install-recommends wget ca-certificates gnupg lsb-release vim net-tools \ wget https://dev.mysql.com/get/mysql-apt-config_0.8.33-1_all.deb \ echo mysql-apt-config mysql-apt-config/select-server select mysql-8.4-lts | debconf-set-selections \ dpkg -i mysql-apt-config_0.8.33-1_all.deb \ apt-get update \ DEBIAN_FRONTENDnoninteractive apt-get install -y mysql-server \ rm -rf /var/lib/apt/lists/* \ rm -f mysql-apt-config_0.8.33-1_all.deb # 自定义入口脚本 COPY docker-entrypoint.sh /usr/local/bin/ RUN chmod x /usr/local/bin/docker-entrypoint.sh # 自定义配置 COPY my.cnf /etc/mysql/conf.d/custom.cnf EXPOSE 3306 VOLUME [/var/lib/mysql] ENTRYPOINT [docker-entrypoint.sh]my.cnf内容按需给我在这份里开了utf8mb4和合理的连接数[mysqld] character-set-server utf8mb4 collation-server utf8mb4_0900_ai_ci max_connections 200 default-time-zone 08:00 innodb_buffer_pool_size 512M innodb_flush_log_at_trx_commit 1 skip-name-resolve其中skip-name-resolve值得说两句它让MySQL不再对客户端IP做反向DNS解析能显著降低连接耗时代价是用户授权表里的Host字段不能用域名只能写IP。容器环境里客户端IP是固定的容器网段用IP授权就够了所以我建议默认开。3.2 CentOS 7路线完整实现CentOS 7路线整体逻辑一样但包管理和目录结构略有不同。下面是可复现的版本FROM centos:7 ENV TZAsia/Shanghai \ MYSQL_DATA_DIR/var/lib/mysql \ MYSQL_RUN_DIR/var/run/mysqld \ MYSQL_LOG_DIR/var/log/mysql \ MYSQL_ROOT_PASSWORDroot123 \ MYSQL_DATABASEappdb \ MYSQL_USERappuser \ MYSQL_PASSWORDapp123 RUN yum install -y https://dev.mysql.com/get/mysql84-community-release-el7-1.noarch.rpm \ rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023 \ yum install -y mysql-community-server \ yum clean all \ mkdir -p /var/run/mysqld \ chown mysql:mysql /var/run/mysqld COPY docker-entrypoint.sh /usr/local/bin/ RUN chmod x /usr/local/bin/docker-entrypoint.sh COPY my.cnf /etc/my.cnf EXPOSE 3306 VOLUME [/var/lib/mysql] ENTRYPOINT [docker-entrypoint.sh]CentOS重点注意两点第一yum install时的“Failed to connect to repo.mysql.com”问题多半是公网访问受限替换成内部镜像源的仓库包即可但记得GPG key要同步导入第二CentOS 7自带的numactl-libs可能版本不够MySQL启动时报“libnuma.so.1: cannot open shared object file”这时候手动yum install -y numactl-libs libaio就能解决。my.cnf在CentOS路线的路径和Ubuntu不同Ubuntu是/etc/mysql/conf.d/CentOS则是直接覆盖/etc/my.cnf这点容易搞混。3.3 构建、启动和镜像体积实测构建命令很直接docker build -t my-mysql:8.4-ubuntu .构建过程第一次比较慢因为要拉基础镜像、安装一堆依赖大概两三分钟。成功后在当前目录执行docker run -d --name mysql84 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDroot123 \ -e MYSQL_DATABASEappdb \ -e MYSQL_USERappuser \ -e MYSQL_PASSWORDapp123 \ -v /data/mysql:/var/lib/mysql \ my-mysql:8.4-ubuntu等十来秒用docker ps看状态。如果STATUS是Up且(healthy)说明一切正常。然后进容器验证docker exec -it mysql84 mysql -uroot -proot123 -e SELECT VERSION();我实测Ubuntu路线的镜像体积在1.2GB左右CentOS路线约1.1GB比官方镜像约600MB大了将近一倍。原因很实在基础镜像本身大再加上源码包安装时残留的doc、man等文件去不净。要瘦身可以后续用多阶段构建做一层清理删掉/usr/share/mysql下的测试文件和/var/cache。但生产环境里稳定优先于体积多几百MB的镜像并没有那么要命反而你该关注的是容器启动速度和数据挂载安全性。3.4 用环境变量控制配置一个启动逻辑的示范前面入口脚本里提到根据环境变量生成配置这里演示一个可以复用的写法。我们在入口脚本里加入以下逻辑if [ ! -z $MYSQL_DATABASE ]; then # 等待 mysqld 真正就绪注意此时尚未 exec mysqld需要先手工拉起临时实例 mysqld --usermysql --datadir${MYSQL_DATA_DIR} --socket${MYSQL_RUN_DIR}/mysqld.sock --skip-networking for i in $(seq 1 30); do if mysqladmin ping --socket${MYSQL_RUN_DIR}/mysqld.sock -uroot /dev/null 21; then break fi sleep 1 done mysql --socket${MYSQL_RUN_DIR}/mysqld.sock -uroot EOF ALTER USER rootlocalhost IDENTIFIED BY ${MYSQL_ROOT_PASSWORD}; CREATE DATABASE IF NOT EXISTS \${MYSQL_DATABASE}\; CREATE USER IF NOT EXISTS ${MYSQL_USER}% IDENTIFIED BY ${MYSQL_PASSWORD}; GRANT ALL PRIVILEGES ON \${MYSQL_DATABASE}\.* TO ${MYSQL_USER}%; FLUSH PRIVILEGES; EOF mysqladmin shutdown --socket${MYSQL_RUN_DIR}/mysqld.sock -uroot -p${MYSQL_ROOT_PASSWORD} fi这个写法的意义在于把“初始化数据库、创建业务库、创建业务账号”全部交给环境变量驱动同一个镜像给不同团队使用时只需改docker run的环境变量拿到手就是各自需要的数据库环境。这里的核心逻辑是在无网络监听状态下临时启动一个mysqld实例用socket完成建库建用户然后干净地关掉最后再正式启动对外提供服务。有一点要小心mysqladmin shutdown之后临时实例完全退出日志里可能出现“Shutdown complete”字样这是正常的。但如果shutdown后进程没有完全退出后续正式启动会被锁文件卡住。稳妥的方式是临时实例启动后记录PIDshutdown时用kill兜底或者加个循环等待进程退出。我实际加过这个循环while kill -0 $TEMP_MYSQLD_PID 2/dev/null; do sleep 1 done这样能保证入口脚本不会带着僵尸体往下走。4. 实战中绕不开的坑4.1 容器启动后MySQL一直退出这个现象最常见表现是docker run -d后容器很快变成Exited日志里能看到mysqld报错。我统计了一下九成是三个原因数据目录权限。日志里出现[ERROR] Cant open the mysql.plugin table或[ERROR] /usr/sbin/mysqld: Cant create/write to file /var/lib/mysql/ib_logfile0这基本可以断定是/var/lib/mysql属主不是mysql。处理方式前面已经说过了宿主机上改属主。残留的配置参数不兼容。8.4对很多老参数已经不支持如果你把8.0时代模板里的innodb_file_formatBarracuda照搬到8.4mysqld会直接报“Unknown variable”退出。解决方式是启动前用mysqld --verbose --help | grep逐个验证或者干脆用官方默认配置做基准再微调。日志文件锁冲突。容器异常退出后再启动残留的/var/run/mysqld/mysqld.pid或socket文件没清掉新进程起不来。入口脚本里加一句清理rm -f /var/run/mysqld/mysqld.sock /var/run/mysqld/mysqld.pid放在初始化和启动之间能解决大量“二次启动失败”的问题。4.2 中文乱码和字符集问题MySQL 8.4默认字符集已经是utf8mb4但如果你在Dockerfile里没有显式指定某些情况下连接层仍是utf8mb4_0900_ai_ci也不一定和预期一致。最彻底的做法是在my.cnf里写死服务端、客户端和连接层的字符集[client] default-character-set utf8mb4 [mysql] default-character-set utf8mb4 [mysqld] character-set-server utf8mb4 collation-server utf8mb4_0900_ai_ci构建完成后进容器查看SHOW VARIABLES LIKE character%; SHOW VARIABLES LIKE collation%;重点看character_set_server和collation_server是否都已经是utf8mb4。如果只有server变了但character_set_client还是latin1那连接时还是会有问题。skip-character-set-client-handshake参数可以强制忽略客户端指定的字符集但副作用是所有客户端都按服务端字符集走慎用。还有一道隐藏坑如果你在初始化脚本里已经执行了建库建表而那时字符集还没被正确设置库表和索引的字符集就固化下来了后续改my.cnf也不影响已存在的表。所以自定义镜像的初始化顺序必须是“先配好字符集再建库建表”这个顺序写进入口脚本第一段别乱。4.3 CentOS 7的glibc兼容和仓库依赖谜题CentOS 7的用户装MySQL 8.4最常见的报错是error: Failed dependencies: libnuma.so.1()(64bit) is needed by mysql-community-server-8.4.x libaio.so.1()(64bit) is needed by mysql-community-server-8.4.x这两个依赖在CentOS 7最小安装里没有而yum又不会自动补全。Dockerfile里在装mysql-community-server前先显式装依赖RUN yum install -y https://dev.mysql.com/get/mysql84-community-release-el7-1.noarch.rpm \ yum install -y libaio numactl-libs \ yum install -y mysql-community-server顺序很重要先把libaio和numactl-libs装上再装MySQLyum在解析依赖时就会直接用已安装的包不会再报错。另一个可能是glibc版本问题。MySQL 8.4官方EL7用的glibc还是2.17起步正常情况下CentOS 7的glibc完全够用。但如果你在基础镜像里动了glibc比如用了某些第三方源升级过就可能出现“version GLIBC_2.28 not found”的诡异报错这时候回退官方CentOS基础镜像、不要动glibc是最省事的解法。4.4 时区问题容器和宿主机时间对不上容器默认时区是UTCMySQL的SYSTEM时区跟着容器走于是NOW()会比北京时间晚8小时。日志和业务数据的时间对不上排查问题时会非常头痛。Dockerfile里已经设置了ENV TZAsia/Shanghai但要注意光设环境变量不一定会自动生成/etc/localtime。在Ubuntu系下还要加一步RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ echo Asia/Shanghai /etc/timezoneCentOS同理RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime然后my.cnf里配上default-time-zone 08:00。这样应用层和数据库层的时间就是一致的了。我自己有一次排查线上订单时间差了8小时最后发现就是容器时区没配从那以后每个MySQL镜像必配时区一步都不省。4.5 几个高频的排查命令遇到问题别急着怀疑人生先用这几条命令把现场固定下来# 看容器实时日志 docker logs -f mysql84 # 进容器里手动启动 mysqld 看前台报错 docker exec -it mysql84 bash mysqld --usermysql --console # 检查关键目录权限 docker exec -it mysql84 ls -ld /var/lib/mysql /var/run/mysqld /var/log/mysql # 检查端口监听 docker exec -it mysql84 netstat -tlnp | grep 3306 # 检查进程和PID文件 docker exec -it mysql84 ps aux | grep mysqld docker exec -it mysql84 cat /var/run/mysqld/mysqld.pidmysqld --usermysql --console这一条特别好用它会让mysqld在前台直接输出日志很多被日志文件吞掉的早期错误线索会在终端里直接刷出来。比如常见的数据目录找不到表空间、配置文件解析失败都能一眼看到。写在最后的一个小技巧如果你打算把这套镜像纳入正式运维体系可以在构建命令里加一个版本标签比如my-mysql:8.4-ubuntu-1.0同时在Dockerfile里用ARG BUILD_VERSION声明版本号用LABEL version$BUILD_VERSION标记。这样镜像和代码一样有了版本出了事故也方便回溯是哪个构建版本引入的问题。我自己吃过大亏有一次改了my.cnf里的空闲超时参数忘了打标签生产环境机器全被回收连接排查了好几天才定位到是哪一版镜像。加了版本标签后这类问题基本不会再有了。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →