1 运行一个 web 应用
前面我们运行的容器并没有一些什么特别的用处。
接下来让我们尝试使用 docker 构建一个 web 应用程序。
我们将在docker容器中运行一个 Python Flask 应用来运行一个web应用。
dd@ubuntu04:~$ docker pull training/webapp
dd@ubuntu04:~$ docker run -d -P training/webapp python app.py
c5dead1b4292096a8450af0ca1967ce7ba7ff50416be4ec7cb68a1a96fa10d9e
参数说明:
- -d:让容器在后台运行。
- -P:将容器内部使用的网络端口映射到我们使用的主机上。
2 查看 WEB 应用容器
使用 docker ps 来查看我们正在运行的容器:
dd@ubuntu04:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c5dead1b4292 training/webapp "python app.py" About a minute ago Up About a minute 0.0.0.0:32768->5000/tcp adoring_elbakyan
这里多了端口信息。
PORTS
0.0.0.0:32768->5000/tcp
Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32769 上。
这时我们可以通过浏览器访问WEB应用
我们也可以通过 -p 参数来设置不一样的端口:
dd@ubuntu04:~$ docker run -d -p 5000:5000 training/webapp python app.py
af2b3a2b078034b3676e18b74ee2e6b1d5ed69f6c3a493cfaeaba6f47b83ee9d
docker ps查看正在运行的容器
dd@ubuntu04:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
af2b3a2b0780 training/webapp "python app.py" 51 seconds ago Up 49 seconds 0.0.0.0:5000->5000/tcp compassionate_grothendieck
c5dead1b4292 training/webapp "python app.py" 5 minutes ago Up 5 minutes 0.0.0.0:32768->5000/tcp adoring_elbakyan
容器内部的 5000 端口映射到我们本地主机的 5000 端口上。
3 网络端口的快捷方式
通过 docker ps 命令可以查看到容器的端口映射,docker 还提供了另一个快捷方式 docker port,使用 docker port 可以查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号。
上面我们创建的 web 应用容器 ID 为 c5dead1b4292名字为adoring_elbakyan。
我可以使用 docker port c5dead1b4292或 docker port adoring_elbakyan来查看容器端口的映射情况。
dd@ubuntu04:~$ docker port c5dead1b4292
5000/tcp -> 0.0.0.0:32768
dd@ubuntu04:~$ docker port adoring_elbakyan
5000/tcp -> 0.0.0.0:32768
4 查看 WEB 应用程序日志
docker logs [ID或者名字] 可以查看容器内部的标准输出。
dd@ubuntu04:~$ docker logs -f c5dead1b4292
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.31.3 - - [07/May/2020 02:21:37] "GET / HTTP/1.1" 200 -
192.168.31.3 - - [07/May/2020 02:21:37] "GET /favicon.ico HTTP/1.1" 404 -
-f: 让 docker logs 像使用 tail -f 一样来输出容器内部的标准输出。
从上面,我们可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。
5 查看WEB应用程序容器的进程
我们还可以使用 docker top 来查看容器内部运行的进程
dd@ubuntu04:~$ docker top c5dead1b4292
UID PID PPID C STIME TTY TIME CMD
root 13524 13501 0 02:18 ? 00:00:00 python app.py
6 检查 WEB 应用程序
使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
dd@ubuntu04:~$ docker inspect adoring_elbakyan
[
{
"Id": "c5dead1b4292096a8450af0ca1967ce7ba7ff50416be4ec7cb68a1a96fa10d9e",
"Created": "2020-05-07T02:18:41.666166526Z",
"Path": "python",
"Args": [
"app.py"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 13524,
"ExitCode": 0,
"Error": "",
"StartedAt": "2020-05-07T02:18:43.031177491Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557",
"ResolvConfPath": "/var/lib/docker/containers/c5dead1b4292096a8450af0ca1967ce7ba7ff50416be4ec7cb68a1a96fa10d9e/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/c5dead1b4292096a8450af0ca1967ce7ba7ff50416be4ec7cb68a1a96fa10d9e/hostname",
"HostsPath": "/var/lib/docker/containers/c5dead1b4292096a8450af0ca1967ce7ba7ff50416be4ec7cb68a1a96fa10d9e/hosts",
"LogPath": "/var/lib/docker/containers/c5dead1b4292096a8450af0ca1967ce7ba7ff50416be4ec7cb68a1a96fa10d9e/c5dead1b4292096a8450af0ca1967ce7ba7ff50416be4ec7cb68a1a96fa10d9e-json.log",
"Name": "/adoring_elbakyan",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Capabilities": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": true,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/2c6a83e7f8a8c263a0aaaa268c1b472aa94db69832fc4d575491369d173e4c7a-init/diff:/var/lib/docker/overlay2/6057a4bd50fb97db04115da4f9f993a1a27343337a35b4b79c7b323705428e05/diff:/var/lib/docker/overlay2/2908b26086d2e5436fae48db5f87233725ebbbd09be57226411cdb98125fe374/diff:/var/lib/docker/overlay2/f08761c82dd3843a116ba20fa05c5096ff4c9bde04204021303cf1c48246204b/diff:/var/lib/docker/overlay2/b73bfe2c8ca647328ebadf79b8f904e95dde429417e86fcf08a4adbe969b3bcb/diff:/var/lib/docker/overlay2/5d1fc3a4fa3ce1520aca785177064a77568735b6a639ff5a170836b75a93415d/diff:/var/lib/docker/overlay2/9fd83aa9f2887f43a0fb2376eda09dbcec584e32a101af81b5e512dd0e8e9210/diff:/var/lib/docker/overlay2/9b936c852f38a612aba40f7723d1009f8f8307fc7d65487ea6381f8cd9aa5fea/diff:/var/lib/docker/overlay2/5d0fe3587d0ad9f1a422a8b58a8cee578fa358f269ba9bbae7cc44bea85fc779/diff:/var/lib/docker/overlay2/974c86eb95ddbaaf5eeff0603f5c46c3ff7d8d5146c688611796c287cffcd97a/diff:/var/lib/docker/overlay2/db2f268ba00f0152185c5debc116c81659eacf5ee52deb8a96c72caa61e8c9d5/diff:/var/lib/docker/overlay2/7676cc3ea719f2f92ca24245435729f4d525d72b33ddb8200076d20790a96420/diff:/var/lib/docker/overlay2/637478046c38a5bfae6196df69bb597d91873b2531ee1480c3b9eb8cf25f1ab7/diff:/var/lib/docker/overlay2/5307cf38da40e0a639e9d0080226357bfcd64f0a4b39d33ddef57ff5f65aef7e/diff",
"MergedDir": "/var/lib/docker/overlay2/2c6a83e7f8a8c263a0aaaa268c1b472aa94db69832fc4d575491369d173e4c7a/merged",
"UpperDir": "/var/lib/docker/overlay2/2c6a83e7f8a8c263a0aaaa268c1b472aa94db69832fc4d575491369d173e4c7a/diff",
"WorkDir": "/var/lib/docker/overlay2/2c6a83e7f8a8c263a0aaaa268c1b472aa94db69832fc4d575491369d173e4c7a/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "c5dead1b4292",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"5000/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"python",
"app.py"
],
"Image": "training/webapp",
"Volumes": null,
"WorkingDir": "/opt/webapp",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "5302a980b2692190898b7b9edc9c586d1728a1ee61816a95c0a692d6e7e8bb8a",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"5000/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "32768"
}
]
},
"SandboxKey": "/var/run/docker/netns/5302a980b269",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "be0237a785d81d875afcb82f469c9016808e9415aeca83a3f4d9f81aa944465b",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "4669621da1df5391a5f3a7975ecd633d49f8c62d669f4712c1f962e36f013c4b",
"EndpointID": "be0237a785d81d875afcb82f469c9016808e9415aeca83a3f4d9f81aa944465b",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
7 停止 WEB 应用容器
dd@ubuntu04:~$ docker stop adoring_elbakyan
adoring_elbakyan
8 重启WEB应用容器
已经停止的容器,我们可以使用命令 docker start 来启动。
dd@ubuntu04:~$ docker start adoring_elbakyan
adoring_elbakyan
docker ps -l 查询最后一次创建的容器:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
af2b3a2b0780 training/webapp "python app.py" 8 minutes ago Up 8 minutes 0.0.0.0:5000->5000/tcp compassionate_grothendieck
正在运行的容器,我们可以使用 docker restart 命令来重启。
9 移除WEB应用容器
我们可以使用 docker rm 命令来删除不需要的容器
dd@ubuntu04:~$ docker rm adoring_elbakyan
adoring_elbakyan
删除容器时,容器必须是停止状态,否则会报如下错误
dd@ubuntu04:~$ docker rm af2b3a2b0780
Error response from daemon: You cannot remove a running container af2b3a2b078034b3676e18b74ee2e6b1d5ed69f6c3a493cfaeaba6f47b83ee9d. Stop the container before attempting removal or force remove
10. 参考文献
[1] Docker 容器使用