如何在docker上运行swoft项目

  • admin
  • PHP笔记
  • 2019-05-18 10:05
  • 134已阅读
简介 如何在docker上运行swoft项目,使用docker-compose编排 Swoft 开发环境

Swoft 开发环境

修改官方默认 docker-compose.yml 文件

我们通过命令 git clone https://github.com/swoft-cloud/swoft 从 Github 上 克隆(clone) Swoft 项目,并使用项目自带的 docker-compose.yml 文件来实现一个用于开发的环境,docker-compose.yml是 docker-compose 的编排配置文件, 我们看一下官方默认文件的内容:

1

2

3

4

5

6

7

8

9

10

11

12

version: '3'

services:

    swoft:

        container_name: swoft

        image: swoft/swoft

        ports:

            - "9501:80"

        volumes:

            - ./:/var/www/swoft

        stdin_open: true

        tty: true

        command: php /var/www/swoft/bin/swoft start

这是一个相对简单的编排文件,仅仅只有 swoft 一个服务,也没有关联过多的内容,关于 docker-compose.yml 的文件格式我们这里不做过多的解释,可自行查找相关的内容进行阅读理解。
简单的解读此文件的内容可以理解为,使用了swoft/swoft官方镜像并设置了容器名称为swoft,绑定容器内的9501端口与宿主机的80端口,设置./当前目录与容器内的/var/www/swoft目录为共享目录,开启与容器的交互式终端并于启动编排文件时启动Swoft服务。 
我们可以注意到默认编排文件上的 command 配置了 php /var/www/swoft/bin/swoft start,也就是启动 Swoft 服务的命令,但如果仅 克隆(clone) 项目并执行 docker-compose up 来尝试启动 容器的话,我们会得到一个失败的结果,因为尚未执行 composer install 来加载 Composer 的依赖而缺少 vendor 文件夹和 autoload 等相关文件,导致无法正确运行 Swoft 实例,我们再看默认的编排文件设置了 stdin_open: true 和 tty: true 两个参数,分别对应 docker 命令上的 -i 和 -t 两个参数,简单的理解就是 -i 开启了 输入(input)功能,-t 开启了一个连接容器里面的 交互式终端(terminal) ,我们可以利用这两个参数,并将编排文件的 command 行改为 command: /bin/bash ,使容器启动后不是直接启动 Swoft 服务,而是由我们手动通过 交互式终端(terminal) 进入容器内去启动。
下面是一个更改后的 docker-compose.yml 文件实例:

1

2

3

4

5

6

7

8

9

10

11

12

version: '3'

services:

    swoft:

        container_name: swoft

        image: swoft/swoft

        ports:

            - "9501:80"

        volumes:

            - ./:/var/www/swoft

        stdin_open: true

        tty: true

        command: /bin/bash

启动开发环境容器

此时我们在编排文件的所在目录启动一个 终端(Shell), 然后执行 docker-compose up -d,-d 的意思是以守护模式(Daemon Mode) 运行,便于我们在同一个 终端(Shell) 进入到容器内,命令执行后我们可以看到 Starting swoft ... done 即表示启动容器成功。
如果在执行启动命令时得到一下错误,则说明宿主机的80端口已经被占用了,更改 docker-compose.yml 文件内的 9501:80 为其它未被占用的端口即可,注意第一个80指的是宿主机的端口,第二个80指的是容器内的端口,也就是说我们只需要更改第一个即可

1

ERROR: for swoft Cannot start service swoft: b'driver failed programming external connectivity on endpoint swoft(dab0f4d00620e2f5c07e33084ca5cac6f08cb48018d6b737eadc035e5aa0b597): Bind for 0.0.0.0:80 failed: port is already allocated'

进入开发环境容器

通过执行 docker ps 命令可以查看启动的容器信息,下面为示例信息:

1

2

CONTAINER ID  IMAGE               COMMAND                 CREATED             STATUS             PORTS               NAMES

f22173763374  swoft/swoft:latest  "docker-php-entrypoin"  About a minute ago  Up About a minute  0.0.0.0:9501->80/tcp  swoft

得知 容器ID(Container ID) 为 f22173763374,容器名称(Container Name)为 swoft,我们可以执行 docker exec -it f22173763374 bash 或 docker exec -it swoft bash 通过 交互式终端(terminal)进入到容器内。

如执行时报错 the input device is not a TTY. If you are using mintty, try prefixing the command with 'winpty',可在 docker exec 命令前面增加 winpty 命令解决,即 winpty docker exec -it swoft bash

运行以及开发调试

安装 Composer 依赖及生成自动加载(Autoload)文件

通过 docker exec 命令进入容器后,我们留意到光标左侧的内容变为 root@f22173763374: 即为已进入容器内,其中 f22173763374 为对应的 容器ID(Container ID)。
由于 Swoft 官方镜像 swoft/swoft 配置的工作目录为 /var/www/swoft,而 docker-compose.yml又将项目当前目录关联了容器 /var/www/swoft 目录,即通过 docker exec 进入的目录已经为 /var/www/swoft 目录,即项目目录,所以我们可以直接执行 composer install 命令来加载 Composer 的依赖并生成 自动加载(Autoload) 文件。
考虑到国内的网络环境,我们在执行 composer install 命令前可以先执行 

composer config -g repo.packagist composer https://packagist.laravel-china.org

 命令配置 Composer 中国镜像源 加速安装速度。

启动 Swoft 服务

安装完 Composer 依赖后,便可以执行 php bin/swoft start 启动服务了,当你看到

                         Information Panel
  **********************************************************************
  * HTTP     | Listen: 0.0.0.0:9501, type: TCP, mode: Process, worker: 1
  * rpc      | Listen: 0.0.0.0:18307, type: TCP
  **********************************************************************
HTTP server start success !
2019/05/18-02:31:40 [INFO] Swoft\Listener\BeforeStartListener:handle(54) Registered swoole events:
 start, shutdown, managerStart, managerStop, workerStart, workerStop, workerError, request, task, finish
Server start success (Master PID: 3755, Manager PID: 3756)


即意味着你的 Swoft 以及启动成功了,我们可以打开浏览器访问一下 当你看到下图即大功告成了!


这个是 swoft 开发内侧版

{C60D6DB6-D030-4E5F-AAD8-77E640D7F00B}_20190518103714.jpg




修改代码并使代码生效

Swoft 跟 PHP-FPM 模式下的开发会有一点差异,在PHP-FPM模式下直接改变代码内容,再访问对应的代码便能得到变更后的内容,是因为PHP-FPM模式下每一次请求都会重新加载PHP代码,而 Swoft是持久化运行的,也就意味着代码在服务启动之后,接受的请求都无需重新加载,这个模式的变化可以使得 Swoft 的大量代码可被重复使用,而无需重新加载和重新实例化,大大提升性能的其中一点原因之一。
这样的变更对开发会造成一定程度的影响,也就是说在 Swoft 下,你需要 重启 Worker 或 重启服务 才能使变更的代码生效,但是得益于 Swoft 的 热重载 功能,可以自动检查代码变更并自动 重启 Worker,我们只需通过项目根目录下的 .env 文件更改 AUTO_RELOAD 项为 true 即可,如项目根目录下没有 .env 文件,可直接复制 .env.example 文件为 .env 并作出对应的更改即可,有一点需要注意的是仅在改变 app 目录下的代码才会被 热重载 功能重载,改变其它代码不会被重载

文章评论