zzxworld

使用 Docker 的容器化 PHP 开发环境实践

最近把系统工作环境迁移到了 Arch Linux,目前使用体验一切良好,而且正在陆续补充各种自己觉得需要的工具和软件。PHP 作为吃饭的工具,自然是必不可少的。所以今天就来分享一下自己是如何通过 Docker 来搭建 PHP 开发环境的。

为什么选择 Docker

关于 PHP 开发环境的搭建方式有很多。比如我前面就分享过一篇在 Linux 系统下,如何通过包管理工具和源码编译来完成 PHP 开发环境的搭建。链接在此:

Arch Linux 系统搭建 PHP 开发环境

这是我以前采用过的开发环境搭建方式,现在我会称它们为“过时的方法”。因为目前我更倾向于使用 Docker 来搭建自己的开发环境。和其他方式比较,我选择 Docker 的原因如下:

  1. 可以保持系统软件环境的纯净。这一点对于喜欢折腾各种工具软件,然后把系统依赖环境搞的一团糟的我来说,特别受用。

  2. 开发环境和当前使用系统不再强依赖。在接触 Docker 之前,我的主力开发设备是一台 MBP,每年出了新系统后都会有一段要重新编译各种开发工具的阵痛,因为系统环境和依赖组件的版本都有变化了。

    在最新的系统上解决各种软件依赖对我来说是一项很痛苦的工作。而 Docker 很好的解决了这个问题。无论系统再怎么升级,都不会再影响到我的开发环境。即便是我的开发环境已经从 macOS 系统换成了 Linux 系统,开发环境毫无大碍。

  3. 开发软件的管理方式更加统一。各种编程语言都有各自的安装流程和步骤,各种应用服务的安装和配置方式也千差万别。通过 Docker,从一个更高的维度抽象和统一了这些差异。不论是 MySQL,还是 Redis,我都只需要拉镜像,映射端口,然后启动容器就行了。

而受益上面这些好处的唯一成本,就是安装一下 Docker 运行环境。这和之前要管理维护各种安装脚本,并处理执行报错的时间相比,完全不叫事儿。如果你还不熟悉 Docker 的安装,可以看看我前面总结的一篇记录文章:《Docker 安装指南》。

拿我这次工作系统迁移到 Arch Linux 举例。如果不使用 Docker,按之前习惯通过源码编译的方式来操作,乐观估计要半天时间才能完成 PHP 开发环境的搭建。而通过 Docker,一个小时都不到,其中主要时间还都是耗费在拉镜像上。

我的搭建思路

使用 Docker 构建开发环境的思路有很多。按我的理解总结一下,大致如下:

  • 项目私有的方式。即每个项目都使用独立的镜像和容器。
  • 全局服务方式。当前开发环境下所有项目都使用一套公共的镜像和容器。
  • 单体方式。这是从另一个唯度来衡量,也就是在构建镜像时就把所有工具都放到一个镜像里面。比如把 node.js,PHP,Python 都放到一起。
  • 分散方式。和单体方式相反,不同的工具都各自独立,需要用哪个就调用相应的容器。

我曾一直想从这些方式中找到一个绝对合理的选择。不过失败了,正所谓:存在即合理。它们虽然都有各自的问题,但也有值得采纳的好处。所以我最终妥协了,得出的结论就是根据自己的实际需要来综合使用。

对于我目前在 PHP 开发上的需求来说,因为项目多而杂,采用项目私有的方式带来的问题就是需要启动过多容器,浪费计算资源。以我的使用场景来衡量,这超过了它能带来的好处。所以我倾向于采用全局服务式。启动一个 PHP 镜像就能服务多个项目。

而工具层面是构建成单体还是分散按需使用,要看具体情况。比如前端打包要用到的 node.js,我就不会构建到 PHP 的镜像里,因为它和后端的语言没有什么依赖关系。而 PHP 的包管理工具 Composer,虽然理论上来说也可以独立使用,但因为其相关指令需要检测当前运行环境的 PHP 版本,所以我还是会选择构建到自己的 PHP 镜像里。

我的 Docker 开发环境

以上是理论部分,接下来介绍一下我目前正在使用 Docker 给 PHP 搭建的开发环境。先来看看目录结构。

目录结构

这套 PHP 开发环境的大致目录结构主要如下:

.
├── docker-compose.yml
├── bin/
│   ├── artisan
│   ├── composer
│   ├── envoy
│   ├── node
│   ├── npm
│   ├── php
│   ├── restart-docker-services
│   └── yarn
├── mysql/
│   └── data/
├── nginx/
│   └── conf.d/
│       ├── default.conf
│       ├── zzxworld-homepage.conf
│       └── zzxworld-blogfinder.conf
├── php/
│   ├── bin/
│   │   ├── add_user.sh
│   │   ├── clean.sh
│   │   ├── config_php_composer.sh
│   │   ├── config_php_fpm.sh
│   │   ├── config_system_mirror.sh
│   │   ├── install_php_extension.sh
│   │   └── install_system_package.sh
│   └── Dockerfile
└── redis/
    ├── data/
    └── redis.conf

这里针对主要文件做一个解释:

  • docker-composer.yml:是这套开发环境的主配置文件。
  • bin/:开发环境要用到的各种命令,基于各种单独的镜像和运行中容器。
  • mysql/:MySQL 的配置目录,有一个 data 子目录,用来映射并存放 MySQL 数据。
  • nginx/:Nginx 的配置目录,每个项目的配置文件都会存放到它下面的 conf.d 目录里。
  • php/:PHP 的配置目录。因为牵涉到自定义扩展,所以这里会有 Dockerfile 构建文件。bin 目录是构建自定义镜像时需要的各种脚本。
  • redis/:Redis 的配置目录。data 是用来映射 Redis 运行时的数据目录。

如何使用

在新的电脑环境上,我只需要先安装好 Docker,然后复制这个目录。在这个目录下执行以下指令:

docker-composer build
docker-composer up -d

PHP 开发环境就运行起来了。

总结

我这次迁移到 Arch Linux 系统,能快速完成 PHP 开发环境的搭建,主要就是依赖于 Docker 提供的容器化服务。推荐还没有充分使用 Docker 的朋友多关注一下它。作为一名开发者,Docker 绝对会让你受益无穷。

另外,我目前还有没公开这套开发环境具体代码的意愿。虽然它让我用着很方便,但其中也掺杂者一些“写死”的个人数据。如果你有这方面的问题需要帮助,可以通过评论留言,我定会知无不言。同时也欢迎通过评论发表你对此的看法和意见。