Dockerfile指令
COPY:复制文件
COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]
COPY
指令将从构建上下文目录中 <源路径>
的文件/目录复制到新的一层的镜像内的 <目标路径>
位置。
比如:
COPY package.json /usr/src/app/
<目标路径>
可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR
指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。
ADD 更高级的复制文件
ADD
指令和 COPY
的格式和性质基本一致。但是在 COPY
基础上增加了一些功能
比如 <源路径>
可以是一个 URL
,这种情况下,Docker 引擎会试图去下载这个链接的文件放到 <目标路径>
去https://github.com/yeasy/docker_practice/blob/master/image/dockerfile/add.md 不推荐使用。
如果 <源路径>
为一个 tar
压缩文件的话,压缩格式为 gzip
, bzip2
以及 xz
的情况下,ADD
指令将会自动解压缩这个压缩文件到 <目标路径>
去。
在某些情况下,这个自动解压缩的功能非常有用,比如官方镜像 ubuntu
中:
FROM scratch ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz / ...
但在某些情况下,如果我们真的是希望复制个压缩文件进去,而不解压缩,这时就不可以使用 ADD
命令了。
因此在 COPY
和 ADD
指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用 COPY
指令,仅在需要自动解压缩的场合使用 ADD
。
CMD 容器启动命令
shell
格式:CMD <命令>
exec
格式:CMD ["可执行文件", "参数1", "参数2"...]
# CMD echo $HOME 等同于下面,不过还是推荐下面写法 CMD [ "sh", "-c", "echo $HOME" ] CMD ["nginx", "-g", "daemon off;"]
ENV 设置环境变量
格式有两种:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
这个指令很简单,就是设置环境变量而已,无论是后面的其它指令,如 RUN
,还是运行时的应用,都可以直接使用这里定义的环境变量。
ENV PYTHONUNBUFFERED 1
ENV TZ=Asia/Shanghai
--
ENV VERSION=1.0 DEBUG=on \ NAME="Happy Feet"
上面这个例子,演示了如何换行,以及对含有空格的值用双引号括起来的办法,这和 Shell 下的行为是一致的。
VOLUME 定义匿名卷
格式为:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
VOLUME /data
带-v和不带-v区别:
docker run -d -p 3306:3306 -v {host_dir映射到宿主机的文件位置}:{docker container 的文件位置} xx(容器名)
docker run -d -p 3306:3306 -v /var/lib/zhou/mydata:/var/lib/mysql xx(容器名)
这样,宿主机的mydata文件和container的mysql文件是同步的,将来即使删除了db container,数据库的数据任然保留
现在把数据库container删除,删除后,查看
ls /var/lib/zhou/mydata
看看你的数据库数据是否还在?
应该是存在的
现在,在创建一个container,
docker run -d -p 3306:3306 --name newdb -v /var/lib/zhou/mydata:/var/lib/mysql xx(容器名)
现在挂载回去后,数据库的数据就能挂载回去了
WORKDIR 指定工作目录
格式为 WORKDIR <工作目录路径>
。
对 Dockerfile
构建分层存储的概念要了解
每一个 RUN
都是启动一个容器、执行命令、然后提交存储层文件变更。第一层 RUN cd /app
的执行仅仅是当前进程的工作目录变更,一个内存上的变化而已,其结果不会造成任何文件变更。而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。
因此如果需要改变以后各层的工作目录的位置,那么应该使用 WORKDIR
指令
USER 指定当前用户
格式:USER <用户名>
USER
指令和 WORKDIR
相似,都是改变环境状态并影响以后的层。WORKDIR
是改变工作目录,USER
则是改变之后层的执行 RUN
, CMD
以及 ENTRYPOINT
这类命令的身份。
当然,和 WORKDIR
一样,USER
只是帮助你切换到指定用户而已,这个用户必须是事先建立好的,否则无法切换。
RUN groupadd -r redis && useradd -r -g redis redis USER redis RUN [ "redis-server" ]