Gin实践 连载九 将Golang应用部署到Docker
将Golang应用部署到Docker项目地址:https://github.com/EDDYCJY/go... (快上车,支持一波) 注:
介绍在这里简单介绍下Docker,建议深入学习
Docker 是一个开源的轻量级容器技术,让开发者可以打包他们的应用以及应用运行的上下文环境到一个可移植的镜像中,然后发布到任何支持Docker的系统上运行。 通过容器技术,在几乎没有性能开销的情况下,Docker 为应用提供了一个隔离运行环境
接下来我们正式开始对项目进行 Golang一、编写Dockerfile在 FROM golang:latest WORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-example COPY . $GOPATH/src/github.com/EDDYCJY/go-gin-example RUN go build . EXPOSE 8000 ENTRYPOINT ["./go-gin-example"] 作用
在进行 注意 说明Dockerfile 文件是用于定义 Docker 镜像生成流程的配置文件,文件内容是一条条指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建;这些指令应用于基础镜像并最终创建一个新的镜像 你可以认为用于快速创建自定义的 Docker 镜像 1、 FROM 指定基础镜像(必须有的指令,并且必须是第一条指令) 2、 WORKDIR 格式为 使用 3、COPY 格式: COPY <源路径>... <目标路径> COPY ["<源路径1>",... "<目标路径>"]
4、RUN 用于执行命令行命令 格式: 5、EXPOSE 格式为
在 Dockerfile 中写入这样的声明有两个好处
6、ENTRYPOINT
<ENTRYPOINT> "<CMD>"
ENTRYPOINT [ "curl","-s","http://ip.cn" ]
二、构建镜像
该命令作用是创建/构建镜像, $ docker build -t gin-blog-docker . Sending build context to Docker daemon 96.39 MB Step 1/6 : FROM golang:latest ---> d632bbfe5767 Step 2/6 : WORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> 56294f978c5d Removing intermediate container e112997b995d Step 3/6 : COPY . $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> 3b60960120cf Removing intermediate container 63e310b3f60c Step 4/6 : RUN go build . ---> Running in 52648a431450 ---> 7bfbeb301fea Removing intermediate container 52648a431450 Step 5/6 : EXPOSE 8000 ---> Running in 98f5b387d1bb ---> b65bd4076c65 Removing intermediate container 98f5b387d1bb Step 6/6 : ENTRYPOINT ./go-gin-example ---> Running in c4f6cdeb667b ---> d8a109c7697c Removing intermediate container c4f6cdeb667b Successfully built d8a109c7697c 三、验证镜像查看所有的镜像,确定刚刚构建的 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE gin-blog-docker latest d8a109c7697c About a minute ago 946 MB docker.io/golang latest d632bbfe5767 8 days ago 779 MB ... 四、创建并运行一个新容器执行命令 $ docker run -p 8000:8000 gin-blog-docker dial tcp 127.0.0.1:3306: connect: connection refused [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) ... Actual pid is 1 运行成功,你以为大功告成了吗? 你想太多了,仔细看看控制台的输出了一条错误 我们研判一下,发现是 Mysql一、拉取镜像从 $ docker pull mysql 二、创建并运行一个新容器运行 $ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=rootroot -d mysql 8c86ac986da4922492934b6fe074254c9165b8ee3e184d29865921b0fef29e64 连接 Mysql初始化的
Golang + Mysql一、删除镜像由于原本的镜像存在问题,我们需要删除它,此处有几种做法
删除原本的有问题的镜像, 若不执行 $ docker rmi -f gin-blog-docker Untagged: gin-blog-docker:latest Deleted: sha256:d8a109c7697c3c2d9b4de7dbb49669d10106902122817b6467a031706bc52ab4 Deleted: sha256:b65bd4076c65a3c24029ca4def3b3f37001ff7c9eca09e2590c4d29e1e23dce5 Deleted: sha256:7bfbeb301fea9d8912a4b7c43e4bb8b69bdc57f0b416b372bfb6510e476a7dee Deleted: sha256:3b60960120cf619181c1762cdc1b8ce318b8c815e056659809252dd321bcb642 Deleted: sha256:56294f978c5dfcfa4afa8ad033fd76b755b7ecb5237c6829550741a4d2ce10bc 二、修改配置文件将项目的配置文件 #debug or release RUN_MODE = debug [app] PAGE_SIZE = 10 JWT_SECRET = 233 [server] HTTP_PORT = 8000 READ_TIMEOUT = 60 WRITE_TIMEOUT = 60 [database] TYPE = mysql USER = root PASSWORD = rootroot HOST = mysql:3306 NAME = blog TABLE_PREFIX = blog_ 三、重新构建镜像重复先前的步骤,回到 四、创建并运行一个新容器关联Q:我们需要将 A:增加命令 运行执行命令 $ docker run --link mysql:mysql -p 8000:8000 gin-blog-docker [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) ... Actual pid is 1 结果检查启动输出、接口测试、数据库内数据,均正常;我们的 Review思考虽然应用已经能够跑起来了 但如果对
创建超小的Golang镜像Q:第一个问题,为什么这么镜像体积这么大? A: 这是有问题的,我们可以不在Golang容器中现场编译的,压根用不到那些东西,我们只需要一个能够运行可执行文件的环境即可 构建Scratch镜像Scratch镜像,简洁、小巧,基本是个空镜像 一、修改DockerfileFROM scratch WORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-example COPY . $GOPATH/src/github.com/EDDYCJY/go-gin-example EXPOSE 8000 CMD ["./go-gin-example"] 二、编译可执行文件CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o go-gin-example . 编译所生成的可执行文件会依赖一些库,并且是动态链接。在这里因为使用的是 三、构建镜像$ docker build -t gin-blog-docker-scratch . Sending build context to Docker daemon 133.1 MB Step 1/5 : FROM scratch ---> Step 2/5 : WORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> Using cache ---> ee07e166a638 Step 3/5 : COPY . $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> 1489a0693d51 Removing intermediate container e3e9efc0fe4d Step 4/5 : EXPOSE 8000 ---> Running in b5630de5544a ---> 6993e9f8c944 Removing intermediate container b5630de5544a Step 5/5 : CMD ./go-gin-example ---> Running in eebc0d8628ae ---> 5310bebeb86a Removing intermediate container eebc0d8628ae Successfully built 5310bebeb86a 注意,假设你的Golang应用没有依赖任何的配置等文件,是可以直接把可执行文件给拷贝进去即可,其他都不必关心 这里可以有好几种解决方案
... 因此这里如果解决了文件依赖的问题后,就不需要把目录给 四、运行$ docker run --link mysql:mysql -p 8000:8000 gin-blog-docker-scratch [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] GET /auth --> github.com/EDDYCJY/go-gin-example/routers/api.GetAuth (3 handlers) ... 成功运行,程序也正常接收请求 接下来我们再看看占用大小,执行 $ docker ps -as CONTAINER ID IMAGE COMMAND ... SIZE 9ebdba5a8445 gin-blog-docker-scratch "./go-gin-example" ... 0 B (virtual 132 MB) 427ee79e6857 gin-blog-docker "./go-gin-example" ... 0 B (virtual 946 MB) 从结果而言,占用大小以 Mysql挂载数据卷倘若不做任何干涉,在每次启动一个 数据卷数据卷 是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除 数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的 数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
注意:数据卷 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的 数据卷。 如何挂载首先创建一个目录用于存放数据卷;示例目录 $ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=rootroot -v /data/docker-mysql:/var/lib/mysql -d mysql 54611dbcd62eca33fb320f3f624c7941f15697d998f40b24ee535a1acf93ae72 创建成功,检查目录 验证接下来交由你进行验证,目标是创建一些测试表和数据,然后删除当前容器,重新创建的容器,数据库数据也依然存在(当然了数据卷指向要一致) 我已验证完毕,你呢? 参考本系列示例代码
本系列目录
书籍
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |