Golang天生适合运行在docker容器中,这得益于:Golang的静态编译,当在编译的时候关闭cgo的时候,可以完全不依赖系统环境。

一些基础

测试容器时我们经常需要进入容器查看运行情况,以下命令启动一个centos容器并进入bash交互环境。

docker run -it --rm centos bash

-it 组合参数-i: 以交互模式运行容器,-t: 为容器重新分配一个伪输入终端。

--rm 在容器退出时就能够自动清理容器。

alpine镜像中没有bash,启动容器并进入终端的命令为

docker run -it --rm alpine sh

启动一个golang编译环境并进入bash

docker run -it -p 8081:8081 -v ./project:/app --env --env GO111MODULE=on --env GOPROXY=https://goproxy.cn,direct --rm  --privileged golang:1.15 bash

-v ./project:/app 绑定本机项目的路径映射到容器中/app

--env 设置环境变量,由于我们网络环境的问题直接使用golang容器会很慢所以设置了GOPROXY=https://goproxy.cn,direct。

--privileged 容器内的root拥有真正的root权限,否则容器内root只是外部的一个普通用户。

-p 8081:8001 将本机的8081端口映射到容器的8001端口

docker打包项目

为了方便演示docker,我们准备一个简单Gin项目。要注意r.Run不能绑定127.0.0.1。

func main() {
r := gin.Default() r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
}) r.Run("0.0.0.0:9999")
}

启动golang容器,在容器中尝试编译并运行程序。

docker run -it -p 9999:9999 -v ./project:/app --env --env GO111MODULE=on --env GOPROXY=https://goproxy.cn,direct --rm  --privileged golang:1.15 bash

Alpine和其他通用Linux发行版对于Golang编译出来的可执行文件要求有所不同,Alpine要求可执行文件必须是静态链接的可执行文件。所以在编译Golang时需要添加 -tags netgo ,来生成静态链接的可执行文件。

go build -tags netgo -o app .

把编译出来的二进制文件和所有依赖项拷贝到发布目录

mkdir publish && cp app publish && \
cp -r docs publish

golang镜像的1.15版本有839M,再加上下载依赖编译项目等各种文件的话最终镜像可能会超过1G,大部分文件是在运行时不需要的。我们编写Dockerfile的时候可以把编译和运行两个阶段分开。编译时使用golang镜像,运行时使用alpine镜像。alpine镜像初始大小只有5M左右,非常适合作为基础镜像。最终Dockerfile如下

FROM golang:1.15 as builder

ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn,direct WORKDIR /app
COPY . .
RUN GOOS=linux GOARCH=amd64 go build -tags netgo -o app . RUN mkdir publish && cp app publish && \
cp -r docs publish FROM alpine
WORKDIR /app
COPY --from=builder /app/publish .
ENV GIN_MODE=release \
PORT=8081 EXPOSE 8081
ENTRYPOINT ["./app"]

构建docker镜像,大功告成。

docker build -t test:0.1 .

文章出处:基于gin的golang web开发:docker

