当前位置: 首页 > news >正文

简单使用scratch镜像

1、编写go-demo项目

hello目录有main.go和go.mod文件

main.go文件: 

package mainimport ("net/http""fmt"
)func main() {http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {w.Write([]byte("hello world"))})fmt.Println("start server: http://127.0.0.1:8000")http.ListenAndServe("0.0.0.0:8000", nil)
}

go.mod文件:

module hellogo 1.21.6

编译成可执行文件:

# 修改go环境变量CGO_ENABLED设置为0,默认为1
# 详见:https://zhuanlan.zhihu.com/p/576103234
go env -w CGO_ENABLED='0'# 编译项目
go build -o app main.go

查看文件:

 

2、构建镜像并运行

编写Dockerfile文件:

FROM scratch
COPY ./app /app
EXPOSE 8000
CMD ["/app"]

构建镜像:

docker build -t app:v1 .

查看镜像:

运行容器:

docker run --rm -p 8000:8000 app:v1

curl访问:

curl http://127.0.0.1:8000

参考:

https://docs.docker.com/build/building/base-images/

https://docs.docker.com/build/building/multi-stage/

3、分析docker文档的Dockerfile文件

源文件地址:docs/Dockerfile at main · docker/docs · GitHub

3.1、定义参数

# syntax=docker/dockerfile-upstream:master
# check=skip=InvalidBaseImagePlatform# ALPINE_VERSION sets the Alpine Linux version for all Alpine stages
ARG ALPINE_VERSION=3.20
# GO_VERSION sets the Go version for the base stage
ARG GO_VERSION=1.22
# HTML_TEST_VERSION sets the wjdp/htmltest version for HTML testing
ARG HTMLTEST_VERSION=0.17.0

alpine镜像版本:ALPINE_VERSION=3.20
go版本:GO_VERSION=1.22
htmltest版本:HTMLTEST_VERSION=0.17.0 

3.2、base阶段:基于golang:1.22镜像构建

# base is the base stage with build dependencies
FROM golang:${GO_VERSION}-alpine AS base
WORKDIR /src
RUN apk --update add nodejs npm git gcompat

工作目录:/src

apk --update add:命令用于安装一个或多个软件包,并在安装前更新软件包列表

安装或更新 nodejs、npm、git、gcompat软件

3.3、node阶段:基于base阶段构建

# node installs Node.js dependencies
FROM base AS node
COPY package*.json .
ENV NODE_ENV=production
RUN npm install

复制当前Dockerfile所在宿主机的package.json等文件 到 当前镜像的/src目录

设置环境变量NODE_ENV

npm install命令:根据package.json,安装依赖下载到node_modules目录

3.4、hugo阶段:基于base阶段构建

# hugo downloads and extracts the Hugo binary
FROM base AS hugo
ARG HUGO_VERSION=0.132.0
ARG TARGETARCH
WORKDIR /tmp/hugo
RUN wget -O "hugo.tar.gz" "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-${TARGETARCH}.tar.gz"
RUN tar -xf "hugo.tar.gz" hugo

hugo版本:HUGO_VERSION=0.132.0

工作目录:/tmp/hugo

使用wget下载hugo安装包,并使用tar命令解压

3.5、build-base阶段:基于base阶段构建

# build-base is the base stage for building the site
FROM base AS build-base
COPY --from=hugo /tmp/hugo/hugo /bin/hugo
COPY --from=node /src/node_modules /src/node_modules
COPY . .

复制hugo阶段的/tmp/hugo/hugo文件 到 当前镜像的/bin/hugo

复制node阶段的/src/node_modules文件 到 当前镜像的/src/node_modules

复制当前Dockerfile所在宿主机的当前文件 到 当前镜像的/src目录

3.6、dev阶段:基于build-base阶段构建

# dev is for local development with Docker Compose
FROM build-base AS dev

3.7、build阶段:基于build-base阶段构建

# build creates production builds with Hugo
FROM build-base AS build
# HUGO_ENV sets the hugo.Environment (production, development, preview)
ARG HUGO_ENV
# DOCS_URL sets the base URL for the site
ARG DOCS_URL
RUN hugo --gc --minify -d /out -e $HUGO_ENV -b $DOCS_URL

生成html文件:hugo --gc --minify -d /out -e $HUGO_ENV -b $DOCS_URL

hugo命令部分参数说明:

  --gc:enable to run some cleanup tasks (remove unused cache files) after the build

  --minify:minify any supported output format (HTML, XML etc.)

  -d, --destination string:filesystem path to write files to

  -e, --environment string:build environment

  -b, --baseURL string:hostname (and path) to the root, e.g. https://spf13.com/

3.8、lint阶段:基于davidanson/markdownlint-cli2镜像构建

