[Docker] 用PHP7.4+Swoole+sdebug打开PHP的二次元世界
本文章是在macOS下操作的
- Linux环境雷同,Windows环境的。。。请安装Ubuntu或者黑苹果吧。
- swoole是不能跟xdebug共存的,还好,官方提供了sdebug可用于调试,https://github.com/swoole/sdebug
- swoole编译,实在是太慢了,要通过nfs挂载本地路径,就变成了飞一般的感觉
构建docker镜像
# @description php image base on the alpine 3.10 # ------------------------------------------------------------------------------------ # @link https://hub.docker.com/_/alpine/ alpine image # @link https://hub.docker.com/_/php/ php image # @link https://github.com/docker-library/php php dockerfiles # ------------------------------------------------------------------------------------ # @build-example docker build . -f Dockerfile -t ppwang/fpm74dev:2.0.0 FROM php:7.4.6-fpm-alpine3.11 LABEL maintainer="tech <tech@ppwang.com>" version="2.0.0" ############################################################################################ # ------------------------------ env settings --------------------------------------------- ############################################################################################ ARG timezone ENV TIMEZONE=${timezone:-"Asia/Shanghai"} ENV PHP_INI_DIR /usr/local/etc/php ENV LIBZIP_VERSION 1.5.2 ENV SWOOLE_VERSION 4.5.1 ENV SDEBUG_VERSION sdebug_2_9-beta ENV TIDEWAYS_XHPROF_VERSION 5.0.2 ENV PHPIZE_DEPS \ autoconf \ dpkg-dev \ dpkg \ file \ g++ \ gcc \ libc-dev \ make \ pkgconf \ re2c \ cmake # ======== You have to change this for your env ======== ENV NGINX_USER_ID 1001 ENV NGINX_GROUP_ID 1001 ############################################################################################ # ------------------------------ install --------------------------------------------- ############################################################################################ RUN set -ex \ # ---------------------------- set timezone ------------------------------------------------ && ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \ && echo "${TIMEZONE}" > /etc/timezone \ # ------------------------------ ensure nginx user exists ---------------------------------- && addgroup -g ${NGINX_USER_ID} -S nginx \ && adduser -u ${NGINX_GROUP_ID} -D -S -G nginx nginx \ # ------------------------------------- php ini folder ------------------------------------- && mkdir -p "$PHP_INI_DIR/conf.d" \ # ------------------------------ update software source ------------------------------------ && sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/' /etc/apk/repositories \ && apk update \ && apk add --no-cache --virtual .build-deps \ $PHPIZE_DEPS \ coreutils \ curl-dev \ libedit-dev \ libxml2-dev \ openssl-dev \ sqlite-dev \ icu-dev \ freetype-dev \ libjpeg-turbo-dev \ libpng-dev \ imagemagick \ imagemagick-dev \ gettext-dev \ libwebp \ libwebp-dev \ libxpm-dev \ libzip-dev \ && apk add --no-cache --virtual .persistent-deps \ imagemagick-libs \ gettext \ icu-libs \ && pecl update-channels # ------------------------------ php settings ---------------------------------------------- RUN set -ex \ && { \ echo "upload_max_filesize=32M"; \ echo "post_max_size=32M"; \ echo "memory_limit=128M"; \ echo "date.timezone=${TIMEZONE}"; \ echo "disable_functions=system,exec,shell_exec,passthru"; \ echo "error_log=/var/log/php/php_errors.log"; \ echo ";error_reporting=E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE"; \ echo "error_reporting=E_ALL"; \ echo "log_errors=on"; \ } | tee ${PHP_INI_DIR}/conf.d/zz-overrides.ini \ && cd /usr/src \ && docker-php-source extract \ && cd /usr/src/php \ && docker-php-ext-configure gd \ && docker-php-ext-install \ intl \ bcmath \ gettext \ gd \ pdo_mysql \ sockets \ sysvshm \ sysvmsg \ sysvsem \ zip \ pcntl # --------------------------------------------- pecl extension ----------------------------- RUN set -ex \ # Redis extension && pecl install redis \ && docker-php-ext-enable --ini-name 20-redis.ini redis RUN set -ex \ # ImageMagick && pecl install imagick \ && docker-php-ext-enable --ini-name 20-imagick.ini imagick RUN set -ex \ # mongodb && pecl install mongodb \ && docker-php-ext-enable --ini-name 20-mongodb.ini mongodb # --------------------------------------------- fpm settings --------------------------- RUN set -ex \ && cd /usr/local/etc \ && if [ -d php-fpm.d ]; then \ # for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf" sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \ cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \ else \ # PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency mkdir php-fpm.d; \ cp php-fpm.conf.default php-fpm.d/www.conf; \ { \ echo '[global]'; \ echo 'include=php-fpm.d/*.conf'; \ } | tee php-fpm.conf; \ fi \ && { \ echo "[global]"; \ echo "pid = /var/run/php-fpm.pid"; \ echo "error_log = /var/log/php/php-fpm.log"; \ echo "[www]"; \ echo "user = nginx"; \ echo "group = nginx"; \ echo "listen = 0.0.0.0:9740"; \ echo "pm.max_children = 150"; \ echo "request_slowlog_timeout = 5"; \ echo "slowlog = /var/log/php/php-fpm-slowlog.log"; \ echo "pm.start_servers = 5"; \ echo "pm.min_spare_servers = 4"; \ echo "pm.max_spare_servers = 32"; \ echo "pm.max_requests = 1024"; \ } | tee php-fpm.d/zz.conf # -------------------------------------- dev install -------------------------------- RUN set -ex \ && apk add --no-cache vim wget net-tools zip unzip apache2-utils git # ---------- install latest composer ---------- RUN set -ex \ && wget https://getcomposer.org/composer.phar \ && mv composer.phar /usr/local/bin/composer \ && chmod 755 /usr/local/bin/composer \ && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ # ---------- vim setting ---------- RUN set -ex \ && { \ echo "set pastetoggle=<F9>"; \ echo "set ts=4"; \ echo "set expandtab"; \ echo "set autoindent"; \ echo "set nu"; \ } | tee /etc/vim/vimrc # ---------- swoole extension ---------- RUN set -ex \ && cd /tmp \ && curl -SL "https://github.com/swoole/swoole-src/archive/v${SWOOLE_VERSION}.tar.gz" -o swoole.tar.gz \ && mkdir -p swoole \ && tar -xf swoole.tar.gz -C swoole --strip-components=1 \ && rm swoole.tar.gz \ && ( \ cd swoole \ && phpize \ && ./configure --enable-async-redis --enable-mysqlnd --enable-swoole-debug --enable-openssl \ && make -j$(nproc) && make install \ ) \ && echo "extension=swoole.so" > ${PHP_INI_DIR}/conf.d/20-swoole.ini # ---------- sdebug extension: xdebug of swoole ---------- RUN set -ex \ && cd /tmp \ && curl -SL "https://github.com/swoole/sdebug/archive/${SDEBUG_VERSION}.tar.gz" -o sdebug.tar.gz RUN set -ex \ && cd /tmp \ && mkdir -p sdebug \ && tar -xf sdebug.tar.gz -C sdebug --strip-components=1 \ && rm sdebug.tar.gz \ && ( \ cd sdebug \ && phpize \ && ./configure --enable-xdebug \ && make clean && make && make install \ ) \ && { \ echo "zend_extension=xdebug.so"; \ echo "xdebug.remote_autostart=on"; \ echo "xdebug.remote_enable=on"; \ echo "xdebug.remote_handler=dbgp"; \ echo "xdebug.remote_mode=req"; \ echo "xdebug.remote_host=192.168.56.1"; \ echo "xdebug.remote_port=9741"; \ echo "xdebug.collect_includes=on"; \ echo "xdebug.collect_params=1"; \ echo "xdebug.collect_return=1"; \ echo "xdebug.default_enable=on"; \ echo "xdebug.extended_info=1"; \ echo "xdebug.manual_url=http://www.php.net"; \ echo "xdebug.show_local_vars=0"; \ echo "xdebug.show_mem_delta=1"; \ echo "xdebug.max_nesting_level=1200"; \ echo "xdebug.auto_trace=0"; \ echo "xdebug.trace_format=1"; \ echo "xdebug.trace_output_dir=/var/log/php/xdebug"; \ echo "xdebug.trace_options=0"; \ echo "xdebug.trace_output_name="xdebug_trace_%t""; \ echo "xdebug.profiler_enable=0"; \ echo "xdebug.profiler_append=0"; \ echo "xdebug.profiler_enable_trigger=1"; \ echo "xdebug.profiler_output_dir=/var/log/php/xdebug"; \ echo "xdebug.profiler_output_name="xdebug_profiler_%t""; \ } | tee ${PHP_INI_DIR}/conf.d/20-sdebug.ini # ---------- Tideways XHProf Extension ---------- # !!!FBI WARNING!! This extension can NOT run with xdebug/sdebug together # So here we just compile this extension but not add to the php ini RUN set -ex \ && cd /tmp \ && curl -SL "https://github.com/tideways/php-xhprof-extension/archive/v${TIDEWAYS_XHPROF_VERSION}.tar.gz" -o php-xhprof-extension.tar.gz RUN set -ex \ && cd /tmp \ && mkdir -p php-xhprof-extension \ && tar -xf php-xhprof-extension.tar.gz -C php-xhprof-extension --strip-components=1 \ && rm php-xhprof-extension.tar.gz \ && ( \ cd php-xhprof-extension \ && phpize \ && ./configure \ && make clean && make && make install \ ) \ && echo "extension=tideways_xhprof.so" > ${PHP_INI_DIR}/conf.d/20-tideways_xhprof.ini_bak ############################################################################################ # ------------------------------------ cleaner --------------------------------------------- ############################################################################################ RUN set -ex \ # && apk del --no-network .build-deps \ # && apk del --no-network .fetch-deps \ # && apk del --no-network .persistent-deps \ && apk del --purge *-dev \ && rm -rf /tmp/pear ~/.pearrc \ && cd / \ && docker-php-source delete \ && rm -rf /var/cache/apk/* /tmp/* /usr/share/man \ && echo -e "\033[42;37m Build Completed :).\033[0m\n"
通过nfs加速swoole的编译速度
参考: [Docker] macOS Catalina下,docker-compose关联nfs
docker运行脚本及nginx相关配置文件
docker-compose.yml配置参考
version: '3' services: php74fpmdev: image: ppwang/fpm74dev:2.0.0 container_name: php74fpmdev ports: - 9740:9740 networks: # create the docker network first: docker network create local_default_network - local_default_network # create the docker network first: docker network create pp_service_network - pp_service_network volumes: - /System/Volumes/Data/Software/Project/docker/log/php-fpm-74:/var/log/php - data-volume:/System/Volumes/Data/Software/Project/pipi stdin_open: true tty: true privileged: true networks: local_default_network: external: true pp_service_network: external: true volumes: data-volume: driver: local driver_opts: type: "nfs" o: "addr=192.168.56.1,nolock,soft,rw" device: ":/System/Volumes/Data/Software/Project/pipi"
nginx配置参考
upstream swooleLive { # Connect IP:Port server php74fpmdev:5120 weight=5 max_fails=3 fail_timeout=30s; # Connect UnixSocket Stream file, tips: put the socket file in the /dev/shm directory to get better performance #server unix:/xxxpath/laravel-s-test/storage/laravels.sock weight=5 max_fails=3 fail_timeout=30s; #server 192.168.1.1:5200 weight=3 max_fails=3 fail_timeout=30s; #server 192.168.1.2:5200 backup; keepalive 16; } server { listen 80; server_name live.ppwang.mine; root /System/Volumes/Data/Software/Project/pipi/live.ppwang.com/public; access_log /var/log/nginx/access/live.ppwang.mine.log; error_log /var/log/nginx/error/live.ppwang.mine.log; autoindex off; index index.html index.htm; # Nginx handles the static resources(recommend enabling gzip), LaravelS handles the dynamic resource. location / { try_files $uri @laravelsLive; } # Response 404 directly when request the PHP file, to avoid exposing public/*.php #location ~* \.php$ { # return 404; #} location @laravelsLive { # proxy_connect_timeout 60s; # proxy_send_timeout 60s; # proxy_read_timeout 120s; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-PORT $remote_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header Scheme $scheme; proxy_set_header Server-Protocol $server_protocol; proxy_set_header Server-Name $server_name; proxy_set_header Server-Addr $server_addr; proxy_set_header Server-Port $server_port; proxy_pass http://swooleLive; } }
注意: 因为是通过swoole跑起来的,所以nginx就相当于反向代理了,所以才采取以上的配置方式。
PHPStorm配置
1. 配置docker环境
弄好了,点ok
弄好了点ok
然后就回到以下界面
调整debug的监听端口
至此,基本就完成了,可以开始调试了
进入容器内部
docker exec -it php74fpmdev /bin/sh
cd到项目根目录
cd /System/Volumes/Data/Software/Project/pipi/live.ppwang.com/
Go!
执行以下命令
php bin/laravels start
通过以上操作,nfs加速了swoole的启动速度,sdebug又可以去调试代码了。还等什么,赶紧进入到PHP的二次元世界吧!