DockerFile

直接上一个例子

from conda/miniconda3

MAINTAINER liangsqrt

COPY ./jupyter /root/.jupyter
COPY ./requirements.txt /home/jupyter/requirements.txt
COPY ./sources.list /etc/apt/sources.list
COPY ./condarc /root/.condarc

RUN pip --disable-pip-version-check --no-cache-dir install pylint -i https://pypi.douban.com/simple \
    && if [ -f "/tmp/conda-tmp/environment.yml" ]; then /opt/conda/bin/conda env update -n base -f /tmp/conda-tmp/environment.yml; fi \
    && rm -rf /tmp/conda-tmp \
    && pip install -i https://pypi.douban.com/simple -r /home/jupyter/requirements.txt \
    # && conda install scrapy

当我想要启动一个jupyter的容器时,我需要个性化定制一下,比如定制开放端口,jupyyter的根路径、用户密码这些。方法有一下几种:

  1. 直接运行jupyter,容器起来后,进入容器,生成密码,并完成相关的个性化功能。缺点:每次重启容器后,部分指令要进入容器重新敲(没有在启动容器的时候就写好的指令);想要创建多个这样的容器太难
  2. Docker-compose 可以,但是启动多个容器时,相当于是在基础容器上安装新功能
  3. DockerFile生成自定义的镜像,直接通过镜像启动

于是我选择了2、3组合使用的方案。比如切换pip安装的依赖项放到了镜像里;加载镜像创建容器的指令我放到了docker-compose里。

DockerFile详解

from

介绍这个镜像是基于哪个镜像的。一般会在本地找,写个本地的镜像即可,如果没有,就会去网上找。

MAINTAINER

维护者或作者,无关紧要。

COPY

将哪些东西复制到容器里边,copy进入容器里边的东西和外部的东西,是两套东西,会占用两个硬盘内存。copy的时候还可以使用正则,~ 源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则 ~

COPY hom* /mydir/
COPY hom?.txt /mydir/
RUN

用于执行后面跟着的命令行命令, 非常重要,很常用。

ADD

用法和copy几乎一样,在copytar文件,且压缩编码方式为gzip,bzip或者zx的情况下,它会自动解压!!!有点坑,有时候会解压时报导致编排失败,或者缓慢。

CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同

  • CMD 在docker run 时运行
  • RUN 是在 docker build

启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。其实用途也不大,多数时候这个功能都被docker-compose替换了。

ENTRYPOINT

理解很容易,当run要带参数运行时,就用它。我们手启run,参数也不会被覆盖,比如:

$ docker run  nginx:test

如果我们镜像里指定好了,那么里边实际运行的指令是:nginx -c /etc/nginx/nginx.conf

除非特意传参-c:

docker run  nginx:test -c /etc/nginx/new.conf    

其实也没什么用。

ENV

环境变量,设置docker里边的环境变量的值。

VOLUME

挂在路径用的。比如要讲容器中的某个路径,映射出来,就可以用这个。跟copy不一样,这个路径是容器和宿主机都可以访问的,文件也只有一份。这个功能很常用。命令行里边用它的方法是 -v

EXPOSE

仅仅只是声明端口。

  • 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
  • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
WORKDIR

指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。

Docker层概念,以及精简docker镜像大小

docker的镜像是分层的,每一个指令都会增加dockerImage的层数,加大docker镜像的体积

image.png

由于docker用到的copy-on-write技术(git中也用到了这个技术),就是说当你在docker里创建了某个文件,之后再删除掉,这个文件还在吗?还在的!而且创建和删除执行了两次,docker就增加了两层。

所以精简的第一步,减少层,通过减少指令的方式

一般随便几层,就有个几百兆的样子。这是影响镜像大小最直观的地方。所以run方法,最好就一个,直接用&&连接符将他们串联起来。一般这样操作后,效果比较直观。

更精简的镜像

用更精简的镜像,效果不大,

用docker的improt 和export

但麻烦的是需要先将容器运行起来,而且这个过程中你会丢失镜像原有的一些信息,比如:导出端口,环境变量,默认指令。

Docker部署

容器导出导入 export import

不管这个容器是不是在运行,都可以导出它,然后交给同事拿去部署,但是会丢失启动指令呀,端口,硬盘映射路径这些,里边只是包含了你的代码环境。

# 导入语法
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
# 例子
docker import  my_ubuntu_v3.tar runoob/ubuntu:v4
# 导入语法
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
# 例子
docker import  my_ubuntu_v3.tar runoob/ubuntu:v4
镜像导出导入
# 导出语法
docker save [OPTIONS] IMAGE [IMAGE...]
# 例子,如果需要跨操作系统,请使用 -o 方式
docker save -o my_ubuntu_v3.tar runoob/ubuntu:v3
docker save runoob/ubuntu:v3 > my_ubuntu_v3.tar

# 导入语法
docker load [OPTIONS]
# 例子,如果需要跨操作系统,请使用 -i 方式
docker load -i ubuntu.tar
docker load < ubuntu.tar
  • docker save 保存的是镜像,docker export 保存的是容器
  • docker load 用来载入镜像包,docker import 用来载入容器包,但两者都会恢复为镜像
  • docker load 不能对载入的镜像重命名,而 docker import 可以为镜像指定新名称

你可能感兴趣的:(DockerFile)