Docker容器数据备份和迁移方法

前言

Docker容器删了数据就没了?想把容器从一台服务器迁到另一台?本文讲Docker容器数据备份和迁移的几种方法,包括容器快照、数据卷备份、镜像导出。

一、Docker数据存哪里

Docker数据有两种存法:

  1. 容器内部:数据存在容器的可写层,容器删了数据就没了
  2. 数据卷(Volume):数据存在宿主机上,容器删了数据还在

重要: 生产环境一定要用数据卷,不然容器一删数据全没。

二、方法1:容器快照(commit)

把容器当前状态打包成一个新镜像。

步骤

第一步:查看容器ID

docker ps

找到要备份的容器ID。

第二步:提交成新镜像

docker commit 容器ID 备份镜像名:标签

例子:

docker commit mynginx nginx-backup:v1

第三步:导出镜像成文件

docker save -o nginx-backup.tar nginx-backup:v1

第四步:传到新服务器

scp nginx-backup.tar root@新服务器IP:/root/

第五步:新服务器导入

docker load -i nginx-backup.tar

第六步:新服务器启动容器

docker run -d --name mynginx -p 80:80 nginx-backup:v1

优缺点

优点: 简单,整个容器都打包了
缺点: 镜像文件大,不适合大数据量

三、方法2:数据卷备份

如果用了数据卷,直接备份数据卷里的文件。

步骤

第一步:看数据卷挂载在哪

docker inspect 容器名 | grep Mounts

输出里找 Source,就是宿主机上的路径。

例子:

"Mounts": [
    {
        "Source": "/data/mysql",
        "Destination": "/var/lib/mysql"
    }
]

数据在宿主机的 /data/mysql 目录。

第二步:打包备份

tar -zcvf mysql-backup.tar.gz /data/mysql

第三步:传到新服务器

scp mysql-backup.tar.gz root@新服务器IP:/root/

第四步:新服务器解压

tar -zxvf mysql-backup.tar.gz -C /data/

第五步:新服务器启动容器,挂载数据卷

docker run -d --name mysql -v /data/mysql:/var/lib/mysql -p 3306:3306 mysql:5.7

优缺点

优点: 数据和容器分离,灵活
缺点: 要自己管理数据目录

四、方法3:docker cp拷贝文件

把容器里的文件拷出来。

拷出来

docker cp 容器名:/容器内路径 宿主机路径

例子:

docker cp mynginx:/usr/share/nginx/html /data/backup/html

拷进去

docker cp 宿主机路径 容器名:/容器内路径

例子:

docker cp /data/backup/html/index.html mynginx:/usr/share/nginx/html/

五、MySQL容器备份

备份MySQL数据

docker exec 容器名 mysqldump -uroot -p123456 数据库名 > backup.sql

例子:

docker exec mysql mysqldump -uroot -p123456 test > test.sql

恢复MySQL数据

docker exec -i 容器名 mysql -uroot -p123456 数据库名 < backup.sql

例子:

docker exec -i mysql mysql -uroot -p123456 test < test.sql

六、常见坑

坑1:容器删了数据没了

没用数据卷,容器删了数据全没。

解决: 一定要用 -v 挂载数据卷。

坑2:commit的镜像太大

把整个容器都打包了,包括临时文件。

解决: 尽量用数据卷备份,不要用commit。

坑3:数据权限不对

备份恢复后,容器里读不了数据。

原因: 文件所有者不对。

解决: 改权限:

chown -R 999:999 /data/mysql

(MySQL容器用的是999用户)

坑4:数据库没停就备份

MySQL还在写数据,备份出来不一致。

解决: 用mysqldump逻辑备份,不要直接拷文件。

总结

记住:

  1. 生产环境一定要用数据卷(-v)
  2. 小容器用commit快照备份
  3. 大数据量直接备份数据卷目录
  4. 数据库用mysqldump逻辑备份
  5. 备份完要测试能不能恢复

最常用:

# 备份数据卷
tar -zcvf backup.tar.gz /data/容器数据/

