dockerfile详解

Dockerfile基础详解

一、前言

笔记配套视频效果更佳哦,视频地址:https://edu.51cto.com/lecturer/14390454.html

​ 对于docker,我们都有了一定的了解,我们知道docker hub上面,能够搜索到各种有用的资源镜像等等,运行起来也比较方便,但是,如果我们有定制的需要的话,则需要做一些调整;以PHP举例,PHP官方提供了很多扩展,但是并不是全部的扩展,如果我们要针对PHP的镜像,进行增加扩展怎么办?
​ 还有种情况,例如我们想搭建一个基于centos的LNMP环境,该怎么办?

这时,dockerfile就有了用武之地,编写好dockerfile添加上相应的功能,直接build进行定制镜像,满足我们的需要;

dockerhub官方镜像仓库地址:https://hub.docker.com/search?q=php&type=image

img

二、基本语法

2.1 dockerfile示例
nginx 官方镜像:

https://github.com/nginxinc/docker-nginx/blob/master/Dockerfile-alpine.template

FROM  #指明构建的镜像是来自于哪个基础镜像,后续的所有操作都是基于此镜像例如
LABEL maintainer="laowang mail:rootwyq@163.com>" #推荐使用 # 指定镜像的作者
RUN  mkdir -p /data/ #用于执行一条命令;Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。可以利用&&符号来连接命令,如此执行,只会创建1层镜像,如:
RUN yum install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz
CMD #启动容器时执行的Shell命令,有点类似于RUN命令,但是二者运行的时间点不同
    # CMD 在docker run的时候运行
    # RUN 是在docker build的时候运行
EXPOST 8987#声明容器运行可能会用到的端口,注意,仅仅只是声明端口;
    #作用:
    - 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射
    - 在运行时使用随机端口映射时,也就是docker run -P时,会自动随机映射EXPOSE的端口
ENV  #设置环境变量,定义了环境变量,就能在后续的指令中使用这个环境变量了
COPY tar.gz tar.gz#(推荐) 拷贝文件或目录到镜像指定的目录中,支持通配符,如
     #COPY hom* /mydir/
     #COPY hom?.txt /mydir/
ADD  tar.gz xxx#与COPY的使用格式一致,唯一不同的是,ADD在gzip,bzip2,及xz的情况下,会自动复制并解压到目标路径,
     # 同样的需求下,官方推荐使用COPY命令
ENTRYPOINT
     #类似于CMD指令,但是不会被docker run中的命令行参数指令覆盖,会被当做参数传给ENTRYPOINT指令指定的程序;
     #但是如果执行docker run的时候指定了 --entrypoint 选项,此选项的参数会覆盖掉ENTRYPOINT指令指定的程序
     #注意:如果dockerfile中如果存在多个ENTRYPOINT指令,仅最后一个生效,另外,推荐在 entrypoint 脚本中使用 exec
VOLUME
     #指定容器挂载点到宿主机自动生成的目录或其他容器,在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点
USER
     #用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户
     # USER <用户名>[:<用户组>]
WORKDIR  /test-web/    #创建工作目录 

图解:

img

2.2 build

用于将dockerfile生成镜像

docker build -t test-web:v1.2 .
[root@ceshi-web01 test-web]# cat dockerfile 
FROM nginx:1.18
LABEL maintainer="laowang mail:rootwyq@163.com>" 
# 案例地址:https://github.com/we11cheng/WCStaticHTML
RUN mkdir -p /test-web \
    && rm /etc/nginx/conf.d/default.conf
