boxmoe_header_banner_img

Hello! 欢迎来到我的博客!

加载中

文章导读

Docker实战 – Dockerfile镜像构建


avatar
xiaoifei 2026年10月16日 13

这一篇主要记录从接口开发、多阶段镜像构建,到接口验证和容器维护的完整过程

操作步骤:

  • 准备业务代码与运行环境
  • 编写Dockerfile与.dockerignore
  • docker build构建自定义docker镜像
  • docker run运行服务
  • 服务状态监控与维护

1. 准备业务代码与运行环境

接口请求方式功能
/healthGET返回服务健康状态
/predictPOST接收文本,返回固定分类结果
package main

import (
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
)

func health(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{"status": "ok"})
}

func predict(c *gin.Context) {
	var request struct {
		Text string `json:"text"`
	}

	if err := c.ShouldBindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请求体必须是 JSON,例如 {\"text\":\"这是一条测试\"}"})
		return
	}
	if strings.TrimSpace(request.Text) == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "text 不能为空"})
		return
	}

	// 第一版使用固定结果,后续替换为真实模型推理。
	c.JSON(http.StatusOK, gin.H{"result": "positive"})
}

func main() {
	// Creates a gin router with default middleware:
	// logger and recovery (crash-free) middleware
	router := gin.Default()

	router.GET("/health", health)
	router.POST("/predict", predict)

	// By default it serves on :8080 unless a
	// PORT environment variable was defined.
	// router.Run()
	router.Run(":8000") // for a hard coded port
}

检查docker是否能够正常运行容器

docker run --rm hello-world

2. Dockerfile 与 .dockerignore

# 第一阶段:编译程序
FROM golang:1.26-alpine AS builder

WORKDIR /app

# 先复制依赖清单,让依赖下载可以复用构建缓存
COPY go.mod go.sum ./
RUN go mod download

# 复制项目源码
COPY . .

RUN CGO_ENABLED=0 GOOS=linux go build \
    -trimpath \
    -o /app/server \
    .

# 第二阶段:运行程序
FROM alpine:3.22

COPY --from=builder /app/server /server

EXPOSE 8000
ENTRYPOINT ["/server"]

解析:
FROM确认镜像构建的基底环境,AS作为镜像构建的阶段名称
使用WORKDIR确认打包环境中的工作目录
通过COPY […SOURCE FILES] [DESTINATION DIR]将本机文件复制到镜像构建的环境中
RUN即在镜像环境中执行一些CMD命令
COPY –from=[STAGENAME] 可以从指定阶段取出文件复制给当前阶段
这样最终镜像包含 Alpine 及编译好的服务,无需把 Go 编译器和整份源码一起带入运行环境

docker在构建环境中会启动一个虚拟机,阶段有各自独立的文件系统状态,可以通过 FROM 继承已有状态,也可以通过 COPY –from 复制文件。如果写成 FROM builder AS another,新阶段就会以 builder 的结果为起点,继承当时的文件系统内容,但后续修改仍然独立。

# Git 信息
.git
.gitignore

# 编辑器配置
.vscode
.idea

# 本地构建产物
bin/
dist/
tmp/
*.exe
*.test
coverage.out

# 日志
logs/
*.log

# 本地环境变量与私钥
.env
.env.*
*.pem
*.key

# 前端依赖
node_modules/

# 文档
README*
docs/

与.gitignore类似,需要排除到构建环节中的文件主要有下面几种

  • 环境变量,密钥
  • 构建产物
  • 包依赖
  • IDE个性化配置,git
  • 开发文档
  • 运行时数据(本地跑的数据)

3. docker build 镜像构建

# 日常构建
docker build -t myapp:dev .

# Dockerfile 放在 docker 目录中
docker build -f docker/Dockerfile -t myapp:dev .

# 查看详细日志,排查构建失败
docker build --progress=plain -t myapp:dev .

# 指定 Linux x86-64 目标平台
docker build --platform linux/amd64 -t myapp:dev .

解析:
-t可以为镜像标注多个Tag,例如myapp:dev,tag为dev。myworker:v1,tag为v1

常用的可选参数如下

参数作用示例
-t / --tag设置镜像名称和标签-t myapp:v1
-f / --file指定 Dockerfile 路径-f docker/Dockerfile
--build-arg传入构建时参数,配合 ARG--build-arg APP_VERSION=v1
--target指定哪个阶段作为构建结果--target builder
--no-cache不复用构建步骤的缓存--no-cache
--pull尝试拉取基础镜像的更新版本--pull
--platform指定目标系统和 CPU 架构--platform linux/amd64
--progress=plain用普通文本显示详细构建日志--progress=plain
--help查看本机版本支持的参数docker build --help

4. docker run 容器运行

docker run -d --name ai-practice -p 8000:8000 ai-service:v1

-d表示容器作为后台运行,不占用当前shell的进程
–name xxx,为容器指定name,后续操作使用name即可
-p 8000:8000,将电脑的8000端口映射到容器的8000端口

有时候会出现-rm,表示运行容器后,如果被结束则自动销毁该容器。
一般不加该参数,停止容器后,容器变为stop状态依旧保留运行的数据。
当容器被销毁时,内部的数据也会被销毁

5. 容器维护

docker ps    # 查看运行的容器
docker ps -a # 查看所有容器

docker logs xxx # 查看xxx容器的日志(非实时)
docker logs --tail 20 ai-practice # 查看xxx容器的日志(最新20条)
docker logs -t xxx # 查看xxx容器的日志(包含timestamp)
docker logs -f xxx # 查看xxx容器的日志(实时)

docker stop xxx
docker start xxx


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字

插入代码