# 恢复数据卷
tar -zxvf backup.tar.gz -C /data/

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-9 07:43 

Docker运行MySQL,数据持久化配置

前言

用Docker跑MySQL,删了容器数据就没了?那是没挂数据卷。本文讲怎么用Docker跑MySQL并持久化数据。

一、基本运行

最简单的跑法

docker run -d \
  --name mysql \
  -e MYSQL_ROOT_PASSWORD=123456 \
  mysql:5.7

问题: 删了容器,数据库里的数据全没了。

二、加数据卷持久化

完整命令

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -v /data/mysql:/var/lib/mysql \
  mysql:5.7

解释

  • -p 3306:3306 端口映射
  • -e MYSQL_ROOT_PASSWORD=123456 设置root密码
  • -v /data/mysql:/var/lib/mysql 数据卷挂载
    • 宿主机 /data/mysql 目录
    • 容器里 /var/lib/mysql 目录

这样容器删了,数据还在宿主机上。

三、其他常用配置

1. 设置字符集

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -v /data/mysql:/var/lib/mysql \
  -v /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf \
  mysql:5.7 \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci

2. 创建数据库和用户

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e MYSQL_DATABASE=mydb \
  -e MYSQL_USER=myuser \
  -e MYSQL_PASSWORD=123456 \
  -v /data/mysql:/var/lib/mysql \
  mysql:5.7

3. 挂载配置文件

先在宿主机创建my.cnf:

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
max_connections=1000

然后挂载:

docker run -d \
  --name mysql \
  -v /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf \
  -v /data/mysql:/var/lib/mysql \
  mysql:5.7

四、Docker Compose方式

version: '3'
services:
  mysql:
    image: mysql:5.7
    container_name: mysql
    restart: always
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: mydb
    volumes:
      - /data/mysql:/var/lib/mysql
      - /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf

启动:

docker-compose up -d

五、连接MySQL

进入容器连接

docker exec -it mysql mysql -uroot -p123456

从宿主机连接

mysql -h127.0.0.1 -P3306 -uroot -p123456

用Navicat等工具

  • 主机:服务器IP
  • 端口:3306
  • 用户名:root
  • 密码:123456

六、备份和恢复

备份数据库

docker exec mysql mysqldump -uroot -p123456 mydb > /data/backup/mydb.sql

恢复数据库

docker exec -i mysql mysql -uroot -p123456 mydb < /data/backup/mydb.sql

七、常见坑

坑1:密码不对

报错:

Access denied for user 'root'@'localhost'

检查: 环境变量 MYSQL_ROOT_PASSWORD 设了没?

坑2:权限问题

宿主机 /data/mysql 目录权限不对:

chmod -R 777 /data/mysql

坑3:端口被占用

3306端口被宿主机的MySQL占了:

Bind for 0.0.0.0:3306 failed: port is already allocated

解决: 换个端口:

-p 3307:3306

坑4:数据没持久化

没加 -v 挂载,删了容器数据就没了。

检查: 有没有 -v /data/mysql:/var/lib/mysql?

坑5:第一次启动慢

MySQL第一次启动要初始化数据,要等个十几秒。

等不及就先别连,过一会再试。

坑6:字符集不对,中文乱码

加参数:

--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci

八、推荐配置

docker run -d \
  --name mysql \
  --restart=always \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=你的密码 \
  -v /data/mysql:/var/lib/mysql \
  -v /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf \
  mysql:5.7
  • --restart=always 开机自动启动
  • 数据挂载到 /data/mysql
  • 配置文件挂载

总结

记住:

  1. 一定要挂数据卷,不然删容器数据就没了
  2. 用 -e MYSQL_ROOT_PASSWORD 设密码
  3. 用 -p 3306:3306 映射端口
  4. 配置文件也可以挂载进去

最常用:

docker run -d --name mysql -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -v /data/mysql:/var/lib/mysql \
  mysql:5.7

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 08:24 

