您现在的位置是:首页 > 技术教程 正文

如何用Docker构建PHP“全能“镜像 (一)

admin 阅读: 2024-03-15
后台-插件-广告管理-内容页头部广告(手机)

省流提示: 文中提到的功能都已经封装到示例镜像中,可以直接拉取使用,dockerfile 附在最后

docker pull leon19910505/php:8.1-allinone

构建全能PHP镜像

        Docker的方便就不用多说了,标准化可移植性,对宿主机无侵入,之前一直也是用docker作为本地的开发环境的,而docker hub上本身就提供各种版本的PHP镜像,为什么还要提出构建全能PHP镜像这个概念呢?有几个方面的原因:

  1. 需要自定义扩展,PHP的扩展安装极为不方便,pecl经常失败,手动编译就更折磨了,碰到个不熟的扩展,可能一个扩展就要耗费一天时间,官方的PHP镜像有提供常用扩展安装方式,但是像 xdebug,swoole,redis这种,还是需要自己安装的
  2. 需要定制一些开发工具,比如内置 composer,Nginx,git,vim
  3. 加入一些系统增强,比如zsh,ohmyzsh,可以提高效率

安装扩展

强烈推荐这个项目: docker-php-extension-installer

具体用法非常的简单:

  1. FROM php:7.2-cli
  2. //在dockerfile文件中通过ADD方法把这个二进制安装包下载下来
  3. ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
  4. //然后就可以用install-php-extensions 加上扩展名进行安装
  5. RUN chmod +x /usr/local/bin/install-php-extensions && \
  6. install-php-extensions gd xdebug ...

重点: 镜像在构建时,请用科学 . 上网!!!!

这个要点是保障你不要在网络上面踩坑 (我已经踩过了),尽量买一些质量好的机场服务,因为你的时间成本远比那几十块钱要贵!!

在使用科学 . 上网时需要注意,目前大多的科学 . 上网软件都是分上网模式的,默认都是规则判断连接,而且这个代理它只代理你的浏览器,并不代理你的终端!所以很多同学可能会踩坑:  明明开了代理了,为什么docker build的时候仍然很慢!这里给两个方法:

1. 打开全局模式

2. 在终端命令行中显示指定 http 代理,比如这样

export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890

如果你不清楚这个命令怎么来的,打开你的上网软件,基本都有一栏类似 "复制终端代理命令"的选项,

不同软件默认监听的端口不一样,不要照抄上面这条命令

这个技巧可以用在很多场景下,像docker拉取image, npm / pip / composer install 等各种包管理器安装package,都很适用,虽然可以配置各种镜像仓库地址,但肯定没有官方仓库来的可靠和稳妥,特别是npm我就遇到很多淘宝源安装报错的情况

集成Nginx

        通常来说部署PHP应用还需要用到 web server,最常用的就是nginx,而nginx和PHP要通信还必须在同一个网络中,并且共同挂载项目目录,虽然可以通过docker-compose实现这个过程,但是相对麻烦了些,所以可以简化这一步,把nginx也封装到镜像中,这样只要运行一个容器就可以支持整个PHP开发环境了。 

增强Shell :zsh + ohmyzsh + auto-suggestions

        有一个好用,强大的shell方案可以极大提高后端开发的效率,这里采用 item2 下非常流行的 ohmyzsh方案,以及必备插件 auto-suggestions。关于ohmyzsh的应用网上文章很多,建议找一些学习一下,是一个后端必备工具。

Composer

        安装就不说了,最主要是把镜像配上,可选阿里云composer镜像:

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

常用工具类命令

        支持 git ,vim ,ps,ping 等命令。

Xdebug使用

        xdebug非常重要,应该说任何语言的debug能力都非常重要,面对复杂项目和代码,它是我们最有力的助手,强烈建议大家掌握这个技能。

        PHP有两个运行场景:http 和 cli 命令行, http就是我们最常用的接口开发后,使用http请求api进行测试,cli通常是一些脚本命令执行调试,类似 laravel下的command。

        下面这些实践都是基于phpstorm,理解之后其他 ide (比如vscode )可以自行配置。

xdebug配置文件

  1. [xdebug]
  2. xdebug.mode = debug
  3. xdebug.client_port = 9000
  4. xdebug.client_host = host.docker.internal
  5. xdebug.idekey = PHPSTORM
  6. xdebug.discover_client_host = no
  7. xdebug.start_with_request = yes
  8. xdebug.log_level = 0

这是一份 xdebug3的配置文件,解释一下需要关注的几个参数:

client_port : xdebug监听的端口,需要和ide的配置端口保持一致,默认9000

client_host: 这里写的host.docker.internal 是docker desktop 的一个特殊host映射,会指向主机的ip(只在docker容器内生效,宿主机是无法直接ping这个host的),配置host的目的是为了知道向哪里转发这个连接

start_with_request:  顾名思义,请求过来的时候会自动唤起ide,用起来比较方便

http触发

