本文已迁移到我的新博客地址,欢迎访问:
Docker安装完毕,我们就可以试着来运行一些命令了,看看docker可以干什么。
首先,让我们运行一个最简单的容器,hello-world。如果安装没有问题,并运行正确的话,应该会出现下面的结果:
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker Hub account:
https://hub.docker.com
For more examples and ideas, visit:
https://docs.docker.com/engine/userguide/
可以看到,上述结果给了我们很多信息,首先,打印出了一条信息:Hello from Docker!
接着简单描述了一下产生该条信息所经历的一系列步骤:
1 Docker客户端连接到守护进程
2 Docker守护进程从Docker Hub拉取了hello-world镜像
3 Docker守护进程从该镜像创建了一个容器,来执行了命令并输出了我们当前看的这条消息
4 Docker守护进程将容器中的标准输出转发到你的终端。
需要补充一点的是,docker在运行一个容器时,首先会检查本地是否存在指定的镜像,如果有,则直接运行,如果没有,才会去Docker Hub上拉取。这也就是命令结果第一行为什么会显示Unable to find image 'hello-world:latest' locally
的原因。
接下来,我们可以看一下目前所有的容器:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1a058b3cde45 hello-world "/hello" 3 minutes ago Exited (0) 3 minutes ago gigantic_austin
可以看到,只有一个我们刚才创建的hello-world容器,结果显示,该容器有一个ID1a058b3cde45
,从hello-world镜像
创建,执行的命令为/hello
,当前状态为3分钟前已退出,最后还有个namegigantic_austin
,需要注意的是,这里的name看着很奇怪,因为它是随机生成的,后续我们可以看到如何自定义容器名称。
需要注意的是,如果你只运行docker ps
,将看不到这个结果,因为它默认只显示正在运行的容器,而我们的hello-world运行完就立马退出了.
或者,你也可以运行docker ps -l
用于查看最后创建的一个容器。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest c54a2cc56cbb 9 weeks ago 1.848 kB
docker images
命令可以显示本机所有的Docker镜像。
如果你不知道都有哪些可用的镜像,在线查找一下或许是个好注意:
直接使用docker search + [你想查找的镜像关键字]
,如:
$ docker search tomcat
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
tomcat Apache Tomcat is an open source implementa... 896 [OK]
dordoka/tomcat Ubuntu 14.04, Oracle JDK 8 and Tomcat 8 ba... 22 [OK]
consol/tomcat-7.0 Tomcat 7.0.57, 8080, "admin/admin" 16 [OK]
consol/tomcat-8.0 Tomcat 8.0.15, 8080, "admin/admin" 15 [OK]
davidcaste/alpine-tomcat Apache Tomcat 7/8 using Oracle Java 7/8 wi... 10 [OK]
cloudesire/tomcat Tomcat server, 6/7/8 9 [OK]
...
结果会默认显示25条记录,通常第一条为官方镜像,即Docker Hub中的镜像。官方镜像会在OFFICIAL一列显示**[OK]**字样,另外,STARS一列的星星数量显示了该镜像的受欢迎程度,星星越多,表明用的人越多,不过为安全起见,通常建议首选官方镜像或自制镜像,而不是第三方的。
使用docker pull [镜像名称[:版本]]
可以拉取一个镜像:
注: 完整的镜像名称由[repository]/name:[tag]构成,[repository]为仓库,如果省略,则默认为library,即从Docker Hub拉取;如果省略tag,则默认拉取latest版本,name为镜像名称,不能省略。
$ docker pull tomcat:7
7: Pulling from library/tomcat
8ad8b3f87b37: Pull complete
751fe39c4d34: Pull complete
b165e84cccc1: Pull complete
65f65ec902a1: Pull complete
c7e29d14c31c: Pull complete
ae323d020901: Pull complete
f53151098775: Pull complete
4ee50529773d: Pull complete
e6cd9c8b5720: Pull complete
2274405e7ff7: Pull complete
ba48c8080acc: Pull complete
Digest: sha256:05749aa3217ba008878ff868de824602aaebcd6250c1510e489dbadb81ee37bd
Status: Downloaded newer image for tomcat:7
一个好的实践是,拉取镜像时,总是指定一个明确的版本,这样能确保在接下来的使用中,明确知道使用的是哪个版本。因为latest版本总是指向最新的版本,这将造成不确定性。
镜像拉取完成后,我们可以用它创建一个新的tomcat容器:
$ docker run -d --name tomcat001 -p 8081:8080 tomcat:7
72d39fb16383dc3ce667de4ea2c12b5c42d6cffdf818c6031fafe88fb6751f0a
其中,-d 指定容器在后台运行;–name用于指定容器的名称;-p 8081:8080 用于将容器内的8080端口映射到主机的8081端口,你也可以换成其他本机端口.如果需要,你可以创建多个容器使用,需要注意的是,本机映射的端口不能重复,name也不能重复。
查看当前容器:
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
72d39fb16383 tomcat:7 "catalina.sh run" 3 minutes ago Up 3 minutes 0.0.0.0:8081->8080/tcp tomcat001
这时,我们就可以访问192.168.1.132:8081来查看运行的tomcat了,注意将IP替换成你的docker主机的IP。
使用 docker logs 容器名称
可以查看容器的日志输出,-f
选项可以指定实时输出最新日志,类似于Linux 下的tail -f
命令。
$ docker logs -f tomcat001
Sep 05, 2016 10:27:49 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Server version: Apache Tomcat/7.0.70
Sep 05, 2016 10:27:49 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Server built: Jun 15 2016 16:27:45 UTC
Sep 05, 2016 10:27:49 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Server number: 7.0.70.0
Sep 05, 2016 10:27:49 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: OS Name: Linux
Sep 05, 2016 10:27:49 AM
...
...
INFO: Deployment of web application directory /usr/local/tomcat/webapps/ROOT has finished in 32 ms
Sep 05, 2016 10:27:49 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-apr-8080"]
Sep 05, 2016 10:27:49 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-apr-8009"]
Sep 05, 2016 10:27:49 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 655 ms
$ docker stop tomcat001
tomcat001
$ docker start tomcat001
tomcat001
删除一个容器前,需要先停止容器,否则,需要使用 -f
选项强制删除(不推荐)。
另外,如果容器包含数据卷的话,可以使用-v
选项连同关联的数据卷一块删除,删除容器时,默认不删除数据卷,因为数据卷通常会包含我们的数据。
$ docker rm tomcat001
tomcat001
到这里,似乎一切都在容器里,我们的应用好像还没怎么跟容器有联系。有多种方法可以运行我们的应用,最简单的就是将应用挂载为容器的一个数据卷,另外更常规的做法是直接把应用制作成一个镜像,方便后期的测试及发布等。容器存放数据的地方主要有两个,一个是数据卷,类似于Linux下挂载的文件夹;另一个是数据卷容器,即单独的用于存放数据的容器。关于容器的数据卷及数据卷容器的概念,还需要一篇文章讨论,在此就不做深入研究了。
最简单的使用数据卷的方式就是在创建一个容器时 增加-v
选项,我们以一个最简单的Java web应用为例:
1 首先创建一个目录:
sudo mkdir -p /opt/data/myapp/ROOT
sudo chown -R $USER:root /opt/data/myapp
注意这里的$USER
变量代表当前运行docker的用户,即安装docker时加入docker组的那个用户,其他用户可能会导致没权限。
2 在/opt/data/myapp/ROOT下创建一个WEB-INF
目录:
$ mkdir /opt/data/myapp/ROOT/WEB-INF
3 新建一个web.xml:
vi /opt/data/myapp/ROOT/WEB-INF/web.xml
贴入以下内容,保存:
Welcome to Tomcat
Welcome to Tomcat
4 新建一个jsp页面:
vi /opt/data/myapp/ROOT/index.jsp
贴入以下内容,保存:
Hello, this is my first docker app!