注:

dockerf-20180324-dockergo-gin-example

介绍

在这里简单介绍下Docker,建议深入学习

image

Docker 是一个开源的轻量级容器技术,让开发者可以打包他们的应用以及应用运行的上下文环境到一个可移植的镜像中,然后发布到任何支持Docker的系统上运行。 通过容器技术,在几乎没有性能开销的情况下,Docker 为应用提供了一个隔离运行环境

  • 简化配置
  • 代码流水线管理
  • 提高开发效率
  • 隔离应用
  • 快速、持续部署

docker

Golang

一、编写Dockerfile

go-gin-example
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"]

作用

golang:latest$GOPATH/src/go-gin-example$GOPATH/src/go-gin-example
go build./go-gin-example
go-gin-exampledocker

说明

Dockerfile 文件是用于定义 Docker 镜像生成流程的配置文件,文件内容是一条条指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建;这些指令应用于基础镜像并最终创建一个新的镜像

你可以认为用于快速创建自定义的 Docker 镜像

1、 FROM

指定基础镜像(必须有的指令,并且必须是第一条指令)

2、 WORKDIR

WORKDIR
WORKDIRWORKDIR

3、COPY

格式:

COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]
COPY

4、RUN

用于执行命令行命令

RUN

5、EXPOSE

EXPOSE
EXPOSE

在 Dockerfile 中写入这样的声明有两个好处

docker run -PEXPOSE

6、ENTRYPOINT

ENTRYPOINTRUN
exec
<ENTRYPOINT> "<CMD>"
shell
ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]
ENTRYPOINT

二、构建镜像

go-gin-exampledocker build -t gin-blog-docker .
-tgin-blog-docker.
$ 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

三、验证镜像

gin-blog-docker
$ 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
$ 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

运行成功,你以为大功告成了吗?

dial tcp 127.0.0.1:3306: connect: connection refused
Mysql

Mysql

一、拉取镜像

DockerDockerhubMySQL
$ docker pull mysql

二、创建并运行一个新容器

Mysql
$ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=rootroot -d mysql
8c86ac986da4922492934b6fe074254c9165b8ee3e184d29865921b0fef29e64

连接 Mysql

Mysql

image

Golang + Mysql

一、删除镜像

由于原本的镜像存在问题,我们需要删除它,此处有几种做法

nametag
-f
-fdocker ps -arm
$ 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

二、修改配置文件

conf/app.ini
#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_

三、重新构建镜像

gin-blogdocker build -t gin-blog-docker .

四、创建并运行一个新容器

关联

GolangMysql
--link mysql:mysqlGolangMysql--link--link

运行

docker run --link mysql:mysql -p 8000:8000 gin-blog-docker
$ 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

结果

GolangMysql

Review

思考

虽然应用已经能够跑起来了

GolangDocker
gin-blog-dockerdocker ps -as | grep gin-blog-dockerMysql

创建超小的Golang镜像

Q:第一个问题,为什么这么镜像体积这么大?

FROM golang:latestgolang

这是有问题的,我们可以不在Golang容器中现场编译的,压根用不到那些东西,我们只需要一个能够运行可执行文件的环境即可

构建Scratch镜像

Scratch镜像,简洁、小巧,基本是个空镜像

一、修改Dockerfile
FROM 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 .
scratch
三、构建镜像
$ 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应用没有依赖任何的配置等文件,是可以直接把可执行文件给拷贝进去即可,其他都不必关心

这里可以有好几种解决方案

  • 依赖文件统一管理挂载
  • go-bindata 一下

...

COPY
四、运行
$ 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
$ 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)
Scratch

Mysql挂载数据卷

Mysql

数据卷

docker rm -v

数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 数据卷 可以在容器之间共享和重用
  • 对 数据卷 的修改会立马生效
  • 对 数据卷 的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除
注意:数据卷 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的 数据卷。

如何挂载

/data/docker-mysql--namemysqldocker rm
$ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=rootroot -v /data/docker-mysql:/var/lib/mysql -d mysql
54611dbcd62eca33fb320f3f624c7941f15697d998f40b24ee535a1acf93ae72
/data/docker-mysql

验证

接下来交由你进行验证,目标是创建一些测试表和数据,然后删除当前容器,重新创建的容器,数据库数据也依然存在(当然了数据卷指向要一致)

我已验证完毕,你呢?

参考

本系列示例代码

本系列目录

书籍