在部署的时候,经常会遇到这样的情况,运维工具和运行时工具互相干扰,借助Docker
可以很方便的解决这个问题,下面以部署Zend Expressive Skeleton
为例说明(这个例子中没有运维工具和运行时工具互相干扰的问题,仅用于演示)。
准备
本例假设在Windows
操作系统中,Linux
的情况可能会更简单些。假设使用docker-machine
命令可以访问到一台Docker
主机。
公共部分
为了不纠缠具体的技术细节,本例已经把和具体项目无关的公共部分独立为开源项目。
进入工作目录。
下载使用Docker
运行nginx
+PHP-fpm
路由模式的代码
git clone https://github.com/huzhenghui/Docker-run-nginx-PHP-fpm-web-server-router-from-Windows-share-folder zend-expressive-skeleton
进入项目文件夹
cd zend-expressive-skeleton
更新子模块代码
git submodule update --init
由于Docker主机上的卷需要唯一名称,本文使用一个环境变量。
$env:VOLUME_NAME="zend-expressive-skeleton"
以管理员权限启动PowerShell
,运行把Windows
文件夹共享到Docker
主机的脚本,此处要求docker-machine
命令能访问到一台运行中的Docker
主机,更多选项请参考其中的源代码。
.\share-windows-folder-to-docker\share-windows-folder-to-docker.ps1 -workingDir . -volumeName ${env:VOLUME_NAME}
测试卷的加载情况。
docker run --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router alpine ls /nginx-PHP-fpm-web-server-router
显示文件夹的内容即代表共享成功。
LICENSE
docker-compose.yml
nginx
php
share-windows-folder-to-docker
- 2
- 3
- 4
- 5
交互安装模式
在公共部分的基础上,可以交互安装。
先删除原有位置的代码。
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "rm -rf /nginx-PHP-fpm-web-server-router/php"
然后安装。
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router composer create-project zendframework/zend-expressive-skeleton /nginx-PHP-fpm-web-server-router/php
安装过程中执行Zend Expressive Skeleton
的安装脚本,可以交互设置安装选项。
What type of installation would you like?
[1] Minimal (no default middleware, templates, or assets; configuration only)
[2] Flat (flat source code structure; default selection)
[3] Modular (modular source code structure; recommended)
Make your selection (2): 3
- Adding package zendframework/zend-expressive-tooling (^0.4.1)
- Copying src/App/src/ConfigProvider.php
Which container do you want to use for dependency injection?
[1] Aura.Di
[2] Pimple
[3] Zend ServiceManager
Make your selection or type a composer package name and version (Zend ServiceManager):
- Adding package zendframework/zend-servicemanager (^3.3)
- Copying config/container.php
Which router do you want to use?
[1] Aura.Router
[2] FastRoute
[3] Zend Router
Make your selection or type a composer package name and version (FastRoute):
- Adding package zendframework/zend-expressive-fastroute (^2.0)
- Copying config/routes.php
- Copying config/autoload/router.global.php
Which template engine do you want to use?
[1] Plates
[2] Twig
[3] Zend View installs Zend ServiceManager
[n] None of the above
Make your selection or type a composer package name and version (n): 3
- Adding package zendframework/zend-expressive-zendviewrenderer (^1.4)
- Copying config/autoload/templates.global.php
- Copying src/App/templates/error/404.phtml
- Copying src/App/templates/error/error.phtml
- Copying src/App/templates/layout/default.phtml
- Copying src/App/templates/app/home-page.phtml
Which error handler do you want to use during development?
[1] Whoops
[n] None of the above
Make your selection or type a composer package name and version (Whoops):
- Adding package filp/whoops (^2.1.7)
- Copying config/autoload/development.local.php.dist
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
自动安装模式
交互安装模式和传统的运维方式相似,如果把Docker
作为运维管理程序,把程序视为被操作的数据,也可以自动安装。
先删除原有位置的代码。
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "rm -rf /nginx-PHP-fpm-web-server-router/php"
下载源代码
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "apk update && apk add git && git clone https://github.com/zendframework/zend-expressive-skeleton.git /nginx-PHP-fpm-web-server-router/php"
运行项目的安装程序,不运行其中的交互脚本。
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router composer install --no-scripts -d /nginx-PHP-fpm-web-server-router/php
复制文件
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "cp /nginx-PHP-fpm-web-server-router/php/src/ExpressiveInstaller/Resources/config/container-zend-servicemanager.php /nginx-PHP-fpm-web-server-router/php/config/container.php"
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "cp /nginx-PHP-fpm-web-server-router/php/src/ExpressiveInstaller/Resources/config/routes-full.php /nginx-PHP-fpm-web-server-router/php/config/routes.php"
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "cp /nginx-PHP-fpm-web-server-router/php/src/ExpressiveInstaller/Resources/config/router-fast-route.php /nginx-PHP-fpm-web-server-router/php/config/autoload/router.global.php"
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "cp /nginx-PHP-fpm-web-server-router/php/src/ExpressiveInstaller/Resources/config/templates-zend-view.php /nginx-PHP-fpm-web-server-router/php/config/autoload/templates.global.php"
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "cp /nginx-PHP-fpm-web-server-router/php/src/ExpressiveInstaller/Resources/src/ConfigProvider.modular.php /nginx-PHP-fpm-web-server-router/php/src/App/src/ConfigProvider.php"
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "mkdir -p /nginx-PHP-fpm-web-server-router/php/src/App/templates/app/"
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "cp /nginx-PHP-fpm-web-server-router/php/src/ExpressiveInstaller/Resources/templates/zend-view-home-page.phtml /nginx-PHP-fpm-web-server-router/php/src/App/templates/app/home-page.phtml"
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "mkdir -p /nginx-PHP-fpm-web-server-router/php/src/App/templates/error/"
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "cp /nginx-PHP-fpm-web-server-router/php/src/ExpressiveInstaller/Resources/templates/zend-view-404.phtml /nginx-PHP-fpm-web-server-router/php/src/App/templates/error/404.phtml"
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "cp /nginx-PHP-fpm-web-server-router/php/src/ExpressiveInstaller/Resources/templates/zend-view-error.phtml /nginx-PHP-fpm-web-server-router/php/src/App/templates/error/error.phtml"
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "mkdir -p /nginx-PHP-fpm-web-server-router/php/src/App/templates/layout/"
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router --entrypoint /bin/sh alpine -c "cp /nginx-PHP-fpm-web-server-router/php/src/ExpressiveInstaller/Resources/templates/zend-view-layout.phtml /nginx-PHP-fpm-web-server-router/php/src/App/templates/layout/default.phtml"
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
运行
上述的交互安装模式或者自动安装模式之后,都可以使用php
自带的内部服务器运行。
docker run -it --rm -v ${env:VOLUME_NAME}:/nginx-PHP-fpm-web-server-router -p 80:80 php -S 0.0.0.0:80 -t /nginx-PHP-fpm-web-server-router/php/public index.php
也可以使用nginx
和PHP-fpm
路由模式运行。
docker-compose up
小结
从上述过程可以看到,在安装过程中使用了alpine
、composer
、php
三个镜像,在运行过程中还使用了nginx
和php:fpm
两个镜像。
安装过程中的镜像相互独立,并不像传统安装过程那样为了安装程序需要安装一大堆工具,本例中使用的git
没有专门的镜像,采用临时安装运行的方式。这样使得安装过程中使用到的工具不仅互相不干扰,而且也不影响到运行时环境。运行过程中的两个镜像也分别在两个容器中,也互相不干扰。
采用这样的方式,可以避免运维工具和运行时工具互相干扰的情况,当然,这个例子中没有运维工具和运行时工具互相干扰的问题,仅用于演示。