1. package main
  2.  
  3. import (
  4. "io"
  5. "log"
  6. "os"
  7. "time"
  8.  
  9. "github.com/docker/docker/api/types"
  10. "github.com/docker/docker/api/types/container"
  11. "github.com/docker/docker/api/types/mount"
  12. "github.com/docker/docker/client"
  13. "github.com/docker/go-connections/nat"
  14. "golang.org/x/net/context"
  15. )
  16.  
  17. const (
  18. imageName string = "my-gin:latest" //镜像名称
  19. containerName string = "mygin-latest" //容器名称
  20. indexName string = "/" + containerName //容器索引名称,用于检查该容器是否存在是使用
  21. cmd string = "./ginDocker2" //运行的cmd命令,用于启动container中的程序
  22. workDir string = "/go/src/ginDocker2" //container工作目录
  23. openPort nat.Port = "7070" //container开放端口
  24. hostPort string = "7070" //container映射到宿主机的端口
  25. containerDir string = "/go/src/ginDocker2" //容器挂在目录
  26. hostDir string = "/home/youngblood/Go/src/ginDocker2" //容器挂在到宿主机的目录
  27. n int = 5 //每5s检查一个容器是否在运行
  28.  
  29. )
  30.  
  31. func main() {
  32. ctx := context.Background()
  33. cli, err := client.NewEnvClient()
  34. defer cli.Close()
  35. if err != nil {
  36. panic(err)
  37. }
  38. checkAndStartContainer(ctx, cli)
  39. }
  40.  
  41. //创建容器
  42. func createContainer(ctx context.Context, cli *client.Client) {
  43. //创建容器
  44. cont, err := cli.ContainerCreate(ctx, &container.Config{
  45. Image: imageName, //镜像名称
  46. Tty: true, //docker run命令中的-t选项
  47. OpenStdin: true, //docker run命令中的-i选项
  48. Cmd: []string{cmd}, //docker 容器中执行的命令
  49. WorkingDir: workDir, //docker容器中的工作目录
  50. ExposedPorts: nat.PortSet{
  51. openPort: struct{}{}, //docker容器对外开放的端口
  52. },
  53. }, &container.HostConfig{
  54. PortBindings: nat.PortMap{
  55. openPort: []nat.PortBinding{nat.PortBinding{
  56. HostIP: "0.0.0.0", //docker容器映射的宿主机的ip
  57. HostPort: hostPort, //docker 容器映射到宿主机的端口
  58. }},
  59. },
  60. Mounts: []mount.Mount{ //docker 容器目录挂在到宿主机目录
  61. mount.Mount{
  62. Type: mount.TypeBind,
  63. Source: hostDir,
  64. Target: containerDir,
  65. },
  66. },
  67. }, nil, containerName)
  68. if err == nil {
  69. log.Printf("success create container:%s\n", cont.ID)
  70. } else {
  71. log.Println("failed to create container!!!!!!!!!!!!!")
  72. }
  73. }
  74.  
  75. //启动容器
  76. func startContainer(ctx context.Context, containerID string, cli *client.Client) error {
  77. err := cli.ContainerStart(ctx, containerID, types.ContainerStartOptions{})
  78. if err == nil {
  79. log.Printf("success start container:%s\n", containerID)
  80. } else {
  81. log.Printf("failed to start container:%s!!!!!!!!!!!!!\n", containerID)
  82. }
  83. return err
  84. }
  85.  
  86. //将容器的标准输出输出到控制台中
  87. func printConsole(ctx context.Context, cli *client.Client, id string) {
  88. //将容器的标准输出显示出来
  89. out, err := cli.ContainerLogs(ctx, id, types.ContainerLogsOptions{ShowStdout: true})
  90. if err != nil {
  91. panic(err)
  92. }
  93. io.Copy(os.Stdout, out)
  94.  
  95. //容器内部的运行状态
  96. status, err := cli.ContainerStats(ctx, id, true)
  97. if err != nil {
  98. panic(err)
  99. }
  100. io.Copy(os.Stdout, status.Body)
  101. }
  102.  
  103. //检查容器是否存在并启动容器
  104. func checkAndStartContainer(ctx context.Context, cli *client.Client) {
  105. for {
  106. select {
  107. case <-isRuning(ctx, cli):
  108. //该container没有在运行
  109. //获取所有的container查看该container是否存在
  110. contTemp := getContainer(ctx, cli, true)
  111. if contTemp.ID == "" {
  112. //该容器不存在,创建该容器
  113. log.Printf("the container name[%s] is not exists!!!!!!!!!!!!!\n", containerName)
  114. createContainer(ctx, cli)
  115. } else {
  116. //该容器存在,启动该容器
  117. log.Printf("the container name[%s] is exists\n", containerName)
  118. startContainer(ctx, contTemp.ID, cli)
  119. }
  120.  
  121. }
  122. }
  123. }
  124.  
  125. //获取container
  126. func getContainer(ctx context.Context, cli *client.Client, all bool) types.Container {
  127. containerList, err := cli.ContainerList(ctx, types.ContainerListOptions{All: all})
  128. if err != nil {
  129. panic(err)
  130. }
  131. var contTemp types.Container
  132. //找出名为“mygin-latest”的container并将其存入contTemp中
  133. for _, v1 := range containerList {
  134. for _, v2 := range v1.Names {
  135. if v2 == indexName {
  136. contTemp = v1
  137. break
  138. }
  139. }
  140. }
  141. return contTemp
  142. }
  143.  
  144. //容器是否正在运行
  145. func isRuning(ctx context.Context, cli *client.Client) <-chan bool {
  146. isRun := make(chan bool)
  147. var timer *time.Ticker
  148. go func(ctx context.Context, cli *client.Client) {
  149. for {
  150. //每n s检查一次容器是否运行
  151.  
  152. timer = time.NewTicker(time.Duration(n) * time.Second)
  153. select {
  154. case <-timer.C:
  155. //获取正在运行的container list
  156. log.Printf("%s is checking the container[%s]is Runing??", os.Args[0], containerName)
  157. contTemp := getContainer(ctx, cli, false)
  158. if contTemp.ID == "" {
  159. log.Print(":NO")
  160. //说明container没有运行
  161. isRun <- true
  162. } else {
  163. log.Print(":YES")
  164. //说明该container正在运行
  165. go printConsole(ctx, cli, contTemp.ID)
  166. }
  167. }
  168.  
  169. }
  170. }(ctx, cli)
  171. return isRun
  172. }

