1 在容器中启动web应用
命令:docker run -d --name webserver -p 120:8080 nigelpoulton/pluralsight-docker-ci
-d:在后台启动该容器,该方式启动的容器将不会连接到终端显示。与之相反的是-it参数。
-name:为该容器取名为“webserver”,取名字的好处在于在使用docker exec在容器中创建新进程时,可以方便地使用名字指示。
-p 120:8080:将宿主机的120号端口映射到容器内的8080端口。
Q:将宿主机120号端口映射到容器内的8080端口是什么意思?为什么要这么做?
A:首先还是要明确容器是进程组的概念,在linux系统下可通过命令lsof -i:120(本列中是120端口)号,查看120号端口被哪一个进程占用,在本机上调用之后返回如下信息。
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
com.docke 538 zhaiwenjie 17u IPv6 0x11db5d4a4315c11 0t0 TCP *:cfdptkt (LISTEN)
可以看到,占用120号端口的是一个pid号为538,其名字为com.docker的进程。也就是说,这就是我们的容器,我们在命令中为这个容器分配了120号端口。这个120号端口是操作系统总实际存在的端口资源。任何访问本机120号端口的TCP请求都会交付至pid-538号进程处理。至于说将120号端口映射到容器内8080端口又是什么意思,可以使用命令docker inspect 查看该容器能够发现下面信息。
"IPAddress": "172.17.0.2",
但是这并不是本机的实际ip地址,也就是说这是容器的虚拟ip地址,这个容器有着自己的ip地址,对外表现出来就像是一台独立的客户端机器(当然它实际上并不是,我们都知道它只是进程组)。通过这一信息,可以推断,容器有着自己的网络协议栈。docker不知道用什么样的操作,为容器虚拟出来了ip地址,既然有了虚拟的ip地址,那么自然需要虚拟的端口号。虚拟的终究是虚拟,总要对应着实际的端口资源,因此会有**“将宿主机120号端口映射到容器内的8080端口”**。
然后在浏览器中键入0.0.0.0:120便能够访问到web。
Q:在docker run命令中,并没有显示的指出要运行哪一个应用(参考docker run命令),但为什么容器却启动了一个web应用?
A:使用docker inspect命令查看镜像,发现有cmd这一栏,这一栏展示了启动容器时将会自动启动的应用,其中有一个node ./app.js,对应着浏览器中访问到的内容。
"Cmd": [
"/bin/sh",
"-c",
"cd /src && node ./app.js"
],
Q:如何在容器中新建一个进程or启动一个应用?
A:使用命令docker exec -it < container-name or container-id>/< app>