如何构建 php-fpm 镜像

在实际的项目部署中,我们有时候会遇到在一个服务器上部署多个 php 环境的情况。遇到这种情况,我们可以在同一物理机上装多个 php-fpm 监听不同端口,Nginx 根据不同的 Vhost 去找不同的 php-fpm 解析。 上述方法虽然可以,但是在项目管理上并不是很友好,比如我需要在某个项目执行 PHP 脚本,那还需要写 /path/php script.php 这样的话就需要每个维护项目的人都十分清楚,哪个项目应该用哪个版本的 PHP 去执行相应的脚本。 其次,如果某天需要把某个项目迁移到其他服务器了,我们还需要在新机器上安装 PHP 环境。 如果用 docker 进行部署,就不会有上面的问题,我们只需要写一次 Dockfile 可以在任何服务器上构建出相同的 php-fpm 环境,从而让迁移更简单,如果需要执行脚本,只需要进入对应的容器,直接执行 php script.php 即可。 php-fpm 官方镜像介绍 在 php Tags | Docker Hub 找到你所需的基础镜像的 tag 扩展安装 Docker PHP 安装有三种方式 Core Extensions: FROM php:8.2-fpm RUN apt-get update && apt-get install -y \ libfreetype-dev \ libjpeg62-turbo-dev \ libpng-dev \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) gd PECL extensions :...

November 17, 2023 · 2 min · 云溪

Dockerfile 介绍

Dockerfile 是用于构建镜像的脚本文件。在某些情况下,需要在基础镜像上加装一些软件,就需要使用 Dockerfile 来构建出自己所需的镜像。 指令介绍 指定基础镜像 ( FROM ) # 不指定版本则默认拉去 latest FROM nginx # 指定版本 FROM nginx:1.25.3 执行命令 ( RUN ) FROM nginx Run apt-get update \ && apt-get install -y --no-install-recommends git vim libpng-dev libjpeg-dev libfreetype6-dev 声明容器运行时监听的端口号( EXPOSE ) FROM nginx Run apt-get update \ && apt-get install -y --no-install-recommends git vim libpng-dev libjpeg-dev libfreetype6-dev EXPOSE 80 设置工作目录 ( WORKDIR ) FROM nginx Run apt-get update \ && apt-get install -y --no-install-recommends git vim libpng-dev libjpeg-dev libfreetype6-dev EXPOSE 80 WORKDIR /var/www 复制文件到容器目录 ( COPY ) FROM nginx Run apt-get update \ && apt-get install -y --no-install-recommends git vim libpng-dev libjpeg-dev libfreetype6-dev WORKDIR /www COPY ....

November 17, 2023 · 2 min · 云溪

docker 入门介绍

Docker 可以理解为一个轻量级虚拟机,你可以在一台物理机上,装 N 个系统,每个系统部署不同的服务。 Docker 有几个非常重要的概念:镜像、仓库、容器。 镜像:可以理解为操作系统的系统盘,用于给容器安装系统用的,你也可以基于别人的镜像创建自己的镜像。 仓库:用于存储镜像的仓库 容器:相当于虚拟出来的一台台主机,他有存储、网络、系统等关键要素。你可以在容器里部署任何你想要部署的服务。 镜像操作 你可以创建 ( docker build )、删除 ( docker rmi )、下载 ( docker pull ) 镜像 设置镜像源 Docker 官方镜像仓库,在国内下载比较慢,可以通过国内的镜像源来加速镜像下载。本文介绍 Windows 通过 Docker Desktop 换源,如果你是其他系统,可以自行搜索。 复制下面信息到 Docker Desktop 设置 "registry-mirrors": [ "https://hub-mirror.c.163.com", "https://mirror.baidubce.com" ] 创建镜像 ( docker build ) 前提是要有构建镜像所需的 Dockerfile,关于 Dockerfile 后面会有专门的文章进行讲解。 docker build -t image_name . 下载镜像 ( docker pull ) 这里就会通过仓库下载镜像到本机。 docker pull ubuntu 删除镜像 ( docker rmi ) docker rmi image_name 容器操作 容器操作分为:启动( docker run ),停止 ( docker stop ),删除 ( docker del ),执行 ( exec )、查看日志(docker logs)。...

November 17, 2023 · 2 min · 云溪

SOLID-开闭原则

