估计很多人应该都有这个烦恼,就是Docker安装完,发现有些关键目录没有映射出来,命令行去管理文件很是头大。比如青龙更新后,新加的deps目录,你一定没有做映射。于是,这篇就给大家指条路,解决这个烦恼。
第一种方法(肯定不是你想要的,可以直接跳过吧):
思路如下:
- 备份配置
- 重装容器,在部署命令行里,把你需要的目录映射加上,
- 部署容器
- 恢复配置
第二种方法(就是你想要的 -_-|| ):
- 备份配置:一开始,还是要先普及一下docker cp命令的用法:把容器内的A文件拷贝到容器外:
docker cp [OPTIONS] 容器名称或ID:容器内的A文件路径 容器外的目标路径|-
把容器外的B文件拷贝到容器内:
docker cp [OPTIONS] 容器外的B文件路径|- 容器名称或ID:容器内的路径
关于路径,容器外路径可以是相对路径也可以是绝对路径,相对路径取决于你当前命令执行的位置;容器内,都是相对于容器的/根路径。
举个栗子,这也是备份的命令:
#把qinglong容器内db及config目录及文件拷贝到本地系统外挂的Udisk盘下 docker cp qinglong:/ql/db /media/Udisk/ docker cp qinglong:/ql/config /media/Udisk/ docker cp qinglong:/ql/deps /media/Udisk/
- docker ps看一下你容器的ID是啥,比如 10381e716af5
- 关闭docker服务,做好修改配置文件的准备,不关停,就改不了:
#关闭docker服务 systemctl stop docker
- 进入docker containers目录找到对应容器的文件夹
cd /var/lib/docker/containers #执行ls命令,列出目录下的内容 ls
你会看到一大串的字符,找到以容器ID开头的目录名字符串
10381e716af519391315fdd90e7dd2d3ddead20c01389d44a519d90462c0670d
- 修改配置文件:你可以vim打开你容器ID对应的配置文件,你也可以用WinSCP之类的工具连上你的主机,可视化编辑配置文件,我推荐后者!!!!!文件路径为: /var/lib/docker/containers/10381e716af519391315fdd90e7dd2d3ddead20c01389d44a519d90462c0670d/config.v2.json
vim /var/lib/docker/containers/10381e716af519391315fdd90e7dd2d3ddead 20c01389d44a519d90462c0670d/config.v2.json
这里开始,就是精细活儿了,如果你对命令行操作实在是没谱,强烈建议你去找类似WinSCP之类的工具连接到你的主机,进行后续的编辑工作,因为要改json啦!!!!
{"StreamConfig":{},"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false, "RemovalInProgress":false,"Dead":false,"Pid":31471,"ExitCode":0,"Error":"","StartedAt":"2021- 11-17T06:45:28.719784715Z","FinishedAt":"2021-11-17T06:39:53.383323079Z","Health":null}, "ID":"10381e716af519391315fdd90e7dd2d3ddead20c01389d44a519d90462c0670d", "Created":"2021-11-05T09:42:23.554999321Z","Managed":false,"Path":"./docker/docker-entrypoint.sh", "Args":[],"Config":{"Hostname":"qinglong","Domainname":"","User":"","AttachStdin":false, "AttachStdout":false,"AttachStderr":false,"ExposedPorts":{"5700/tcp":{}},"Tty":true, "OpenStdin":true,"StdinOnce":false,"Env":["ENABLE_HANGUP=true","ENABLE_WEB_PANEL=true", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","NODE_VERSION=16.13.0", "YARN_VERSION=1.22.15","LANG=zh_CN.UTF-8","SHELL=/bin/bash","PS1=\\[email protected]\\h:\\w $ ","QL_DIR=/ql"],"Cmd":null,"Image":"whyour/qinglong:latest","Volumes":null,"WorkingDir":"/ql", "Entrypoint":["./docker/docker-entrypoint.sh"],"OnBuild":null,"Labels":{"maintainer":"whyour"}}, "Image":"sha256:81eaf0110f12b0e523f9c526e3f009ddfd3c83efc7d65afdd72d8ec7d3ba8850", "NetworkSettings":{"Bridge":"","SandboxID":"e4e275e452db1fcde94f1b6397992a61e204f6ac9288ec6d4a188975a0c52a63", "HairpinMode":false,"LinkLocalIPv6Address":"","LinkLocalIPv6PrefixLen":0,"Networks":{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"11e1af9f8dbda5a5383048a0aad41951087405db2412ab959d9f787d9e6b313c", "EndpointID":"a62774057a7aef93b6f2864bef87312c48415208c3c47b71d76d6f6c31e47ae5", "Gateway":"172.17.0.1","IPAddress":"172.17.0.3","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"", "GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:03","DriverOpts":null,"IPAMOperational":false}}, "Service":null,"Ports":{"5700/tcp":[{"HostIp":"0.0.0.0","HostPort":"5700"}]},"SandboxKey":"/var/run/docker/netns/e4e275e452db", "SecondaryIPAddresses":null,"SecondaryIPv6Addresses":null,"IsAnonymousEndpoint":false,"HasSwarmEndpoint":false}, "LogPath":"/var/lib/docker/containers/10381e716af519391315fdd90e7dd2d3ddead20c01389d44a519d90462c0670d/ 10381e716af519391315fdd90e7dd2d3ddead20c01389d44a519d90462c0670d-json.log", "Name":"/qinglong","Driver":"overlay2","OS":"linux","MountLabel":"","ProcessLabel":"", "RestartCount":0,"HasBeenStartedBefore":true,"HasBeenManuallyStopped":false, "MountPoints":{ "/ql/config":{"Source":"/ql/config","Destination":"/ql/config","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/ql/config","Target":"/ql/config"},"SkipMountpointCreation":false}, "/ql/db":{"Source":"/ql/db","Destination":"/ql/db","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/ql/db","Target":"/ql/db"},"SkipMountpointCreation":false}, "/ql/jbot":{"Source":"/ql/jbot","Destination":"/ql/jbot","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/ql/jbot","Target":"/ql/jbot"},"SkipMountpointCreation":false}, "/ql/log":{"Source":"/ql/log","Destination":"/ql/log","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/ql/log","Target":"/ql/log"},"SkipMountpointCreation":false}, "/ql/raw":{"Source":"/ql/raw","Destination":"/ql/raw","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/ql/raw","Target":"/ql/raw"},"SkipMountpointCreation":false}, "/ql/repo":{"Source":"/ql/repo","Destination":"/ql/repo","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/ql/repo","Target":"/ql/repo"},"SkipMountpointCreation":false}, "/ql/scripts":{"Source":"/ql/scripts","Destination":"/ql/scripts","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/ql/scripts","Target":"/ql/scripts"},"SkipMountpointCreation":false}}, "SecretReferences":null,"ConfigReferences":null,"AppArmorProfile":"", "HostnamePath":"/var/lib/docker/containers/10381e716af519391315fdd90e7dd2d3ddead20c01389d44a519d90462c0670d/hostname", "HostsPath":"/var/lib/docker/containers/10381e716af519391315fdd90e7dd2d3ddead20c01389d44a519d90462c0670d/hosts", "ShmPath":"/var/lib/docker/containers/10381e716af519391315fdd90e7dd2d3ddead20c01389d44a519d90462c0670d/mounts/shm", "ResolvConfPath":"/var/lib/docker/containers/10381e716af519391315fdd90e7dd2d3ddead20c01389d44a519d90462c0670d/resolv.conf", "SeccompProfile":"","NoNewPrivileges":false}
你看到的就是这么一堆鬼玩意儿。。。。不要晕。。。淡定!
找到“MountPoints”,你就能看到你映射的目录了,json数据是很有规律的!我们此行的目的:把容器内的/ql/deps映射为本地系统的/ql_local/deps
公务员考试找规律,这简直小菜吧!!
"/ql/scripts":"Source":"/ql/scripts","Destination":"/ql/scripts","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":"Type":"bind","Source":"/ql/scripts","Target":"/ql/scripts"},"SkipMountpointCreation":false}},
蓝色的部分 是容器内的目录, 黄色的部分 是本地系统即容器外的目录,我们改一改得到
"/ql/deps":"Source":"/ql/deps","Destination":"/ql_local/deps","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":"Type":"bind","Source":"/ql/deps","Target":"/ql_local/deps"},"SkipMountpointCreation":false}},
把改好的这部分,粘贴到 "MountPoints":{ 之后,再检查一下,不要破坏json的结构哈,你可以找个json校验的工具,比如 https://www.sojson.com/ ,如果告诉你老铁没毛病,压缩完,贴回去就好。
- 到这里,配置文件改好存好,你基本上成功了,接下来请把刚才备份的deps文件拷进你映射目标路径/ql_local/deps里,否则你启动docker后,不管容器里还是容器外,deps目录下都是空的。。。不要问我怎么知道的了
我们把刚才停掉的docker服务打开
#启动docker服务
systemctl start docker
- 等待一下下,青龙都是自启的,要没起来你就 “docker start 你的青龙容器名称”,启动一下!
- 目录映射便添加成功了
写这么多,感觉比登天还难,实际操作起来非常简单,不要被纸老虎吓到了!!
如果你对docker命令很熟悉的话,或者有冲动想要学习的话,你研究一下docker export和docker import,在重新run新容器时,把新目录映射加上也可以。
docker container export -o 本地路径的qinglong.docker 青龙容器名称
docker import 本地路径的qinglong.docker 新青龙容器名称
docker run -ti -v "/ql_local/deps":/ql/deps 新青龙容器名称 /bin/bash
#如果对老名字情有独钟 可以rm老容器 再rename新容器为老名字即可
好吧,就这样吧!
感觉还是直接备份新建简单点
谢谢,分享学习了
辛苦大佬分享了,我先学习一下
感谢分享,插眼学习
真棒,感谢分享!
先看看,不明白的地方再问