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
二、基本语法
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/ #创建工作目录
图解:
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