在docker中使用xdebug会涉及到路径映射的问题,所以需要设置一下,第一次请求时因为xdebug的配置中: xdebug.start_with_request = yes

所以phpstorm应该会自动调起,并且会报一个路径找不到错误,我们去phpstorm的debug配置下,修改server中的path映射,如下图在红框处写入 /www 就搞定了(因为我在docker-compose中把项目根目录映射在了docker容器中的/www)

另外默认的xdebug.ini配置文件的端口写的是9000,如果你需要修改,注意ini文件和ide修改一致

cli触发

cli命令行触发,需要在shell中增加对应xdebug环境变量 (示例镜像中已封装):

  1. export XDEBUG_CONFIG="xdebug.mode=debug xdebug.start_with_request=yes xdebug.client_host=host.docker.internal xdebug.client_port=9000 xdebug.idekey = PHPSTORM"
  2. export PHP_IDE_CONFIG="serverName=local.com"

构建Dockerfile

除了Dockerfile文件外还有几个依赖的静态文件,放到同一目录下,tree结构如下:

Dockerfile

  1. FROM php:8.1-fpm-alpine3.16
  2. LABEL MAINTAINER="leon19910505@163.com"
  3. #composer
  4. RUN curl -sSL https://getcomposer.org/download/latest-stable/composer.phar -o /usr/local/bin/composer && chmod +x /usr/local/bin/composer
  5. #composer镜像
  6. RUN composer config -g repo.packagist composer https://mirrors.aliyun.com/composer
  7. #安装一些工具软件
  8. RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories
  9. RUN apk update && apk add --no-cache nginx vim git zsh tzdata
  10. #修改时区
  11. RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
  12. echo 'Asia/Shanghai' > /etc/timezone && \
  13. echo "date.timezone=Asia/Shanghai" > /usr/local/etc/php/conf.d/timezone.ini
  14. #ohmyzsh定制安装
  15. RUN sh -c "$(wget -O- https://gitee.com/leon19910505/ohmyzsh/raw/master/tools/install.sh)"
  16. #下载扩展安装脚本
  17. ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
  18. #给脚本可执行权限
  19. RUN chmod +x /usr/local/bin/install-php-extensions
  20. #安装扩展,这里分写多行是因为想充分利用缓存,如果某一个扩展安装失败下次重试的时候前面的构建就可以直接跳过
  21. #如果担心镜像体积,可以构建完成之后优化,消除镜像层
  22. RUN install-php-extensions redis bcmath pdo_mysql xdebug opcache
  23. RUN install-php-extensions gd imagick pdo_pgsql zookeeper swoole
  24. RUN install-php-extensions zip uuid rdkafka
  25. RUN install-php-extensions mcrypt
  26. RUN install-php-extensions protobuf
  27. RUN install-php-extensions grpc
  28. #nginx配置文件
  29. ADD nginx.conf /etc/nginx/http.d/default.conf
  30. #xdebug配置文件
  31. ADD xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini
  32. #定义一个sh脚本作为Entrypoint,因为要同时执行php-fpm和nginx
  33. #这里的策略是把PHP以daemon模式运行,nginx挂起
  34. ADD entrypoint.sh /entrypoint.sh
  35. #xdebug从cli启动的配置
  36. RUN echo 'export XDEBUG_CONFIG="xdebug.mode=debug xdebug.start_with_request=yes xdebug.client_host=host.docker.internal xdebug.client_port=9000 xdebug.idekey = PHPSTORM"' >> ~/.zshrc && echo 'export PHP_IDE_CONFIG="serverName=local.com"' >> ~/.zshrc
  37. #定义工作目录,运行容器时通常把项目代码挂载到该目录
  38. WORKDIR /www
  39. ENTRYPOINT [ "/entrypoint.sh" ]

entrypoint.sh

  1. #!/usr/bin/env sh
  2. set -e
  3. php-fpm -D
  4. nginx -g 'daemon off;'

nginx.conf

  1. server {
  2. listen 80;
  3. server_name local.com;
  4. root /www/public;
  5. index index.php;
  6. charset utf-8;
  7. location / {
  8. root /www/public;
  9. if (!-e $request_filename) {
  10. rewrite ^/index.php(.*)$ /index.php?s=$1 last;
  11. rewrite ^(.*)$ /index.php?s=$1 last;
  12. break;
  13. }
  14. }
  15. location ~ .+\.php($|/) {
  16. fastcgi_pass 127.0.0.1:9000;
  17. fastcgi_index index.php;
  18. fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  19. include fastcgi_params;
  20. }
  21. }

xdebug.ini

  1. [xdebug]
  2. xdebug.mode = debug
  3. xdebug.client_port = 9000
  4. xdebug.client_host = host.docker.internal
  5. xdebug.idekey = PHPSTORM
  6. xdebug.discover_client_host = no
  7. xdebug.start_with_request = yes
  8. xdebug.log_level = 0

给这个镜像起了个名称: all in one ,详细使用方法请看第二章节

Docker PHP“全能“镜像使用手册

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索
排行榜