feat(gitea): 添加 Dockerfile 模板和 Rust 支持,优化 runner 网络配置说明
- 新增 Go、Node.js、Rust 服务的 Dockerfile 模板 - 新增 Rust 快速参考指南 - 新增 Rust 后端工作流模板 - 优化 create-runner.md,明确 host 网络模式为缓存必需条件 - 更新 gitea skill 主文档
This commit is contained in:
550
skill/gitea/dockerfile-templates/go-service.md
Normal file
550
skill/gitea/dockerfile-templates/go-service.md
Normal file
@@ -0,0 +1,550 @@
|
||||
# Go 服务 Dockerfile 模板
|
||||
|
||||
Go 后端服务的 Docker 容器化模板,支持多种构建场景。
|
||||
|
||||
## 模板类型
|
||||
|
||||
### 1. CI 构建镜像(Dockerfile.ci)
|
||||
|
||||
**适用场景**:在 CI/CD 中使用,二进制文件已在外部构建完成。
|
||||
|
||||
**优点**:
|
||||
- 镜像体积最小(~15MB)
|
||||
- 构建速度快
|
||||
- 适合生产环境
|
||||
|
||||
```dockerfile
|
||||
# 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"]
|
||||
```
|
||||
|
||||
**使用说明**:
|
||||
1. 将 `your-binary-name` 替换为实际的二进制文件名
|
||||
2. 创建 `docker-healthcheck.sh` 健康检查脚本
|
||||
3. 在 CI workflow 中先构建二进制,再构建镜像
|
||||
|
||||
### 2. 完整构建镜像(Dockerfile)
|
||||
|
||||
**适用场景**:本地开发、无 CI 环境、独立构建。
|
||||
|
||||
**优点**:
|
||||
- 自包含构建流程
|
||||
- 可在任何环境构建
|
||||
- 利用 Docker 缓存加速
|
||||
|
||||
```dockerfile
|
||||
# ============================================
|
||||
# 构建阶段
|
||||
# ============================================
|
||||
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"]
|
||||
```
|
||||
|
||||
**使用说明**:
|
||||
1. 将构建命令修改为项目实际的构建命令
|
||||
2. 调整 ldflags 参数(版本号注入、符号表去除等)
|
||||
3. 修改端口号
|
||||
|
||||
### 3. 代码生成支持版(Dockerfile.codegen)
|
||||
|
||||
**适用场景**:需要在容器中生成代码(如 Ent、Wire、oapi-codegen)。
|
||||
|
||||
```dockerfile
|
||||
# ============================================
|
||||
# 构建阶段
|
||||
# ============================================
|
||||
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(基础版)
|
||||
|
||||
```bash
|
||||
#!/bin/sh
|
||||
# Docker 健康检查脚本
|
||||
|
||||
# 检查应用端口是否在监听
|
||||
if nc -z localhost 8080 2>/dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
exit 1
|
||||
```
|
||||
|
||||
### docker-healthcheck.sh(HTTP 端点版)
|
||||
|
||||
```bash
|
||||
#!/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(多端口版)
|
||||
|
||||
```bash
|
||||
#!/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
|
||||
# 在 Dockerfile 中设置默认环境变量
|
||||
ENV MODE=production
|
||||
ENV LOG_LEVEL=info
|
||||
ENV GIN_MODE=release
|
||||
|
||||
# 运行时可覆盖
|
||||
# docker run -e MODE=test -e LOG_LEVEL=debug your-image
|
||||
```
|
||||
|
||||
### 配置文件挂载
|
||||
|
||||
```dockerfile
|
||||
# 创建配置目录
|
||||
RUN mkdir -p /app/configs
|
||||
|
||||
# 运行时挂载配置文件
|
||||
# docker run -v ./configs:/app/configs your-image
|
||||
```
|
||||
|
||||
### 非 root 用户运行
|
||||
|
||||
```dockerfile
|
||||
# 创建非特权用户
|
||||
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"]
|
||||
```
|
||||
|
||||
### 多阶段构建优化
|
||||
|
||||
```dockerfile
|
||||
# ============================================
|
||||
# 依赖下载阶段(缓存 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. 减小镜像体积
|
||||
|
||||
```dockerfile
|
||||
# 使用 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. 利用构建缓存
|
||||
|
||||
```dockerfile
|
||||
# 先复制 go.mod 和 go.sum,利用依赖缓存
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
# 再复制源码(源码变化频繁)
|
||||
COPY . .
|
||||
```
|
||||
|
||||
### 3. 合并 RUN 命令
|
||||
|
||||
```dockerfile
|
||||
# 合并多个 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/
|
||||
```
|
||||
|
||||
## 构建命令示例
|
||||
|
||||
### 本地构建
|
||||
|
||||
```bash
|
||||
# 基础构建
|
||||
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 构建
|
||||
|
||||
```bash
|
||||
# 使用 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 \
|
||||
.
|
||||
```
|
||||
|
||||
## 运行容器示例
|
||||
|
||||
```bash
|
||||
# 基础运行
|
||||
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. 使用特定版本标签
|
||||
|
||||
```dockerfile
|
||||
# 不推荐:使用 latest
|
||||
FROM alpine:latest
|
||||
|
||||
# 推荐:使用特定版本
|
||||
FROM alpine:3.21
|
||||
```
|
||||
|
||||
### 2. 定期更新依赖
|
||||
|
||||
```bash
|
||||
# 更新 Go 模块
|
||||
go get -u ./...
|
||||
go mod tidy
|
||||
|
||||
# 更新基础镜像
|
||||
docker pull alpine:3.21
|
||||
```
|
||||
|
||||
### 3. 扫描漏洞
|
||||
|
||||
```bash
|
||||
# 使用 Trivy 扫描
|
||||
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
|
||||
aquasec/trivy image your-service:latest
|
||||
```
|
||||
|
||||
### 4. 最小权限原则
|
||||
|
||||
```dockerfile
|
||||
# 使用非 root 用户
|
||||
USER appuser
|
||||
|
||||
# 只读文件系统(如果适用)
|
||||
# docker run --read-only your-service
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1: 时区不正确
|
||||
|
||||
**原因**: 容器默认使用 UTC 时区
|
||||
|
||||
**解决方案**:
|
||||
```dockerfile
|
||||
RUN apk add --no-cache tzdata && \
|
||||
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
```
|
||||
|
||||
### Q2: 网络连接超时
|
||||
|
||||
**原因**: DNS 解析问题或网络配置
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 运行时指定 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'`
|
||||
|
||||
**解决方案**:
|
||||
```dockerfile
|
||||
# 禁用 CGO
|
||||
ENV CGO_ENABLED=0
|
||||
|
||||
# 或安装 gcc
|
||||
RUN apk add --no-cache gcc musl-dev
|
||||
```
|
||||
|
||||
### Q4: 静态链接失败
|
||||
|
||||
**错误信息**: `dynamic executable`
|
||||
|
||||
**解决方案**:
|
||||
```dockerfile
|
||||
# 确保 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
|
||||
```
|
||||
|
||||
## 参考资源
|
||||
|
||||
- [Go 官方 Docker 指南](https://docs.docker.com/language/golang/)
|
||||
- [Alpine Linux 包搜索](https://pkgs.alpinelinux.org/packages)
|
||||
- [Docker 多阶段构建文档](https://docs.docker.com/build/building/multi-stage/)
|
||||
- [Go 编译器标志](https://pkg.go.dev/cmd/go)
|
||||
Reference in New Issue
Block a user