使用DockerFile构建属于自己的Docker镜像 DockerFile简介和使用

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 镜像名:版本号

发布到阿里云镜像服务上

  1. 登陆阿里云
  2. 找到容器镜像服务
  3. 创建命名空间 为了防止冲突 一个账号只能创建3个
  4. 创建仓库

自己创建的镜像尽量带上版本号

docker login -u 用户名

docker logout

完结撒花

作者:yufire © [email protected]

你可能感兴趣的:(云相关,Linux)