news 2026/9/28 5:42:38

用Docker跑MySQL:从环境准备到数据持久化的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Docker跑MySQL:从环境准备到数据持久化的完整指南

我一直觉得,用 Docker 跑 MySQL 是本地开发最省心的方案,没有之一。你不需要去官网找下载链接,不需要担心系统里残留旧版本,更不用为了给测试环境换一个 MySQL 8.0 而把自己机器上的 5.7 卸载掉。一条docker run命令,MySQL 就在你手边,用完还能随手删掉,删完数据文件照样留在宿主机里。这篇文章我直接以“用 Docker 启动 MySQL”为主线,从环境准备、镜像选择、容器启动、数据持久化到日常维护和问题排查,把步骤拆开讲透。适合刚接触 Docker 的新手,也适合那些已经装了 Docker 但每次启动 MySQL 都要翻文档的人。

先说清楚我能帮你解决什么:如果你经常需要在本机起一个 MySQL,或者准备写 JavaWeb 项目需要数据库环境,又或者想快速起一个指定版本的 MySQL 做测试,这篇文章都能直接照着抄。我会把每一步背后的原理讲明白,比如为什么要挂载数据卷、为什么要指定字符集,而不是只丢给你一串命令。

1. 为什么用 Docker 跑 MySQL 而不是直接装

1.1 本地安装的痛点

直接在操作系统里装 MySQL,最麻烦的就是“环境残留”。Windows 上卸载 MySQL 要手动删服务、清注册表,Linux 上要处理一堆依赖,稍不注意系统里就同时存在 mysql 和 mariadb 两个版本,3306端口被占、mysql命令指向另一个客户端,这些问题我踩过不止一次。你排查了半天,最后发现是环境变量 PATH 指向了旧版本,这种挫败感相信很多人都有。

还有多版本切换的问题。项目 A 用的是 MySQL 8.0,项目 B 用的是 5.7,本地直装方案几乎没法优雅共存。有人用 Docker 之前是怎么解决的?装两遍?用虚拟机再开一个?要么麻烦,要么笨重。Docker 把这些问题全部消灭在容器层面。

1.2 Docker 方案的核心优势

Docker 跑 MySQL 的核心逻辑就是“把数据库当作一个可随时创建和销毁的进程”。镜像把 MySQL 的二进制文件、配置模板、依赖环境全部打包好,容器启动后就是一个独立运行实例。你不需要关心它实际装在哪个目录,只需要通过端口、数据卷和环境变量来跟它交互。

隔离性是最直观的好处。宿主机上不需要安装任何 MySQL 相关的库,所有依赖都藏在镜像里。端口我是通过-p 3306:3306手动映射的,你想让 MySQL 暴露在 3307 端口也可以,完全不影响宿主机上已有的其他服务。

可重复性也极其重要。一个项目的数据库环境可以通过一段docker run命令或者一份docker-compose.yml完整描述,新同事入职拉下仓库,一条命令就还原出和你一模一样的 MySQL,彻底告别“在我电脑上是好的”这种经典借口。

1.3 适用场景

如果你问我什么场景下适合用 Docker 跑 MySQL,我列几个典型场景:

  • 日常本地开发:写代码需要连数据库,随时起一个临时 MySQL,用完就停。
  • 测试环境:反复初始化数据、切换版本,容器删掉重来只需要几秒钟。
  • 多项目并行:不同项目依赖不同 MySQL 版本,用不同容器、不同端口相互隔离。
  • 学习练手:学 SQL、学索引优化、学主从复制,不想弄脏自己的机器。

相反,如果是生产环境、高性能要求的正式业务,我一般不建议用 Docker 跑 MySQL,倒不是说容器技术不行,而是生产环境对运维监控、性能调优、故障恢复的要求更高,直接原生部署更容易跟监控系统对接。文章后面讲的都是开发、测试和个人项目场景。

2. 环境准备:先把 Docker 装好

2.1 Windows 上安装 Docker Desktop

Windows 上最常用的方案是 Docker Desktop。安装包可以直接从 Docker 官网下载,但有一个前提条件:系统需要开启虚拟化。如果你在安装后启动 Docker Desktop 时看到报错virtualization support not detected,大概率是虚拟化没开。