copy ./dist/* /test-web/
copy test-ui.conf /etc/nginx/conf.d/default.conf
expose 80
RUN /bin/bash -c 'echo init ok'
[root@ceshi-web01 test-web]# cat test-ui.conf 
server {
  listen 80;
  location / {
        root /test-web/;
    index index.html;
    }
    }
docker build -t test-web:v1.0 .
[root@ceshi-web01 test-web]# docker run -d -p 8889:80 test-web:v1.0

三、dockerfile构建生产环境使用案例

传统发布过程:

1、如果是前端文件一般 npm install npm run build 在项目目录下生成dist包

2、安装nginx配置域名进行请求匹配

3、用户访问我们的应用

  • 构建前端服务(将公司前端文件打包成自己所需的镜像服务)
[root@ceshi-web01 ~]# mkdir laowang
[root@ceshi-web01 ~]# cd laowang/
#在实际公司项目中将编译好的dist目录使用copy命令拷贝到容器中即可
[root@ceshi-web01 laowang]# cat Dockerfile 
FROM nginx:1.18
LABEL maintainer="laowang mail:rootwyq@163.com>" 
RUN mkdir -p /test-web \
    && rm /etc/nginx/conf.d/default.conf \
    && echo "这是我们公司的前端项目" > /test-web/index.html
copy test-ui.conf /etc/nginx/conf.d/default.conf
expose 80
RUN /bin/bash -c 'echo init ok'
[root@ceshi-web01 laowang]# cat test-ui.conf 
server {
  listen 80;
  location / {
        root /test-web/;
    index index.html;
    }
    }
[root@ceshi-web01 laowang]# docker build -t xxx-web:v1.2 .
[root@ceshi-web01 laowang]# docker run -d -p 8589:80 xxx-web:v1.2
#浏览器访问
#前端项目编译-----步骤
#1.centos 安装编译环境
#首先配置nodejs环境
# wget https://nodejs.org/dist/v12.18.1/node-v12.18.1-linux-x64.tar.xz
# tar xf node-v12.18.1-linux-x64.tar.xz 
# mv node-v12.18.1-linux-x64 /usr/local/node
# vi /etc/profile
......最后加......
export PATH=$PATH:/usr/local/node/bin
#使环境变量失效
# source /etc/profile
# cd /usr/local/node/bin
#查看版本(当前位置生效)
# ./node -v
v12.18.1
#配软连接:
#相当于全局变量,在任何文件夹都能查看版本信息
# ln -s /usr/local/node/bin/node /usr/local/bin/
# ln -s /usr/local/node/bin/npm /usr/local/bin/
#测试全局是否生效
# cd
# node -v
v12.18.1
#2.下载项目https://github.com/ShinyHwong/Practice
# 在服务器新建一个目录进行解压,然后进入项目目录进行编译
# unzip vue-element-admin-master.zip 
# ls
vue-element-admin-master  vue-element-admin-master.zip
[root@ceshi-web01 laowang]# cd vue-element-admin-master/
[root@ceshi-web01 vue-element-admin-master]# npm install
[root@ceshi-web01 vue-element-admin-master]# npm run build:stage
#会在当前目录下生成dist编译好的可访问的目录-->自行测试
  • 如何制作java项目应用镜像?----------->回顾传统微服务启动方式

    1.服务器安装java环境、mvn环境

    2.代码编译

    3.mvn编译

    4.java -jar 启动查看日志有无报错(或者将jar启动写成脚本进行启动)

    • docker启动
    • 1.docker pull 官方java环境
    • 2.编写dockerfile,将编译好的jar包拷贝至容器中
    • 3.构建自己的业务镜像
    • 4.启动自己的业务镜像
    • 5.一次编译,处处运行(测试、生产)

这里带大家先了解和熟悉如何编写企业项目的dockerfile,具体在后面的微服务部署章节会带大家跑一套完整的微服务项目。

四、注意事项

4.1 尽可能的制作小镜像(使用官方镜像)
4.2 容器运行单个应用

从技术的角度来讲,一个Docker容器中,可以运行多个进程,例如LNMP环境,我们可以基于Centos系统镜像,将Nginx、Php、Mysql集合到一个Docker 容器中,但是会非常的痛苦,例如我们要对镜像做一个改动的时候,需要build生成镜像,这个就会耗费大量的时间,当然还有其他的问题。

    • 非常长的构建时间(修改前端之后,整个后端也需要重新构建)
    • 非常大的镜像大小
    • 多个应用的日志难以处理(不能直接使用 stdout,否则多个应用的日志会混合到一起)
    • 横向扩展时非常浪费资源(不同的应用需要运行的容器数并不相同)
    • 僵尸进程问题 - 你需要选择合适的 init 进程

因此,生产环境建议大家为每个应用构建单独的 Docker 镜像,然后使用Docker Compose 或者k8s运行多个公司应用Docker容器

4.3 多个RUN执行合并为一个
     Dockerfile 中的每个指令都会创建一个新的镜像层。镜像层将被缓存和复用,当 Dockerfile 的指令发生了改变,对应的镜像层缓存就会失效,某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效;
     多个RUN指令,会生成过多无意义的层,会造成镜像膨胀过大。可以利用&&符号来连接命令,如此执行,只会创建1层镜像;

另外还需要注意, RUN 指令完成后记得删除多余文件,避免整个容器过大;

4.4 选择合适的基础镜像(alpine 版本最好)

在我们编写dockerfile文件的时候,选择基础镜像最好使用alpine版本的镜像,alpine是一个极小化的Linux发行版,且只有4M,非常适合作为基础镜像;

笔记配套视频效果更佳哦,视频地址:https://edu.51cto.com/lecturer/14390454.html

posted @ 2022-01-19 17:44  老王教你学Linux  阅读(69)  评论(0编辑  收藏  举报