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

Docker部署Golang服务

不管是开发还是生产环境,通过 docker 方式部署服务都是一种不错的选择,能够解决不同开发环境一致性的问题。

本文以项目:https://github.com/johncxf/go-api 为例。

Dockerfile 构建 Go 运用环境

在项目根目录下添加 Dockerfile 文件:

FROM golang:alpine# 在容器内部设置环境变量
ENV GO111MODULE=on \GOPROXY=https://goproxy.cn,direct \CGO_ENABLED=0 \GOOS=linux \GOARCH=amd64# 设置后续指令的工作目录
WORKDIR /build# 复制项目中的 go.mod 和 go.sum文件并下载依赖信息
COPY go.mod .
COPY go.sum .
RUN go mod download# 将代码复制到容器中
COPY . .# 将代码编译成二进制可执行文件
RUN go build -o go-api .WORKDIR /distRUN cp /build/go-api .COPY ./config ./config# 需要运行的命令
ENTRYPOINT ["/dist/go-api", "/dist/config/env.yml"]

如果需要缩小镜像大小,则可以用以下方式进行构建

FROM golang:alpine AS builder# 在容器内部设置环境变量
ENV GO111MODULE=on \GOPROXY=https://goproxy.cn,direct \CGO_ENABLED=0 \GOOS=linux \GOARCH=amd64# 设置后续指令的工作目录
WORKDIR /build# 复制项目中的 go.mod 和 go.sum文件并下载依赖信息
COPY go.mod .
COPY go.sum .
RUN go mod download# 将代码复制到容器中
COPY . .# 将代码编译成二进制可执行文件
RUN go build -o go-api .# 创建一个小镜像
#FROM scratch
FROM debian:stretch-slimCOPY ./config /config# 从builder镜像中把 /build/go-api 拷贝到当前目录
COPY --from=builder /build/go-api /# 需要运行的命令
ENTRYPOINT ["/go-api", "config/env.yml"]

注:镜像scratch没有bash,会导致无法通过docker exec进入容器,建议直接改成debian:stretch-slim镜像

构建 docker 镜像 go-web-app

$ docker build -t go-web-app .# 查看镜像
$ docker images

启动容器来运行镜像:

$ docker run -p 8888:8088 go-web-app# 后台启动
$ $ docker run -p 8888:8088 -d go-web-app# 查看容器
$ docker ps -a
CONTAINER ID   IMAGE        COMMAND                  CREATED          STATUS          PORTS                    NAMES
959ee47f203b   go-web-app   "/go-api config/env.…"   23 seconds ago   Up 22 seconds   0.0.0.0:8888->8088/tcp   nostalgic_mclean

标志位-p用来定义端口绑定,容器中go服务端口为 8088,绑定到本机端口 8888,接下来就可以通过http://127.0.0.1:8888进行访问了。

Mysql 容器
拉取 Mysql 镜像:
# 拉取最新版本 mysql,也可以指定版本
$ docker pull mysql:latest# 查看镜像
$ docker images
运行 Mysql 容器:
$ docker run --name mysql -p 8306:3306 -e MYSQL_ROOT_PASSWORD=root123456 -v ~/docker-data/mysql:/var/lib/mysql -d mysql:latest# 查看容器
$ docker ps -a
  • --name mysql-latest:容器命名为 mysql-latest
  • -p 8306:3306:映射容器服务的 3306 端口到宿主机的 8306 端口,外部主机可以直接通过 宿主机ip:8306 访问到MySQL服务
  • -e MYSQL_ROOT_PASSWORD=root123456:设置 MySQL 服务 root 用户密码
  • -v /Users/john/docker-data/mysql:/var/lib/mysql:表示将宿主机的/Users/john/docker-data/mysql卷映射到容器里的 /var/lib/mysql卷中,为了把数据保存在宿主机中,防止容器删掉就没了
  • -d:后台运行
  • mysql:latest:使用这个mysql镜像
连通性测试:

进入 docker 容器连接 mysql:

# 进入容器
$ docker exec -it mysql-latest /bin/sh
# 连接 mysql
$ mysql -uroot -proot123456 -h 127.0.0.1 -P3306

或者本机可以通过 navicat 等工具进行连接。

Redis 容器
拉取 Redis 镜像:
$ docker pull redis# 查看镜像
$ docker images
运行 Redis 容器:
$ docker run --name redis -v ~/docker-data/redis:/usr/local/redis -p 6379:6379 -d redis:latest --requirepass "root123456"# 查看容器
$ docker ps -a

其他参数同mysql配置,--requirepass 用来设置 Redis 密码

连通性测试:

直接在本地使用 redis-cli 测试 redis 连通性:

> redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> auth root123456
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>

进入容器:

> docker exec -it redis /bin/sh
# redis-cli -p 6379
127.0.0.1:6379> auth root123456
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> exit
# exit
修改配置

由于要连接不同容器内的数据库,需要修改项目数据库配置HOST地址为容器名,这里以我的项目配置 env.yml为例子:

# MySQL 配置
mysql:
#  host: 127.0.0.1 # 服务器地址host: mysqlport: 3306 # 端口db_name: test # 数据库名称username: root # 数据库用户名password: root123456 # 数据库密码...# Redis 配置
redis:
#  host: 127.0.0.1 # 地址host: redisport: 6379 # 端口db: 0password: root123456 # 密码

然后重新 build Go服务镜像:

$ docker build -t go-web-app .

重新启动容器,并使用--link关联Mysql、Redis容器:

$ docker run --name go-api --link=mysql:mysql --link=redis:redis -p 8888:8088 -d go-web-app

注:使用这种方式构建环境,每次都需要单独启动Mysql、Redis、go服务容器,并通过 --link关联容器

文章推荐:

  • Docker 入门指南
  • Docker compose 常用指令

相关文章:

  • leaflet学习笔记-带过滤的图例(九)
  • uniapp开发小程序—scroll-view实现内容滚动时, 标题也滚动
  • ESP32-HTTP_webServer库(Arduino)
  • Cacti 前台SQL注入漏洞复现(CVE-2023-39361)
  • Unity中URP下的 额外灯 逐像素光 和 逐顶点光
  • props传值
  • 自然语言处理的崛起:从初步分析到深度理解
  • PLC从HTTP服务端获取JSON文件,解析数据到寄存器
  • Linux编辑器---vim
  • 2.2.1.1-一个关于定投的故(姿)事(势)
  • CloudPanel RCE漏洞复现(CVE-2023-35885)
  • 探索设计模式的魅力:一次设计,多次利用,深入理解原型模式的设计艺术
  • EasyExcelFactory 导入导出功能的实战使用
  • 《数据结构》第七章:树和森林
  • 解开缺省参数与函数重载的衣裳
  • python3.6+scrapy+mysql 爬虫实战
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • AWS实战 - 利用IAM对S3做访问控制
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • Git的一些常用操作
  • JavaScript类型识别
  • python大佬养成计划----difflib模块
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • Vue2 SSR 的优化之旅
  • VuePress 静态网站生成
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • windows-nginx-https-本地配置
  • 服务器之间,相同帐号,实现免密钥登录
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 写代码的正确姿势
  • 在Unity中实现一个简单的消息管理器
  • UI设计初学者应该如何入门?
  • 如何在招聘中考核.NET架构师
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • #laravel 通过手动安装依赖PHPExcel#
  • (145)光线追踪距离场柔和阴影
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (C语言)字符分类函数
  • (分布式缓存)Redis持久化
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (原創) 如何優化ThinkPad X61開機速度? (NB) (ThinkPad) (X61) (OS) (Windows)
  • (转)使用VMware vSphere标准交换机设置网络连接
  • (轉貼) UML中文FAQ (OO) (UML)
  • .“空心村”成因分析及解决对策122344
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .NET delegate 委托 、 Event 事件
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • .project文件
  • @取消转义