go -- go 程序 启动docker容器的更多相关文章

  1. Centos 配置开机启动脚本启动 docker 容器

    Centos 配置开机启动脚本启动 docker 容器 Intro 我们的 Centos 服务器上部署了好多个 docker 容器,因故重启的时候就会导致还得手动去手动重启这些 docker 容器,为 ...

  2. 启动Docker容器

    启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动. 因为 Docker 的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器. 新建并 ...

  3. 启动docker容器时的Error response from daemon: devmapper: Error mounting: invalid argument. 错误解决

    错误出现 在一台物理机重启后,以前创建的容器无法启动了.一启动,则会报出错误. [root@217TN1V ~]# docker start e7e Error response from daemo ...

  4. 启动 docker 容器时报错

    错误信息: iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9300 -j DNAT --to-dest ...

  5. 启动docker容器 防火墙问题报错 ! -i docker0' failed: iptables: No chain/target/match by that name.

    COMMAND_FAILED: '/sbin/iptables -t nat -A DOCKER -p tcp -d 0/0 --dport 8111 -j DNAT --to-destination ...

  6. windows上启动docker容器报错:standard_init_linux.go:211: exec user process caused “no such file or directory” - Docker

    解决方案: standard_init_linux.go:190: exec user process caused "no such file or directory" - D ...

  7. Docker容器运行GUI程序的配置方法

    0.环境说明 Ubuntu 16.04 docker 1.35 1.Docker的“可视化” Docker本身的工作模式是命令行的,因为主要的使用场景可能是做服务器后端方面的比较多. 但有时候我们会有 ...

  8. docker容器安装及使用技巧

    关于docker前言 A)首先是关于虚拟化 虚拟化我们可以简单的理解为一种资源管理方式.有如下几种虚拟化的方式: 1.完全虚拟化:对底层硬件实现完全的虚拟.例如:Vmware Workstation ...

  9. 在Windows上弄一个redis的docker容器

    [本文出自天外归云的博客园] Docker核心概念简介 镜像是一个面向docker引擎的只读模板,包含了文件系统. 镜像是创建容器的基础,容器类似于一个沙箱,用来运行和隔离应用. 容器是从镜像创建的应 ...

随机推荐

  1. Java 之 设计模式——代理模式

    设计模式——代理模式 一.概述 1.代理模式 (1)真实对象:被代理的对象 (2)代理对象:代理真实对象的 (3)代理模式:代理对象代理真实对象,达到增强真实对象功能的目的 二.实现方式 1.静态代理 ...

  2. ubuntu16.04安装openssh中报错解决

    在使用apt-get直接进行安装时会报错: sudo apt-get install openssh-server 正在读取软件包列表... 完成 正在分析软件包的依赖关系树       正在读取状态 ...

  3. 编程风格统一配置EditorConfig

    EditorConfig 以纯原生无需任何插件支持 EditorConfig 代码风格配置的编辑器: Visual Studio 2017 开始添加了对 EditorConfig 的原生支持.Visu ...

  4. idea安装与注册码破解

    idea安装与注册码破解 https://www.cnblogs.com/jajian/p/7989032.html

  5. kali 攻击wordpress + trunkey linux wordpress 安装方法

    Kali-linux攻击WordPress和其他应用程序   今天越来越多的企业利用SAAS(Software as a Service)工具应用在他们的业务中.例如,他们经常使用WordPress作 ...

  6. Codeforces I. Vessels(跳转标记)

    题目描述: Vessels time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  7. 微信小程序-数组操作

    Page({ data: { list:[{ id:, name:'芒果', count: },{ id:, name:'香蕉', count: }, }] } }) 向前插入数据 //要增加的数组 ...

  8. Python学习进阶

    阅读目录 一.python基础 二.python高级 三.python网络 四.python算法与数据结构 一.python基础 人生苦短,我用Python(1) 工欲善其事,必先利其器(2) pyt ...

  9. .gitignore文件配置的内容为:

    /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project ...

  10. Python 生成 JWT(json web token) 及 解析方式

    一.关于 jwt 的原理及概念可以自行在网络上搜索了解一下,这里推荐一篇写的比较好的博客 深入了解Json Web Token之概念篇 另附 JWT 的官方文档: https://jwt.io/int ...