开闭原则-对扩展开放,对修改关闭。 开闭原则要求在扩展新功能时应当避免对旧代码的改动。但现实的开发中,新增功能多数情况下都要涉及到旧代码的改动,这主要是因为在业务刚开始推进的时候并不能很清晰的看出业务的拓展方向,因此通常情况下都不会进行预留扩展的设计(避免过度设计)。 当扩展需求出现时,就是开始重构原有代码的时机,而开闭原则就是指导重构的主要思想,在重构过程中,应将此次扩展的业务方向做一个通用方案的处理,保证下次再出现同类型的扩展可以做到不改动或少改动旧代码。 依据开闭原则做架构设计时,我们应该清楚要保护什么,可以通过分层来决定保护级别,最高层的保护级别最高,最低层的保护级别最低。低层级的改动不会影响高层。 层级的划分可以根据业务来划分,核心业务逻辑应该是最高等级,其他层级根据与核心业务的关联程度依次向下划分等级。这样的划分逻辑我们能够保证核心业务规则不会因为其他相关模块的改动而受影响。 接下来通过《架构整洁之道》(clean architecture) 中的一张图来解释一下分层设计 图 8.2 < I > 表示接口,< DS > (data struct) 表示数据类,数据类的特性是第一次访问的时候会创建类,后续则是对该实体的读操作(实体类特性也是如此)。空心箭头表示对应接口的实现,实心箭头表示依赖关系, A->B 则是 A 依赖 B,A 知道 B 的存在,B 对 A 一无所知。 正是由于依赖的这种特性,我们可以把被保护的代码,写到被依赖的类中,这样被依赖的类不会以为依赖方代码的改动而受影响。 上图中:Interactor > (database) > Controller > Presenter 关于图 8.2 调用链路如下: 这种设计 Controller、Presenter、Database 任何模块代码的改动,都不会影响 Interactor ,从而达到了对 Interactor 代码的保护,如果某天对 Presenter 中的 PDF View 进行改动出现了 bug,仅仅印象 PDF View 这一个功能,把 bug 进行最大程度的隔离,实现功能的稳定。 总结 开闭原则保证了程序的扩展性,同时用分层的思想设计架构,通过依赖保护核心业务逻辑,避免核心逻辑的频繁改动,隔离低层代码的改动影响高层。 如果你对架构设局同样感兴趣,推荐给你一本书《架构整洁之道》(clean architecture) 。这本书对架构设计的讲解十分深刻,相信你也一定会有所收获。

August 20, 2023 · 1 min · 云溪

从面向接口编程看标准化问题

面向接口编程: 当一个实体依赖另一个实体时,不依赖实体而是依赖实体的抽象。 比如说生产一个电灯,电灯需要一个开关来控制电灯的点亮和关闭,如果电灯依赖某个具体的开关,,比如电灯出场内置开关依赖了 A 品牌,当有一天买电灯的客户家里是 B 品牌的开关,那么电灯就没办法使用了。但是如果我依赖的是开关的抽象接口,它提供打开和关闭两个行为给电灯,电灯根据打开和关闭的行为去控制电灯的点亮和关闭。 这种设计可以让生产的电灯适应市面上的所有开关,那怕未来实现了脑机接口的开关,只要这个它遵循开关的抽象提供打开和关闭两种行为,这款电灯就能受这种新开关的控制。 从上面例子上可以看出,所谓的接口是依赖双方提前的一种约定,依赖方按照这种约定去调用,被依赖方按照这种约定去实现,这种约定其实就是标准化,调用方按照约定去实现功能,使用方按照约定去使用功能。 标准化的好处 从上面的例子中可以看出,标准化带来最大的好处就是复用,你可以任意的生产各种各样的开关,只要是按照标准制定的,我的电灯都是可以使用的。 其次标准化会带来效率的提升,现实中交通规则就是一个很好的例子,交规就是一个标准, 只要是在路上的走的,都受到交规的约束,而正是有了这种约束我们才有了更高效的通勤,绿灯了可以走,红灯了,就停下来等待,我们对路上所有的车辆和行人的轨迹都有预期,从而提升通行效率。 可以设想一下没有交规,是一个什么样的场景,大概率会出现所有车辆堵在了路口,整个路口堵的水泄不通,最后整体通行效率变得无比低下。 标准化还会带来工具化,再拿生活中常见的交通为例,有了完善的交通规则,后续就可以生产适用这种规则的自动驾驶车辆,这将大大改善人们的出行效率。 标准化在工作中的用处 标准化在工作中也有着十分重要的作用,如今的工作大多都会有工种之间的划分,工种和工种之间就存在着依赖关系,上一个工种的工作要到什么程度,下一个工种应该怎么衔接,这就是一个依赖,而在这两个工种之间就需要一个明确的约定。 有了这种约定,可以减少很多不必要的沟通,不需要去关心上个工种的实现细节,只需要双方按照约定各自生产,在产品成型阶段把各个工种生产出的设备进行组装即可。 当公司来了新人的时候,他也不需要重新去每个环节去了解其他工种的产品特性,只需要去了解约定的标准化制度即可投入到生产中。 标准化的问题 标准化也并非都是好处,它在设计阶段需要投入相当的人力去设计,并且需要在后续的生产阶段通过实践中得到的反馈,去不断的完善标准。 如果标准设计的不好,频繁的变更标准,将会导致所有依赖的标准方都要进行变动,这种变动的成本是相当高的。 因此在标准设计的时候要进行必要的论证和演练,确保标准没有明显的问题,最大限度的减少标准化带来的成本。 总结 标准化相当于在一个有限范围内设计了一个小型的生态系统,标准化制定了基本的流程和规则,生态系统的其他元素按照这种流程和规则去演化出标准化所期望达成的效果。 标准化的制定是有难度的,有些时候仅从设计阶段,无法看到最终的结果,这时可以通过抓大放小的形式去解决。刨除细节,去设计整体框架,保证大方向的正确,在标准化实践的过程中去不断的丰富细节,完善标准,从而让标准化实现最终的落地。 可能某些情况下理想下的标准化永远也无法达成,但这不能成为放弃标准化的理由,不能因为我们理想是得到 100 分的好处,因为我们拿不到 100 分就放弃。拿不到 100 分,能拿 60 分也比一分都没有要好一些,你觉得呢?

August 7, 2023 · 1 min · 云溪