Docker PHP 入门实践(三)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker PHP 入门实践(三)相关的知识,希望对你有一定的参考价值。
参考技术A
在本教程的其余部分,我们将基于 Thinkphp 框架完成一个天气查询的应用。使用 天气查询-API文档-开发指南-Web服务 API | 高德地图API 的接口来实现我们的功能。把查询数据缓存到 mysql 中,这样就不用每次频繁的请求第三方的接口了(有请求次数限制)
选择高德开放平台-天气查询 API 主要是因为它是免费的。当然你也可以使用其他的第三方天气查询接口,看个人喜好。
该应用是一个非常简单的 REST API 应用,主要实现两个接口。
在我们进行应用编码之前,首先使用 Docker 安装并运行 ThinkPHP
ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简代码的同时,更注重易用性。遵循 Apache2 开源许可协议发布,意味着你可以免费使用ThinkPHP,甚至允许把你基于ThinkPHP开发的应用开源或商业产品发布/销售 。
这就是为什么我选择它作为本教程的教学框架。我不想让你因为一个框架而放弃,但我也不想从头开始建立所有的东西,因为该教程的重点是Docker,而不是我们的PHP应用。
用Docker 创建 ThinkPHP 应用 实际上比用本地配置PHP环境所需的操作少。并且为我们还需要使用 Composer,多亏了Docker,我们甚至不需要在主机上安装它。
首先打开你的终端,创建一个项目目录。
并进入到该目录中
现在使用[官方Composer Docker镜像](https://hub.docker.com/_/composer/)安装 ThinkPHP 。
如果你查看weather-app/目录,你会看到 ThinkPHP 6 的项目目录,如下所示:
我们的 docker 运行命令与第二章中的命令相似,但我们使用了不同的镜像。我们没有使用运行hello.php 脚本的 PHP 镜像,而是使用了一个 Composer 镜像。让我们来看看有什么变化。
项目创建完成后,我们需要添加几个路由 URL 和 Controller 文件 。让我们打开 weather-app 目录下的 app/controller , 然后新建 Weather.php 文件,内容如下:
然后打开 weather-app 目录下的 app/route , 在 app.php 文件中追加如下内容:
现在我们可以在 Docker 容器中运行我们的应用程序,只是为了验证我们的程序是否运行正常,因为我们只添加了两个路由 URL。打开命令行,运行。
现在,在浏览器中打开 http://localhost:38000/weather-app/public/index.php/weather/1,你应该看到一个空页面,上面有以下文字:
那么恭喜你,你刚刚已经成功地在 Docker 中运行了你的第一个 ThinkPHP 应用程序。
这次我们使用的docker run命令与我们用来运行 hello.php 脚本 和composer create-project ...的两个命令不同。原因是这次我们想获得包含 Apache 的最新版本的PHP,这样我们就可以为我们的 Web 应用提供服务。让我们更详细地了解新增的命令部分。
你可以通过向终端发送一个 "中断 "信号来停止和退出终端。在 windows 上,这可以通过按 Ctrl 和按c来实现。
运行你的新网络应用程序的另一个选择是在 "Detached"模式中运行容器。这意味着你在终端将不会看到来自你的容器的输出。这可以通过在我们之前的命令中添加-d标志来实现。
在分离模式下启动容器后,你的终端将显示新容器的完整ID--类似于a70d25c2a7cedae673f8ab...如果你想停止这个容器,你可以使用docker stop命令,用容器的ID告诉Docker。比如说
因为输入整个ID是很麻烦的,如果你愿意,Docker允许你只输入前三个或更多的字符。
最后,我建议为你的容器命名。我们在本书后面的许多例子中都会这样做,因为用名字来记住一个容器比用随机分配的ID要容易得多,再加上ID是随机的,所以每次你运行一个新版本的容器时,它都会得到一个新的ID。只要不是已经有一个同名的容器,名字就可以多次发出来。为了给我们的新应用容器命名,我们可以用传入的--name标志重新创建它。
在使用docker run命令时,还有许多可用的选项,所以你可能想更详细地阅读文档。在我们开发其余的应用程序时,我们会涉及其中的一些选项。
现在我们要引入高德的天气 SDK ,在使用该 SDK 之前你需要阅读高德开放平台-天气查询的技术文档,再添加 SDK 之前我们首先要确保所有现有的容器都停止了。
这个命令将列出所有正在运行的容器。你也可以通过添加-a标志来查看停止的容器。
如果有任何容器正在运行,那么在我们继续前进之前,使用docker stop 来停止它们。
该命令将在你的项目中装新的软件包。在这个过程中,你应该在终端看到一些类似这样的输出。
现在 SDK 已经安装完毕,可以使用了。
我们将使用刚刚添加的高德天气 SDK 来完善我们的业务逻辑,打开 controller 目录下的 Weather.php 添加以下内容:
我们做了一些更新--主要是对引入天气 API 初始化天气类
我们的应用程序已经初步完成了向API传递一个真实的位置ID并返回一些数据。首先,使用这个高德位置查询找到一个位置ID。我使用的是上海的ID进行测试。310000,当然你直接传 上海 也是可以的。ok,让我们再次运行Docker容器。
并在你的浏览器中访问正在运行的应用程序,地址是http://localhost:38000/weather-app/public/index.php/weather/310000。你应该可以看到一个JSON数据,看起来像这样。
你的 Docker 化的 PHP 应用程序现在正从外部数据源返回真实数据,并在Apache中提供服务,但你可能会注意到,它的速度并不快(我的页面加载时间为1.92秒!)。
高德天气 API 是一个免费的服务,其他国家可能无法访问。为了解决这个问题,我们将把查询的数据保存在我们自己的 MySQL 数据库中,可以再下次访问的时候可以快速地响应。这将极大地提高性能,下个章节我们将学习如何用 Docker 将 MySql 与 PHP 应用程序相结合。
Docker 从入门到实践系列三 - Docker 常用命令
文章目录
帮助命令
# 查看docker版本
docker version
# 查看docker基本信息
docker info
# 查看具体docker命令的解释
docker --help
镜像命令
镜像检索
通常情况下,Docker 的镜像都放在 Docker 的官网 Docker Hub 上,点此前往官网
docker search 镜像名称:查找镜像,会把相似的结果也查询出来
除了可以在 Docker Hub 上搜索镜像外,还可以通过命令 docker search xxx
进行搜索,下面以hello-world
为例:
docker search hello-world
输出结果
NAME
:镜像名称DESCRIPTION
:镜像描述STARS
:星数(点赞)OFFICAL
:是否是官方镜像AUTOMATED
:是否是自动构建的
另外,docker search -参数
含义:
-f, --filter filter
:根据提供的条件过滤输出,比如:docker search -f stars=30 hello-world
列出星数不小于30的hello-world
镜像;--no-trunc
:显示镜像完整描述信息;--limit int
:最大搜索结果数(默认 25)
镜像下载
镜像下载命令为:docker pull [IMAGE_NAME]:[TAG]
其中,IMAGE_NAME
:镜像名,TAG
:标签,镜像版本,可选的,默认为 latest
;
在生产环境中,推荐指定 TAG,选择稳定版本的镜像,具体有哪些版本可以上Docker Hub去查找。
docker pull hello-world
镜像列表
获取已下载镜像列表命令:docker images
其中,
RESPOSITORY
:镜像名;TAG
:镜像版本,latest
代表最新版;IMAGE_ID
:镜像唯一 ID;CREATED
:镜像的创建时间;SIZE
:镜像的大小。
docker images -参数
含义:
-a
:all 的简写,列出本地所有镜像(包含中间映像层);-q
:只显示镜像 ID;--digests
:显示镜像摘要信息;--no-trunc
:显示完整的镜像信息。
镜像删除
删除指定镜像:
docker rmi image-id
删除多个镜像:
docker rmi mysql tomcat
删除所有镜像:
docker rmi $(docker images -q)
强制删除镜像:
强制删除(当前镜像启动的容器正在运行中,是无法正常删除的,可以通过 -f 强制删除)
如果删除时不指定 TAG,默认为最新版 Least。
docker rmi -f image-id
容器命令
镜像运行起来后,称为容器。 下面以 Tomcat 为例
搜索镜像
docker search tomcat
下载镜像
docker pull tomcat
运行容器
运行tomcat
docker run --name tomcat -d -p 8080:8080 tomcat
如果docker运行Tomcat后访问首页报404,详细解决方案可参考:https://cloud.tencent.com/developer/article/1704573
最简单的根据镜像新建并启动容器的命令如下:
docker run --name container-name -d image-name
运行一个容器,使用 docker run
命令即可。 另,docker run -参数
含义:
-- name
:为容器起一个名称;-d
:detached,执行完这句命令后,控制台将不会阻塞,可以继续输入命令操作,不会阻塞,也就是启动守护式容器,如果执行docker run --name tomcat -it tomcat
会进入启动容器的命令控制台,也就是启动交互式容器;-i
:以交互方式运行容器,通常与-t
搭配使用;-t
:为容器重新分配一个伪输入终端,通常与-i
搭配使用;-P
:随机端口映射;-p
:指定端口映射;image-name
:要运行的镜像名称;
端口映射
启动做端口映射的容器
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P(大写)
或 -p (小写)
参数来指定端口映射。启动容器的时候如果不指定对应参数,在容器外部是无法通过网络来访问容器内的网络应用和服务的。
Docker 的端口映射通过 -p
或 -P
参数实现,命令如下:
docker run --name tomcat1 -d tomcat
docker run --name tomcat2 -d -p 8888:8080 tomcat
如上,就把主机端口 8888 请求映射到 Docker 容器内部端口 8080 了。
-p
和 -P
区别为:
-P : 随机映射一个49000~49900的端口到内部容器开放的网络端口
-p : 可以指定要映射的IP和端口,但是在一个指定端口上只可以绑定一个容器
执行完这两条命令后,通过 docker ps
查看:
通过 PORTS
可以看出,tomcat2
是做了端口映射的,tomcat1
是没进行映射过的。
分别通过浏览器访问:
http://*.*.*.*:8080/
// tomcat1默认端口;
http://*.*.*.*:8888/
// 做过端口映射的 Tomcat2,8888 会转发请求到 tomcat2 的 8080。
结果如下:
第一个请求是无法请求到的,原因开篇处说过了。
第二个请求是可以正常进行请求的,会由 tomcat2 容器进行处理
端口映射格式
#指定ip、指定主机port、指定容器port
#ip:hostport:containerport
docker run --name tomcat -d -p 127.0.0.1:8080:8080 tomcat
#指定映射使用一个特定地址,比如 localhost地址 127.0.0.1
#指定ip、未指定主机port、指定容器port
#ip::containerport
docker run --name tomcat -d -p 127.0.0.1::8080 tomcat
#绑定 localhost 的任意端口到容器的 8080 端口,本地主机会自动分配一个端口,还可以使用 udp 标记来指定 udp 端口
docker run --name tomcat -d -p 127.0.0.1:8080:8080/udp tomcat
#未指定ip port、指定主机port、指定容器port
#hostport:containerport
docker run --name tomcat -d -p 8080:8080 tomcat
#将本地的 8080 端口映射到容器的 8080 端口,默认会绑定本地所有接口上的所有地址
查看端口映射
可以通过如下命令查看容器映射了哪些端口及协议:
docker port container-id
示例:
[root@iZwz9inovbad1hkjy16akvZ tmp]#docker port 1596abf8d8a3
8080/tcp -> 0.0.0.0:8888
8080/tcp -> :::8888
[root@iZwz9inovbad1hkjy16akvZ tmp]#docker port 67751753d5da
如果返回空,则代表没进行端口映射。
小结
- 容器有自己的内部网络和 ip 地址,可以使用
docker inspect container-id
可以获取所有的变量 - Docker 还可以有一个可变的网络配置
- -p 标记可以多次使用来绑定多个端口 eg.
docker run --name tomcat -d -p 8080:8080 -p 3000:80 tomcat
查看容器
可通过如下命令,查看运行中的容器列表:
docker ps
CONTAINER ID
:启动时生成的容器 ID;IMAGE
:该容器使用的镜像;COMMAND
:容器启动时执行的命令;CREATED
:容器创建时间;STATUS
:当前容器状态;PORTS
:当前容器所使用的端口号;NAMES
:启动时给容器设置的名称。
另,docker ps -参数
含义:
-a
:查看所有容器,包括已停止运行的;
-q
:静默模式,只显示容器编号;
-l
:显示最近创建的容器;
-n 3
:显示最近创建的 num(此处为 3)个容器;
--no-trunc
:不截断输出,显示完整信息。
停止容器
通过以下命令来停止运行中的容器:
docker stop container-name/container-id
强制停止容器(类似强制关机):
docker kill container-name/container-id
启动容器
通过以下命令启动容器:
docker start container-name/container-id
docker run和docker start的区别:
1.docker run
docker run只有在第一次运行时使用,将镜像放到容器中,以后再次启动这个容器的时候,只需要使用命令docker start就可以。
docker run相当于执行了两步操作:将镜像(Image)放到容器(Container)中,这一步过程叫做docker create,然后将容器启动,使之变成运行时容器(docker start)。
2.docker start
docker start的作用是:重新启动已经存在的容器。也就是说,如果使用这个命令,我们必须先要知道这个容器的ID、或者这个容器的名字,我们可以使用docker ps命令找到这个容器的信息。
重启容器
通过以下命令启动容器:
docker restart container-name/container-id
删除容器
删除单个容器:
docker rm container-id
删除多个容器:
docker rm container-id container-id
删除所有容器:
docker rm $(docker ps -a -q )
另,docker rm -参数
含义:
-f
:强制删除,如果在运行中,先停止,再删除
其他重要命令
查看容器日志
查看当前容器日志,可通过如下命令:
docker logs container-id/container-name
另,docker logs -参数
含义:
-t
:加入时间戳;-f
:跟随最新的日志打印;-n
:显示最后多少条。
连接到正在运行容器
docker attach container-id
:连接到正在运行的容器;
要attach
上去的容器必须正在运行,可以同时连接上同一个container来共享屏幕(与screen
命令的attach
类似)。
官方文档中说 attach
后可以通过 CTRL-C
来 detach
,但实际上经过我的测试,如果 container 当前在运行 bash
,CTRL-C
自然是当前行的输入,没有退出;如果 container 当前正在前台运行进程,如输出 nginx
的 access.log
日志,CTRL-C
不仅会导致退出容器,而且还 stop
了。
这不是我们想要的,detach
的意思按理应该是脱离容器终端,但容器依然运行。好在 attach
是可以带上 --sig-proxy=false
来确保 CTRL-D
或 CTRL-C
不会关闭容器。
docker attach --sig-proxy=false 7f237caad43b
在运行的容器中执行命令
运行中的容器其实是一个功能完备的简易版 Linux 操作系统,所以我们可以像常规系统一样进行登陆及退出操作。
命令为:
docker exec -it container-id/container-name bash
退出命令为:
exit
exec
和 attach
区别:
attach
:直接进入容器启动命令的终端,不会启动新的进程;exec
:在容器中打开新的终端,并且可以启动新的进程,可在宿主机中直接执行操作容器的命令,eg.docker exec -it 7f237caad43b ls /tmp
。
查看容器中正在运行进程
可用通过如下命令查看容器中正在运行进程:
docker top container-id/container-top
查看容器内部细节
可用通过如下命令查看容器内部细节,返回为 json:
docker inspect container-id
容器和宿主机互相拷贝文件
宿主机拷贝文件到容器:
docker cp 文件 container-id:目标文件/文件夹
# 将宿主机tmp文件夹下test.txt文件拷贝到容器7f237caad43b中tmp目录中
docker cp /tmp/test.txt 7f237caad43b:/tmp
从容器拷贝文件到宿主机:
docker cp container-id:目标文件/文件夹 宿主机目标文件/文件夹
# 将容器7f237caad43b中tmp目录下yum.log拷贝到宿主机/tmp目录下
docker cp 7f237caad43b:/tmp/yum.log /tmp
更多操作命令
更多命令可以参考:https://docs.docker.com/engine/reference/commandline/docker/
常用命令小结
以下是 Docker 的一些常用命令,通过 docker --help
就可以查看,只是将其翻译成中文而已:
命令 | 英文 | 中文 |
---|---|---|
attach | Attach to a running container | 当前 shell 下 attach 连接指定运行镜像 |
build | Build an image from a Dockerfile | 通过 Dockerfile 定制镜像 |
commit | Create a new image from a container changes | 提交当前容器为新的镜像 |
cp | Copy files/folders from the containers filesystem to the host path | 从容器中拷贝指定文件或者目录到宿主机中 |
create | Create a new container | 创建一个新的容器,同 run,但不启动容器 |
diff | Inspect changes on a container’s filesystem | 查看 docker 容器变化 |
events | Get real time events from the server | 从 docker 服务获取容器实时事件 |
exec | Run a command in an existing container | 在已存在的容器上运行命令 |
export | Stream the contents of a container as a tar archive | 导出容器的内容流作为一个 tar 归档文件[对应 import] |
history | Show the history of an image | 展示一个镜像形成历史 |
images | List images | 列出系统当前镜像 |
import | Create a new filesystem image from the contents of a tarball | 从 tar 包中的内容创建一个新的文件系统映像[对应 export] |
info | Display system-wide information | 显示系统相关信息 |
inspect | Return low-level information on a container | 查看容器详细信息 |
kill | Kill a running container | kill 指定 docker 容器 |
load | Load an image from a tar archive | 从一个 tar 包中加载一个镜像[对应 save] |
login | Register or Login to the docker registry server | 注册或者登陆一个 docker 源服务器 |
logout | Log out from a Docker registry server | 从当前 Docker registry 退出 |
logs | Fetch the logs of a container | 输出当前容器日志信息 |
port | Lookup the public-facing port which is NAT-ed to PRIVATE_PORT | 查看映射端口对应的容器内部源端口 |
pause | Pause all processes within a container | 暂停容器 |
ps | List containers | 列出容器列表 |
pull | Pull an image or a repository from the docker registry server | 从 docker 镜像源服务器拉取指定镜像或者库镜像 |
push | Push an image or a repository to the docker registry server | 推送指定镜像或者库镜像至 docker 源服务器 |
restart | Restart a running container | 重启运行的容器 |
rm | Remove one or more containers | 移除一个或者多个容器 |
rmi | Remove one or more images | 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除] |
run | Run a command in a new container | 创建一个新的容器并运行一个命令 |
save | Save an image to a tar archive | 保存一个镜像为一个 tar 包[对应 load] |
search | Search for an image on the Docker Hub | 在 docker hub 中搜索镜像 |
start | Start a stopped containers | 启动容器 |
stop | Stop a running containers | 停止容器 |
tag | Tag an image into a repository | 给源中镜像打标签 |
top | Lookup the running processes of a container | 查看容器中运行的进程信息 |
unpause | Unpause a paused container | 取消暂停容器 |
version | Show the docker version information | 查看 docker 版本号 |
wait | Block until a container stops, then print its exit code | 截取容器停止时的退出状态值 |
以上是关于Docker PHP 入门实践(三)的主要内容,如果未能解决你的问题,请参考以下文章