go聊天室接入mysql的项目docker部署流程

go聊天室接入mysql的项目部署流程:

聊天室项目 Docker 部署笔记

一、Dockerfile 设计要点

1️⃣ 服务端 Dockerfile(server)

  • 使用 多阶段构建
    • 构建阶段:golang:1.22.2-alpine
      • 设置 WORKDIR /app
      • COPY go.mod go.sum ./ → 下载依赖 (go mod download)
      • COPY . . → 复制源码
      • RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o server ./server → 构建静态二进制
    • 最终镜像阶段:alpine:latest
      • WORKDIR /root/
      • COPY --from=builder /app/server .
      • chmod +x ./server 确保可执行
      • mkdir -p ./logs
      • EXPOSE 8888
      • CMD ["./server"]
bash 复制代码
# 使用官方Golang镜像作为构建环境
FROM golang:1.22.2-alpine AS server-builder

# 设置工作目录
WORKDIR /app
# 设置GOPROXY
ENV GOPROXY=https://goproxy.cn,direct
# 复制go模块文件
COPY go.mod go.sum ./

# 下载依赖
RUN go mod download

# 复制源代码
COPY . .

# 构建服务端应用
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o server ./server

# 最终镜像
FROM alpine:latest AS server

WORKDIR /root/

# 从构建阶段复制二进制文件
COPY --from=server-builder /app/server .
# 确保二进制文件有执行权限
RUN chmod +x ./server

# 创建日志目录
RUN mkdir -p ./logs

# 暴露端口
EXPOSE 8888

# 运行服务
CMD ["./server"]

2️⃣ 客户端 Dockerfile(client)

  • 与 server 类似,构建阶段生成二进制 client
  • 终镜像阶段同样保证可执行权限,并创建日志目录
  • 注意:client 是交互式程序,所以 stdin_open: truetty: true 在 compose 中配置
bash 复制代码
# 使用官方Golang镜像作为构建环境
FROM golang:1.22.2-alpine AS client-builder


# 设置工作目录
WORKDIR /app

ENV GOPROXY=https://goproxy.cn,direct

# 复制go模块文件
COPY go.mod go.sum ./

# 下载依赖
RUN go mod download

# 复制源代码
COPY . .

# 构建客户端应用
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o client ./client/client.go

# 最终镜像
FROM alpine:latest AS client

WORKDIR /root/

# 从构建阶段复制二进制文件
COPY --from=client-builder /app/client .

# 确保二进制文件有执行权限
RUN chmod +x ./client
# 创建日志目录
RUN mkdir -p ./logs

# 运行客户端
CMD ["./client"]

二、.dockerignore 使用

  • 避免无关文件被 COPY 进镜像,提高构建速度

  • 常见内容:

    复制代码
    .git
    node_modules
    logs
    *.md

三、Docker Compose 配置要点

1️⃣ 服务定义

  • server、client、mysql(可选)分开定义

  • depends_on 确保启动顺序,但不保证服务端口就绪

  • environment 配置容器所需变量,例如:

    yaml 复制代码
    environment:
      SERVER_HOST: server
      SERVER_PORT: 8888
  • client 设置交互模式:

    yaml 复制代码
    stdin_open: true
    tty: true

2️⃣ 网络管理

  • 默认情况下,Compose 自动创建 <项目名>_default 网络
  • 手动创建网络 (chatroom-net) 并不影响 Compose 默认行为,除非在 compose 文件中指定 external networks
  • 容器 DNS 名称解析依赖于网络,同一 network 下服务名可以互相访问

docker-compose文件:

yaml 复制代码
# version: '3.8'

services:
  # 数据库服务(如果需要)
  #   mysql:
  #     image: mysql:8.0
  #     container_name: chatroom-mysql
  #     environment:
  #       MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
  #       MYSQL_DATABASE: ${DB_NAME}
  #       MYSQL_USER: ${DB_USER}
  #       MYSQL_PASSWORD: ${DB_PASSWORD}
  #     ports:
  #       - "3306:3306"
  #     volumes:
  #       - mysql_data:/var/lib/mysql
  #     logging:
  #       driver: "json-file"
  #       options:
  #         max-size: "10m"  # 单个日志文件最大10MB
  #         max-file: "3"    # 保留3个日志文件
  #     restart: unless-stopped

  # 聊天室服务端
  server:
    build:
      context: .
      dockerfile: Dockerfile
      target: server #新加一个target标签
    container_name: chatroom-server
    ports:
      - "8888:8888"
    # depends_on:
    #   - mysql
    environment:
      - DB_HOST=mysql8.0  # mysql容器名
      - DB_PORT=3306
      - DB_USER=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}
      - DB_NAME=${DB_NAME}
    networks:
      - chatroom-net   # 需要将mysql加入到该网络中
    logging:
      driver: "json-file"
      options:
        max-size: "10m"  # 单个日志文件最大10MB
        max-file: "5"    # 保留5个日志文件
    restart: unless-stopped

  # 聊天室客户端(示例,实际使用时可能需要交互式运行)
  client:
    build:
      context: .
      dockerfile: Dockerfile.client
      target: client  #新加一个targer标签
    container_name: chatroom-client
    depends_on:
      - server
    environment:
      - SERVER_HOST=server
      - SERVER_PORT=8888
    stdin_open: true
    tty: true
    logging:
      driver: "json-file"
      options:
        max-size: "5m"   # 单个日志文件最大5MB
        max-file: "2"    # 保留2个日志文件
    # 注意:客户端通常需要交互式运行,所以这主要用于测试目的