# lint lints markdown files
FROM davidanson/markdownlint-cli2:v0.13.0 AS lint
USER root
RUN --mount=type=bind,target=. \/usr/local/bin/markdownlint-cli2 \"content/**/*.md" \"#content/engine/release-notes/*.md" \"#content/desktop/previous-versions/*.md"

--mount=type=bind,from=构建阶段或镜像名称,source=源路径,target=目标路径 

RUN --mount 

RUN --mount=type=bind 

https://blog.51cto.com/gugu/6085739 

3.9、test阶段:基于htmltest:0.17.0镜像构建

# test validates HTML output and checks for broken links
FROM wjdp/htmltest:v${HTMLTEST_VERSION} AS test
WORKDIR /test
COPY --from=build /out ./public
ADD .htmltest.yml .htmltest.yml
RUN htmltest

wjdp/htmltest:测试生成的HTML是否存在问题

工作目录:/test

复制build阶段的/out目录 到 当前镜像的/test/public目录

复制当前Dockerfile所在宿主机的.htmltest.yml文件 到 当前镜像的/test/.htmltest.yml

GitHub - wjdp/htmltest: :white_check_mark: Test generated HTML for problems 

3.10、update-modules阶段:基于build-base阶段构建

# update-modules downloads and vendors Hugo modules
FROM build-base AS update-modules
# MODULE is the Go module path and version of the module to update
ARG MODULE
RUN <<"EOT"
set -ex
if [ -n "$MODULE" ]; thenhugo mod get ${MODULE}RESOLVED=$(cat go.mod | grep -m 1 "${MODULE/@*/}" | awk '{print $1 "@" $2}')go mod edit -replace "${MODULE/@*/}=${RESOLVED}";
elseecho "no module set";
fi
EOT
RUN hugo mod vendor

hugo mod vendor:Vendor all module dependencies into the _vendor directory.

将依赖写入_vendor目录

Here-Documents

# syntax=docker/dockerfile:1
FROM debian
RUN <<EOT bashset -exapt-get updateapt-get install -y vim
EOT

set参数说明(Linux系统使用 man set 查看):

-e      Exit immediately if a pipeline (which may consist of a single simple command),  a subshell command enclosed in parentheses, or one of the  commands  executed  as part  of  a command list enclosed by braces (see SHELL GRAMMAR above) exits with a non-zero status.  The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in  a  && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command's return value is being inverted with !.  A trap on ERR, if set, is executed before the shell exits.  This option applies to the shell environment and each subshell environment separately (see COMMAND EXE‐CUTION ENVIRONMENT above), and may cause subshells to exit before executing all the commands in the subshell. 

-x      After expanding each simple command, for command, case command, select command, or arithmetic for command, display the expanded value of  PS4,  followed  by  the command and its expanded arguments or associated word list.

3.11、vendor阶段:基于scratch镜像构建

# vendor is an empty stage with only vendored Hugo modules
FROM scratch AS vendor
COPY --from=update-modules /src/_vendor /_vendor
COPY --from=update-modules /src/go.* /

复制update-modules阶段的/src/_vendor文件 到 当前镜像的/_vendor

复制update-modules阶段的/src/go.*文件 到 当前镜像的/

3.12、build-upstream阶段:基于build-base阶段构建

# build-upstream builds an upstream project with a replacement module
FROM build-base AS build-upstream
# UPSTREAM_MODULE_NAME is the canonical upstream repository name and namespace (e.g. moby/buildkit)
ARG UPSTREAM_MODULE_NAME
# UPSTREAM_REPO is the repository of the project to validate (e.g. dvdksn/buildkit)
ARG UPSTREAM_REPO
# UPSTREAM_COMMIT is the commit hash of the upstream project to validate
ARG UPSTREAM_COMMIT
# HUGO_MODULE_REPLACEMENTS is the replacement module for the upstream project
ENV HUGO_MODULE_REPLACEMENTS="github.com/${UPSTREAM_MODULE_NAME} -> github.com/${UPSTREAM_REPO} ${UPSTREAM_COMMIT}"
RUN hugo --ignoreVendorPaths "github.com/${UPSTREAM_MODULE_NAME}" -d /out

upstream_module_name、upstream_repo、upstream_commit

hugo部分参数说明:

  --ignoreVendorPaths string:ignores any _vendor for module paths matching the given Glob pattern

  -d, --destination string:filesystem path to write files to 

3.13、validate-upstream阶段:基于wjdp/htmltest:0.17.0镜像构建

# validate-upstream validates HTML output for upstream builds
FROM wjdp/htmltest:v${HTMLTEST_VERSION} AS validate-upstream
WORKDIR /test
COPY --from=build-upstream /out ./public
ADD .htmltest.yml .htmltest.yml
RUN htmltest

