Docker初学者问题 - 如何让容器启动后不会自动停止

通常使用docker run --name XX image:tag这样的命令来启动容器后,会遇到两种情况。

  1. 容器启动后再标准输出打印了一些信息,然后就停在那里了。如果我们使用ctrl-cctrl-d退出后容器就结束了。
  2. 容器启动后很快就自己结束了,然后就没有然后了。

这两种都不熟我们期望的结果。我们希望容器在启动后持续运行,等待我们的再次临幸。对于这个问题网上有很多文章介绍,但能够将清楚的很少。我这里整理了一下希望能够让读者清晰的理解这种现象的原因以及应对方法。

没有耐心读长文的同学可以直接看最后的总结

CMD执行命令的三种差别

Docker Image在制作时通过DockerfileCMD命令指定了容器启动后执行的程序。这个指定程序决定了容器是否结束和如何结束。

我们来看看三种不同的情况:

1. CMD指定了一个持续运行的程序.

持续运行就是说程序不会主动退出。我们拿postgres的举栗子。

# 先来看一看postgres的CMD程序是哪个
$ docker pull postgres:11-alpine
...
...

$ docker inspect postgres:11-alpine
...

"Cmd": [
    "postgres"
],

...

我们看到容器在启动后会指定postgres程序,这个程序会持续运行。我们运行起来看看。

$ docker run --name pp postgres:11-alpine
...[一堆输出信息]...
2019-02-03 13:46:46.117 UTC [1] LOG:  database system is ready to accept connections
[停在这里不动了]
[我们该怎么办?]

ctrl-c
[然后就没有然后了]

容器成功启动了postgres程序,一旦按下ctrl-c程序终止了,容器也就退出了。

解决办法

运行时添加-d参数

$ docker run --name pp -d postgres:11-alpine
1c1e99ac3fd3f18c6558bfc8b0fd08e4bf7aaad80535dd6ea709892f20f06f27

可以看到添加-d参数后docker run命令输出了容器的ID而不是像之前那样输出postgres程序执行的内容。

$ docker ps
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS               NAMES
1c1e99ac3fd3        postgres:11-alpine   "docker-entrypoint.s…"   3 minutes ago       Up 3 minutes        5432/tcp            pp

通过docker ps命令看到容器确实启动起来,并持续运行。完美。

我们看看-d参数的解释

$ docker run --help
...
-d, --detach   Run container in background and print container ID
...

这个参数的含义就是对容器说:"我知道你在努力做事,但我也很忙,你自己到旁边干活去吧,有事儿我再找你"

2. CMD指定了一个shell

这次我们用node举栗子

$ docker pull node:10-alpine

$ docker inspect node:10-alpine
...
"Cmd": [
    "node"
],
...

node程序与postgres程序不太一样。node并不是我们上面谈的"持续运行"的概念。
它作为一种shell程序自身并不知道要做什么,而是需要与操作者交流从而执行操作者交付的任务。
shell与操作者之间交流的方式是通过tty进行的。如果tty没有了那么shell发现没有人理它了,它就会在孤独和寂寞中睡觉去了。
而当容器启动的时候并不会给程序分配一个tty,所以这就是我们看到启动shell程序的容器自动退出的原因。

解决办法

运行时添加-t参数

$ docker run --name nn -t node:10-alpine
> [这是shell提示符]

我们来看看-t参数的解释

$ docker run --help
...
 -t, --tty    Allocate a pseudo-TTY
...

这个参数的含义是:"瞧这个泰迪熊多可爱,你去和它聊天吧"

现在我们看到了shell 提示符,现在的状态与第一种情况类似了,下面我们只需要再加入-d参数就完美了

$ docker run --name nn -dt node:10-alpine  
bfeead85bf01dd182e4c631ee9077afbb5c989e9c75abdd4776086dd223b9cdc

我们期待的容器ID由出现了,完美。

3. CMD指定了一个普通程序

这种镜像不好找,我们用参数模拟一下。在启动容器是通过命令行参数指定容器启动的程序,这将替换CMD指定的程序。

$ docker run --name nn -dt node:10-alpine pwd
412baf5fc0428567bcce3a2cb00fc41a696c10ecda0447d23a9291c2a2b52f20

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
412baf5fc042        node:10-alpine      "pwd"               2 minutes ago       Exited (0) 2 minutes ago                       nn

虽然容器启动时返回了容器ID,但当我们查看容器状态时它已经Exited
起始这种容器设计之初就不是让它持续运行的,它只是为了完成一项专门的动作,然后去睡觉。

那么对于这样的容器我们改怎么办呢?
♪ Let it go, ♪ let it go
♫ Can't hold it back anymore
♪ Let it go, ♪ let it go
♬ Turn my back and slam the door

### 总结
根据CMD指定的程序不同,有三种情况需要考虑

  1. 对于自身持续运行的程序,指定-d参数。它就可以自己到角落里画圈圈去了。
  2. 对于一个shell程序,指定-dt参数。给它一只泰迪熊,它就去角落和和泰迪熊聊天去了。
  3. 对于一个执行完就结束的程序。我们只能Let it go
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容

  • 转载自 http://blog.opskumu.com/docker.html 一、Docker 简介 Docke...
    极客圈阅读 10,499评论 0 120
  • docker基本概念 1. Image Definition 镜像 Image 就是一堆只读层 read-only...
    慢清尘阅读 8,748评论 1 21
  • 《Docker从入门到实践》阅读笔记 原书地址: https://yeasy.gitbooks.io/docker...
    GuoYuebo阅读 11,382评论 1 39
  • 五、Docker 端口映射 无论如何,这些 ip 是基于本地系统的并且容器的端口非本地主机是访问不到的。此外,除了...
    R_X阅读 1,749评论 0 7
  • –1– 老天爷前列腺终于好了,雨水像喷头一样从开始滴答到倾盆而下,用了几分钟时间。 酒吧旁边的小巷在此时泥泞不堪,...
    老港阅读 321评论 2 5