一、上传你的go项目

如:这是我的项目目录

可以直接进行拖拽

二、在虚拟机上创建这样的目录结构

~/GoProJect/pro1/test01 我这样是为了确保导入包的路径正确,确保项目能正常运行。

然后就把common\server\user\vin 这四个文件拖到 test01目录下,还有go.mod和go.sum也放到test01目录下

三、构建Dockerfile文件

注意:也是放在test01目录下,当然也可以放在其他目录,不过这样更方便

# 构建阶段

# 多阶段构建,第一阶段专门用于编译
# 基础镜像:golang:1.21-alpine 包含go编译环境的轻量级 Alpine Linux
# 别名:As builder 给这个阶段命令,方便第二阶段引用
FROM golang:1.21-alpine AS builder

# 设置工作目录,容器默认的工作目录
WORKDIR /app

# 设置Go模块代理(国内加速)
ENV GOPROXY=https://goproxy.cn,direct

# 复制go.mod和go.sum文件
COPY go.mod go.sum ./

# 下载依赖
RUN go mod download

# 复制所有源代码
COPY . .

# 编译Go程序 - 修改为你的main.go路径
# CGO_ENABLED=0:禁用CGO,生成纯Go的静态二进制文件
# GOOS=linux:目标操作系统为Linux
# GOARCH=amd64:目标CPU架构为x86_64
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /app/chat-server ./server/

# 运行阶段
FROM alpine:latest

WORKDIR /app
# 安装必要的包
# ca-certificates HTTPS证书 tzdata 时区数据
RUN apk --no-cache add ca-certificates tzdata

# 设置时区(可选)
ENV TZ=Asia/Shanghai

# 从构建阶段复制可执行文件
COPY --from=builder /app/chat-server .

# 创建必要的目录结构(用于日志等)
RUN mkdir -p /app/logs


# 声明容器端口
EXPOSE 8080

# 运行程序
CMD ["./chat-server"]

四、构建docker-compose.yml 文件

version: '3.8'
services:
  chat-server:
    build: .
    container_name: chat-server
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      DB_HOST: mysql
      DB_PORT: 3306
      DB_USER: root
      DB_PASSWORD: root
      DB_NAME: chatroom
    depends_on:
      mysql:
        condition: service_healthy
    networks:
      - chat-net

  mysql:
    image: mysql:8.0
    container_name: chat-mysql
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: "root"
      MYSQL_DATABASE: chatroom
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
      interval: 3s
      timeout: 5s
      retries: 10
    volumes:
      - mysql_data:/var/lib/mysql
      - ./mysql-init:/docker-entrypoint-initdb.d
    ports:
      - "3307:3306"
    networks:
      - chat-net

networks:
  chat-net:
    driver: bridge

volumes:
  mysql_data:

五、数据库初始化

创建数据库初始化脚本;

# 创建数据库初始化脚本
mkdir -p mysql-init
cat > mysql-init/init.sql << 'EOF'
CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
EOF

六、修改服务端数据库的连接

func InitDB() error {
	var err error

	// 从环境变量读取配置(Docker Compose设置)
	dbHost := os.Getenv("DB_HOST")
	dbPort := os.Getenv("DB_PORT")
	dbUser := os.Getenv("DB_USER")
	dbPassword := os.Getenv("DB_PASSWORD")
	dbName := os.Getenv("DB_NAME")

	// 设置默认值
	if dbHost == "" {
		dbHost = "localhost"
	}
	if dbPort == "" {
		dbPort = "3306"
	}
	if dbUser == "" {
		dbUser = "root"
	}
	if dbPassword == "" {
		dbPassword = "root"
	}
	if dbName == "" {
		dbName = "chatroom"
	}

	// 构建DSN
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=true",
		dbUser, dbPassword, dbHost, dbPort, dbName)

	fmt.Printf("正在连接数据库: %s@%s:%s\n", dbUser, dbHost, dbPort)

	// 重试连接
	for i := 0; i < 10; i++ {
		db, err = sql.Open("mysql", dsn)
		if err != nil {
			fmt.Printf("连接失败,重试 %d/10: %v\n", i+1, err)
			time.Sleep(3 * time.Second)
			continue
		}

		err = db.Ping()
		if err != nil {
			fmt.Printf("Ping失败,重试 %d/10: %v\n", i+1, err)
			db.Close()
			time.Sleep(3 * time.Second)
			continue
		}

		fmt.Println("数据库连接成功")
		return nil
	}

	return fmt.Errorf("无法连接数据库: %v", err)
}

注意:主要是增加了环境变量的配置

当运行时,可以读取到设置的环境变量,如果没有,就按照默认的

七、启动服务

1.构建镜像

docker-compose build --no-cache

2.启动服务:

docker-compose up --build -d 

3.检查状态:

docker-compose logs -f chat-server

因该可以看到:数据库连接成功

4.在test01目录下:

go run user/user.go 就可以正常进行登录或注册了

更多推荐