Windows 多项目开发环境
问题与解决方案
多个 PHP 项目同时部署在 Windows 环境下会出现不少问题:
- 项目都在同一个域名下 cookie、session 等数据互相干扰
- 不同项目的 PHP 版本不一样
- PHP 在 Windows 下运行效率低下,项目越复杂越明显
- 邮件模板开发的测试非常麻烦
为了解决这些问题,节省给新项目配置环境的时间,我用 Docker 构建了这样一个框架:
- 不同的项目有各自独立的域名
- 使用 Docker 让不同的项目工作在各自独立的容器中,解决了 PHP 版本冲突的问题
- 使用 Docker 虚拟 LAMP 环境,提高运行效率
- 本地即时收取邮件
框架内容
这个框架使用 docker-compose 构建,包含以下内容:
- 基于 nginx 镜像的自定义 router 容器,用于域名转发
- 基于 mailhog/mailhog 镜像的 mailer 容器,用于本地邮件测试
- 基于 phpmyadmin 镜像的同名容器,用于数据库管理
- 名为 dev_net 的 network
其中 nginx 容器的自定义部分主要包括:
- 安装
openssh-server
以便通过这个容器 SSH 到其他项目容器,从而避免为每个项目容器指派一个 SSH 端口 - 安装
openssl
使其支持 HTTPS 请求的转发
这个框架的主要机制是建立一个 Docker 内部网络把各个项目容器和 router 容器连接起来,并将本机的 80/443 端口映射到 router 容器。这样所有指向本地 IP(127.0.0.1)的不同域名(在 Windows 的 hosts 文件中设置)请求都会通过 router 容器转发到对应的项目容器,从而达到不同项目对应不同域名的目的。
更新文件可以通过 putty 等软件设置 tunnel 通道,这样 SSH 连通 router 容器后就可以用 FTP 工具把文件上传到项目容器中;或者直接将项目容器的 22 端口映射到本机的某个端口,然后直接通过该端口上传。一定不要直接把项目文件挂载到 Windows,否则程序运行起来效率比直接在 Windows 下还要低。
下面简述框架的主要结构,完整内容请访问 https://github.com/zengliwei/dev。
目录结构
框架的目录结构如下:
+-- config
+ +-- phpmyadmin
+ +-- router
+ +-- ssl
+-- images
+ +- router
+-- projects
+
+-- .env
+-- docker-compose.yml
+-- reload.cmd
+-- start.cmd
这些目录和文件功能如下:
- config/phpmyadmin - 挂载 phpmyadmin 容器的配置文件目录(/etc/phpmyadmin),方便直接在 Windows 下修改
- config/router - 挂载 router 容器的配置文件目录(/etc/nginx/conf.d),方便直接在 Windows 下修改
- config/ssl - 挂载 router 容器的证书目录(/etc/ssl/certs),作用下文会提及
- images/router - 用于创建 router 容器的自定义部分内容
- projects - 项目文件的安放目录,每个项目放在这个文件夹的一个子目录中,结构根据项目类型有所不同,下文会提及
- .env - 框架配置文件
- docker-compose.yml - docker-compose 配置文件
- reload.cmd - 修改配置文件后要执行的批处理命令
- start.cmd - 安装框架时要执行的批处理命令。执行后会自动创建容器,修改 Windows 的 hosts 文件,并在 Windows 的启动目录中创建一个自动关闭所有容器的批处理文件
docker-compose.yml
配置文件 docker-compose.yml 内容如下:
version: "3"
services:
mailer:
image: mailhog/mailhog
container_name: ${COMPOSE_PROJECT_NAME}_mailer
restart: ${RESTART}
networks:
- network
phpmyadmin:
image: phpmyadmin
container_name: ${COMPOSE_PROJECT_NAME}_phpmyadmin
restart: ${RESTART}
environment:
PMA_ARBITRARY: 1
volumes:
- ${PHPMYADMIN_CONFIG_DIR}:/etc/phpmyadmin
networks:
- network
router:
image: dev-router
build:
context: ./images/router
args:
ssh_pswd: ${ROUTER_SSH_PSWD}
container_name: ${COMPOSE_PROJECT_NAME}_router
depends_on:
- mailer
- phpmyadmin
restart: ${RESTART}
networks:
- network
ports:
- ${ROUTER_PORT}:80
- ${ROUTER_SSL_PORT}:443
- ${ROUTER_SSH_PORT}:22
volumes:
- ${ROUTER_CONFIG_DIR}:/etc/nginx/conf.d
- ${ROUTER_SSL_DIR}:/etc/ssl/certs
networks:
network:
.env
配置文件 .env 内容如下:
COMPOSE_PROJECT_NAME=dev
ROUTER_CONFIG_DIR=./config/router
ROUTER_PORT=127.0.0.1:80
ROUTER_SSH_PORT=127.0.0.1:22
ROUTER_SSH_PSWD=root
ROUTER_SSL_DIR=./config/ssl
ROUTER_SSL_PORT=127.0.0.1:443
DB_PSWD=root
PHPMYADMIN_CONFIG_DIR=./config/phpmyadmin
RESTART=on-failure
项目容器
不同类型项目容器的结构都不一样,通常包含以下内容:
- config - 挂载配置文件的目录
- src - 项目源文件的放置目录
- .env - 项目配置文件,设定域名、项目名等内容
- docker-compose.yml - docker-compose 配置文件
- start.cmd - 开启项目容器时要执行的批处理命令。在新项目中执行还会自动创建容器,在框架的 config 目录创建配置文件,并修改 Windows 的 hosts 文件增加域名指向
- stop.cmd - 关闭项目容器
- uninstall.cmd - 卸载项目容器,清理相关 router、phpMyAdmin、host 等配置文件
docker-compose.yml
不同类型项目的 docker-compose.yml 文件有所不同,格式如下:
version: "3"
services:
...
networks:
network:
external:
name: ${NETWORK}
.env
不同类型项目的配置文件有所不同,格式如下:
COMPOSE_PROJECT_NAME=project
DOMAIN=project.mine.com
SSH_PSWD=root
DB_ROOT=root
DB_NAME=project
DB_USER=project
DB_PSWD=project
RESTART=no
NETWORK=dev_net
项目环境容器列表
下边是一些做好的环境容器:
- dev-php-5.3
- dev-php-5.6
- dev-php-7.4
- dev-magento - 支持 Magento 1.9 到 2.4 几个版本
- dev-drupal-9.x
- dev-jupyter-tensorflow
- dev-rabbitmq
- dev-varnish
使用方法
安装框架
- 正确安装并配置 Docker Desktop 和 docker-compose
- 点击【这里】下载并解压框架文件到本地目录(解压后的目录为 dev_master,里边一层才是正式内容)
- 确保本机的 22、80、443 几个端口未被占用,否则要修改框架配置文件 .env 让这个框架使用其他端口
- 运行批处理文件 start.cmd 安装框架
- 运行完毕后,在浏览器可以正常访问 http://db.localhost 和 http://mail.localhost 说明安装成功
SSH 设置如下图所示:
安装新项目
- 从项目环境容器列表中选择一个合适的容器下载并解压到框架目录的 projects 文件夹下
- 解压后修改目录名为合适的名称
- 修改 .env 项目配置文件,主要是修改项目名和域名
- 运行批处理文件 start.cmd 初始化和开启容器
- 每次重启 Docker 后都需要运行所需项目的批处理文件 start.cmd 开启容器
通过 Tunnel 通道上传文件的 SSH 设置如下图所示: