一些使用docker的tips
作为docker重度使用者,有时也会犯一些低级错误,记录一下长期使用下来的一些经验,长期更新
ADD or COPY
不只一位同事问过我这个问题:在Dockerfile里面看到了下面这一句,但是进入容器之后,在/tmp目录并没有发现buildkit-v0.12.3.darwin-amd64.tar.gz,只看到了解压后的`bin`文件夹,为何没看到解压呢?
ADD buildkit-v0.12.3.darwin-amd64.tar.gz /tmp
# ls /tmp
# bin
这是因为在Dockerfile里面,ADD不仅有COPY字面上的意义,还可以
下载网络资源
解压文件
不要需要注意的,下载和解压这两件事是或的关系,也就是说
ADD https://xxx.tar.gz .
与
RUN curl -O https://xxx.tar.gz
的效果是一致的。(ps: 千万不要期望`ADD https://xxx.tar.gz .` 既能下载又帮你解压)
COPY/ADD文件/文件夹
当你想要在Dockerfile上COPY文件夹的时候
FROM busybox:1.35.0-glibc
COPY bin /tmp
# ls /tmp
# buildctl
但其它我想要复制的整个文件夹,而不仅仅是将文件夹里面的内容复制到/tmp文件夹下,
FROM busybox:1.35.0-glibc
COPY bin /tmp/bin
# ls /tmp
# bin
之前踩到这个坑,因为会不自觉地把COPY当`mv`命令来用
heredocs
我是在推上看到这个的,果然要与时俱进哇
RUN apt-get update -y \
&& apt-get install -y --no-install-recommends curl libsasl2-2 gsasl libnss-ldapd libssl-dev netcat-traditional procps krb5-user locales \
&& rm -rf /var/lib/apt/lists/*
虽然我不是一个强迫症患者,但我也是爱整洁的,所以更喜欢下面这种写法
RUN <<EOF
apt-get update -y
apt-get install -y --no-install-recommends curl libsasl2-2 gsasl libnss-ldapd libssl-dev netcat-traditional procps krb5-user locales
rm -rf /var/lib/apt/lists/*
EOF
值得注意的是,因为你使用`docker buildx build`而不是docker build, 则需要在Dockerfile的第一行加上以下语句:
# syntax=docker/dockerfile:1
ARG
将ARG赋值给ENV
就在前两天我被自己坑了
ARG MY_ARG
FROM busybox:1.35.0-glibc
ENV MY_ENV=$MY_ARG
`docker build --build-arg MY_ARG=test -t argtest .`
docker run --rm -it argtest env |grep MY_ENV
MY_ENV=
我第一反应是:竟然是空的,这不对呀,就很奇怪
FROM busybox:1.35.0-glibc
ARG MY_ARG
ENV MY_ENV=$MY_ARG
原来需要调整下ARG的位置
docker run --rm -it argtest env |grep MY_ENV
MY_ENV=test
只是,没有找到为何这样做以及出处
多阶段构建传递ARG
ARG MY_ARG
FROM busybox:1.35.0-glibc
FROM alpine:3.18
ENV MY_ENV=$MY_ARG
没有意外,MY_ENV是空的
若要将MY_ARG传到alpine:3.18那一层,显示声明MY_ARG即可
ARG MY_ARG
FROM busybox:1.35.0-glibc
FROM alpine:3.18
ARG MY_ARG
ENV MY_ENV=$MY_ARG
多架构镜像的构建
其实,若不是要支持所谓的“信创”,平时工作中也没机会构建ARM镜像的,但既然有这个机会,借此契机,自然也折腾了一番,除了docker官网,我主要参考了这篇文章Multi-Architecture Docker Images。
唯一需要补充的是关于配置方面,如果你使用的是一个私有的harbor镜像仓库(eg: 私有镜像仓库是:172.16.2.130),需要在buildkit的配置文件中添加以下配置
# /etc/buildkitd.toml
debug = true
[registry."172.16.2.130"]
http = true
insecure = true
还是来上一个实际的使用案例吧
FROM busybox:1.35.0-glibc
CMD ["uname", "-i"]
构建amd64和arm64镜像,并推送到私有harbor镜像仓库
docker buildx build --platform linux/amd64,linux/arm64 \
-t 172.16.2.130/capops/multiarch:v0.0.1 . --push
使用这种方法的好处的: 同一份Dockerfile,构建出来的不同架构的镜像,共用同一个镜像tag,例如以上命令,在amd64的机器上执行docker pull 172.16.2.130/capops/multiarch:v0.0.1 获取的是amd64格式的镜像,如下所示
$ docker inspect --format='{{.Os}}/{{.Architecture}}' 172.16.2.130/capops/multiarch:v0.0.1
linux/amd64
而在arm64的机器上执行docker pull 172.16.2.130/capops/multiarch:v0.0.1 获取的是arm64格式的镜像,应用层无需要做任何变动。
参考: