前言
a. 本文主要为 Docker 的视频教程 https://edu.51cto.com/course/19702.html?source=so 笔记.
b. 环境为 CentOS 7.0 云服务器
c. 上一篇: Dockerfile 自动制作 Docker 镜像 (一)-- 基本命令
Dockerfile 其它命令
1. ADD 和 COPY 命令
在 Dockerfile 中使用 ADD 或 COPY 命令向容器中复制文件. 但 ADD 会自动解压 tar.gz 包.
例:
- [[email protected]_0_2_centos ~]# gzip -dc test.tar.gz | tar -tvf -
- drwxr-xr-x root/root 0 2020-05-13 20:47 test/
- -rw-r--r-- root/root 0 2020-05-13 20:47 test/a.txt
- -rw-r--r-- root/root 0 2020-05-13 20:47 test/b.txt
使用 ADD 命令: ADD test.tar.gz / 后
- [email protected]:/# ls -al | grep test
- drwxr-xr-x 2 root root 4096 May 13 12:47 test ???# 注意此时 test 已经变为目录
使用 COPY 命令: COPY test.tar.gz / 后
- [email protected]:/# ls -al | grep test
- -rw-r--r-- 1 root root 153 May 13 12:55 test.tar.gz ???# 注意此时 test 仍为 tar.gz 包
- TIPS:
之前 test.tar.gz 在主机 root 用户的的根目录下, 试图使用 ADD ~/test.tar.gz / 的写法来拷贝文件, 会报:
ADD failed: stat /var/lib/docker/tmp/docker-builder291398651/~/test.tar.gz: no such file or directory
ADD 和 COPY 只能拷贝当前目录下的文件.
cat /var/log/mysqld.log | grep -o [email protected]*$ | awk '{print $2}' | tail -n 1
2. EXPOSE 命令:
EXPOSE <YOUR_PORT1> <YOUR_PORT2> ...
指定容器中的程序要使用的端口, 以便在使用 "-P" 启动容器时, 自动做端口映射. 一般写在 CMD 之前.
3. ENTRYPOINT 命令:
将用户启动容器时的输入作为参数给到 ENTRYPOINT 后面的程序. 如写为:
- ENTRYPOINT ["/bin/bash"] # dockerfile 中
- docker run <IMAGE_ID> some_string # 执行命令时
则容器实际执行
/bin/bash some_string
4. ENV 命令
用于设置环境变量
5. ENTRYPOINT, ENV 结合使用实现自动设置 MySQL 密码
主要思路:
ENTRYPOINT 可以将用户启动容器时的输入变为参数, 配合脚本可以完成设置密码的操作. 同时为了应对用户不输入的情况, 需要使用 ENV 设置一个变量作为默认的密码, 并在脚本中加入判断.
Dockerfile 文件:
- FROM centos7_mysql
- COPY change_mysql_password.sh /
- RUN rm -rf /var/lib/MySQL
- RUN mkdir /var/lib/MySQL
- RUN mysqld --initialize --user=MySQL --datadir=/var/lib/MySQL
- ENV [email protected]
- EXPOSE 3306
- ENTRYPOINT ["/bin/bash", "/change_mysql_password.sh"] # 只有在执行脚本时才需要 / bin/bash
change_mysql_password.sh 文件:
- #!/bin/bash
- if [ ! -z $1 ];then
- MYSQL_NEW_PASSWORD=$1
- fi
- mysqld -u root &
- sleep 10 # 极不严谨! 在 MySQL 未启动时无法设置密码, 而启动需要一定时间, 因此睡 10s 等待启动完成
- old_password=`cat /var/log/mysqld.log | grep -o [email protected]*$ | awk '{print $2}' | tail -n 1`
- mysqladmin -u root -p${old_password} password ${MYSQL_NEW_PASSWORD}
- touch hang && tail -f hang # 命令执行完成后自动退出, 因此需要手工阻塞一下
注意在 Dockerfile 中定义了 MYSQL_NEW_PASSWORD , 调用 change_mysql_password.sh 脚本. 于此对应的是在 change_mysql_password.sh 中对 MYSQL_NEW_PASSWORD 进行判断处理. 设置的密码强度不能太低否则会设置失败.
- docker run -it <IMAGE_ID> [email protected]
- [[email protected] /]# netstat -lntup | grep mysqld
- tcp6 0 0 :::3306 ::?? LISTEN 5/mysqld
可以看到 MySQL 已经启动.
docker run -it -d 238f7fa4f4a7, 不加参数时, 密码为 [email protected]; 如果后面加参数, 则密码为参数值.
其它注意项:
在
mysqladmin? -u? root? -p${old_password}? password? ${MYSQL_NEW_PASSWORD}
一句中, 原来写成了
mysqladmin? -u? root? -p'${old_password}'? password ?'${MYSQL_NEW_PASSWORD}'(多了单引号)
发现总是密码错误, 单引号的作用应该是把单引号中的部分直接理解为字符串而不作任何处理
6. VOLUME 命令
表示哪些部分映射到卷中, 启动容器时使用 --volume, 或者 --volumes-from 加一个已经存在容器的名字. 如果运行有 VOLUME 的镜像而不加 -- volume 或者 --volumes-from 参数, 则会新建一个卷.
Dockerfile 文件如:
- FROM alpine:latest
- RUN mkdir /mydir
- COPY index.HTML /mydir/index.HTML
- RUN touch hang
- VOLUME /mydir
- CMD ["tail","-f","hang"]
执行启动命令: docker run -it -d 675cc3517e1c, 可以看到多出了一个卷:
- [[email protected]_0_2_centos volume]# docker volume ls
- DRIVER VOLUME NAME
- local 5701d2644d069ebf07265afe190116ac19d95e89b755ddc9409f2d1649f8297e
使用 --volume 手工指定要使用的卷:
docker run -it -d --volume <VOLUME_ID>:<DIR_IN_CONTAINER_TO_MAP> <IMAGE_ID>
如:
- [[email protected]_0_2_centos volume]# docker run -it -d --volume 5701d2644d069ebf07265afe190116ac19d95e89b755ddc9409f2d1649f8297e:/mydir 675cc3517e1c
- 90d52a27e81dbf110e2fd38f5d5889a312ff3baabff37460dfea2a49d8b625f3
使用 --volumes-from 和别的容器共用一个卷, 注意无需指定映射目录, 自动与容器 id 所对应容器相同:
docker run -it -d --volumes-from <CONTAINER_ID> <IMAGE_ID>
如:
- [[email protected]_0_2_centos volume]# docker run -it -d --volumes-from 90d52a27e81dbf110e2fd38 675cc3517e1c
- b1bb18594adbbfa6fa0cb34302a747db2db04027348a3bd5f8d57393be70ad48
执行以上操作后
- [[email protected]_0_2_centos volume]# docker volume ls
- DRIVER VOLUME NAME
- local 5701d2644d069ebf07265afe190116ac19d95e89b755ddc9409f2d1649f8297e
这些容器共用了一个卷, 卷中的文件在各个容器中也可以看到.
TIPS: 使用 docker image prune 删除名字和标签均为 "<none>" 的镜像 (强制删除有容器使用的镜像 和 构建过程中被终止时会产生).
参考:
Linux 下文件压缩: https://www.cnblogs.com/henry2018/p/9653010.html
查看压缩文件内容: https://www.jianshu.com/p/866192f04391
来源: http://www.bubuko.com/infodetail-3563407.html