处理方式很简单:重启进 BIOS,找到 Intel Virtual Technology(Intel VT-x)或者 AMD SVM Mode,把它设为 Enabled,保存退出。如果 BIOS 里已经开了但还是报错,那就检查 Windows 的“虚拟机平台”和“适用于 Linux 的 Windows 子系统”这两个功能有没有启用。建议在“控制面板 - 程序 - 启用或关闭 Windows 功能”里勾选这两个选项,重启后再启动 Docker Desktop。

装好 Docker Desktop 后,建议在设置里把 WSL 2 作为后端,这是目前 Windows 下跑 Docker 最稳定的方案。WSL 2 的性能比老的 Hyper-V 方案更好,内存占用也更可控。安装时 Docker Desktop 一般会提示你启用 WSL,照着来就行。

2.2 macOS 与 Linux 上的安装

macOS 也是直接用 Docker Desktop,Apple Silicon 芯片选对应 arm64 版本,Intel 芯片选 x86_64 版本。双击安装,拖进 Applications 就行。Ubuntu 这类 Linux 发行版不需要桌面版,直接命令行装 Docker Engine:

sudo apt update sudo apt install -y docker.io sudo systemctl enable --now docker

CentOS/RHEL 系用yum install -y docker-ce或者yum install -y docker,具体看发行版本。装完验证一下:

docker version

能看到 client 和 server 两段信息就说明安装成功。如果 server 段报错Cannot connect to the Docker daemon,多半是当前用户没有 docker 组权限,运行sudo usermod -aG docker $USER后重新登录一次。这是 Linux 上最常见的新手问题,一定要先加上。

2.3 验证 Docker 环境

容器能不能跑,先执行docker ps看当前运行的容器列表。如果没有任何报错,说明 Docker 守护进程是正常的。然后再跑一个最简单的测试:

docker run hello-world

能正常打印出 Hello from Docker 的提示,说明整个流程通了。这一步其实很关键,因为后面 MySQL 容器启动失败时,你要能区分是 Docker 本身的问题还是 MySQL 配置的问题。我习惯在排查一切容器问题前先确保 hello-world 能跑通。

3. 选择镜像与版本:该拉哪个 MySQL 镜像

3.1 官方镜像与版本选择

Docker Hub 上的 MySQL 官方镜像叫mysql,我建议直接使用官方镜像,不要使用第三方打包的版本。官方镜像的维护质量、安全更新和文档完整度都是最有保障的。

版本方面,我的建议是:新项目直接用mysql:8.0,老项目需要兼容再选mysql:5.7。MySQL 8.0 是当前的主流版本,新建的 JavaWeb 项目、Spring Boot 项目基本都是围绕 8.0 开发的,8.0 的默认字符集是utf8mb4,对中文、emoji 的支持更完善。如果项目代码里用了老版本的mysql-connector-java或者某些老的 ORM 框架,那就要谨慎一点,8.0 的认证插件变化比较大,稍后我会在问题排查章节单独讲。

具体某个小版本可以不指定,直接用大版本标签就行,比如mysql:8.0会自动指向最新的 8.0 版本。如果你要复现一个特定环境,那就精确到mysql:8.0.38这样的完整标签。注意,mysql:latest目前也是 8.0 系列,但不建议用 latest 标签,因为它会随着官方更新变动,容易导致环境漂移。

3.2 镜像拉取与国内加速配置

拉取镜像:

docker pull mysql:8.0

如果你在国内,直接拉官方镜像可能会比较慢,甚至超时。这时候可以配置镜像加速器。Docker Desktop 的设置里有一个 Docker Engine 配置项,把仓库地址写进去:

{ "registry-mirrors": [ "https://docker.m.daocloud.io" ] }

保存后重启 Docker Desktop,再重新拉取镜像,速度会好很多。Linux 上则是修改/etc/docker/daemon.json,内容一样,改完重启 docker 服务:

sudo systemctl restart docker

拉取完成后用docker images查看当前本地已有的镜像,能看到mysql镜像和对应的 tag 就说明拉取成功了。

3.3 镜像大小与分层视角

用 Docker 跑 MySQL 之前,你还要理解一个概念:镜像和容器的关系。镜像是一个只读模板,容器是它的运行实例。你可以把镜像理解为“光盘里的安装包”,容器是“电脑上跑起来的程序”。同一个镜像可以同时启动多个容器,只要端口和容器名不冲突就行。所以我拉取一个 MySQL 镜像后,可以同时跑一个 3306 端口的开发库和一个 3307 端口的测试库,互不干扰。