networks:
  chatroom-net:
    external: true

# 告诉所有容器,你已经建立一个网络了,不用在创建网络了
# networks:
#   default:
#     external:
#       name: chatroom-net

# volumes:
#   mysql_data:

四、常见问题及解决方法

问题 原因 解决方案
client 容器启动立即退出 Go 程序连接 127.0.0.1:8888 → 连接不到 server 将 client 代码改为 conn, err := net.Dial("tcp", "server:8888") 或使用环境变量读取 host/port
client 报 server misbehaving client 不在 server 同一网络,DNS 无法解析 删除旧 client 容器,使用 docker compose up -d clientdocker network connect
Docker Compose 自动生成 chatroomplus_default Compose 默认网络机制 可以通过 networks: default: external: name: chatroom-net 指定使用自定义网络
修改 client/server 代码后旧镜像未更新 镜像是静态文件,不会自动刷新 重新 build client 镜像:docker compose build client --no-cache

五、调试技巧

  1. 查看容器日志

    bash 复制代码
    docker logs -f chatroom-client
    docker logs -f chatroom-server
  2. 进入容器调试

    bash 复制代码
    docker exec -it chatroom-client /bin/sh
    # 或者 attach
    docker attach chatroom-client
  3. 检查网络和 DNS

    bash 复制代码
    docker network inspect chatroomplus_default
    ping server  # 在容器内测试 DNS 是否解析
  4. 容器交互式启动

    • client 是 CLI,需要 stdin_open: true + tty: true

六、最佳实践总结

  • 多阶段构建:减少镜像体积,仅拷贝编译好的二进制
  • 环境变量配置:程序不要写死 IP,容器间通信使用服务名 + 环境变量
  • 网络管理:同一 Compose 网络内 DNS 名称可互相访问
  • 容器重建策略:修改代码后,只 rebuild 需要更新的服务,旧服务可以保留
  • 日志和调试:保证容器日志可查,调试方便

七、本篇注意点:

1.docker镜像源的更换需要重启docker才能使用

bash 复制代码
# 重启docker
sudo systemctl restart docker

# 清理旧缓存
docker system prune -f  # 清理无用镜像/缓存

2.客户端进入方式

bash 复制代码
# 依据# 运行客户端
# CMD ["./client"]
# 所以启动方式是:
.client

注意:当 dockerfile和dockerfile-client写在同级目录中时,需要注意不能使用相同的构建名,否则同时搭建镜像时,构建名字相同后后者顶替前者,导致构建文件无法找到

对于客户端容器启动失败原因:

client没有 和server在同一个网络中,需要让两个容器 在同一个网络中。

删除原来容器,重新创建。(不用)

bash 复制代码
docker rm chatroom-client
docker compose up -d client

对于某个容器启动失败,修改该容器网络,使通信的容器在同一个网络内,然后可以单独启动该容器,不用每次都启动使用docker compose up -d

手动把现有的client容器加入网络。

bash 复制代码
# 连接到 chatroomplus_default 网络
docker network connect chatroomplus_default chatroom-client

# 重启 client
docker restart chatroom-client

八、构建并运行

如果go文件有变动,需要重新构建,使用代码

docker compose build --no-cache来确保使用最新的代码和依赖。

注意构建完毕后需要手动把原来的镜像删除。

输入docker compose up -d直接运行即可。

运行完后,可以通过docker compose logs 服务名 [-f]来查看运行状态和日志输出

注意:进入mysql容器时,输入docker exec -it netchat-mysql /bin/bash,最后的路径是/bin/bash

进入客户端容器是,输入docker exec -it chatroom-client /bin/sh,最后的路径是/bin/sh(Alpine Linux 默认使用 sh)

相关推荐
梦想的旅途21 小时前
企微全自动化运营的可视化与度量
数据库·mysql
lead520lyq1 小时前
Golang GPRC流式传输案例
服务器·开发语言·golang
定偶1 小时前
C语言操作MYSQL
c语言·mysql·adb
只是懒得想了1 小时前
Go语言ORM深度解析:GORM、XORM与entgo实战对比及最佳实践
开发语言·数据库·后端·golang
molaifeng1 小时前
从 Stdio 到 HTTP:用 Go 打造按需加载的 SQLite MCP Server
http·golang·sqlite·mcp
源代码•宸1 小时前
Leetcode—144. 二叉树的前序遍历【简单】
经验分享·算法·leetcode·面试·职场和发展·golang·dfs
Nandeska2 小时前
11、MySQL主从复制的基本概念
数据库·mysql
岁岁种桃花儿2 小时前
构建SpringBoot项目Docker镜像并发布到k8s集群中进行运行
spring boot·docker·kubernetes
海兰2 小时前
Docker单节点部署Elasticsearch 9.0+(开发环境)
运维·docker·容器