本文将手把手讲解如何将一个 Go 语言实现的聊天系统部署到 Docker 环境中,包括服务端、客户端、Redis、MySQL 的完整配置,同时解决容器间网络和数据库表初始化问题。
一、项目概述
本项目包含四个核心组件:
-
服务端 (chat_app):Go 编写,监听 TCP 端口 8080,处理用户注册、登录和消息转发。
-
客户端 (chat_client):Go 编写,通过 TCP 连接服务端,支持注册和登录。
-
Redis (chat_redis):存储在线用户信息和消息缓存。
-
MySQL (chat_mysql):存储用户信息,包括用户名、密码和最近消息。
二、项目目录结构
假设项目目录如下:
Chat/
├─ server/
│ └─ main.go
├─ client/
│ └─ client.go
├─ Dockerfile
├─ Dockerfile.client
├─ docker-compose.yml
└─ init.sql
-
server/main.go:服务端入口 -
client/client.go:客户端入口 -
Dockerfile:服务端镜像构建 -
Dockerfile.client:客户端镜像构建 -
docker-compose.yml:多容器编排 -
init.sql:初始化 MySQL 数据库表
三、Dockerfile 配置
1. 服务端 Dockerfile
# =========================
# 构建阶段
# =========================
FROM golang:1.24 AS builder
WORKDIR /app
ENV GOPROXY=https://goproxy.cn,direct
COPY . .
RUN go mod tidy
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o chat ./server/main.go
# =========================
# 运行阶段
# =========================
FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/chat .
CMD ["./chat"]
2. 客户端 Dockerfile
FROM golang:1.24 AS builder
WORKDIR /app
ENV GOPROXY=https://goproxy.cn,direct
COPY . .
RUN go mod tidy
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o chat_client ./client/client.go
FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/chat_client .
CMD ["./chat_client"]
⚠️ 注意:
构建阶段用 Go 官方镜像
运行阶段使用轻量 Alpine
四、docker-compose.yml 配置
version: "3.9"
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: chat_app
restart: unless-stopped
ports:
- "8080:8080"
depends_on:
- redis
- mysql
environment:
REDIS_HOST: redis
REDIS_PORT: 6379
MYSQL_HOST: mysql
MYSQL_PORT: 3306
MYSQL_USER: root
MYSQL_PASSWORD: 实际密码
MYSQL_DATABASE: 数据库名称
client:
build:
context: .
dockerfile: Dockerfile.client
container_name: chat_client
depends_on:
- app
environment:
SERVER_HOST: app
SERVER_PORT: 8080
REDIS_HOST: redis
REDIS_PORT: 6379
redis:
image: redis:5.0.5
container_name: chat_redis
restart: unless-stopped
mysql:
image: mysql:8.0
container_name: chat_mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 数据库密码
MYSQL_DATABASE: 数据库名称
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
✅ 优化点:
depends_on确保启动顺序数据库数据持久化
MySQL 密码统一,服务端可连接
根据实际情况修改PASSWORD与DATABASE名
五、MySQL 初始化 SQL
创建 init.sql,保证表存在:
CREATE DATABASE IF NOT EXISTS tcp;
USE tcp;
CREATE TABLE IF NOT EXISTS user (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(100) NOT NULL,
last_message VARCHAR(50) DEFAULT NULL
);
启动 MySQL 容器后执行:
docker compose exec mysql mysql -uroot -p214451 < init.sql
六、部署步骤
构建镜像
docker compose build --no-cache
启动 MySQL 和 Redis
docker compose up -d mysql redis
初始化数据库表
docker compose exec mysql mysql -uroot -p214451 < init.sql
启动服务端
docker compose up -d app
启动客户端
docker compose up client
⚠️ 提示:
客户端启动前服务端必须已经监听 8080
客户端连接失败时可以增加重试逻辑
七、常见问题及解决方案
| 问题 | 解决方案 |
|---|---|
connect: connection refused | 确保服务端监听 0.0.0.0:8080 而不是 127.0.0.1 |
| MySQL 表不存在或字段不匹配 | 执行 init.sql 创建表,字段名与 Go 代码一致(name, password, last_message) |
| 容器停止无法 exec | 使用 docker compose logs app 查看原因,通常是数据库连接失败 |
客户端报 EOF | 服务端未启动或数据库操作 panic,先启动服务端并保证数据库正常 |
| 容器无法联网下载镜像 |
检查宿主机网络,重启 Docker 服务,或配置 DNS |
八、测试连接
进入 MySQL 检查:
docker compose exec mysql mysql -uroot -p214451 USE tcp; SELECT * FROM user;
进入服务端容器调试:
docker compose exec app sh
客户端运行后可以注册、登录:
九、总结
-
Dockerfile 分阶段构建:减小镜像体积
-
docker-compose 管理服务依赖:Redis、MySQL、服务端、客户端
-
数据库初始化:保证表和字段存在
-
网络与端口:容器间通过服务名访问 (
app:8080) -
容器调试:查看日志和
docker compose exec -
代码更新:保证项目代码与你compose的高度统一
通过以上流程,你可以快速在 Docker 上完整部署 Go 聊天项目,并解决常见容器网络和数据库问题。

被折叠的 条评论
为什么被折叠?



