Dockerfile常用指令
dockerfile概述
dockerfile常用指令
https://blog.51cto.com/u_12020737/4539268
指令 | 说明 |
---|---|
FROM | 指明当前的镜像基于哪个镜像构建 |
LABEL | 标记镜像信息,添加元数据 |
ARG | 定义构建镜像过程中使用的变量 |
ENV | 指定环境变量 |
VOLUME | 创建一个数据卷挂载点 |
USER | 指定运行容器时的用户名或 UID |
WORKDIR | 配置工作目录 |
EXPOSE | 容器运行时的端口,默认是TCP |
ADD | 从本地或URL添加文件或压缩包到镜像中,并自动解压 |
COPY | 拷贝文件或目录到镜像中 |
ONBUILD | 创建子镜像时指定自动执行的操作指令 |
STOPSIGNAL | 指定退出的信号值 |
HEALTHCHECK | 配置启动容器如何进行健康检查 |
SHELL | 指定默认 shell 类型 |
RUN | 构建镜像时运行的指定命令 |
CMD | 运行容器时默认执行的命令,如果有多个CMD质量,最后一个生效。 |
ENTRYPOINT | 指定镜像的默认入口命令 |
MAINTAINER
参数已经弃用,用LABEL Author(作者名)="网站"
替代。
ARG和ENV指定变量
https://www.jdon.com/58758.html
- ARG 定义
构建镜像过程中
使用的变量,RUN
可以使用ARG
变量,CMD
和ENTRYPOINT不能使用ARG变量
- ENV 指定
容器运行时
使用的变量,ARG
指定的变量不会容器运行时生效
# ENV示例:
# ENV <key1>=<value1> <key2>=<value2>...
ENV VERSION=1.0 DEBUG=on \
NAME="Happy Feet"
USER指定用户运行
注意:用户需事先建立好,否则无法切换
https://www.hi-linux.com/posts/44367.html
# 创建redis用户和redis组
RUN groupadd -r redis && useradd -r -g redis redis
以指定用户和组运行
# 指定用户和组
USER <user>[:<group>]
# 或
USER <UID>[:<GID>]
# 切换到redis用户运行
USER redis:redis
# 或
USER 1000:1000
WORKDIR设置工作目录
# 设置工作目录--相当于cd到/app目录
## 没有这个目录会自动创建
WORKDIR /app
EXPOSE暴露端口
默认是TCP协议
,如果要暴露UDP端口
,需要单独添加
# 同时在 TCP、UDP 上暴露端口
EXPOSE 80/tcp
EXPOSE 80/udp
# 暴露端口段
EXPOSE 443-26000
EXPOSE 443-26000/udp
ADD和COPY有什么区别
COPY
: 把本地文件
复制到容器;ADD
:COPY
的加强版,可以从url
复制文件,并自动解压
.- 如果 <源路径> 为一个
tar压缩文件
的话,压缩格式为gzip
,bzip2
以及xz
的情况下,ADD
指令将会自动解压缩
这个压缩文件到 <目标路径> 去。 URL下载
和自动解压
特性不能一起使用
。任何压缩文件通过URL拷贝,都不会自动解压
。
- 如果 <源路径> 为一个
RUN,CMD,ENTRYPOINT的区别
RUN命令
执行命令并创建新的镜像层,通常用于安装软件包CMD命令
设置容器启动后默认执行的命令及其参数,但CMD设置的命令能够被docker run命令后面的命令行参数替换ENTRYPOINT
配置容器启动时的执行命令(不会被忽略,一定会被执行,即使运行 docker run时指定了其他命令)
ENTRYPOINT
非json
则已ENTRYPOINT
为准,如果ENTRYPOINT
和CMD
都是json
,则ENTRYPOINT+CMD
拼接成shell
ONBUILD子镜像指令
ONBUILD
是一个特殊的指令
,它后面跟的是其它指令,比如 RUN
, COPY
等,而这些指令,在当前镜像构建时并不会被执行;
只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行
Dockerfile
中的其它指令都是为了定制当前镜像而准备的,唯有ONBUILD
是为了帮助别人定制自己而准备的.
AS阶段构建指令
https://blog.51cto.com/u_12020737/4539269
一个 dockerfile
可以有多个 FROM
来创建多个镜像
,或区分构建阶段
,将一构建阶段作
为二构建阶段
的依赖项;
AS <阶段名>
就是命名当前构建阶段;
在后续构建阶段,可以给 FROM
、COPY
指令用上,通过 --from=<上一个阶段名>
引用上一阶段
构建的镜像.
例如:
1
阶段编译
好二进制文件
;
2
阶段COPY
编译好的二进制文件
;2
阶段构建的容器会很小
.
分阶段构建镜像,可以有效减小镜像
.
# 阶段1,解压gost压缩包
## 请勿使用latest标签
FROM alpine:latest as unzip
# 设置gost版本号
ARG GOST_VERSION=3.0.0-rc8
# 下载GOST3压缩包
ADD https://github.com/go-gost/gost/releases/download/v"${GOST_VERSION}"/gost_"${GOST_VERSION}"_linux_amd64.tar.gz .
# 解压gost压缩包
RUN tar xvf gost_${GOST_VERSION}_linux_amd64.tar.gz
# 阶段2,复制gost可执行程序
FROM alpine:latest as copy_gost_bin
# 作者信息
LABEL qiaofei.li="https://blog.youkuaiyun.com/omaidb"
# 设置工作目录
WORKDIR /app
# 将unzip阶段的的gost可执行程序复制到当前目录
COPY --from=unzip gost .
# 将本地的配置文件复制到当前目录
COPY gost.yaml .
# USER <用户名>[:<用户组>]
# USER nobody:nobody
# 容器使用的端口
# EXPOSE 1080/tcp
# EXPOSE 1080/udp
# 运行主程序--指定绝对路径
ENTRYPOINT /app/gost -C gost.yaml
构建镜像
# 构建镜像
docker build -t gost .
# 修改tag
docker tag gost:latest omaidb/gost:latest
# 推送到仓库
docker push omaidb/gost:latest
HEALTHCHECK健康检查指令
https://blog.51cto.com/u_12020737/4539257
编辑dockerfile
建议使用VScode
安装docker
插件,能提供部分自动补全。
# 创建nginx项目目录
mkdir -p nginx
# 创建dockerfile文件
## dockerfiles的默认名称:dockerfile和Dockerfile
vim nginx/Dockerfile
Dockerfile设置时区
/etc/localtime
是用来描述本机时间
,而 /etc/timezone
是用来描述本机所属的时区
# 设置上海时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
变量ENV
和.dockerignore
忽略文件
参考: https://www.yafa.moe/post/cka-docker-basic/
# 忽略文件
.dockerignore
示例:构建nginx镜像
# 基于redhat8镜像构建新镜像
## 请勿使用latest标签
#FROM redhat/ubi8:8.7-1090
## --platform 指定镜像的cpu架构
FROM --platform=linux/arm64/v8 almalinux:8.7-minimal-20230222
# 标签:作者信息
## LABEL key="value"
LABEL qiaofei.li="https://blog.csdn.com/omaidb"
# 构建镜像时运行的命令
RUN yum makecache && \
yum install -y gcc make \
pcre pcre-devel zlib zlib-devel \
openssl openssl-devel && \
yum clean all && \
rm -rf /var/cache/yum/*
# 设置软件的版本号为变量
ENV VERSION=1.18.0
# 解压并拷贝文件到镜像
## copy --把`文件`复制到容器
## add --是copy的加强版,可以从url复制文件
ADD nginx-${VERSION}.tar.gz /
# 构建镜像时运行的命令,编译安装nginx
RUN cd nginx-${VERSION} && \
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_realip_module \
--with-threads && \
make -j && make install && \
mkdir /usr/local/nginx/conf/vhost && \
cd / && rm -rf nginx* && \
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# 设置环境变量
ENV PATH $PATH:/usr/local/nginx/sbin
# 将配置文件copy到镜像中
# COPY nginx.conf /usr/local/nginx/config/nginx.conf
# 设置工作目录
WORKDIR /usr/local/nginx
# 容器使用的端口
# 默认是tcp
EXPOSE 80
# 如果要开放udp,需要单独加
EXPOSE 80/udp
# 容器运行的命令,Nginx守护进程的固定格式
CMD ["nginx", "-g", "daemon off;"]
docker build-构建nignx镜像
Dockerfile文件
的名称没有任何扩展名
,一般默认是大写D
和小写f
.
dockerfiles
的默认名称:dockerfile
和Dockerfile
. 如果文件名中有其他大写字母
,它很可能会失败
。
如果你不需要使用buildkit
,在执行构建Dockerfile之前
禁用。
export DOCKER_BUILDKIT=0
export COMPOSE_DOCKER_CLI_BUILD=0
https://stackoverflow.com/questions/64985913/failed-to-solve-with-frontend-dockerfile
# 在dockerfile同目录下执行build命令
## -f dockerfile文件可以是任何后缀名
## -t 构建出的镜像名:标签
## .表示dockerfile文件在当前目录下
docker build -f ./path/to/Dockerfile -t my-image .
# 构建一个针对 arm64 平台的镜像,并指定基础镜像
docker build --platform linux/arm64 -f Dockerfile.arm64 -t nginx-arm64:v1.
构建多cpu平台容器—未经测试
buildx
需要单独安装
,buildx
项目地址:https://github.com/docker/buildx
Docker Buildx
: 建议使用 Docker Buildx
来进行多平台构建,它提供了更强大的功能和更好的用户体验。
基础镜像: 确保你选择的基础镜像支持你目标的平台。
Dockerfile
: 如果你的 Dockerfile 中有针对不同平台的特殊配置
,可以考虑使用构建参数
或者多阶段构建
来实现。
# 构建一个针对 amd64 和 arm64 平台的镜像
docker buildx build --platform linux/amd64,linux/arm64 -f Dockerfile -t nginx-arm64-amd64:v1 .
示例2:构建httpd
下一代构建工具BuildKit
BuildKit
也是非常好的dockfile
构建工具
项目地址: https://github.com/moby/buildkit
dockerfile优化
将Docker镜像体积减小99%
: https://juejin.cn/post/6844904101348638734
构建镜像Dockerfile
文件优化:
减少镜像层
: 一次RUN
指令形成新的一层
,尽量Shell命令都写在一行
,减少镜像层。清理无用文件
: 清理对应的残留数据,例如yum缓存。清理无用的软件包
: 基础镜像默认会带一些debug工具,可以删除掉,仅保留应用程序所需软件,防止黑客利用。选择最小的基础镜像
: 例如alpine
使用非root用户运行
:USER
指令指定普通用户,降低权限
查看镜像层
分析镜像构建 https://blog.youkuaiyun.com/omaidb/article/details/122044116
# 查看nginx镜像的文件层
docker history omaidb/gost:3.0.0-rc6
build常见错误
ERROR: failed to solve: failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount2237603866/Dockerfile: no such file or directory
原因:dockerfile名称不对。
将dockerfile文件重命名为Dockerfile