Skip to main content

Docker 部署

本文说明 ovra-zero 使用纯 Docker 的部署方式,不依赖 k3d、Kubernetes 或 Helm。适合单机服务器、开发测试环境,以及希望先用容器把后端服务跑起来的场景。

tip

当前仓库中的 deploy/docker/docker-compose.yaml 仍是占位文件,本文以 docker networkdocker run 和服务镜像构建为主。需要 Kubernetes 本地集群部署时,请参考 k3d 部署

准备工作

环境要求

环境说明
Docker运行 MySQL、Redis、etcd 和后端服务
Go 1.24+构建 Linux 服务二进制
MySQL 8.0+业务数据库
Redis 7+缓存、验证码、幂等控制
etcd 3.5+go-zero RPC 服务发现

服务端口

服务容器名容器端口宿主机端口
MySQLovra-zero-mysql33063306
Redisovra-zero-redis63796379
etcdovra-zero-etcd23792379
authovra-zero-auth80918091
systemovra-zero-system8092 / 90928092 / 9092
demoovra-zero-demo8099 / 90998099 / 9099

创建 Docker 网络

创建统一网络,后续容器通过服务名互相访问:

docker network create ovra-zero

如果网络已存在,Docker 会提示重复创建,可以忽略。

启动基础组件

MySQL

docker run -d --name ovra-zero-mysql --network ovra-zero \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD='Pl@1221view' \
-e MYSQL_DATABASE=ovra_zero \
-v "$PWD/bin/sql/ovra_zero.sql:/docker-entrypoint-initdb.d/ovra_zero.sql:ro" \
mysql:8.4

查看初始化日志:

docker logs ovra-zero-mysql --tail=100

Redis

docker run -d --name ovra-zero-redis --network ovra-zero \
-p 6379:6379 \
redis:7-alpine redis-server --requirepass 'Pl@1221view'

验证:

docker exec ovra-zero-redis redis-cli -a 'Pl@1221view' ping

etcd

docker run -d --name ovra-zero-etcd --network ovra-zero \
-p 2379:2379 \
-p 2380:2380 \
quay.io/coreos/etcd:v3.5.13 \
etcd \
--name ovra-zero-etcd \
--listen-client-urls http://0.0.0.0:2379 \
--advertise-client-urls http://ovra-zero-etcd:2379 \
--listen-peer-urls http://0.0.0.0:2380 \
--initial-advertise-peer-urls http://ovra-zero-etcd:2380 \
--initial-cluster ovra-zero-etcd=http://ovra-zero-etcd:2380 \
--initial-cluster-state new \
--initial-cluster-token ovra-zero-etcd

验证:

docker exec ovra-zero-etcd etcdctl --endpoints=http://127.0.0.1:2379 endpoint health

准备 Docker 配置

服务在容器中需要访问 Docker 网络内的服务名,不能继续使用 127.0.0.1。建议创建一套 Docker 环境配置:

mkdir -p etc/docker
cp etc/dev/common.yaml etc/docker/common.yaml
cp etc/dev/auth.yaml etc/docker/auth.yaml
cp etc/dev/system.yaml etc/docker/system.yaml
cp etc/dev/demo.yaml etc/docker/demo.yaml

编辑 etc/docker/common.yaml,把地址改为容器名:

RpcConf:
Etcd:
Hosts:
- ovra-zero-etcd:2379

SystemRpc:
Etcd:
Hosts:
- ovra-zero-etcd:2379

Data:
Database:
Username: root
Password: Pl@1221view
Host: ovra-zero-mysql
Port: 3306
Database: ovra_zero
Redis:
Pass: Pl@1221view
Host: ovra-zero-redis:6379
Type: node
Tls: false
tip

程序默认按 ENV 读取 etc/<ENV>/<service>.yaml。容器启动时设置 ENV=docker 后,会读取 etc/docker/auth.yamletc/docker/system.yamletc/docker/demo.yaml,并自动合并同目录的 common.yaml