Docker数据卷挂载,容器数据持久化

前言

删了Docker容器,数据全没了?那是因为你没挂数据卷。本文讲怎么用数据卷让容器数据持久化。

一、为什么需要数据卷

容器里的数据,容器删了就没了。

docker run -d --name mysql mysql:5.7
# 删了容器,数据就没了
docker rm -f mysql

解决: 把数据存到宿主机,容器删了数据还在。

二、三种数据持久化方式

1. 绑定挂载(bind mount)

把宿主机的目录直接挂到容器里。

docker run -v /宿主机路径:/容器路径 镜像名

例子:

docker run -d \
  -v /data/mysql:/var/lib/mysql \
  mysql:5.7

特点: 简单直接,数据在你自己的目录里。

2. 命名卷(named volume)

Docker管理的数据卷。

docker volume create mydata
docker run -v mydata:/var/lib/mysql mysql:5.7

特点: Docker帮你管理位置,不用你关心存在哪。

3. 临时挂载(tmpfs)

存在内存里,重启就没。

docker run --tmpfs /tmp 镜像名

特点: 临时用,存敏感数据。

三、常用场景

场景1:MySQL数据持久化

docker run -d \
  --name mysql \
  -v /data/mysql:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=123456 \
  mysql:5.7

场景2:Nginx挂载网站文件

docker run -d \
  --name nginx \
  -v /data/www:/usr/share/nginx/html \
  -p 80:80 \
  nginx

场景3:挂载配置文件

docker run -d \
  -v /data/nginx/nginx.conf:/etc/nginx/nginx.conf \
  nginx

场景4:挂载日志

docker run -d \
  -v /data/logs/nginx:/var/log/nginx \
  nginx

四、Docker Compose里的挂载

services:
  mysql:
    image: mysql:5.7
    volumes:
      - /data/mysql:/var/lib/mysql
      # 或者用命名卷
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:

五、常用命令

查看所有数据卷

docker volume ls

查看数据卷详情

docker volume inspect 数据卷名

删除没用的数据卷

docker volume prune

查看容器挂载

docker inspect -f '{{.Mounts}}' 容器名

六、只读挂载

只想让容器读,不让写:

docker run -v /data/www:/usr/share/nginx/html:ro nginx

后面加个 :ro 就是只读。

七、常见坑

坑1:改了配置文件不生效

挂了配置文件,改了宿主机的文件,重启容器还是旧的。

原因: 容器没真正重启。

解决:

docker restart 容器名

坑2:权限问题

挂载的目录,容器里的用户读不了。

原因: 宿主机目录权限不对。

解决:

chmod -R 777 /data/mysql

坑3:Windows/Mac路径问题

Windows路径写法不一样:

docker run -v D:\data:/var/lib/mysql mysql

Mac/Linux用:

docker run -v /Users/xxx/data:/var/lib/mysql mysql

坑4:挂载文件不存在

宿主机的文件不存在,Docker会自动建一个目录。

比如:

docker run -v /data/nginx.conf:/etc/nginx/nginx.conf nginx

如果 /data/nginx.conf 不存在,Docker会建一个叫 nginx.conf 的目录,容器里就挂错了。

解决: 先创建文件:

touch /data/nginx.conf

坑5:数据卷删了数据就没了

docker volume rm mydata

数据卷删了,里面的数据也没了。

解决: 重要数据定期备份。

八、最佳实践

  1. 数据库一定要挂载数据卷,不然容器删了数据就没了
  2. 配置文件挂载到宿主机,改起来方便
  3. 日志挂载到宿主机,方便查看和切割
  4. 网站文件挂载到宿主机,更新代码不用重新打镜像

总结

记住:

  1. -v 宿主机路径:容器路径 就是挂载
  2. 数据库一定要挂数据卷
  3. 删容器不删数据,因为数据在宿主机
  4. 挂载文件不存在会变成目录,要注意

最常用:

docker run -v /data/mysql:/var/lib/mysql mysql

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 08:19 
'); })();