- 新增 Go、Node.js、Rust 服务的 Dockerfile 模板 - 新增 Rust 快速参考指南 - 新增 Rust 后端工作流模板 - 优化 create-runner.md,明确 host 网络模式为缓存必需条件 - 更新 gitea skill 主文档
11 KiB
11 KiB
Go 服务 Dockerfile 模板
Go 后端服务的 Docker 容器化模板,支持多种构建场景。
模板类型
1. CI 构建镜像(Dockerfile.ci)
适用场景:在 CI/CD 中使用,二进制文件已在外部构建完成。
优点:
- 镜像体积最小(~15MB)
- 构建速度快
- 适合生产环境
# CI 构建专用 Dockerfile
# 将不常变化的层放在前面,最大化利用缓存
# 使用固定版本避免 latest 导致的缓存失效和不确定性
FROM alpine:3.21
# 基础设置层 - 很少变化,可以长期缓存
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk add --no-cache tzdata wget netcat-openbsd && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# 健康检查脚本 - 偶尔变化
COPY docker-healthcheck.sh .
RUN chmod +x docker-healthcheck.sh
# 应用二进制 - 每次构建都变化,放在最后
COPY your-binary-name .
# 健康检查(根据实际服务修改端口和端点)
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD ./docker-healthcheck.sh
CMD ["./your-binary-name"]
使用说明:
- 将
your-binary-name替换为实际的二进制文件名 - 创建
docker-healthcheck.sh健康检查脚本 - 在 CI workflow 中先构建二进制,再构建镜像
2. 完整构建镜像(Dockerfile)
适用场景:本地开发、无 CI 环境、独立构建。
优点:
- 自包含构建流程
- 可在任何环境构建
- 利用 Docker 缓存加速
# ============================================
# 构建阶段
# ============================================
FROM golang:1.25-alpine AS builder
# 安装构建依赖
RUN apk add --no-cache git make
# 设置工作目录
WORKDIR /build
# 设置 Go 代理(国内加速)
ENV GOPROXY=https://goproxy.cn,direct
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
# 先复制依赖文件,利用 Docker 层缓存
COPY go.mod go.sum ./
RUN go mod download
# 复制源码
COPY . .
# 构建应用(根据项目需求修改)
RUN go build -o app \
-ldflags '-s -w -X main.GitTag=dev' \
.
# ============================================
# 运行阶段
# ============================================
FROM alpine:3.21
# 安装运行时依赖
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk add --no-cache tzdata wget netcat-openbsd && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
WORKDIR /app
# 从构建阶段复制二进制文件
COPY --from=builder /build/app .
COPY --from=builder /build/docker-healthcheck.sh .
RUN chmod +x app docker-healthcheck.sh
# 暴露端口(根据实际服务修改)
EXPOSE 8080
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD ./docker-healthcheck.sh
CMD ["./app"]
使用说明:
- 将构建命令修改为项目实际的构建命令
- 调整 ldflags 参数(版本号注入、符号表去除等)
- 修改端口号
3. 代码生成支持版(Dockerfile.codegen)
适用场景:需要在容器中生成代码(如 Ent、Wire、oapi-codegen)。
# ============================================
# 构建阶段
# ============================================
FROM golang:1.25-alpine AS builder
# 安装构建工具
RUN apk add --no-cache git make
WORKDIR /build
ENV GOPROXY=https://goproxy.cn,direct
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
# 复制依赖文件
COPY go.mod go.sum ./
RUN go mod download
# 安装代码生成工具(根据项目需求选择)
RUN go install entgo.io/ent/cmd/ent@latest && \
go install github.com/google/wire/cmd/wire@latest && \
go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest && \
go install golang.org/x/tools/cmd/stringer@latest
# 复制源码
COPY . .
# 代码生成(根据项目需求修改)
RUN go generate ./...
# 或使用 go tool 调用
# RUN go tool ent generate ./ent/schema
# RUN go tool wire ./...
# RUN go tool oapi-codegen -config oapi.yaml api.yaml
# 测试(可选)
RUN go test ./...
RUN go vet ./...
# 构建
RUN go build -o app \
-ldflags '-s -w' \
.
# ============================================
# 运行阶段
# ============================================
FROM alpine:3.21
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk add --no-cache tzdata wget netcat-openbsd && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
WORKDIR /app
COPY --from=builder /build/app .
COPY --from=builder /build/docker-healthcheck.sh .
RUN chmod +x app docker-healthcheck.sh
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD ./docker-healthcheck.sh
CMD ["./app"]
健康检查脚本
docker-healthcheck.sh(基础版)
#!/bin/sh
# Docker 健康检查脚本
# 检查应用端口是否在监听
if nc -z localhost 8080 2>/dev/null; then
exit 0
fi
exit 1
docker-healthcheck.sh(HTTP 端点版)
#!/bin/sh
# Docker 健康检查脚本
# 检查 HTTP 端点是否可访问
# 使用 /health 或 /metrics 端点
if wget --spider --quiet --timeout=5 http://localhost:8080/health 2>/dev/null; then
exit 0
fi
# 备用:检查端口是否在监听
if nc -z localhost 8080 2>/dev/null; then
exit 0
fi
exit 1
docker-healthcheck.sh(多端口版)
#!/bin/sh
# Docker 健康检查脚本
# 检查多个端口(适用于多个 API 服务)
# 检查端口 2020 (Platform API)
if ! nc -z localhost 2020 2>/dev/null; then
echo "Port 2020 is not responding"
exit 1
fi
# 检查端口 2021 (WxMP API)
if ! nc -z localhost 2021 2>/dev/null; then
echo "Port 2021 is not responding"
exit 1
fi
# 或使用 HTTP 端点
# if ! wget --spider --quiet --timeout=5 http://localhost:2020/metrics 2>/dev/null; then
# exit 1
# fi
exit 0
高级配置
环境变量配置
# 在 Dockerfile 中设置默认环境变量
ENV MODE=production
ENV LOG_LEVEL=info
ENV GIN_MODE=release
# 运行时可覆盖
# docker run -e MODE=test -e LOG_LEVEL=debug your-image
配置文件挂载
# 创建配置目录
RUN mkdir -p /app/configs
# 运行时挂载配置文件
# docker run -v ./configs:/app/configs your-image
非 root 用户运行
# 创建非特权用户
RUN addgroup -g 1000 appuser && \
adduser -D -u 1000 -G appuser appuser
WORKDIR /app
# 复制文件
COPY --from=builder --chown=appuser:appuser /build/app .
# 切换用户
USER appuser
CMD ["./app"]
多阶段构建优化
# ============================================
# 依赖下载阶段(缓存 go.mod)
# ============================================
FROM golang:1.25-alpine AS deps
WORKDIR /build
ENV GOPROXY=https://goproxy.cn,direct
COPY go.mod go.sum ./
RUN go mod download
# ============================================
# 构建阶段
# ============================================
FROM golang:1.25-alpine AS builder
WORKDIR /build
# 从依赖阶段复制缓存
COPY --from=deps /go/pkg /go/pkg
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
COPY . .
RUN go build -o app -ldflags '-s -w' .
# ============================================
# 运行阶段
# ============================================
FROM alpine:3.21
# ... 省略后续步骤
镜像优化技巧
1. 减小镜像体积
# 使用 Alpine 基础镜像
FROM alpine:3.21
# 去除符号表和调试信息
RUN go build -ldflags '-s -w' -o app
# 使用 upx 压缩(可选,启动时间会变长)
RUN apk add --no-cache upx && \
upx --best --lzma app && \
apk del upx
2. 利用构建缓存
# 先复制 go.mod 和 go.sum,利用依赖缓存
COPY go.mod go.sum ./
RUN go mod download
# 再复制源码(源码变化频繁)
COPY . .
3. 合并 RUN 命令
# 合并多个 RUN 命令减少层数
RUN apk add --no-cache tzdata wget netcat-openbsd && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
addgroup -g 1000 appuser
4. 使用 .dockerignore
# .dockerignore
.git/
.gitignore
*.md
docs/
tests/
.github/
.gitea/
Dockerfile*
docker-compose.yml
*.log
tmp/
vendor/
构建命令示例
本地构建
# 基础构建
docker build -t your-service:latest .
# 指定 Dockerfile
docker build -f Dockerfile.ci -t your-service:latest .
# 传递构建参数
docker build --build-arg GIT_TAG=v1.0.0 -t your-service:1.0.0 .
# 查看构建过程
docker build --progress=plain -t your-service:latest .
CI/CD 构建
# 使用 BuildKit 缓存
export DOCKER_BUILDKIT=1
# 使用注册表缓存
docker build \
--cache-from=type=registry,ref=your-service:buildcache \
--cache-to=type=registry,ref=your-service:buildcache,mode=max \
-t your-service:latest \
.
运行容器示例
# 基础运行
docker run -d -p 8080:8080 your-service:latest
# 挂载配置文件
docker run -d \
-p 8080:8080 \
-v ./configs:/app/configs \
-v ./logs:/app/logs \
your-service:latest
# 设置环境变量
docker run -d \
-p 8080:8080 \
-e MODE=production \
-e DATABASE_URL=postgres://... \
your-service:latest
# 查看日志
docker logs -f <container-id>
# 进入容器调试
docker exec -it <container-id> /bin/sh
安全建议
1. 使用特定版本标签
# 不推荐:使用 latest
FROM alpine:latest
# 推荐:使用特定版本
FROM alpine:3.21
2. 定期更新依赖
# 更新 Go 模块
go get -u ./...
go mod tidy
# 更新基础镜像
docker pull alpine:3.21
3. 扫描漏洞
# 使用 Trivy 扫描
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image your-service:latest
4. 最小权限原则
# 使用非 root 用户
USER appuser
# 只读文件系统(如果适用)
# docker run --read-only your-service
常见问题
Q1: 时区不正确
原因: 容器默认使用 UTC 时区
解决方案:
RUN apk add --no-cache tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
Q2: 网络连接超时
原因: DNS 解析问题或网络配置
解决方案:
# 运行时指定 DNS
docker run --dns 8.8.8.8 your-service
# 或在 Dockerfile 中配置
RUN echo 'nameserver 8.8.8.8' > /etc/resolv.conf
Q3: CGO 依赖问题
错误信息: binary was compiled with 'CGO_ENABLED=1'
解决方案:
# 禁用 CGO
ENV CGO_ENABLED=0
# 或安装 gcc
RUN apk add --no-cache gcc musl-dev
Q4: 静态链接失败
错误信息: dynamic executable
解决方案:
# 确保 CGO_ENABLED=0
ENV CGO_ENABLED=0
# 或使用 musl 交叉编译
RUN apk add --no-cache musl-dev
RUN go build -ldflags '-linkmode external -extldflags "-static"' -o app