构建服务镜像

先编译 Linux 二进制到项目根目录。ARM64:

GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags='-s -w' -tags no_k8s -o app-auth app/auth/auth.go
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags='-s -w' -tags no_k8s -o app-system app/system/system.go
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags='-s -w' -tags no_k8s -o app-demo app/demo/demo.go

x86_64 环境将 GOARCH=arm64 改为:

GOARCH=amd64

构建镜像:

docker build -t ovra-zero-auth:local -f deploy/docker/auth/Dockerfile .
docker build -t ovra-zero-system:local -f deploy/docker/system/Dockerfile .
docker build -t ovra-zero-demo:local -f deploy/docker/demo/Dockerfile .

启动后端服务

建议先启动 system,再启动 authdemo

system

docker run -d --name ovra-zero-system --network ovra-zero \
-e ENV=docker \
-p 8092:8092 \
-p 9092:9092 \
ovra-zero-system:local

auth

docker run -d --name ovra-zero-auth --network ovra-zero \
-e ENV=docker \
-p 8091:8091 \
ovra-zero-auth:local

demo

docker run -d --name ovra-zero-demo --network ovra-zero \
-e ENV=docker \
-p 8099:8099 \
-p 9099:9099 \
ovra-zero-demo:local

查看日志:

docker logs ovra-zero-system --tail=100
docker logs ovra-zero-auth --tail=100
docker logs ovra-zero-demo --tail=100

验证系统

查看容器:

docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'

验证 etcd 注册:

docker exec ovra-zero-etcd etcdctl --endpoints=http://127.0.0.1:2379 get system.rpc --prefix

验证接口:

curl -sS http://127.0.0.1:8091/auth/code
curl -sS http://127.0.0.1:8092/system/user/getInfo

/system/user/getInfo 需要认证时返回未登录或鉴权错误也属于服务已正常响应。

可选:使用 Traefik

如果希望统一入口,可以把 bin/traefik 配置挂载到 Traefik 容器,并让 Traefik 加入同一个 Docker 网络。需要确保动态配置中的服务地址指向:

ovra-zero-auth:8091
ovra-zero-system:8092
ovra-zero-demo:8099

示例:

docker run -d --name ovra-zero-traefik --network ovra-zero \
-p 28080:28080 \
-v "$PWD/bin/traefik:/etc/traefik:ro" \
traefik:v3.0 \
--configfile=/etc/traefik/traefik.yaml

停止与清理

停止服务:

docker stop ovra-zero-auth ovra-zero-system ovra-zero-demo
docker stop ovra-zero-etcd ovra-zero-redis ovra-zero-mysql

删除容器:

docker rm ovra-zero-auth ovra-zero-system ovra-zero-demo
docker rm ovra-zero-etcd ovra-zero-redis ovra-zero-mysql

删除网络:

docker network rm ovra-zero

常见问题

服务连接不上 MySQL、Redis 或 etcd

确认容器处于同一个 Docker 网络:

docker network inspect ovra-zero

确认 etc/docker/common.yaml 中使用的是容器名,不是 127.0.0.1

auth 调用 system 失败

先确认 system 已启动并完成 RPC 注册:

docker logs ovra-zero-system --tail=100
docker exec ovra-zero-etcd etcdctl --endpoints=http://127.0.0.1:2379 get system.rpc --prefix

exec format error

说明二进制架构和镜像运行架构不一致。ARM64 使用 GOARCH=arm64,x86_64 使用 GOARCH=amd64,重新构建二进制和镜像。

数据没有初始化

MySQL 只会在首次创建空数据目录时执行 /docker-entrypoint-initdb.d 中的 SQL。若容器已初始化过,需要删除容器和数据卷后重建,或手动导入:

docker exec -i ovra-zero-mysql mysql -uroot -p'Pl@1221view' ovra_zero < bin/sql/ovra_zero.sql