将go-tcp项目部署到docker容器下运行
一.将项目传输到虚拟机上
1.使用 scp(推荐)
在本机终端运行以下命令,将本地项目传输至虚拟机指定目录:
scp -r D:\go\data\src\go-Internet username@your_vm_ip:~/go-Internet
参数说明:
-r表示递归传输整个目录username替换为虚拟机登录用户名your_vm_ip替换为虚拟机实际 IP 地址
2.使用 git 克隆
若项目已托管在 GitHub 或 Gitee 等平台,可直接通过 git 克隆到虚拟机:
git clone https://github.com/yourname/go-Internet.git
注意:需确保虚拟机已安装 git,且网络可访问代码托管平台。
3.压缩后传输
适用于大文件或需减少传输次数的场景:
在本地压缩项目目录:
cd D:\go\data\src
tar -czvf go-Internet.tar.gz go-Internet
传输压缩包到虚拟机:
scp go-Internet.tar.gz username@your_vm_ip:~
登录虚拟机并解压:
ssh username@your_vm_ip
tar -xzvf go-Internet.tar.gz
关键点:
tar -czvf创建 gzip 压缩包tar -xzvf解压并保留原始文件结构
4.通过远程连接软件,或者VM虚拟机上直接拖
比如在finalshall软件中支持直接上传主机文件
二.启动计划
1.确认项目结构
go-Internet/
├── docker-compose.yml # 我们要新增的文件
├── tcp/
│ ├── serve/
│ │ ├── main.go
│ │ └── Dockerfile
│ ├── client/
│ │ ├── main.go
│ │ └── Dockerfile
│ └── ...
├── go.mod
2.认识到需要构建两个dockerfile
因为go-tcp项目需要客户端与服务端同时运行,有两个main()函数运行,则需要构建两个镜像,同时有两个容器运行
3.认识到docker-compose的用处
你的项目有多个容器(server、client、数据库、缓存等);
它们之间有依赖(先启动MySQL,redis,然后server 必须先启动,client 再连);
可以用同一个网络、卷、环境变量自动管理。
只需要一键构建,就能启动所有的容器
三.dockerfile的构建
1.client客户端的dockerfile
FROM golang:1.24.3 AS builder
使用官方的 Go 镜像(
golang:1.24.3)作为构建环境。
AS builder给这个阶段起了一个名字(方便后面引用)。这个镜像里有 Go 编译器,所以适合用来编译你的代码。
WORKDIR /app
设置当前工作目录为
/app。后续命令(如
COPY、RUN)都在/app目录下执行。
COPY . .
把 当前构建上下文(build context) 的所有内容复制进镜像的
/app目录。
也就是整个项目源码(tcp/client,tool/,Samemethod/等)。这样编译时就能找到所有 Go 包。
RUN go env -w GOPROXY=https://goproxy.cn,direct
配置 Go 模块代理,加速依赖下载(特别是在中国大陆环境中)。
意思是:
优先从
https://goproxy.cn拉取依赖。如果找不到,则
direct直连原仓库。
RUN cd tcp/client && go mod tidy && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /app/client🔹 这行是编译客户端程序的关键步骤。
分开解释:
cd tcp/client
进入项目中的客户端源码目录。
go mod tidy
自动拉取依赖并清理无用依赖。
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /app/client
编译生成一个 Linux 平台的静态可执行文件:
CGO_ENABLED=0关闭 CGO,防止依赖 C 库(便于跨平台部署)。
GOOS=linux生成 Linux 可执行文件。
GOARCH=amd64生成 64 位架构的可执行文件。
-o /app/client指定输出路径(放在/app目录)。最终输出的是一个二进制文件:
/app/client
FROM alpine:latest
使用一个非常轻量的 Linux 发行版(Alpine)来运行程序。
镜像大小只有几 MB。
不再需要 Go 编译器(节省空间)。
WORKDIR /app
设置容器内的工作目录为
/app。
COPY --from=builder /app/client .
从第一个阶段(
builder)中复制编译好的可执行文件/app/client到当前镜像的/app。注意
--from=builder就是用到了前面起的名字。
RUN apk add --no-cache tzdata
安装时区数据包
tzdata,否则容器内的时间是 UTC。
--no-cache表示不缓存安装包(减小镜像体积)。
ENV TZ=Asia/Shanghai设置系统时区为中国上海时间。
CMD ["./client"]
容器启动时默认执行的命令。
即运行编译好的客户端程序。
2.server服务端的dockerfile
# --------- 构建阶段 --------- FROM golang:1.24.3 AS builderWORKDIR /app COPY . .RUN go env -w GOPROXY=https://goproxy.cn,directRUN cd tcp/serve && go mod tidy && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /app/server
cd tcp/serve
→ 进入到你的服务端源码目录。
go mod tidy
→ 整理并下载依赖模块,确保 go.mod/go.sum 是最新的。
CGO_ENABLED=0
→ 禁用 CGO,确保构建出的程序是 纯静态链接(没有动态库依赖)。
→ 方便在轻量镜像(如alpine)中运行。
GOOS=linux GOARCH=amd64
→ 指定编译目标为 Linux 64 位系统。
→ 即使在 Windows/Mac 上构建,也能得到 Linux 可执行文件。
go build -o /app/server
→ 编译生成可执行文件,输出到/app/server。输出产物:一个二进制文件
/app/server# --------- 运行阶段 --------- FROM alpine:latest WORKDIR /app COPY --from=builder /app/server .RUN apk add --no-cache tzdata ca-certificates && update-ca-certificates这行命令的作用是让容器更“可用”和“安全”:
apk add --no-cache tzdata
→ 安装时区数据包,使容器内时间能正确显示为你设定的时区(默认是 UTC)。
apk add ca-certificates
→ 安装 HTTPS 根证书,确保程序能访问 HTTPS 站点。
update-ca-certificates
→ 刷新证书缓存。EXPOSE 9000
声明该容器会监听 9000 端口。
只是声明,不是真正暴露端口,需要在
docker run或docker-compose.yml里映射CMD ["./server"]
四.docker compose的构建
services:mysql:image: mysql:8.0container_name: mysqlrestart: alwaysenvironment:MYSQL_ROOT_PASSWORD: "1234"MYSQL_DATABASE: systemctl1MYSQL_USER: go_userMYSQL_PASSWORD: go_passports:- "3306:3306"volumes:- mysql_data:/var/lib/mysqlnetworks:- go-netredis:image: redis:5.0container_name: redisrestart: alwaysports:- "6379:6379"volumes:- redis_data:/datacommand: ["redis-server", "--appendonly", "yes"]networks:- go-netserver:build:context: .dockerfile: tcp/serve/Dockerfilecontainer_name: go-serverdepends_on:- mysql- redisenvironment:MYSQL_HOST: mysqlMYSQL_USER: go_userMYSQL_PASSWORD: go_passMYSQL_DB: systemctl1REDIS_ADDR: redis:6379 networks:- go-netports:- "9000:9000"client:build:context: .dockerfile: tcp/client/Dockerfilecontainer_name: go-clientdepends_on:- serverenvironment:SERVER_ADDR: go-server:9000networks:- go-netcommand: tail -f /dev/null networks:go-net:driver: bridgevolumes:mysql_data:redis_data:
MySQL 服务配置解析
image: mysql:8.0
使用官方 MySQL 8.0 镜像作为基础镜像,确保稳定性和兼容性。
container_name: mysql
将容器命名为 mysql,便于通过名称直接引用容器。
restart: always
配置容器自动重启策略,确保服务意外终止或 Docker 重启时自动恢复。
environment 环境变量
MYSQL_ROOT_PASSWORD: "root1234":设置 MySQL root 用户密码为root1234。MYSQL_DATABASE: systemctl1:初始化时自动创建名为systemctl1的数据库。MYSQL_USER: go_user与MYSQL_PASSWORD: go_pass:设置密码。创建新用户go_user
ports: "3306:3306"
将容器内 MySQL 默认端口 3306 映射到宿主机的 3306 端口,允许从宿主机访问数据库。
volumes: mysql_data:/var/lib/mysql
使用命名卷 mysql_data 持久化存储 MySQL 数据,避免容器删除后数据丢失。
networks: go-net
将容器加入自定义网络 go-net,使其他服务可通过 mysql:3306 访问。
注意:在go代码中初始化mysql连接时,连接的ip和端口号都需要改变
Redis 服务配置解析
image: redis:5.0
使用官方 Redis 5.0 镜像,平衡功能与稳定性。
container_name: redis
命名容器为 redis,便于直接引用。
restart: always
配置自动重启,保障服务高可用。
ports: "6379:6379"
映射容器内 Redis 端口 6379 到宿主机,支持外部连接。
networks: go-net
加入 go-net 网络,其他容器可通过 redis:6379 访问。
volumes: - redis_data:/data
将容器内的 /data(Redis 持久化目录)挂载到宿主机;
command: ["redis-server", "--appendonly", "yes"]
开启 AOF 持久化模式;
Redis 会在 /data 目录下生成:appendonly.aof(操作日志) dump.rdb(快照文件)
Go 服务端配置解析
build 配置
context: .:基于当前目录构建镜像。dockerfile: tcp/serve/Dockerfile:指定构建使用的 Dockerfile 路径。
container_name: go-server
命名容器为 go-server,便于管理。
depends_on: mysql, redis
确保 MySQL 和 Redis 服务启动后再启动 Go 服务端。
environment 环境变量
MYSQL_HOST: mysql:通过网络别名访问 MySQL 容器。REDIS_ADDR: redis:6379:指定 Redis 服务地址。
ports: "9000:9000"
映射容器端口 9000 到宿主机,允许外部访问服务端。
networks: go-net
加入 go-net 网络,实现容器间通信。
Go 客户端配置解析
build 配置
context: .:使用当前目录作为构建上下文。dockerfile: tcp/client/Dockerfile:指定客户端 Dockerfile 路径。
container_name: go-client
命名容器为 go-client。
depends_on: server
确保服务端启动后再启动客户端。
environment: SERVER_ADDR: go-server:9000
配置客户端连接服务端的地址。
networks: go-net
加入同一网络,实现与服务端通信。
command: tail -f /dev/null
保持容器运行不退出,支持通过 docker exec 进入容器手动操作。
网络与数据卷配置
networks: go-net
driver: bridge:使用桥接模式,容器间通过名称直接通信。
volumes: mysql_data,redis_data
定义命名卷 mysql_data redis_data,持久化 MySQL ,redis数据,确保数据安全。
五.运行,使用
| 操作 | 命令 |
|---|---|
| 构建compose | docker compose build --no-cache |
| 启动所有服务 | docker compose up -d |
| 查看端口监听 | netstat -tuln | grep 9000 |
| 查看运行状态 | docker ps |
| 查看日志 | docker logs go-server |
| 进入容器 | docker exec -it go-client sh |
| 手动启动客户端程序 | ./client |
| 停止并删除容器+卷 | docker compose down -v |