4. 用 docker run 启动 MySQL 容器

4.1 一条完整的启动命令

下面是我日常最常用的命令,直接复制就能用:

docker run -d \ --name mysql-dev \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=root123456 \ -e TZ=Asia/Shanghai \ -v mysql-data:/var/lib/mysql \ -v mysql-config:/etc/mysql/conf.d \ mysql:8.0

-d表示后台运行,不加的话容器会占据当前终端,关掉终端容器就停了,很不方便。--name给容器起个名字,方便后续用docker stop mysql-dev、docker logs mysql-dev这样的命令操作。-p 3306:3306把宿主机的 3306 端口映射到容器的 3306 端口,前者是宿主机端口,后者是容器内端口。如果你宿主机 3306 被占,可以改成-p 3307:3306,那么客户端连接时就要连localhost:3307。

4.2 环境变量详解

MYSQL_ROOT_PASSWORD是 root 用户的初始密码,这是 MySQL 容器最核心的环境变量。MYSQL_DATABASE可以指定容器启动时自动创建数据库,MYSQL_USER和MYSQL_PASSWORD则可以创建一个普通用户并授权。比如:

docker run -d \ --name mysql-dev \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=root123456 \ -e MYSQL_DATABASE=mydb \ -e MYSQL_USER=test \ -e MYSQL_PASSWORD=test123 \ -v mysql-data:/var/lib/mysql \ mysql:8.0

这样启动完成后,容器里就已经存在一个mydb数据库,以及test这个只对mydb有权限的用户。注意MYSQL_USER只会被赋予MYSQL_DATABASE的权限,不会自动赋予其他库的权限,需要额外用 SQL 授权。

TZ=Asia/Shanghai是时区设置。MySQL 容器默认时区是 UTC,如果不设置,NOW()函数的返回值会比北京时间早 8 个小时,排查问题时很容易让你怀疑人生。我没有用官方推荐的-e TZ=Asia/Shanghai时,写日志的时间全是 UTC 时间,后来踩过一次坑之后就养成了必加时区的习惯。

4.3 数据卷与持久化

MySQL 容器最忌讳的事情就是“删容器丢数据”。默认情况下,容器内的/var/lib/mysql目录是 MySQL 存放数据文件的位置,一旦容器被删除,数据会跟着容器消失。解决方式就是挂载数据卷。

-v mysql-data:/var/lib/mysql表示把名为mysql-data的 Docker 数据卷挂载到容器内的数据目录。这种叫 named volume,Docker 负责在宿主机上管理这个数据卷的实际存储位置,你不需要关心它在哪,备份和迁移时也有统一的接口。如果你想直接绑定宿主机的某个具体目录,也可以写:

-v /home/me/mysql/data:/var/lib/mysql

这种叫 bind mount。好处是数据文件清晰可查,直接进目录就能看到;坏处是目录权限偶尔会出问题,比如容器里的 mysql 用户 UID 和宿主机的 UID 不一致可能导致无法写入。我个人更推荐 named volume,省心。

第二次挂载的-v mysql-config:/etc/mysql/conf.d是把配置目录挂载出来,后续想追加自定义my.cnf配置而不进入容器,直接往数据卷里放配置文件就行。这一步不是必须的,但值得做,因为 MySQL 调优、修改字符集等场景下你会感谢这个挂载。

4.4 启动后验证

执行完docker run,马上验证容器状态:

docker ps

输出里能看到mysql-dev的状态是Up,端口一列显示0.0.0.0:3306->3306/tcp,说明启动成功。如果状态是Exited或者还在Restarting,继续往下看日志:

docker logs mysql-dev

看到类似于ready for connections的日志,又或者是mysqld: ready for connections,就可以尝试连接了。在宿主机上执行:

mysql -h127.0.0.1 -P3306 -uroot -p

如果你宿主机没有安装 MySQL 客户端,可以进入容器执行:

docker exec -it mysql-dev mysql -uroot -p

输入之前设置的MYSQL_ROOT_PASSWORD,出现mysql>提示符就说明整套流程已经走通。之所以用-h127.0.0.1而不是localhost,是因为有些客户端把localhost解析成 socket 文件连接,而容器里的 socket 文件路径跟宿主机不一样,容易报ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock'。用 IP 连接可以绕过这个问题。