基于gin的golang web开发:docker的更多相关文章

  1. 基于gin的golang web开发:路由

    Gin是一个用Golang编写的HTTP网络框架.它的特点是类似于Martini的API,性能更好.在golang web开发领域是一个非常热门的web框架. 启动一个Gin web服务器 使用下面的 ...

  2. 基于gin的golang web开发:路由二

    在基于gin的golang web开发:路由中我们介绍了Gin的路由和一些获取链接中参数的方法,本文继续介绍其他获取参数的方法. 文件上传 在web开发中文件上传是一个很常见的需求,下面我们来看一下基 ...

  3. 基于gin的golang web开发:模型绑定

    在前两篇文章介绍路由的时候,我们了解到gin可用通过类似DefaultQuery或DefaultPostForm等方法获取到前端提交过来的参数.参数不多的情况下也很好用,但是想想看,如果接口有很多个参 ...

  4. 基于gin的golang web开发:模型验证

    Gin除了模型绑定还提供了模型验证功能.你可以给字段指定特定的规则标签,如果一个字段用binding:"required"标签修饰,在绑定时该字段的值为空,那么将返回一个错误.开发 ...

  5. 基于gin的golang web开发:访问mysql数据库

    web开发基本都离不开访问数据库,在Gin中使用mysql数据库需要依赖mysql的驱动.直接使用驱动提供的API就要写很多样板代码.你可以找到很多扩展包这里介绍的是jmoiron/sqlx.另外还有 ...

  6. 基于gin的golang web开发:使用数据库事务

    在前文介绍访问数据库时介绍了github.com/jmoiron/sqlx包,本文基于这个包使用数据库事务. defer 在使用数据库事务之前,首先需要了解go语言的defer关键字.defer是go ...

  7. 基于gin的golang web开发:mysql增删改查

    Go语言访问mysql数据库需要用到标准库database/sql和mysql的驱动.标准库的Api使用比较繁琐这里再引入另一个库github.com/jmoiron/sqlx. go get git ...

  8. 基于gin的golang web开发:中间件

    gin中间件(middleware)提供了类似于面向切面编程或路由拦截器的功能,可以在请求前和请求之后添加一些自定义逻辑.实际开发中有很多场景会用到中间件,例如:权限验证,缓存,错误处理,日志,事务等 ...

  9. 基于gin的golang web开发:集成swagger

    在前后端分离的项目维护一份完整且及时更新的api文档会极大的提高我们的工作效率,传统项目中接口文档都是由后端开发手写的,这种文档很难保证及时性,久而久之便失去了参考意义.swagger给我们提供了一种 ...

随机推荐

  1. c++ 让你的应用支持相对路径

    std::string GetCurrentExeDir(){ char szPath[1024] = { 0 };#ifdef WIN32 GetModuleFileName(NULL, szPat ...

  2. leetcode117search-in-rotated-sorted-array

    题目描述 给出一个转动过的有序数组,你事先不知道该数组转动了多少 (例如,0 1 2 4 5 6 7可能变为4 5 6 7 0 1 2). 在数组中搜索给出的目标值,如果能在数组中找到,返回它的索引, ...

  3. Go语言如何像foreach一样有序遍历map

    目录 问题 解决 给key排序思路 开源实现 问题 Go语言的Map是无序遍历的,遍历一个map代码如下 package main import ( "fmt" ) func ma ...

  4. IAuthorizationFilter学习笔记(权限控制)以及非全局的filter

    第一步:新建类CheckLoginFilter实现接口IAuthorizationFilter.请注意接口位于命名空间using System.Web.Mvc; public void OnAutho ...

  5. 谈谈synchronized

    为什么要用synchronized关键字: synchronized是java的一种内部锁,是一种排他锁,通常也被称为悲观锁,它能够保障原子性,可见性,有序性. 当多个线程去调用同一个方法的时候,如果 ...

  6. create event[]

    一.前言自 MySQL5.1.6起,增加了一个非常有特色的功能–事件调度器(Event Scheduler),可以用做定时执行某些特定任务(例如:删除记录.对数据进行汇总等等),来取代原先只能由操作系 ...

  7. mybatis print sql config

    log4j.rootLogger=DEBUG, Console #Console log4j.appender.Console=org.apache.log4j.ConsoleAppender log ...

  8. margin的讲究

    什么元素允许有margin值,无论块状元素还是行内元素都可以,只是各有限制. 先说行内元素,这个是不允许有上下 外边距的, 再说块状元素,上下左右外边距都允许  但是相邻元素的外边距会合并,要注意的是 ...

  9. [MIT6.006] 9. Table Doubling, Karp-Rabin 双散列表, Karp-Rabin

    在整理课程笔记前,先普及下课上没细讲的东西,就是下图,如果有个操作g(x),它最糟糕的时间复杂度为Ο(c2 * n),它最好时间复杂度是Ω(c1 * n),那么θ则为Θ(n).简单来说:如果O和Ω可以 ...

  10. waeshall算法原理和实现

    传递闭包Warshall方法简要介绍 ① 在集合X上的二元关系R的传递闭包是包含R的X上的最小的传递关系.R的传递闭包在数字图像处理的图像和视觉基础.图的连通性描述等方面都是基本概念.一般用B表示定义 ...