工作目录:/test

复制build-stream阶段的/out文件 到 当前镜像的/test/public

复制当前Dockerfile所在宿主机的.htmltest.yml文件 到 当前镜像的/test/.htmltest.yml

GitHub - wjdp/htmltest: :white_check_mark: Test generated HTML for problems 

3.14、unused-media阶段:基于alpine:3.20镜像构建

# unused-media checks for unused graphics and other media
FROM alpine:${ALPINE_VERSION} AS unused-media
RUN apk add --no-cache fd ripgrep
WORKDIR /test
RUN --mount=type=bind,target=. <<"EOT"
set -ex
./scripts/test_unused_media.sh
EOT

不使用缓存安装fd、ripgrep软件

工作目录:/test

3.15、path-warnings阶段:基于build-base阶段构建

# path-warnings checks for duplicate target paths
FROM build-base AS path-warnings
RUN hugo --printPathWarnings > /path-warnings.txt
RUN <<EOT
DUPLICATE_TARGETS=$(grep "Duplicate target paths" /path-warnings.txt)
if [ ! -z "$DUPLICATE_TARGETS" ]; thenecho "$DUPLICATE_TARGETS"echo "You probably have a duplicate alias defined. Please check your aliases."exit 1
fi
EOT

hugo命令部分参数说明:

 --printPathWarnings:print warnings on duplicate target paths etc.

3.16、pagefind阶段:基于base阶段构建

# pagefind installs the Pagefind runtime
FROM base AS pagefind
ARG PAGEFIND_VERSION=1.1.0
COPY --from=build /out ./public
RUN --mount=type=bind,src=pagefind.yml,target=pagefind.yml \npx pagefind@v${PAGEFIND_VERSION} --output-path "/pagefind"

pagefind版本:1.1.0

复制build阶段的/out文件 到 当前镜像/src/public

npx pagefind@v1.1.0 --output-path "/pagefind":生成文件输出到/pagefind

Pagefind CLI configuration options | Pagefind — Static low-bandwidth search at scale 

3.17、index阶段:基于scratch镜像构建

# index generates a Pagefind index
FROM scratch AS index
COPY --from=pagefind /pagefind .

复制pagefind阶段的/pagefind文件 到 当前镜像 

3.18、test-go-redirects阶段:基于alpine:3.20镜像构建

# test-go-redirects checks that the /go/ redirects are valid
FROM alpine:${ALPINE_VERSION} AS test-go-redirects
WORKDIR /work
RUN apk add yq
COPY --from=build /out ./public
RUN --mount=type=bind,target=. <<"EOT"
set -ex
./scripts/test_go_redirects.sh
EOT

工作目录:/work

安装yq

复制build阶段的/out文件 到 当前镜像的/work/public

3.19、release阶段:基于scratch镜像构建

# release is an empty scratch image with only compiled assets
FROM scratch AS release
COPY --from=build /out /
COPY --from=pagefind /pagefind /pagefind

复制build阶段的/out文件 到 当前镜像的/

复制pagefind阶段的/pagefind文件 到 当前镜像的/pagefind

3.20、Dockerfile部分指令说明

https://docs.docker.com/reference/dockerfile/

1)FROM……AS……

Name your build stages

Use a previous stage as a new stage

2)COPY --from

Use an external image as a stage

3)--mount=type=bind

RUN --mount

RUN --mount=type=bind

https://blog.51cto.com/gugu/6085739

4)<<EOT

Here-Documents


http://www.mrgr.cn/news/7653.html

相关文章:

  • 数据增强常见方法汇总
  • NoSQL之Redis配置与优化
  • pyintaller pyqt5 pytest打包后 找不到测试实例
  • 【正点原子K210连载】第三十二章 音频FFT实验 摘自【正点原子】DNK210使用指南-CanMV版指南
  • leetcode 438 找到字符串中所有字母异位词
  • 使用Python+winshell/shutil清空回收站
  • QML 界面切换的方法
  • Vue.js学习笔记(七)使用sortablejs或el-table-draggable拖拽ElementUI的el-table表格组件
  • C#高效异步文件监控与日志记录工具
  • node npm nvm 地址
  • 【Qt】输入类控件QDail
  • Python算法工程师面试整理-数据结构
  • 【数据结构】链表
  • 使用React和AntDesign构建初始前端项目及路由配置
  • vscode修改选中文字颜色及当前tab颜色
  • 红黑树
  • C++动态规划及九种背包问题
  • ESP RainMaker OTA 自动签名功能的安全启动
  • 井盖异动传感器:为城市安全加码
  • MATLAB 手动实现点云投影滤波器 (76)