Docker跑MySQL容器化部署全指南:镜像选择、数据卷、端口映射与配置实践
发布时间:2026/10/3 9:26:44 作者:尧图编辑部 阅读量:1,286

1. 为什么我建议你用Docker跑MySQL容器化数据库的实际收益先说结论Docker跑MySQL不是炫技而是把数据库从本机装一个、环境乱一团的泥潭里捞出来的最干净方案。你可能遇到过这种情况——新电脑想装MySQL去官网下安装包中途要你装各种依赖库装完还得配环境变量、调my.ini折腾一晚上终于能连上了结果某天删数据误操作想重装又得把注册表清理一遍。用Docker这些全都省了。Docker下MySQL的安装本质上是镜像即安装包容器即运行实例。你拉一个MySQL镜像它就内置了完整的MySQL发行版和最小化的操作系统层你启动一个容器就是创建了一个隔离的数据库运行环境。这个环境里的MySQL版本、配置文件、数据目录都是独立自包含的删掉容器不会残留垃圾到宿主机换版本也只需要换镜像标签。需要明确的一点是Docker跑MySQL和直接装在系统里性能差异在绝大多数业务场景下可以忽略。MySQL进程在容器内跑底层依然是Linux内核只是多了一层namespace隔离和cgroup资源控制。真正有影响的是磁盘IO和网络栈的轻微开销对个人开发、测试环境、中小型生产库来说完全够用。我自己在一台8GB内存的笔记本上跑MySQL 8.0容器同时开两个项目后端毫无压力。这篇文章面向的读者有两类第一是刚接触Docker、想在本地快速搭一个MySQL环境做学习或联调的新手第二是已经有MySQL使用经验、但想规范管理多个数据库实例的开发者。看完你能学会镜像怎么选、容器怎么起、配置怎么改、SQL怎么在容器里执行以及遇到坑怎么排。全程用命令说话每步都附解释照着敲就行。1.1 容器化MySQL和本机安装的核心差异本机安装MySQL本质是让数据库进程直接跑在操作系统上进程间通信走localhost文件系统直接落在宿主机的目录里。这带来的问题是多实例管理麻烦、环境依赖冲突、卸载不干净。Docker改变了这个模型MySQL进程被封装在镜像里运行时只看到自己容器内的文件系统和网络栈对外暴露的端口和服务与你本机其他程序互不干扰。举一个最常见的场景你的老项目用的是MySQL 5.7新项目要求MySQL 8.0。本机装的话要么装两个版本在不同端口改来改去要么升级老项目大概率挂掉。Docker就简单了拉两个镜像起两个容器一个跑3306端口一个跑3307端口数据目录分别挂载到不同宿主机路径完全隔离又同时可用。另一个差异在数据管理上。本机MySQL的数据目录散落在系统盘备份就是把data目录拷出去恢复就是拷回来路径不好找还容易漏文件。容器方案下通过数据卷volume把容器内的/var/lib/mysql映射到宿主机指定目录备份就是拷这个目录迁移服务器时把目录和启动命令带走换台机器分分钟恢复。这种基础设施即代码的体验一旦用上就很难再回去。1.2 谁适合用Docker跑MySQL谁不适合先说不适合的如果你维护的是高并发、海量数据的线上核心数据库比如每秒上万次的写入、单表亿级、对IOPS和延迟极其敏感Docker可能不是首选。不是说容器跑不了而是生产环境的数据库需要精细调优和极端的稳定性保障裸机或云数据库服务更成熟可控。另外如果你用的是Windows且没开启虚拟化支持装了Docker Desktop也跑不起来这种情况得先解决Hyper-V或WSL2的问题。适合的非常广本机开发调试、自动化测试的临时数据库、CI/CD流水线里的集成测试、多版本兼容性验证、学习练手、内部工具的数据存储。我见过很多团队把Docker MySQL用成了标准开发规范——新成员入职拉一个通用脚本一分钟起一个和线上同版本的数据库环境一致性问题直接消灭。一句话总结Docker MySQL是开发环境和个人项目的最佳姿势是生产环境的备选方案。如果你的目标是把数据库跑起来并专注于业务本身用容器准没错。2. 镜像选型与拉取版本、平台、标签的讲究2.1 镜像版本怎么选8.0、5.7还是latest在拉镜像前第一件事是决定MySQL版本。很多教程直接让你拉mysql:latest我强烈不建议。latest标签会随官方更新漂移今天拉的是8.0.x过一阵再拉可能就变成8.1、8.2了环境不可复现备份恢复都可能出兼容性问题。生产级做法是锁定主版本比如mysql:8.0甚至精确到小版本mysql:8.0.33。选版本还要考虑你的业务兼容性。MySQL 5.7是经典稳定版配置习惯和第三方工具兼容性极佳MySQL 8.0带来了窗口函数、CTE公共表表达式、更优的查询优化器和默认的utf8mb4字符集但默认认证插件换成了caching_sha2_password老版本客户端连接需要额外处理。新项目直接用8.0老项目保守选5.7我的经验是除非有强兼容性需求否则选8.0。拉取命令很简单docker pull mysql:8.0。这会从Docker Hub拉取官方MySQL镜像到本地。拉取过程会显示分层下载进度镜像大约500多MB取决于网络状况可能需要几分钟。国内网络慢的话可以配置镜像加速器具体方法后面问题章节会说。拉完之后可以用docker images确认镜像已经在本地注意看IMAGE ID和TAG那一列。2.2 官方镜像与第三方镜像的选择Docker Hub上有mysql官方镜像mysql/mysql-server和一些第三方镜像。我的原则是优先官方。官方镜像在Dockerfile质量、安全补丁更新、文档完整性上都有保障唯一的偶尔吐槽点是它基于Oracle Linux精简版但实际使用上没有任何影响。第三方镜像比如mariadb是MySQL分支二者大体兼容但底层存储引擎有差异不建议在没搞清楚差异时盲目替换。还有一个容易踩的坑是平台架构。如果你用的是Apple SiliconM系列芯片的Mac直接拉mysql:8.0会拉取arm64架构的镜像跑起来没问题。如果你在x86的云服务器上构建了镜像传到arm机器上跑会报exec format error。跨平台部署前一定要确认镜像架构可以用docker inspect命令查看Architecture字段或使用docker buildx构建多架构镜像。拉完镜像后建议顺手验证一下镜像文件是否完整。执行docker images确认REPOSITORY为mysql、TAG为8.0SIZE在合理范围。再执行docker run --rm mysql:8.0 mysql --version用一次性容器查看版本号如果不报错说明镜像可正常启动为下一步容器创建扫清障碍。3. 容器创建与启动初跑MySQL的关键参数3.1 端口映射、数据卷、密码这三个参数必须一次配对启动MySQL容器的完整命令如下docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDYourPassword123 \ -e TZAsia/Shanghai \ -v mysql_data:/var/lib/mysql \ -v mysql_config:/etc/mysql/conf.d \ mysql:8.0拆开解释参数的含义。-d是后台运行容器启动后不占用当前终端--name mysql8给容器取名后续管理都靠这个名字-p 3306:3306做端口映射宿主机3306端口转发到容器内3306端口这样外部工具连接localhost:3306就能访问容器里的MySQL-e MYSQL_ROOT_PASSWORD设置root用户的初始密码首次启动时官方镜像的初始化脚本会读取并创建用户-e TZAsia/Shanghai把容器时区设为东八区不设置的话MySQL的NOW()会返回UTC时间与本地时间差8小时非常坑-v mysql_data:/var/lib/mysql把数据目录挂载到命名卷容器删了数据还在-v mysql_config:/etc/mysql/conf.d挂载配置目录方便后边加自定义配置。这三个-v和-e参数是整个启动过程的核心很多人前期忽略后边数据丢了才回头补。数据卷必须要挂不挂载的话数据存在容器可写层容器删除数据全部蒸发这是新手最容易犯的灾难性错误。密码初始化参数只在首次启动时生效容器创建后改密码得进容器里用SQL改麻烦很多所以第一次启动就要设一个自己记得住的强密码。端口映射的3306:3306是宿主机端口:容器端口。如果宿主机3306已经被占用可以改成3307:3306外部用3307访问。有个小坑要注意如果之前用本机MySQL占了3306先把本机MySQL停掉或改端口否则容器起不来会报端口占用错误。3.2 启动后如何确认容器真的在健康运行docker run -d执行完终端会输出一串容器ID但这不代表容器已经能提供服务。容器启动后有个初始化过程初始化数据目录、创建root用户、加载配置耗时大约10到30秒。你需要用docker ps查看容器状态STATUS列显示Up且没有反复重启才说明基本正常。docker ps # 输出示例CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # mysql8 启动中... Up 5 seconds 0.0.0.0:3306-3306/tcp mysql8更好的办法是看日志。docker logs mysql8会输出MySQL的启动日志看到ready for connections字样就说明服务就绪。如果日志里出现[ERROR]开头的内容说明有问题常见的有密码策略不满足、字符集配置错误、端口占用等。日志是排查问题的最直接入口比瞎猜强一百倍。启动成功后可以用docker ps -a查看所有容器包括已停止的。以后管理容器的常用命令还有docker stop mysql8停止容器、docker start mysql8重新启动、docker restart mysql8重启、docker rm mysql8删除容器。记住这套命令组合你就能随时让MySQL容器在宿主机上自如地启动和停止。4. MySQL容器配置进阶字符集、时区、慢查询与资源限制4.1 默认配置的局限为什么初始化后还要配官方镜像启动后基本能用但离适合生产实践还差几步。最典型的问题是字符集。MySQL 8.0默认字符集是utf8mb4但服务端的collation排序规则默认是utf8mb4_0900_ai_ci而很多迁移过来的老库用的是utf8mb4_general_ci。字符集不一致会导致应用层排序、比较异常更重要的是如果建表时没显式指定字符集新表会沿用服务端默认一旦入库中文数据出现乱码或排序异常回溯成本很高。时区问题刚才提了不设置TZ环境变量容器默认UTC时间。对业务来说日志时间、统计报表全差8个小时排查问题像倒时差。用-e TZAsia/Shanghai可以解决容器级时区但不一定能覆盖MySQL服务端的time_zone变量。为了确保MySQL内部时间也正确我习惯在配置文件里再设一次default-time-zone 08:00。慢查询日志默认是关闭的连接数上限默认151max_allowed_packet默认64MB。这些参数在开发环境无所谓但在压测或异常流量场景下不加配置可能直接导致连接被拒或性能瓶颈。所以一个规范化的MySQL容器需要在启动后或启动时把常规优化参数一并配上。4.2 通过配置文件定制MySQLconf.d目录的正确用法官方镜像设计了一个友好的配置扩展机制容器内的/etc/mysql/conf.d目录下的所有.cnf文件会被MySQL自动读取。所以最简单的配置方法是挂载一个自定义配置文件到这个目录然后重启容器。比如宿主机上的/opt/mysql/custom.cnf内容如下[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ci default-time-zone08:00 max_connections500 max_allowed_packet128M slow_query_log1 slow_query_log_file/var/log/mysql/slow.log long_query_time2然后在启动命令里添加挂载docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDYourPassword123 \ -v mysql_data:/var/lib/mysql \ -v /opt/mysql/custom.cnf:/etc/mysql/conf.d/custom.cnf:ro \ mysql:8.0注意挂载单个文件时宿主机文件路径必须写绝对路径-v冒号后是容器内路径:ro表示只读挂载防止容器内修改破坏宿主机文件。重启容器后查看配置是否生效可以执行docker exec mysql8 mysql -uroot -p -e SHOW VARIABLES LIKE character%;用这个方式确认character_set_server是utf8mb4collation_server是utf8mb4_unicode_ci说明配置加载成功。如果还是默认值大概率是挂载路径写错或文件权限问题检查容器内/etc/mysql/conf.d/目录是否存在你的文件。max_connections要根据宿主机内存调整不是越大越好。每个MySQL连接大概占用几MB内存500连接对2GB内存的容器就有些吃力了。我一般按总内存/256MB粗略估算连接数上限比如4GB内存配256个连接留足余量。4.3 用docker命令调资源限制不让MySQL吃满宿主机如果你在本机同时跑多个容器或者还有其他服务必须对MySQL容器做资源限制。docker run时可加参数docker run -d --name mysql8 \ --memory1g \ --cpus1.0 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDYourPassword123 \ -v mysql_data:/var/lib/mysql \ mysql:8.0--memory1g限制容器最多使用1GB内存--cpus1.0限制最多使用1个CPU核心。这个限制是硬性的容器超过内存限制就会被OOM killer杀掉所以设值时要留足余量比如你预估MySQL占500MB就别设512MB给到768MB或1GB相对安全。对于已创建的容器可以用docker update动态调整资源限制docker update --memory2g --cpus2.0 mysql8。这个命令改完即时生效对运行中的容器也有效。我把这套配合方案固定成自己的标准模板数据卷挂载、配置文件挂载、资源限制一次配齐。换环境时只要改密码和路径其余原样复制。配置这一块的思路和本机MySQL没本质区别但Docker的挂载机制让配置即文件、文件即代码成为现实。整个MySQL配置散落在宿主机明确目录里git管理起来以后任何机器都能复现同样环境。5. 进入容器执行SQL查询从连接到实操5.1 用docker exec进入容器的正确姿势配置搞定、容器正常启动之后就该面对真正高频的需求进入MySQL执行SQL。两种进入方式第一个是进入容器内部的shell再调用mysql客户端docker exec -it mysql8 bash # 进入容器后执行 mysql -uroot -p这条命令的-it表示分配一个交互式终端这样你能看到MySQL客户端的mysql提示符输入密码后即可执行SQL。注意容器内可能没有bash官方镜像基于Oracle Linux精简版一般带bash如果提示bash: not found换shdocker exec -it mysql8 sh。第二个更推荐的方式是直接在宿主机上执行mysql客户端免去进入容器的步骤docker exec -it mysql8 mysql -uroot -p这条命令等价于在mysql8容器里运行mysql -uroot -p但操作体验上你还在宿主机终端里。和上面那种方式的区别是节省了一层shell少敲一条命令出错概率更低。不管是哪种方式-p后面可以跟密码但强烈不建议一是密码会出现在shell历史记录里二是docker exec进程列表里会明文暴露密码。正确做法是不带密码执行让mysql客户端交互式提示输入。对于自动化脚本可以用环境变量方式docker exec -e MYSQL_PWDYourPassword123 mysql8 mysql -urootMYSQL_PWD是MySQL客户端支持的环境变量避免命令行泄露密码。5.2 执行SQL查询的三种典型方式进入mysql命令行后执行查询和本机MySQL完全一致。我常用的一个习惯是先用SHOW DATABASES;确认连接正常再用USE 数据库名;切换库。下面演示一遍从创建库到查询的标准流程docker exec -it mysql8 mysql -uroot -p # 输入密码后进入mysql mysql CREATE DATABASE IF NOT EXISTS test_db DEFAULT CHARACTER SET utf8mb4; mysql USE test_db; mysql CREATE TABLE user_info ( - id INT AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(50) NOT NULL, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP - ); mysql INSERT INTO user_info (name) VALUES (张三), (李四); mysql SELECT * FROM user_info;执行SELECT * FROM user_info;后终端会显示一个表格包含id、name、created_at三列的数据。如果中文显示正常说明字符集配置在起作用如果出现乱码回头检查4.2节的配置是否生效。这张表格就是验证一切是否配置成功的试金石。除了交互式查询还有两种非交互式执行方式在脚本和自动化环境里特别有用。第一种是直接通过-e参数执行单条SQL不进入交互环境docker exec mysql8 mysql -uroot -pYourPassword123 -e SHOW DATABASES;这种方式适合快速抽查状态但注意-p后直接跟密码会在进程列表暴露脚本里用环境变量替代。第二种是从宿主机文件执行SQL脚本这是做初始化数据、批量导入时的最佳方式# 把test.sql放到宿主机当前目录 docker exec -i mysql8 mysql -uroot -pYourPassword123 test.sql-i参数保持标准输入打开宿主机上的test.sql内容通过标准输入重定向注入到容器内的mysql客户端。脚本里可以放建表语句和INSERT语句一次性执行完。这里有个细节如果是中文内容的SQL文件建议文件保存为UTF-8编码并在第一条加上SET NAMES utf8mb4;否则中文容易乱。5.3 宿主机与容器内数据交互的注意事项容器内的mysql客户端往容器外导出数据常见做法是把结果重定向到宿主机文件。交互式查询结果人工复制粘贴当然可以但数据量大时不现实。更专业的方式是配合mysqldump导出比如docker exec mysql8 sh -c exec mysqldump -uroot -pYourPassword123 --databases test_db backup.sql这条命令的思路是在容器内执行mysqldump导出SQL内容通过stdout输出到宿主机再由宿主机shell重定向写入backup.sql。注意-p后接密码最好不要这样用我用--defaults-extra-file方式更好但上面展示的是最直接的逻辑。备份文件在宿主机上方便拷贝、git管理、定时任务处理。反过来从宿主机导入数据上一节说的docker exec -i重定向上都可以。要注意字符集和编码问题SQL文件的换行符、BOM头都有可能造成导入报错。我的习惯是用Notepad或VS Code把文件转成UTF-8无BOM格式再导入避开大部分乱码源头。最后提醒一个安全习惯退出mysql客户端输入exit;或按CtrlD退出容器shell输入exit。如果只是临时查一下数据不进入shell直接docker exec加-e参数是最高效的省去了一次终端会话切换。6. 常见问题与排查实录容器的坑我替你踩过了6.1 端口占用、数据卷权限、认证失败的完整对策我把实际使用中高频出现的问题整理成一张排查表遇到问题直接对号入座。现象可能原因解决办法容器启动后立即退出docker ps看不到端口被占用或数据目录权限异常先docker ps -a看容器状态和退出代码再看docker logs mysql8定位Navicat等客户端连接报1130错误用户没有远程访问权限进入容器执行ALTER USER root% IDENTIFIED BY 密码;并FLUSH PRIVILEGES;连接报caching_sha2_password错误客户端版本太低不支持新认证插件改用支持新插件的客户端或ALTER USER root% IDENTIFIED WITH mysql_native_password BY 密码;中文乱码客户端连接字符集与服务端不一致连接串加?useUnicodetruecharacterEncodingutf8服务端确认utf8mb4mysql命令行显示Access denied密码错误或host限制确认密码是否包含特殊字符特殊字符在shell里要转义或用单引号括起来docker exec提示exec failed: no such file or directory容器内没有你指定的解释器把bash换成sh或直接用完整路径如/usr/bin/mysql其中1130错误是新手最常碰到的容器默认只允许root从localhost连接外部工具连不上。我的标准处理是创建专用用户而不是直接放开root远程权限更安全docker exec -it mysql8 mysql -uroot -p mysql CREATE USER app% IDENTIFIED BY AppPassword123; mysql GRANT ALL PRIVILEGES ON test_db.* TO app%; mysql FLUSH PRIVILEGES;%表示任意主机可连如果只想让某台机器连换成具体的IP比如app192.168.1.100。6.2 容器停止后数据还在不在以及如何彻底重置容器停止docker stop不会删除数据数据卷中的数据完好无损重新docker start mysql8后数据照旧。但容器删除docker rm就有讲究了如果你挂载的是命名卷或宿主机目录数据依然存在重新docker run时挂载同一卷就能找回旧数据如果你没用数据卷数据跟着容器一起没了。这个逻辑必须刻进脑子里数据卷是数据的生命线。彻底重置MySQL环境的标准步骤是docker stop mysql8 docker rm mysql8 docker volume rm mysql_datadocker volume rm会删除命名卷里的所有数据这是不可逆操作执行前确认里面没有重要数据。如果是宿主机目录挂载直接删除挂载目录即可。重置后重新执行docker run一个全新的MySQL就绪。还有一个容易被忽略的是容器时间与宿主机不同步问题。如果宿主机启用了自动校时但容器起来后时间还是错的检查创建容器时是否设置了TZ。已创建的容器可以这样补救docker exec mysql8 sh -c ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime docker restart mysql8这个操作手动修正了容器内的时区链接重启后生效。虽然不如启动时就加-e TZ干净但算是一剂应急药。6.3 Docker Desktop在Windows/Mac上的特有坑Windows和Mac用户用Docker Desktop跑MySQL有平台特有的问题。最常见是文件挂载性能差Windows下把-v D:/mysql_data:/var/lib/mysql挂载Windows目录MySQL每秒刷盘的文件操作走的是文件共享通道性能可能比Linux环境差数倍。解决办法有三种选择直接用Docker命名卷不挂Windows目录适合不关心数据落盘位置的场景修改Docker Desktop的File Sharing设置把D盘加入共享列表升级到WSL2后端让文件IO走Linux原生路径。Windows还有一个经典报错WSL 2 installation is incomplete。这是Docker Desktop的WSL2内核没装好去微软官网下载并安装最新的WSL2内核更新包即可。Mac上则可能遇到Cannot connect to the Docker daemon一般是Docker Desktop没启动点开应用等它跑完再操作。我对新手在Windows上折腾Docker MySQL的建议是优先装Docker Desktop并启用WSL2不要用老旧的Hyper-V模式。WSL2在文件系统兼容性和资源占用上都更友好。另外防火墙如果开了记得放行3306端口很多外部工具连不上的坑其实是被Windows防火墙拦了和MySQL本身没关系。7. 从手动敲命令到一键拉起几个值得收藏的脚本实践7.1 把启动参数固化成Shell脚本折腾到这一步你已经能从零起一个MySQL容器了。但每次都敲一大串docker run命令容易敲错且不可复现。我习惯把这些参数写成一个start_mysql.sh放在项目目录里换台机器git clone下来就能启动#!/bin/bash MYSQL_ROOT_PASSWORD${MYSQL_ROOT_PASSWORD:-YourPassword123} MYSQL_CONTAINER_NAME${MYSQL_CONTAINER_NAME:-mysql8} MYSQL_PORT${MYSQL_PORT:-3306} docker run -d \ --name ${MYSQL_CONTAINER_NAME} \ -p ${MYSQL_PORT}:3306 \ -e MYSQL_ROOT_PASSWORD${MYSQL_ROOT_PASSWORD} \ -e TZAsia/Shanghai \ -v mysql_data:/var/lib/mysql \ -v $(pwd)/config/custom.cnf:/etc/mysql/conf.d/custom.cnf:ro \ --memory1g \ mysql:8.0脚本里的${MYSQL_ROOT_PASSWORD:-YourPassword123}是Shell默认值语法环境变量没设置时用默认密码。这样脚本本身不硬编码机密密码通过环境变量注入更安全。$(pwd)取当前目录配置文件路径始终跟随项目位置。有了脚本后我还搭配一个create_database.sql初始化文件内容如下CREATE DATABASE IF NOT EXISTS app_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER IF NOT EXISTS app% IDENTIFIED BY AppPassword123; GRANT ALL PRIVILEGES ON app_db.* TO app%; FLUSH PRIVILEGES;启动脚本运行后再执行docker exec -i mysql8 mysql -uroot -p -e source /dev/stdin create_database.sql数据库和用户就自动建好了。整个过程几分钟内完成项目组成员复制脚本就能获得完全一致的数据库环境开发环境从此不再各搞各的。7.2 用Docker Compose管理多容器数据库当项目多了之后我只用docker-compose.yml来管理MySQL因为它把容器定义、数据卷、网络、启动顺序都写在一个文件里可读性和复用性远超Shell脚本。下面是一个参考配置version: 3.8 services: mysql: image: mysql:8.0 container_name: mysql8 environment: MYSQL_ROOT_PASSWORD: YourPassword123 TZ: Asia/Shanghai ports: - 3306:3306 volumes: - mysql_data:/var/lib/mysql - ./config:/etc/mysql/conf.d:ro - ./init:/docker-entrypoint-initdb.d:ro command: - --character-set-serverutf8mb4 - --collation-serverutf8mb4_unicode_ci restart: unless-stopped volumes: mysql_data:这个Compose文件里有个我特别喜欢的特性/docker-entrypoint-initdb.d目录挂载。镜像首次启动时会自动执行该目录下的所有.sql或.sh文件按文件名顺序执行。也就是说把建库建表的SQL文件丢进去第一次启动就自动初始化完毕省去了手动执行SQL的步骤。启动方式docker compose up -d。停止docker compose stop。查看日志docker compose logs -f mysql。这套命令组合基本覆盖日常全部操作。如果是老版本的docker-compose单文件命令则将docker compose换成docker-compose。Compose还解决了容器间网络互通的问题。如果你的Java后端容器要和MySQL容器通信不用暴露端口到宿主机直接让两个容器在同一个自定义网络里后端连接串写mysql:3306即可。这个网络层面的隔离和发现是Shell脚本很难优雅实现的。到这一步你已经不再只是会用Docker跑MySQL而是进入了用编排工具管理基础设施的层面。8. 最后分享两个我常用的实用技巧第一招如何快速给MySQL容器做健康检查。写脚本判断数据库是否就绪不能只看容器Up状态因为进程在不代表连接数可用。我习惯用docker exec mysql8 mysqladmin -uroot -pYourPassword123 ping返回mysqld is alive说明服务完全就绪。这个命令可以配合shell循环做启动等待逻辑自动化部署时特别好用。注意如果容器里有多个数据库实例mysqladmin要指定连接参数不然可能检查错实例。第二招临时起一个干净MySQL用于测试用完即焚。我们经常需要一个隔离的数据库跑单元测试测试完不污染开发数据。命令docker run -d --rm --name mysql_test -e MYSQL_ROOT_PASSWORDtest123 -p 3307:3306 mysql:8.0--rm参数表示容器停止后自动删除测试完docker stop mysql_test容器连同可写层一起清理不留垃圾。如果在同一台机器上同时起开发库3306和测试库3307互不干扰这种一机多库的管理能力是本机安装方案很难企及的。我个人在实际操作中的体会是Docker跑MySQL最大的价值不在于能跑起来而在于让环境的创建、销毁、复现都变成可编排、可追溯的操作。当你把启动脚本和初始化SQL提交到代码仓库后任何一个新同事都能在十分钟内获得一套和其他人完全一致的数据库环境这比任何技术选型都更影响团队的交付效率。把这套流程跑顺了你就算真正入了容器化的门。