部署
部署
go-web 编译后是单一二进制(包含模板和静态资源),既可以裸机部署,也可以容器化运行。本章列出最常见的几种部署方式。
二进制构建
# 默认构建(包含调试符号)
go build -o bin/go-web main.go
# 生产构建(去除符号表 + 调试信息,体积更小)
go build -ldflags="-s -w" -o bin/go-web main.go
# 交叉编译到 Linux amd64
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 \
go build -ldflags="-s -w" -o bin/go-web main.go得到 bin/go-web 后,把它和 config.yaml 一起发到目标机器即可。模板与静态资源已通过 //go:embed 编译进二进制。
启动 / 停止
通过 gomander 暴露的子命令:
./bin/go-web start # 前台
./bin/go-web start -d # 守护进程模式
./bin/go-web stop
./bin/go-web restart
./bin/go-web reload # 等价于 SIGHUP,触发热重载
./bin/go-web status守护进程模式会把进程 PID 写入文件,后续的 stop / reload / status 都依赖它。
Docker 部署
仓库根目录提供了多阶段构建的 Dockerfile:
# 构建镜像
docker build -t go-web-app .
# 运行
docker run -d \
--name go-web \
-p 8080:8080 \
-e DATABASE_DRIVER=mysql \
-e DATABASE_HOST=mysql.internal \
-e DATABASE_PORT=3306 \
-e DATABASE_USERNAME=app \
-e DATABASE_PASSWORD=secret \
-e DATABASE_DBNAME=myapp \
-e REDIS_HOST=redis.internal \
go-web-app镜像特点:
- 多阶段构建 —— builder 用
golang:1.25.0-alpine,运行阶段用alpine:latest,最终镜像 ~15MB - 非 root 用户 —— 运行用户
appuser(uid=1001) - 时区 —— 默认
Asia/Shanghai - 健康检查 —— 内置
HEALTHCHECK调用/health/simple - CGO 关闭 —— 二进制纯静态链接
环境变量映射
go-web 中所有 config.yaml 的键都可以用环境变量覆盖,规则:把 . 替换成 _,字母变成大写。
config.yaml → 环境变量
─────────────────────────── → ──────────────────────────
app.app_name → APP_APP_NAME
app.mode → APP_MODE
database.driver → DATABASE_DRIVER
database.host → DATABASE_HOST
database.port → DATABASE_PORT
database.username → DATABASE_USERNAME
database.password → DATABASE_PASSWORD
database.dbname → DATABASE_DBNAME
database.migration.dir → DATABASE_MIGRATION_DIR
redis.host → REDIS_HOST
redis.port → REDIS_PORT
redis.password → REDIS_PASSWORD
redis.db → REDIS_DB
cache.driver → CACHE_DRIVER完整列表见「配置系统」章节。
docker-compose 示例
version: "3.9"
services:
app:
image: go-web-app:latest
ports:
- "8080:8080"
environment:
DATABASE_DRIVER: mysql
DATABASE_HOST: db
DATABASE_PORT: 3306
DATABASE_USERNAME: app
DATABASE_PASSWORD: secret
DATABASE_DBNAME: myapp
REDIS_HOST: redis
CACHE_DRIVER: redis
depends_on:
- db
- redis
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: rootpw
MYSQL_DATABASE: myapp
MYSQL_USER: app
MYSQL_PASSWORD: secret
volumes:
- db_data:/var/lib/mysql
redis:
image: redis:7-alpine
volumes:
db_data:Kubernetes 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-web
spec:
replicas: 2
selector:
matchLabels: { app: go-web }
template:
metadata:
labels: { app: go-web }
spec:
containers:
- name: go-web
image: registry/go-web-app:1.0.0
ports:
- containerPort: 8080
env:
- name: DATABASE_DRIVER
value: postgresql
- name: DATABASE_HOST
value: pg.internal
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: go-web-db
key: password
livenessProbe:
httpGet: { path: /health/simple, port: 8080 }
periodSeconds: 10
readinessProbe:
httpGet: { path: /health, port: 8080 }
periodSeconds: 10
failureThreshold: 3数据库迁移与部署
推荐两种模式:
- 启动时自动迁移 —— 在
AppProvider.Servers()中启用migration.Migration{},部署时无需额外步骤 - CI 中独立执行 —— 部署前在 CI pipeline 里跑
go run cmd/migrate/main.go up,然后再上线新版本;适合需要在迁移和上线之间做人工 verify 的场景
详见「数据库迁移」章节。
优雅关闭
go-web 在收到 SIGINT / SIGTERM 时会:
- 停止接收新的 HTTP 请求(
HttpServer.Stop()) - 等待正在处理的请求结束
- 销毁所有实现
Destroyable的容器实例 - 进程退出
Kubernetes 默认在 terminationGracePeriodSeconds(默认 30s)内允许进程优雅退出,这通常足够。
热重载
发送 SIGHUP 或调用 ./bin/go-web reload 即可不停机重载配置:
kill -HUP $(cat go-web.pid)
# 或
./bin/go-web reload热重载会停止当前 Server,清空 DI 容器,重新执行装配链并启动 Server。这意味着所有单例都会被重新构建,可读取最新的 config.yaml 与环境变量。