Dockerfile概念

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本
每条指令都必须为大写字母且后面跟随至少一个参数
#表示注释
每条指令都会创建一个新的镜像层并对镜像进行提交

CMD指定容器启动后要干的事情
在指定了ENTRYPOINT指令后,用CMD指定具体的参数
Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换

#正常启动,能访问http://localhost:8080
docker run -it -p 8080:8080 billygoo/tomcat8-jdk8

#tomcat的CMD被替换成/bin/bash,tomcat本身并没有被启动
docker run -it -p 8080:8080 billygoo/tomcat8-jdk8 /bin/bash

ENTRYPOINT类似于CMD指令,但时ENTRYPOINT不会被docker run后面的命令覆盖,而且这些命令行参数会被当作参数送给ENTRYPOINT指令指定的程序
vi Dockerfile

FROM nginx
ENTRYPOINT ["nginx", "-c"]
CMD ["/etc/nginx/nginx.conf"]
#构建新镜像
docker build -t nginx:test .
docker run nginx:test
docker run nginx:test -c /etc/nginx/new.conf

docker-entrypoint.sh文件中是shell代码,可以动态替换参数
docker-entrypoint.sh 文件的作用


SpringBoot应用打包Dockfile文件

FROM java:8
VOLUME /tmp
ADD demo-0.0.1-SNAPSHOT.jar app.jar
#touch命令的作用是修改这个文件的访问时间和修改时间为当前时间
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java", "-jar", "/app.jar"]
EXPOSE 8080

虚悬镜像

虚悬镜像:仓库名、标签都是的镜像
构建或删除镜像时出现一些错误,导致仓库和标签都是none,建议删除这些数据
vi Dockerfile

form ubuntu
CMD echo 'action is success'
#构建时不传入tag名称
docker build .
docker images

#查询本地所有的虚悬镜像
docker images ls -f dangling=true

#删除虚悬镜像
docker image prune
y

Dockerfile常用命令

CMD:启动容器默认执行的命令,会被覆盖
ENTRYPOINT:启动容器真正执行的命令,不会被覆盖
ENV:配置环境变量
ADD:复制文件到容器,一般拷贝文件,压缩包自动解压
COPY:复制文件到容器,一般拷贝目录
WORKDIR:设置容器的工作目录
USER:容器使用的用户
ARG:设置编译镜像时传入的参数

docker version 
docker info
Cgroup Driver: systemd  #生产环境中建议使用systemd
Docker Root Dir: /var/lib/docker #Docker根目录,建议用SSD硬盘或者独立的磁盘

CMD与ENTRYPOINT区别

vi Dockerfile

FROM centos:7
ENV envir=test version=1.0
ENTRYPOINT echo "envir:$envir version:$version"

CMD 可以被覆盖
ENTRYPOINT 指定的不能被直接覆盖
docker run 指定 --entrypoint 参数,比如指定 entrypointls,后置命令为/tmp 就相当于 ENTRYPOINTlsCMD/tmp

docker build -t centos:entrypoint .
docker run --rm --entrypoint=ls centos:entrypoint /tmp

Dockerfile传参

使用ARG和build-arg传入动态变量

FROM centos:7
ARG USERNAME
ARG DIR="defaultValue"
RUN useradd -m $USERNAME -u 1001 && mkdir $DIR


docker build --build-arg USERNAME="test_arg" -t test:arg .
docker run -it --rm test:arg bash

镜像大小优化

  1. 使用Alpine作为基础镜像
FROM alpine:3.12
MAINTAINER dot
RUN adduser -D dot


docker build -t alpine:user .
docker images | grep alpine:user
#查看每个层的大小 
docker history alpine:user
  1. 多阶段构建
    准备一个go程序 vi hw.go
package main
import "fmt"
func main() {
  fmt.Println("Hello World!")
}

单阶段构建:

FROM golang:1.14.4-alpine
WORKDIR /opt
COPY hw.go /opt
RUN go build /opt/hw.go 
CMD "./hw"


docker build -t hw:one .
docker image | grep hw:one

多阶段Dockerfile构建:把编译过程拆分出来

# 构建过程
FROM golang:1.14.4-alpine as builder
WORKDIR /opt
COPY hw.go /opt
RUN go build /opt/hw.go 
# CMD "./hw"

# 生成应用镜像过程
FROM alpine:3.12
COPY --from=builder /opt/hw .
CMD [ "./hw" ]



docker build -t hw:multi .
docker images |grep hw:multi