Dockerfile的使用
Dockerfile简介
Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
基础知识
- 每个命令都是大写 保留关键字
- 执行顺序从上到下依次执行 每个命令都是一层
- #表示注释
使用Dockerfile常用指令
命令 | 作用 | 示例 |
---|---|---|
FROM | 基础镜像 告诉镜像的妈妈是谁 | FROM ubuntu |
MAINTAINER | 镜像是谁写的 姓名 + 邮箱 | |
RUN | 你想让镜像干啥 | |
COPY | 拷贝文件到容器里 | |
ADD | 如果源路径是http路径ADD命令可以去自动下载 再拷贝到指定路径 、如果拷贝的文件是tar.gz ADD会自动解压缩 并删除压缩包 | |
WORKDIR | 容器的工作目录 就是cd | |
VOLUME | 存放数据的地方 | |
EXPOSE | 暴露出镜像的端口 | |
CMD | 容器启动的时候指定的命令 只能放在最后才生效 会被替换 | |
ENTRYPOINT | 容器启动的时候指定的命令,可以追加命令 会被追加 | |
ONBUILD | 但构建一个被继承的Dockerfile | |
ENV | 构建镜像的时候设置环境变量 |
命令 | 作用 | 示例 |
---|---|---|
FROM imageName | 定制的Dockerfile基于哪个镜像 必须打头 | FROM tomcat 或者 FROM tomcat:8.5.32 |
WORKDIR 要切换的目录 | 切换工作空间 可以代替cd命令 | WORKDIR /usr/local/tomcat 就可以把当前的目录切换为指定目录 |
RUN bash命令 | 执行一句bash命令 | RUN echo “Hello World” > /usr/local/1.txt 等等 |
COPY 上下文路径的文件 / 容器路径 | 拷贝文件到容器里 | COPY index.js /usr/local/docker/test |
ADD 上下文路径的文件 .容器路径 | 拷贝文件到容器里 | 如果源路径是http路径ADD命令可以去下载 在拷贝到指定路径 、如果拷贝的文件是tar.gz ADD会自动解压缩 并删除 |
CMD 命令 | 启动镜像里的程序 | CMD [“nginx”, “-g”, “daemon off;”] |
EXPOSE 端口 [端口2,端口3,…] | 暴露Docker容器里镜像的端口 | EXPOSE [80,8080] 或者 EXPOSE 80 |
。。。等等 |
构建镜像
docker build -f dockerfile名称 -t 镜像名称 .
# -f 指定dockerfile文件名
# -t 构建的镜像名称
# . 上下文路径
注意事项
CMD和ENTRYPOINT的区别
RUN命令执行多条命令
#正确用法
RUN buildDeps='gcc libc6-dev make' \
&& apt-get update \
&& apt-get install -y $buildDeps \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
&& mkdir -p /usr/src/redis \
&& tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
&& make -C /usr/src/redis \
&& make -C /usr/src/redis install \
&& rm -rf /var/lib/apt/lists/*
#错误用法
FROM debian:jessie
RUN apt-get update
RUN apt-get install -y gcc libc6-dev make
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz"
RUN mkdir -p /usr/src/redis
RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1
RUN make -C /usr/src/redis
RUN make -C /usr/src/redis install
在Dockerfile中每一个指令都代表一层,RUN也一样,而上面这种写法,创建了7层镜像。这是完全没有意义的,不仅仅会增加构建时间,还会增加出错几率!
注意: Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过 127 层。
而正确的写法是将 Dockerfile 指令以 \ 符号换行 使用&&进行串连起来,这样就将以前的七层转换为一层了。
附、Docker定制镜像的上下文解释
如果注意,会看到 docker build
命令最后有一个 .
。.
表示当前目录,而 Dockerfile
就在当前目录,因此不少初学者以为这个路径是在指定 Dockerfile
所在路径,这么理解其实是不准确的。如果对应上面的命令格式,你可能会发现,这是在指定 上下文路径。那么什么是上下文呢?
- 就比如这个命令
docker build -t imageName .
当构建Dockerfile的时候,用户会指定构建镜像上下文的路径,docker build - t name .
命令得知这个路径后,会将用户指定路径下的所有内容打包,然后上传给 Docker 引擎。这样 Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。
如果在 Dockerfile
中这么写:
COPY ./package.json /app/
这并不是要复制执行 docker build
命令所在Dockerfile的目录下的 package.json
,也不是复制 Dockerfile
所在目录下的 package.json
,而是复制 上下文(context) 目录下的 package.json
。
发布自己的镜像
发布到DockerHub上
注册账户
# 先登录自己的账户
docker login -u yufire
# 输入密码
Password:
# 提示你没有把将未加密地存储在/root/.docker/config.json中。
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
# 登陆成功
Login Succeeded
docker push 镜像名:版本号
发布到阿里云镜像服务上
- 登陆阿里云
- 找到容器镜像服务
- 创建命名空间 为了防止冲突 一个账号只能创建3个
- 创建仓库
自己创建的镜像尽量带上版本号
docker login -u 用户名
docker logout
完结撒花
作者:yufire © yufirem@vip.qq.com