# helloDocker **Repository Path**: hammercui/helloDocker ## Basic Information - **Project Name**: helloDocker - **Description**: 关于docker的入门工程 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-10-30 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 本文讲述如何写一个docker项目 ### alpine alpine是最小的linux发行版,如果需要linux环境,Dockerfile里 ``` FROM alpine ``` 如果需要包含linux运行时的golang时 ``` FROM golang:alpine ``` ### CMD与ENTRYPOINT 的区别与联系 #### 相同点 都拥有exec格式和shell格式(我们一般使用shell格式) ``` exce格式:CMD/CMD与ENTRYPOINT ["可执行文件","参数1","参数2",.....] ``` #### 区别 ##### CMD CMD一般作为容器主进程的默认命令,如果容器启动的时候,手动指定了命令,会覆盖默认的命令。 比如Dockerfile文件 ``` CMD ["ls","-all"] ``` run启动时执行` -it my-test-docker `,结果如下 ![image](/image/1.png) run启动时执行` -it my-test-docker ps -a`,结果如下 ![image](/image/2.png) ##### ENTRYPOINT 大家想一下,如果我们需要一个镜像做CLI,也就是自定义命令行程序。该怎么做呢?这就是CMD与ENTRYPOINT要做的事。 ENTRYPOINT的本质是 ``` "" ``` 就是会把【可执行文件】当做必须要执行的命令,不能覆盖,然后参数1,2.....一定会执行,如果有新增命令,只能是Dockerfile填写的 【可执行文件】的命令参数。 下面来验证,首先重新打包镜像 ``` ENTRYPOINT ["ls","-all"] ``` run启动时执行` -it my-test-docker `,结果不变 run启动时执行` -it my-test-docker ps -a`,结果如下 ![image](/image/3.png) 因为`ps`不是`ls`的命令参数,一定会出错。 修改之后run启动时执行` -it my-test-docker -t`,结果如下 ![image](/image/4.png) 相当于执行了`ls -all -t` ### 执行镜像时`executable file not found in $PATH`问题 发生的原因是Dockerfile末尾`CMD ["main"]`,执行的时候没有shell环境,而shell环境位于/bin/sh -c,因此需要修改为`ENTRYPOINT ["/bin/sh","-c","./main"]` ### 挂载容积卷 首先在Dockerfile文件声明需要外部挂载的路径,比如日志路径: ``` # Declare volumes to mount VOLUME ["/go/helloDocker/logger"] ``` 然后启动命令使用`-v`挂载真实机器路径`/usr/local/megatech/helloDocker/logger` ``` docker run -p 8284:8284 -v /usr/local/megatech/helloDocker/logger:/go/helloDocker/logger -it my-test-docker ``` 镜像产生的日志,成功的写入到了物理机 ![image](/image/5.png) ### 如何精简镜像 >首先使用golang编译构建二进制应用,然后使用scratch包裹生成二进制程序 ``` #基础镜像 FROM xxx FROM golang:1.13.1-alpine as builder MAINTAINER liyang.cui@sdbean.com #设置环境变量 ENV GOPROXY=https://goproxy.cn,direct #声明工作路径(虚拟) WORKDIR /go/helloDocker COPY . . #编译go RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . RUN ls -all ``` 二进制打包镜像 ``` ######## stage2: 从 scratch再次打包,精简体积 ####### FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ # Copy the Pre-built binary file from the previous stage COPY --from=builder /go/helloDocker/main . RUN ls -all #修改权限 RUN chmod +x main # Declare volumes to mount VOLUME ["/root/logger"] # 容器启动命令 ENTRYPOINT ["/bin/sh","-c","./main"] ``` 最终打包之后体积: ![image](/image/6.png)