Dockerfile应用之----自动化打包

功能:将编译的基础环境,编译构建通过dockerfile一步完成(目的是将git下载的代码编译并将生成的目录同步到宿主机)

思路:git上不同的分支和包名定义成变量,将一个shell放入dockerfile中,shell中的变量通过env定义的环境变量来赋值,而定义的环境变量的值dockerfile中为空,通过docker run运行时来赋值;可能很多人会问这样不是复杂化了,本人刚开始动手时也并没有这样而是直接通过arg赋值的方式加RUN 执行下载编译过程的,而这种方式首先上面的目的中目录同步只能通过Volume实现它的缺点是只能同步到/var/lib/volume下并随机生成一长串名字的目录不方便后期取包操作,第二是这种方式需要每次都build构建镜像然后run.而下面介绍的这种方式是只构建一次镜像每次打包只需run 后面加上变量就可以了,反而简单化了

dockerfile

#如果对基础镜像和依赖包版本没有要求,可使用dockhub上官方发布集成的基础环境
FROM node:8.9.4-alpine
#FROM node:12.16.1-alpine
RUN apk add --no-cache -U make git  python g++
RUN yarn config set registry https://registry.npm.taobao.org
WORKDIR /pack
WORKDIR /build
COPY build.sh .
RUN chmod +x /build/build.sh
ENV branch=
ENV packname=
RUN node -v && yarn -v && npm -v

ENTRYPOINT ["sh","./build.sh"]

第一步:FROM 引用基础基础镜像,并安装编译环境使用的包(这个需要git odeyarn)并配置环境变量

第二步:将本地build.sh上传到镜像中代码如下:

#!/bin/bash
git clone -b $branch https://账号:密码@gogs.xiao*******.com/h5app/"$packname".git
echo $?
cd $packname
echo $?
yarn install
echo $?
npm run prod
echo $?
ls -l /
pwd
cp -r dist /pack

cd /pack/dist
sed -i 's;<script src="assets/lib/mock.js"></script>;;g' index.html
sed -i 's;<script src="main.js"></script>;;g' index.html
..............

echo $?

第三步:docker build -t packdocker .   

第四步:docker run -v 宿主机目录:容器目录 -e "branch=分支名" -e "packname=包名" 镜像id

--------------------------------------------------------------------------------------------------------------------

Dockerfile中使用的命令详情

FROM  <image>

  必须引用一个基础镜像,首先本地查找没有到话自动官方下载,也可以是阿里云自己上传镜像复制阿里云镜像地址就可以

  重点:贼好用的from多阶构建(docker17.05以后版本)

     示例:

   

FROM centos7 as build    #as给镜像起个名

WORFDIR /build

RUN touch a              #在build目录下创建个文件

FROM centos7         #没有看错继续在创建了镜像

COPY --from=build /build/a /home  # from引用上个镜像并把上个镜像中的文件拷到当前镜像

....

     这个image最终会以第二个from的镜像为基础,注意:2个镜像系统可以不同,也可以是单纯的文件系统,可以多层

    如果第一个镜像不用as  第二个可以用--from=0  默认就是第一个镜像,以此类推。

    更多复杂应用慢慢研究。。。。

WORKDIR 

   进入目录,没有自动创建,另一篇docker基础中可以查看

COPY和ADD <本地><镜像>

  相同点:把本地文件拷贝到镜像,本地文件必须是上下级目录中,只拷贝目录中文件不包含目录自身

  不同:copy可以用在上面说的多阶构建中,add不可以;add可以自动解压压缩文件;add可以从url拷贝文件这个目前没用到过

ENV <key><value>

  设置环境变量,可以是系统有的如:PATH=    可以自己创建 ABC=  

  workdir、volume、run、entryoint...中都可以使用,可以定义个空值,在docker run -e “ABC=” 来赋予一个变量

  具体示例可以参考 https://www.cnblogs.com/Json1208/p/8974978.html  转载自<飘来荡去>作者

ARG

  arg可以说也是设置环境变量,和env不同的是arg设置的是构建环境的环境变量,在 docker build --build-arg “ 参数名=值”

  只在构建中生效,在生成的image中无效,可以当做参数-赋值来使用

FROM centos7

ARG dir

WORKDIR /$dir

.......


docker build --build-arg "dir=home"

CMD

  exec和shell两种模式

  CMD 【“curl”,“-s”,“http://ip.cn” 】

  CMD command param1 param2

  指定启动程序,只能一条,如果多条以最后一条为准,前面的被覆盖

  可以在docker run -t centos 后面跟curl -s http://ip.cn -i 加了一个-i的参数 必须cmd内容重新输一遍后面再加-i

FROM ubuntu:16.04 
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
CMD [ "curl", "-s", "http://ip.cn" ]

$ docker run myip
当前 IP:61.148.226.66 来自:北京市 联通

   可以结合entrypoint命令来使用

ENTRYPOINT

  指定容器的启动程序和参数

  只能一条,多条以最后一条为准,可以不被docker run 提供的参数覆盖

  docker run -t centos /bin/bash

FROM centos7

ENTRYPOINT ["/bin/echo", "hell0"]

docker run -it centos7 word #entrypoint会把word当成一个echo的字符串参数,不会进入到容器中
#输出
hello word

docker run -it centos --entrypoint=this is word 后面加参数可替代dockerfile中定义的
输出
this is word

   例子二

FROM centos7
ENTRYPOINT ["sh","build.sh"]
CMD ["packname"]

指定一个参数packname 给 build.sh

补充:

ls: can't open '/pack': Permission denied
cp: can't create directory '/pack/dist': Permission denied
ls: can't open '/pack': Permission denied

挂载目录后 容器内复制目录出现权限问题错误

给容器加特权: --privileged=true

docker run -v /ceshi:/pack --privileged=true -e "branch=master" -e "packname=staff-seed" ceshi2.0

通过shell调用

通过dockerfile生成镜像,每次操作都需要docker run .....  执行带来重复工作

思路:通过打包界面的接口调用shell打包,首先外部接口调用存放下面第一个脚本的服务器192.168.175.30传送两个参数分别是包名和分支,接着30将参数传送到10上执行第二个脚本,最后将生成的包放到共享服务器20上

#!/bin/bash
echo $1
echo $2

ssh root@192.168.175.10 "/bin/sh /root/h5appdocker.sh $1 $2"

#ssh root@192.168.175.10 "[ -d /root/h5app/$1/dist ]" >/dev/null 2>&1
if [ $? -ne 0 ]; then
        echo "打包失败"
else

        echo "打包成功"
        rm -r /root/go/src/ant-builder/build/k8s/h5appdocker/$1

        #rm -r $1
        scp -r root@192.168.175.10:/root/h5appdocker/$1 /root/go/src/ant-builder/build/k8s/h5appdocker

        ssh root@192.168.175.20 "rm -r /staticdocker/$1"
        scp -r /root/go/src/ant-builder/build/k8s/h5appdocker/$1 root@192.168.175.20:/staticdocker/$1
fi
#!/bin/bash
docker run -v /root/h5appdocker:/pack --privileged=true -e "branch=$2" -e "packname=$1" packdocker-node:8.9

mv /root/h5appdocker/dist /root/h5appdocker/$1
cd /root/h5appdocker/$1
#添加的参数
sed -i 's;<script src="assets/lib/mock.js"></script>;;g' index.html
sed -i 's;<script src="main.js"></script>;;g' index.html
.........

echo $?
原文地址:https://www.cnblogs.com/aloneysir/p/12628152.html