5. 日常操作:进入容器管理 MySQL

5.1 容器内执行 SQL

容器启动起来之后,日常管理操作用得最多的是docker exec。这个命令的语法是:

docker exec -it mysql-dev mysql -uroot -p

-it组合参数表示开启交互式终端。进去之后就是正常的 MySQL 命令行,你想执行 SQL 就敲 SQL。除了交互模式,还可以直接传入 SQL 命令,适合写脚本和快速查看数据:

docker exec mysql-dev mysql -uroot -p123456 -e "show databases;"

注意-p和密码之间不要有空格,直接连写-p123456,否则会提示你手动输入。这种方式在脚本里很实用,比如快速查看某个表的数据、快速执行一条更新。我不建议把密码写在命令里用于生产环境,但本地开发图个方便完全没问题。

5.2 创建数据库与用户授权

进入 MySQL 后,第一件事通常是创建业务库和一个专门的业务账号。用 root 直接跑业务代码不是好习惯,root 权限太大,一旦代码里存在 SQL 注入漏洞,数据库会被整个拖走。我的习惯是每个业务库配一个独立账号。

创建数据库:

CREATE DATABASE myapp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

创建用户并授权:

CREATE USER 'myapp_user'@'%' IDENTIFIED BY 'myapp_pass123'; GRANT ALL PRIVILEGES ON myapp.* TO 'myapp_user'@'%'; FLUSH PRIVILEGES;

这里的'%'表示允许从任意主机连接。如果只想允许本机连接,改成'localhost'即可,但容器环境下一般客户端是通过宿主机 IP 连接,所以%更实用。记得把字符集明确指定为utf8mb4,MySQL 8.0 默认就是utf8mb4,但手动写出来可以避免老配置文件带来的不确定性。

5.3 修改 root 密码与认证插件

本地开发时可以随时改 root 密码:

ALTER USER 'root'@'%' IDENTIFIED BY 'newpassword123'; FLUSH PRIVILEGES;

改完以后重启容器或者重新连接生效。很多时候客户端工具连接不上 MySQL 8.0,报Authentication plugin 'caching_sha2_password' cannot be loaded,这是因为 MySQL 8.0 默认认证插件是caching_sha2_password,而一些老的客户端(特别是老版本 Navicat、旧版 JDBC 驱动)不支持。这种情况有两个解法:

第一种,升级客户端到最新版本。现在 Navicat 16+、最新 MySQL Workbench、最新的mysql-connector-java都支持caching_sha2_password。

第二种,把用户的认证插件改回mysql_native_password:

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root123456'; FLUSH PRIVILEGES;

这个操作对老客户端兼容性最好,但安全性理论上低于caching_sha2_password。本地开发图省事可以直接改,生产环境建议升级客户端而不是降级认证插件。

5.4 容器内配置自定义 my.cnf

如果你需要修改 MySQL 配置,比如开启慢查询日志、调整max_connections、修改sql_mode,推荐的做法不是直接docker exec进容器改文件,因为容器重建后修改就没了。正确做法是往挂载的配置目录里放一个自定义的my.cnf文件。

前面我挂载了mysql-config:/etc/mysql/conf.d,现在往这个数据卷里写一份配置:

docker run -it --rm -v mysql-config:/etc/mysql/conf.d mysql:8.0 bash

进入容器后创建文件:

echo -e "[mysqld]\nmax_connections=500\ncharacter-set-server=utf8mb4\ncollation-server=utf8mb4_general_ci" > /etc/mysql/conf.d/custom.cnf exit

然后重启容器:

docker restart mysql-dev

重启后用SHOW VARIABLES LIKE 'max_connections';看到值是 500,说明配置生效了。--rm参数表示容器退出后自动删除,这种方式可以快速进入一个临时容器修改数据卷里的文件,不会影响正在运行的mysql-dev容器。

6. 用 Docker Compose 管理 MySQL

6.1 为什么需要 Compose

当你只需要跑一个 MySQL 容器时,docker run足够。但现实情况往往是:一个项目里除了 MySQL,还有 Redis、Nginx、后端应用,如果全部手动docker run,记不住参数不说,清理和重建也麻烦。Docker Compose 用一份 YAML 文件描述“一组容器”的启动配置,一条命令全部拉起,一条命令全部停掉。

MySQL 的 Compose 配置其实是把docker run里的参数翻译成 YAML 结构,本质没有任何区别,但可读性和可维护性大大提升。配置还能提交到 Git,团队成员拿到项目仓库后一条命令就能还原数据库环境,这是我强烈推荐你使用 Compose 的原因。

6.2 编写 docker-compose.yml

创建一个项目目录,比如docker-mysql-demo,在里面新建docker-compose.yml:

services: mysql: image: mysql:8.0 container_name: mysql-compose restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: root123456 MYSQL_DATABASE: mydb TZ: Asia/Shanghai ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql - ./mysql-conf:/etc/mysql/conf.d command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci volumes: mysql_data:

这里的./mysql-conf是宿主机当前目录下的一个文件夹,用来放自定义配置。command里可以直接追加 mysqld 的启动参数,效果和写配置文件差不多。restart: unless-stopped表示除非手动停止,否则容器会自动重启,这个参数对开发机和服务器很友好。

6.3 Compose 常用命令

在docker-compose.yml所在目录执行:

docker compose up -d

这条命令会自动拉取镜像、创建数据卷、启动容器。-d表示后台运行。查看状态:

docker compose ps

查看日志:

docker compose logs -f mysql

停止但不删除容器:

docker compose stop

停止并删除容器(数据卷里的数据还在):

docker compose down

注意,down默认不会删除 named volume,数据卷mysql_data还在,下次up数据自动恢复。如果你连数据卷也想一起删就是docker compose down -v,除非你确定数据不要了,否则别加-v。

Docker 的新版命令默认是docker compose(带空格),老的docker-compose命令在旧版本里也能用,新项目直接学新命令即可。如果你还需要批量管理多个 Docker 环境,后续可以把 Compose 项目扩展到 K8s,但那是后话了,先把 Compose 用熟,日常开发已经非常够用。

6.4 数据库备份与恢复

备份 MySQL 数据,最直接的方案是使用mysqldump。即使你的容器在运行,也可以用它导出逻辑备份:

docker exec mysql-compose mysqldump -uroot -p123456 mydb > mydb_backup.sql

注意这里mysqldump是在容器内执行的,输出的内容通过 shell 重定向保存到宿主机当前目录。恢复时反过来:

cat mydb_backup.sql | docker exec -i mysql-compose mysql -uroot -p123456 mydb

-i参数表示保持标准输入打开,让管道里的 SQL 进入容器内的 mysql 进程。两边都要指定数据库名,恢复前先确保目标数据库存在。这套备份恢复方案在开发环境里已经足够可靠,生产环境一般还要做物理备份和 binlog 增量备份。

7. 常见问题与排查实录

7.1 端口被占用

启动容器时报错Bind for 0.0.0.0:3306 failed: port is already allocated,说明宿主机 3306 端口已经被占用。最常见的原因是本机直接装过 MySQL,服务还开着。排查方式:

netstat -ano | grep 3306

找到占用进程后,要么停掉本机 MySQL 服务,要么把容器的宿主机端口映射改成 3307:

docker run -d --name mysql-dev -p 3307:3306 \ -e MYSQL_ROOT_PASSWORD=root123456 \ -v mysql-data:/var/lib/mysql \ mysql:8.0

后续连接时使用-P 3307即可。这个方案也适用于同时跑多个 MySQL 实例,比如一个 5.7、一个 8.0,各占一个端口,互不干扰。

7.2 容器启动后秒退或反复重启

容器启动后状态一直显示Restarting,或者起来几秒就退了,第一件事看日志:

docker logs mysql-dev

常见错误之一:

[ERROR] [MY-011087] [Server] Different lower_case_table_names settings for server ('1') and data dictionary ('0').

这个错误的意思是:数据目录里的初始化配置和容器启动参数里的lower_case_table_names不一致。首次初始化数据卷时使用过某个参数,之后再用不同参数启动同一数据卷就会报这个错。解决办法就是删除数据卷重新初始化:

docker stop mysql-dev docker rm mysql-dev docker volume rm mysql-data

注意这个操作会清空所有数据,执行前先确认数据是否已经备份。重新初始化后保持一致参数即可,比如统一使用默认值。

另一个常见错误是权限问题:

[ERROR] [MY-012574] [InnoDB] Unable to lock ./ibdata1 error: 11

这个大概率是数据卷目录的权限问题。如果是 bind mount 挂在宿主机目录,容器内 mysql 用户没有写入权限。解决办法是给目录授权:

chown -R 1000:1000 /home/me/mysql/data

MySQL 官方镜像内的 mysql 用户 UID 是 999 还是 1000,不同版本有细微差别,检查后调整。最省事的方案是改用 named volume,让 Docker 自己管理目录权限。

7.3 无法连接:socket 文件报错

宿主机上执行mysql -uroot -p时报:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock'

这个报错在 Docker 环境下非常经典。原因是mysql客户端默认通过 socket 文件连接,但容器里的 socket 文件路径是/var/run/mysqld/mysqld.sock,宿主机当然找不到。解决办法就是强制走 TCP:

mysql -h127.0.0.1 -P3306 -uroot -p

加了-h127.0.0.1后客户端就不再尝试 socket 而是走 TCP 协议。还有一种类似情况是容器内执行mysql命令时正常,但宿主机执行报错,也是同一个原因。

7.4 Navicat 等客户端连不上

用 Navicat 连接 Docker 里的 MySQL,遇到以下报错要分清原因:

报错信息原因解决办法
Access denied for user 'root'@'...'密码错误或用户未授权检查密码,确认 root 允许%远程登录
Authentication plugin 'caching_sha2_password' cannot be loaded客户端版本过老升级 Navicat/客户端,或者改回mysql_native_password
SSL connection error客户端开启了 SSL 但服务器证书不可用连接时把 SSL 选项置为 DISABLED

Navicat 新版一般不会遇到认证插件问题,老版本建议直接升级。SSL 问题在本地环境也可以关掉,因为内网传输默认不加密问题不大,生产环境才需要认真配置证书。

7.5 容器删了数据还在吗

这是新手最容易恐慌的问题。直接回答:只要你用了-v mysql-data:/var/lib/mysql之类的挂载,容器删除后数据还在。你把容器删了、镜像删了,数据卷里的数据文件依然完好。下次重新启动挂载同一个数据卷,数据自动恢复。

如果当初没有挂载数据卷,容器删除后就真的什么都没了。所以我的建议从第一条启动命令开始就加上-v参数,养成习惯。

查看当前数据卷列表:

docker volume ls

查看某个数据卷的详细信息:

docker volume inspect mysql-data

在这个输出里可以看到Mountpoint路径,这是宿主机上真实存储数据的位置。备份时可以直接打包这个目录,恢复时放到原位置。

7.6 Docker Desktop 启动失败

在 Windows 上遇到 Docker Desktop 无法启动,常见报错有Docker Desktop failed to start because virtualization support is disabled、Cannot connect to the Docker daemon这类。排错顺序我建议是:

  1. 确认 BIOS 里的虚拟化已开启。
  2. 确认 Windows 功能里的“虚拟机平台”和“适用于 Linux 的 Windows 子系统”已启用。
  3. 确认 WSL2 已安装:wsl --status或者wsl --update。
  4. 关闭第三方杀毒软件和防火墙试试。
  5. 检查 Docker Desktop 是否需要更新,旧版本对新系统兼容性差。

遇到failed to connect to the docker api at npipe:////./pipe/dockerDesktopLinuxEngine这样的报错,通常是 Docker 引擎还没启动完成就尝试连接。点击 Docker Desktop 图标,等托盘图标稳定成绿色再执行命令,别急。

8. 几个实操层面的小建议

8.1 容器资源限制

MySQL 是吃内存的大户。如果你本机内存有限,启动容器前最好就限制资源:

docker run -d --name mysql-dev \ --memory=512m --memory-swap=512m \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=root123456 \ -v mysql-data:/var/lib/mysql \ mysql:8.0

--memory=512m限制容器最多使用 512MB 内存,--memory-swap同时限制 swap。这样跑多个容器时不会因为一个数据库把整机内存吃满。在做生产级调优之前,先用资源限制保证自己的开发机不卡,这是最直接有效的保护手段。

8.2 用别名和脚本固化操作

每次敲一长串docker run命令确实容易打错。我的做法是写一个start_mysql.sh脚本,放在项目里,内容就是完整的docker run命令。以后只要执行脚本就能起一个标准环境。进阶一点可以写几个 alias:

alias mysql-dev='docker exec -it mysql-dev mysql -uroot -p'

