使用 Docker Compose 部署 Go 聊天项目的完整流程

本文将手把手讲解如何将一个 Go 语言实现的聊天系统部署到 Docker 环境中,包括服务端、客户端、Redis、MySQL 的完整配置,同时解决容器间网络和数据库表初始化问题。


一、项目概述

本项目包含四个核心组件:

  1. 服务端 (chat_app):Go 编写,监听 TCP 端口 8080,处理用户注册、登录和消息转发。

  2. 客户端 (chat_client):Go 编写,通过 TCP 连接服务端,支持注册和登录。

  3. Redis (chat_redis):存储在线用户信息和消息缓存。

  4. 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

客户端运行后可以注册、登录:

九、总结

  1. Dockerfile 分阶段构建:减小镜像体积

  2. docker-compose 管理服务依赖:Redis、MySQL、服务端、客户端

  3. 数据库初始化:保证表和字段存在

  4. 网络与端口:容器间通过服务名访问 (app:8080)

  5. 容器调试:查看日志和 docker compose exec

  6. 代码更新:保证项目代码与你compose的高度统一

通过以上流程,你可以快速在 Docker 上完整部署 Go 聊天项目,并解决常见容器网络和数据库问题。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值