Golang 从入门到放弃 -0x16
编译交付、交叉编译、Docker 打包与部署前排查清单。
写了这么多章,终于到了一个非常现实的问题:代码在你电脑上能跑,不代表换个环境也能跑。真正让一个 Go 服务变得像“产品”而不是“作业”的,往往不是多写了几个接口,而是部署这一关过不过得去。
先从编译开始
Go 的一个大优点,就是编译交付很直接。很多简单服务,一个二进制文件就能带走。
go build -o app编出来以后,当前目录就会有个可执行文件。对很多小工具、小服务来说,这已经非常省心了。
交叉编译也很常见
比如你在 macOS 上开发,但要发到 Linux 服务器上跑,那就可以这样:
GOOS=linux GOARCH=amd64 go build -o appGo 在这方面确实挺讨喜,不用先写一堆玄学打包脚本才发现第一步就卡住。
为什么还要 Docker
理论上直接把二进制传到服务器也能跑,但一旦牵涉到环境变量、时区、证书、依赖文件、启动命令统一这些问题,Docker 很快就会显得方便很多。
一句话概括:Docker 不是为了显得高级,而是为了让“在哪都一样跑”这件事更接近现实。
一个最简单的 Dockerfile
FROM golang:1.24 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o server .
FROM alpine:3.20
WORKDIR /root/
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]这就是一个典型的多阶段构建:前面负责编译,后面负责运行。这样最终镜像会比直接把整个 Go 编译环境塞进去小得多,也干净得多。
启动时别忘了环境变量
docker run -d -p 8080:8080 -e APP_PORT=8080 -e MYSQL_DSN="user:pass@tcp(db:3306)/demo" my-go-app前面讲过的配置外置,到这里就真正派上用场了。代码不需要改,环境一换,行为就能跟着变。
上线前至少检查这些
- 端口是不是暴露对了
- 环境变量是不是齐了
- 日志是不是能看到
- 数据库地址和权限是不是正常
- 时区、证书、静态文件有没有漏
很多“服务起不来”的锅,并不是 Go 代码本身,而是这些部署细节没对上。
小结
这一章算是把系列往“能交付”这一步推了一把:
- Go 编译交付简单,单二进制是很大的优势。
- 交叉编译能让你在本地编、在服务器跑。
- Docker 的价值是统一运行环境,不是装饰。
- 上线前多检查环境和依赖,能少掉很多玄学问题。
到这里,这个系列已经从入门语法走到了服务开发和部署的门口。后面如果继续写,差不多就可以开始更完整的实战项目了。