首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Dockerfile 支持内置Shell脚本, 从此告别 && 链接符号

Dockerfile 支持内置Shell脚本, 从此告别 && 链接符号

作者头像
老麦
发布2023-09-07 10:04:49
发布2023-09-07 10:04:49
9620
举报
文章被收录于专栏:Go与云原生Go与云原生

Dockerfile 支持内置Shell脚本, 从此告别 && 链接符号

建议点击 查看原文 查看最新内容。

原文链接: https://typonotes.com/posts/2023/09/03/dockerfile-buildkit-here-syntax-wonderful/

前几天, 我测试 Dockerfile 的 Here-Doc 语法[1], 说其是 鸡肋语法, 是我 浅薄 了。

关于 Dockerfile Here-Document 的测试和介绍文章, 点击图片跳转链接

重新看了 docker 官网文档关于 buildkit[2] 的介绍, 从 docker engine 23.0 开始就是默认 builder 了。

BuildKitopen_in_new is an improved backend to replace the legacy builder. BuildKit is the default builder for users on Docker Desktop, and Docker Engine as of version 23.0.

换句话说, 我们上一篇文章说的的诸多不便, 都自然消失了。

之所以得出 HereDoc 是鸡肋语法谬论, 我仔细分析了一下, 有以下几个原因。

  1. 我测试服务器上的 docker 版本过低, (20.x)
  2. 太久没写 基础镜像 了, 因此没有复杂的 RUNCOPY 命令。

基于以上几点, 我做了一些优化。

  1. 于是我根据官网文档,重新安装 docker engine, 将版本升级到了 24.0.5
  2. 找到了在 Docker Hub 上的 redis 官方 dockerfile 重新测试。

得到的结论是, Here-Doc 语法真的是 太香了

一句话总结:不仅指支持多行语法, 是直接支持内置 Shell 脚本

超级棒的 Dockerfile Here-Document Syntax 语法

首先, 按照官网文档将 docker engine 版本升到最新。以 ubuntu - docker[3] 为例

代码语言:javascript
复制
sudo apt-get install docker-ce docker-ce-cli containerd.io \
    docker-buildx-plugin docker-compose-plugin

其次, 在 Docker Hub 上找到对应的 redis 官方 dockerfile[4]

可以看到, RUN 内容虽然没有通过 && 链接, 但是都是使用 ; 和 \ 进行 分段,换行 管理的, 还是有一定不便。

稍微改造一下, (1) 删除所有 链接作用; \, (2) 取消 RUN 的所有缩进。

划重点:这就是 一个Shell脚本 了。 换句话说, 在本地测试完成之后, 可以直接复制到 Dockerfile 中了。而之前, 还需要使用 && 链接整理命令。

注意: 这里必须使用以下格式, 否则 局部变量向下无法传递

代码语言:javascript
复制
RUN <<EOT
#!/bin/bash
# statment
EOT

直接使用 docker build 命令构建镜像, 看看执行结果

Troubleshooting

变量传递问题

关于以下两种模式, 官网文档并没有说明为什么。仅从对比实验效果上推测, 具体实现还没有研究。

模式1 bash 直接根在 EOT 后面。

代码语言:javascript
复制
RUN <<EOT bash
dist=$(uname -s)
wget -O example.com/app-${dist} app-${dist}
EOT

这种模式下, 第一行的变量 dist 在第二行 wget 中无法使用。因此 wget 行实际解析出来的命令为

代码语言:javascript
复制
wget -O example.com/app- app-

模式2, 在多行内容中 首行 指定解释器 #!/bin/bash, 则所有内容整体被看作一个 Shell 脚本。

代码语言:javascript
复制
RUN <<EOT
#!/bin/bash
dist=$(uname -s)
wget -O example.com/app-${dist} app-${dist}
EOT

这种模式下, wget 行实际解析出来的命令为

代码语言:javascript
复制
wget -O example.com/app-Linux app-Linux

符合预期

没有 buildkit 配置文件

代码语言:javascript
复制
ls: cannot access '/root/.docker/buildx/instances/default': No such file or directory

找不到默认的 buildx 配置, 使用如下即可。

代码语言:javascript
复制
{
    "Name": "localbuilder",
    "Driver": "docker-container",
    "Nodes": [
        {
            "Name": "localbuilder0",
            "Endpoint": "unix:///var/run/docker.sock",
            "Platforms": [
                {
                    "architecture": "amd64",
                    "os": "linux"
                },
                {
                    "architecture": "arm64",
                    "os": "linux"
                }
            ],
            "Flags": null,
            "ConfigFile": "",
            "DriverOpts": {}
        }
    ],
    "Dynamic": false
}

参考资料

[1]

Dockerfile 的 Here-Doc 语法: https://docs.docker.com/engine/reference/builder/#here-documents

[2]

buildkit: https://docs.docker.com/build/buildkit/

[3]

ubuntu - docker: https://docs.docker.com/engine/install/ubuntu/

[4]

redis 官方 dockerfile: https://raw.githubusercontent.com/docker-library/redis/9b538c33746872dcd1e8c809cbde9f21ac2ec3ac/7.2/Dockerfile

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-09-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 熊猫云原生Go 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Dockerfile 支持内置Shell脚本, 从此告别 && 链接符号
    • 超级棒的 Dockerfile Here-Document Syntax 语法
    • Troubleshooting
      • 变量传递问题
      • 没有 buildkit 配置文件
      • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档