在服务器部署的进阶之路上,部署限制内存的数据库是一个必经的关卡 。对于这种小内存的 VPS(比如 RackNerd),如果直接裸跑默认配置的 MySQL 8.0,它会一口气吞掉 400MB 甚至更多的内存,极易导致服务器 OOM(内存溢出)死机。
这篇文章记录了如何通过 Docker 配合自定义 my.cnf 文件,将 MySQL 的内存占用极限压榨到 200MB 以内 ,同时理清了“环境容器化”的核心思想 。
💡 核心认知:MySQL 是“发电厂”,不是“随用随插的 U 盘”#
在刚接触全栈部署时,很容易产生一个误区:以为“只要 JSP 或 Vue 项目跑起来了,才需要把 MySQL 拉起来”。
真实情况是:
MySQL 是一个需要 24 小时常驻后台独立运行的基础设施。它就像市里的“发电厂”,而我们的各种 Web 项目(无论是以前写的 JSP,还是以后的 Spring Boot/C#)都只是“用电器”。不管用电器开没开,发电厂都必须在那运转,守着 3306 端口等待连接。
一台服务器上,通常只需要运行这一个 MySQL 容器实例。未来不管开发多少个新项目,只需要在这个实例里 CREATE DATABASE 创建新的库即可,数据完全隔离。
🛠️ 实战步骤:打造精简版 MySQL 容器#
为了方便日后在 VS Code 里通过 Remote-SSH 直接修改配置,我们将配置文件和数据目录挂载到宿主机。
1. 创建宿主机目录#
mkdir -p ~/mysql/conf ~/mysql/data
cd ~/mysql2. 编写极限压缩内存的 my.cnf (INI 格式)#
这是限制 MySQL 内存消耗的核心图纸。在 ~/mysql/conf/my.cnf 中写入:
[mysqld]
# 核心杀手锏:关闭性能监控,省下 100MB+ 内存
performance_schema = OFF
# 核心参数:限制 InnoDB 缓冲池大小(默认通常 128M,压缩到 64M)
innodb_buffer_pool_size = 64M
# 限制最大连接数(默认 151,压缩到 50 足够个人全栈项目使用)
max_connections = 50
# 跳过 DNS 解析,提升连接速度
skip-name-resolve
# 统一字符集,防止前后端中文乱码
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci注意:将其用作个人博客这个配置还算不错,但要注意“skip-name-resolve”功能,MySQL将不再解析
localhost,连接地址必须硬编码写成120.0.0.1。
3. 编写 docker-compose.yml#
在 ~/mysql/ 目录下创建 docker-compose.yml,把我们的图纸挂载进去:
services:
mysql-lite:
image: mysql:8.0
container_name: mysql-lite
restart: always
environment:
MYSQL_ROOT_PASSWORD: "这里填你的强密码"
ports:
- "3306:3306"
volumes:
- ./conf/my.cnf:/etc/mysql/conf.d/my.cnf
- ./data:/var/lib/mysql
command: --default-time-zone='+08:00'4. 一键启动与内存验证#
# 后台启动容器
docker compose up -d
# 查看内存占用情况(检验压榨成果)
docker stats正常情况下,内存占用会被稳稳控制在 150MB - 180MB 左右。
🔧 常见运维操作回顾#
1. 修改配置后如何生效?#
MySQL 只有在启动的那一刻才会读取 my.cnf 文件。所以如果后续修改了配置文件,必须重启容器强迫它重新加载规则:
docker restart mysql-lite2. 如何优雅清理废弃的旧数据库容器?#
为了防止旧容器占用端口和内存,必须将其彻底清理:
# 1. 停止运行
docker stop 旧容器名称或ID
# 2. 删除容器
docker rm 旧容器名称或ID
# 3. (可选) 清理未被使用的无用数据卷,释放硬盘空间
docker volume prune总结: 这套组合拳打完,不仅跳出了以前“只懂写增删改查”的代码舒适区 ,更重要的是在服务器部署层面建立起了“容器化隔离”和“底层参数调优”的思维 。以后无论换什么云服务器,这套方案都可以几分钟内快速复刻。










