V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lyusantu
V2EX  ›  程序员

Docker 保存镜像问题求解

  •  
  •   lyusantu · 2023-04-11 11:43:24 +08:00 · 1370 次点击
    这是一个创建于 593 天前的主题,其中的信息可能已经有所发展或是发生改变。
    需求:
    想把部署在 Docker 中的 MySQL 镜像携带数据源打包,然后部署至一台不能链接外网的服务器

    目前是做法:
    1. 进入 mysql 容器,迁移 /var/lib/mysql 至自定义文件夹
    2. 更改 mysql 配置文件 datadir=自定义文件夹
    3. 退出容器,docker restart mysql
    4. docker save 命令打包
    5. 将打包后的文件上传至另一台服务器,并通过 docker load 命令加载容器
    6. docker run mysql 后,只有 mysql 的 yuanshiwenj 原始文件,自定义的数据库丢失

    求解,如何能把数据源一起打包为镜像并且加载后仍然存在(导出 sql 并在重新加载后执行的方式是可行的,但是不适用需求的应用场景)
    10 条回复    2023-04-11 21:11:21 +08:00
    bugmakerxs
        1
    bugmakerxs  
       2023-04-11 11:54:55 +08:00   ❤️ 1
    #!/bin/bash

    BASE_DIR=$(cd `dirname $0`;pwd)
    echo $BASE_DIR

    docker run -p 3306:3306 \
    --name mysql \
    -e TZ='Asia/Shanghai' \
    -v $BASE_DIR/log:/var/log/mysql \
    -v $BASE_DIR/data:/var/lib/mysql \
    -v "$BASE_DIR/conf/mysql.conf.d":"/etc/mysql/mysql.conf.d" \
    -e MYSQL_ROOT_PASSWORD=pwd -d mysql:5.7

    数据挂载到物理机上,物理机上的$BASE_DIR/data 可以复制到另一个机器,数据都在。
    512357301
        2
    512357301  
       2023-04-11 11:58:13 +08:00 via Android   ❤️ 3
    docker save 保存的是镜像( image ),docker export 保存的是容器( container );
    docker load 用来载入镜像包,docker import 用来载入容器包,但两者都会恢复为镜像;

    你这种情况应该用 docker export 导出容器,用 docker import 导入 tar 包

    参考链接(用 base64 解码):aHR0cHM6Ly93d3cucnVub29iLmNvbS9kb2NrZXIvZG9ja2VyLWNvbW1hbmQtbWFudWFsLmh0bWw=
    aru
        3
    aru  
       2023-04-11 11:59:05 +08:00
    楼上正解
    还有更好的办法是使用 docker-compose
    lyusantu
        4
    lyusantu  
    OP
       2023-04-11 13:27:34 +08:00
    @512357301 #2 export 我试过,但是 import 后再执行时会报错 docker: Error response from daemon: No command specified.

    网上搜了一下说是需要在结尾指定 command ,我于是在结尾追加 /bin/bash ,可以成功启动,但是状态会变为 Exited

    并且 docker logs 不会显示任何日志
    lyusantu
        5
    lyusantu  
    OP
       2023-04-11 13:32:09 +08:00
    @512357301 #2 已经解决了,是我的命令追加的有问题,但是仍然没有数据库存在,我再试试其它方式
    thinkershare
        6
    thinkershare  
       2023-04-11 13:44:43 +08:00   ❤️ 2
    @lyusantu 数据是单独的卷,你要讲卷重新挂载上去。我日常开发常常这样完,完全没问题。容器应该状态,将所有可以变更的东西都放到容器外,这样可以就可以再另外一台机器直接启动一个同版本的新容器,挂载上目录就可以跑了。避免需要将容器导出为镜像的流程。
    lyusantu
        7
    lyusantu  
    OP
       2023-04-11 14:04:14 +08:00
    @thinkershare #6 好的,感谢解惑,本来是想通过直接导出来解决的

    挂载数据盘其实跟我把数据库导出为 sql 文件,然后再重新导入的结果一样吧
    kaedeair
        8
    kaedeair  
       2023-04-11 14:44:57 +08:00   ❤️ 1
    你如果用的官方镜像可以把 /var/lib/mysql 和 /etc/mysql/conf.d 打包出来,然后起新的容器时挂载回去就行了
    thinkershare
        9
    thinkershare  
       2023-04-11 14:55:10 +08:00   ❤️ 1
    @lyusantu 挂载数据卷要简单很多,SQL 导出费事又费力。直接将卷打包后再另外一台机器上解压后,重新使用相同命令启动新容器,什么都不需要。不过调试阶段,怎么折腾都无所谓。
    512357301
        10
    512357301  
       2023-04-11 21:11:21 +08:00 via Android
    @lyusantu 可以先把容器停止了,别删除哈,然后用 docker cp 命令,把容器里的 /var/lib/mysql 和 /etc/mysql/conf.d 分别拷贝到本地某个目录下,然后把这个目录打包成.tar 格式的(tar 包能保留 linux 的文件夹权限),传到新机器,解包。然后在新机器直接用 mysql 的镜像启动,官方镜像就行,把这两个目录挂载到对应位置,理论上能一次性启动成功。
    第一次玩 docker 的话,可能没法搞定,那可以在新机器先不挂载任何目录的情况下通过教程先启动一个干净的 mysql(跟旧机器同版本哈,理论上不用追加 cmd),确认启动成功没问题的话,再在这个容器基础上加上挂载目录,说起来有点绕,其实本质是 mysql 镜像初始化启动的时候会自己加一些环境变量或者其他的杂七杂八的,所以才先启动一个,然后再它的基础上改。
    可以用 Portainer 管理 docker ,很好用,改容器配置也很直观。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2721 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:14 · PVG 23:14 · LAX 07:14 · JFK 10:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.