以后想进 MySQL 命令行,直接敲mysql-dev就行。这套习惯在项目维护中很省时间,尤其是一段时间没碰,回头再看脚本就明白当时是怎么配置的。

8.3 避免使用 root 跑业务

刚用 Docker 跑 MySQL 时,最容易犯的错就是用 root 账号连接业务代码。当年我偷懒直接 root 跑了一个内部系统,后来发现 compile time 没问题,但审计时心里总是不舒服。正确的做法是每个项目建一个独立账号,只授予它需要的库权限。这不是什么高性能技巧,但却是数据库安全的基本素养。用 Docker 建库建用户如此简单,没必要图省事。

9. 最后分享一个我常用的完整流程

我每次在新机器上搭建 MySQL 环境,基本就是下面这套节奏,你可以直接抄:

# 1. 拉镜像 docker pull mysql:8.0 # 2. 启动容器 docker run -d \ --name mysql-dev \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=root123456 \ -e MYSQL_DATABASE=mydb \ -e TZ=Asia/Shanghai \ -v mysql-data:/var/lib/mysql \ -v ./mysql-conf:/etc/mysql/conf.d \ mysql:8.0 # 3. 验证 docker ps docker logs mysql-dev # 4. 连接 mysql -h127.0.0.1 -P3306 -uroot -p # 5. 创建业务账号(在 mysql> 里执行) CREATE USER 'app'@'%' IDENTIFIED BY 'app123456'; GRANT ALL PRIVILEGES ON mydb.* TO 'app'@'%'; FLUSH PRIVILEGES;

以上这套流程,我在 Windows、macOS、Linux 三种系统上都实测过,能覆盖 90% 的开发场景。Docker 跑 MySQL 真正上手后,你会觉得安装数据库这件事再也不是项目的阻碍,而是基础设施里最平平无奇的一环。对我个人而言,最大的体会有两个:一是数据卷的使用越早养成习惯越好,二是任何奇怪的问题先看docker logs永远比瞎猜高效。希望这篇文章能让你少走点弯路,把更多时间花在真正有价值的业务代码上。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 5:42:35

Docker启动MySQL实战:从基础安装到数据持久化与故障排查

“用docker启动mysql”这个需求,我几乎每周都会碰到一次。不管是给新项目搭一个测试库,还是帮同事在本地还原生产环境,最顺手的方案就是Docker跑MySQL。为什么?因为MySQL能力很强,但传统方式安装起来真的折磨人&#x…

作者头像 李华
网站建设 2026/9/28 5:42:18

Azure Container App Debug Console 实战:无 SSH 时代容器排障的终极利器

容器应用崩了,日志里只剩一行exit code 139,剩下的全是空白。你想进到容器里看看进程状态、跑几个命令定位问题,却发现 Azure Container App 不像传统 VM 那样给你开 SSH。这是不少人第一次被 Azure Container App 的 Debug Console “救回来…

作者头像 李华
网站建设 2026/9/28 5:42:17

Claude Code + Chrome MCP:浏览器自动化测试配置与验证指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 5:39:46

基于AlexNet的PyTorch动漫角色识别实战:从训练到PyQt界面

简介:这份资源面向具备Python与PyTorch基础、希望入门卷积神经网络图像分类的开发者与学习者,以AlexNet模型为核心,解决动漫角色识别这一具体分类任务。压缩包共9个文件,包含3个py脚本、4张jpg提示图、1个txt依赖清单和1份docx说明…

作者头像 李华
网站建设 2026/9/28 5:39:43

工厂设备报修管理系统:Node.js+Vue全栈开发实战

1. 项目背景与核心需求做工厂设备维护报修管理系统,是我近几年接过比较典型的企业内部工具类项目。这类系统单看技术含量不算顶尖,但真要落地好用,涉及的业务细节一点都不少。这个项目用 Node.js Vue 实现了生产设备的台账管理、故障报修、维…

作者头像 李华
网站建设 2026/9/28 5:39:36

Wi-Fi 7部署避坑指南:从MLO配置到PoE供电的十大高频问题

1. 选型期的三个坑:别把Wi-Fi 7当万能药去年年底第一次给客户部署Wi-Fi 7 AP,我原本以为只是把设备从Wi-Fi 6换到Wi-Fi 7,插上PoE网线、更新一下后台模板就能收工。结果从第一天起就不断踩坑:客户会议室里明明显示连接速率1882Mbp…

作者头像 李华