📌服务组件📌Docker📌1-Dockerfile指令.txt
Dockerfile参考:https://docs.docker.com/reference/dockerfile/
docker官方镜像列表:https://hub.docker.com/search?q=&image_filter=official

构建镜像时不应该将无关文件复制到镜像,可以通过.dockerignore文件指定忽略文件和目录。
Dockerfile一般采用多阶段构建,将编译环境和运行环境分割,使得构建的镜像尽可能轻量。

如需在构建时传递命令参数,需声明
ARG 参数名[=默认值]
FROM指令之前声明的ARG只能用于FROM指令(可多个),FROM后声明的ARG才可以用于当前stage阶段指令。
使用 ${参数名}

========== ========== Go项目构建 ========== ==========

golang:1.22镜像约830M,包含有时区文件、ssl证书等可供后阶段复制。

FROM golang:1.22 as builder
WORKDIR /build
ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
    GOPROXY=https://goproxy.cn,direct \
    GOSUMDB=sum.golang.google.cn
COPY . .
RUN go mod download && go build -o app

第一阶段使用golang镜像构建,生成的二进制文件位于/build/app
第二阶段需将二进制文件和运行所依赖的文件复制到基础镜像中。
基础镜像可以包含操作系统也可以是一个空镜像,常用的对比如下:
debian:约116M大小,包含了一个轻量的Linux操作系统。
alpine:约7M大小,包含了一个最小规模的Linux发行版。
scratch:空镜像,无法在容器内运行终端,且默认缺少证书文件需要从别处复制到/etc/ssl/certs/ca-certificates.crt。
timezone和certs打包到镜像内不是必要操作,也可以在启动容器的时候将宿主机的对应文件挂载到容器。
若选择从宿主机挂载或复制timezone和certs文件到容器,构建阶段也可以使用体积更小的golang:1.22-alpine镜像。

基于alpine示例:
FROM alpine
RUN apk add --no-cache tzdata \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone \
    && apk del tzdata
WORKDIR /app
COPY --from=builder /build/app .
COPY filename .
COPY dirname dirname
ENTRYPOINT ["./app"]

基于空镜像示例:
FROM scratch
WORKDIR /app
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=builder /build/app .
COPY filename .
COPY dirname dirname
ENTRYPOINT ["./app"]

scratch构建出来的镜像比alpine的小7M多,差值大约就是alpine基础镜像的大小。
同理,使用debian构建出来的镜像会比alpine的大100M多。

========== ========== .NET项目构建 ========== ==========

mcr.microsoft.com/dotnet/sdk:8.0镜像约892M,用于第一阶段构建。
mcr.microsoft.com/dotnet/aspnet:8.0镜像约249M,用于第二阶段部署。

# Build
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder
WORKDIR /build
COPY . .
RUN dotnet restore && dotnet publish -c Release -o app -p:AssemblyName=app

# Deploy
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=builder /build/app .
ENTRYPOINT ["dotnet", "app.dll"]

========== ========== 前端静态项目构建 ========== ==========

node:20-alpine镜像大小约135M,而node:20镜像约1.1G,构建阶段可选前者。

FROM node:20-alpine as builder
WORKDIR /build
COPY . .
RUN npm install --registry=https://registry.npmmirror.com && npm run build

第一阶段使用node镜像编译打包到/build/dist目录。
第二阶段通常基于nginx镜像,官方的nginx镜像大小约192M。需将第一阶段打包生成的目录复制到基础镜像中。
使用自定义的nginx.conf文件替换镜像中/etc/nginx/conf.d/default.conf

自定义的nginx配置只需以下几行
server {
   listen       80;
   server_name  localhost;
   location / {
      root       /www;
      index      index.html;
      try_files  $uri  $uri/  /index.html;
   }
}
容器内的nginx只作静态代理,其余的gzip压缩、缓存、限流、域名证书等配置都放在网关ingress入口做。

FROM nginx:1.25
COPY nginx.conf /etc/nginx/conf.d/default.conf 
COPY --from=builder /build/dist www
ENTRYPOINT ["nginx", "-g", "daemon off;"]