当前位置: 首页 > news >正文

将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

  • 后续命令(如 COPYRUN)都在 /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

🔹 这行是编译客户端程序的关键步骤。

分开解释:

  1. cd tcp/client
    进入项目中的客户端源码目录。

  2. go mod tidy
    自动拉取依赖并清理无用依赖。

  3. 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
  1. cd tcp/serve
    → 进入到你的服务端源码目录。

  2. go mod tidy
    → 整理并下载依赖模块,确保 go.mod/go.sum 是最新的。

  3. CGO_ENABLED=0
    → 禁用 CGO,确保构建出的程序是 纯静态链接(没有动态库依赖)。
    → 方便在轻量镜像(如 alpine)中运行。

  4. GOOS=linux GOARCH=amd64
    → 指定编译目标为 Linux 64 位系统。
    → 即使在 Windows/Mac 上构建,也能得到 Linux 可执行文件。

  5. 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 rundocker-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_userMYSQL_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数据,确保数据安全。

五.运行,使用

操作命令
构建composedocker 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



http://www.dtcms.com/a/560699.html

相关文章:

  • 华为OD机试双机位A卷 - 几何平均值最大的子数组 (C++ Python JAVA JS GO)
  • PostgreSQL死锁排查攻略:从日志分析到实时监控
  • 佛山响应式网站开发二级域名免费分发站
  • 【软考架构】案例分析-Web应用设计(应用服务器概念)
  • C++中的过滤器模式:原理、实现与应用
  • Kanass实践指南(4) - 测试团队如何通过kanass管理跟踪用例与缺陷
  • 天河做网站技术松江做网站费用
  • 面试Redis篇—————缓存穿透问题及解决策略
  • 【ComfyUI】通用 文生图转视频
  • 怎样建网站?西湖区住房和城市建设局网站
  • 教做宝宝衣服的网站济南网站优化多少钱
  • 分布式文件存储服务设计与实现优化
  • Qt-Nice-Frameless-Window: 一个跨平台无边框窗口(Frameless Window)解决方案
  • 跨平台游戏引擎 Axmol-2.9.1 发布
  • Redis性能优化避坑指南
  • 【Cache缓存】两路组相连和全相连
  • 青岛门头设计制作长春百度关键词优化
  • 青海网站制作的公司天津市网站建设公司
  • 数据结构04:链表的概念及实现单链表
  • springCloud二-SkyWalking3-性能剖析-⽇志上传-告警管理-接入飞书
  • 【项目基础】vue-class-component、vue-property-decorator、vuex-class、GeoJson
  • JWT 是由哪三个部分组成?如何使用JWT进行身份认证?
  • 【JUnit实战3_24】 第十四章:JUnit 5 扩展模型(Extension API)实战(下)
  • PostgreSQL pg_stat_bgwriter 视图各个字段详解
  • 简单的购物网站设计网页设计尺寸pc端
  • Unity 高效 ListView GridView
  • 【3DV 进阶-4】VecSet 论文+代码对照理解
  • Oracle实用参考(13)——Oracle for Linux (RAC)到Oracle for Linux(单实例)间OGG单向复制环境搭建(2)
  • 前端开发 网站建设头像logo图片在线制作免费
  • 电话语音接入扣子介绍