V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
seth19960929
V2EX  ›  PHP

记一次 Laravel5 升级到 Laravel10 经过 + 使用 octane 进行容器化

  •  
  •   seth19960929 · 14 天前 · 865 次点击

    已有方案

    升级过程

    项目准备
    • 假设我现在的项目名为/var/www/monday-shop
    • monday-shop项目内创建一新的laravel项目(同一个项目内方便复制粘贴文件)
      • composer create-project laravel/laravel=10.* laravel10
      • 这时候项目内多了一个/var/www/monday-shop/laravel10
    依赖处理
    • 更新依赖
      • /var/www/monday-shop/laravel10/composer.jsonrequirerequire-dev部分更新到/var/www/monday-shop/composer.json(注意删除旧版本的部分)
      • 删除/var/www/monday-shop/composer.lock
    • 安装依赖
      1. 运行composer install, 这时候会出现很多错误, 只能照着报错不断更新依赖
      2. 如果报错类似下面的问题, 就去github找到ramsey/uuid设配的版本, 然后修改composer.json文件, 重复执行1, 2步骤
    composer install
    No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information.
    Loading composer repositories with package information
    Updating dependencies
    Your requirements could not be resolved to an installable set of packages.
    
      Problem 1
        - laravel/framework[v10.10.0, ..., v10.48.4] require ramsey/uuid ^4.7 -> found ramsey/uuid[4.7.0, ..., 4.7.5] but it conflicts with your root composer.json require (^3.8).
    
    • 升级之后, 如果不确定这个依赖是否有用, 执行composer depends xxx/xxxx来查看是否有用, 如果不用到删除即可

    文件更改

    • 复制/var/www/monday-shop/laravel10的基础文件到/var/www/monday-shop/
    ├─app
    │  ├─Console
    │  ├─Exceptions
    │  ├─Http
    │  │  ├─Controllers
    │  │  └─Middleware
    │  ├─Models
    │  └─Providers
    ├─bootstrap
    │  └─cache
    ├─config
    ├─database
    │  ├─factories
    │  ├─migrations
    │  └─seeders
    ├─public
    ├─resources
    │  ├─css
    │  ├─js
    │  └─views
    ├─routes
    ├─storage
    │  ├─app
    │  ├─framework
    │  └─logs
    ├─tests
    │  ├─Feature
    │  └─Unit
    
    • 例如app/Exceptions/Handler.php,app/Http/Kernel.php等等, 这些文件复制内容的时候需要仔细对比是否自己修改过
    1. 我处理的时候一般一个文件夹一个文件夹处理, 比如从app/Console开始处理
    2. 处理完之后删除app/Console目录(删除目录是/var/www/monday-shop/laravel10)
    3. 下一个目录是app/Exceptions, 重复1, 2 步骤, 直至/var/www/monday-shop/laravel10目录为空

    处理报错

    • 运行服务: php artisan serve
    • 运行之后如果有报错按需解决, 服务启动之后, 查看storage/logs下的目录错误, 按需解决
    • 可能遇到的laravelhelpers函数不存在执行composer require laravel/helpers

    容器化

    composer require laravel/octane
    
    .rr.yaml
    • 如果出现: RoadRunner can't communicate with the worker
    • 请修改.rr.yaml为下面的配置, 主要是logs.channels的配置为标准输出
    version: '3'
    rpc:
      listen: 'tcp://127.0.0.1:6001'
    server:
      command: ""
      relay: pipes
    http:
      middleware: [ "static", "gzip", "headers" ]
      max_request_size: 20
      access_logs: false
      static:
        dir: "public"
        forbid: [ ".php", ".htaccess" ]
      uploads:
        forbid: [".php", ".exe", ".bat", ".sh"]
      address: "0.0.0.0:2114"
      pool:
        allocate_timeout: 10s
        destroy_timeout: 10s
        supervisor:
          max_worker_memory: 256
          exec_ttl: 60s
    ## 这里注意如果要输出标准输出必须在 channels 才会写 stdout
    logs:
      mode: production
      level: debug
      encoding: console
      output: stderr
      err_output: stderr
      channels:
        http:
          mode: production
          level: panic
          encoding: console
          output: stdout
          err_output: stderr
        server:
          mode: production
          level: info
          encoding: json
          output: stdout
          err_output: stdout
        rpc:
          mode: production
          level: debug
          encoding: console
          output: stderr
          err_output: stdout
    status:
      address: localhost:2114
    
    
    Dockerfile
    FROM composer:latest AS vendor
    
    FROM php:8.2-cli-bookworm AS base
    ARG TZ=PRC
    ENV DEBIAN_FRONTEND=noninteractive \
      TERM=xterm-color \
      OCTANE_SERVER=roadrunner \
      ROOT=/var/www \
      COMPOSER_FUND=0 \
      COMPOSER_MAX_PARALLEL_HTTP=24
    
    WORKDIR ${ROOT}
    
    SHELL ["/bin/bash", "-eou", "pipefail", "-c"]
    
    RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \
      && echo ${TZ} > /etc/timezone
    
    ################################################################################################
    ## 安装依赖
    ################################################################################################
    ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
    RUN apt-get update; \
      apt-get upgrade -yqq; \
      apt-get install -yqq --no-install-recommends --show-progress \
      apt-utils \
      curl \
      wget \
      nano \
      ncdu \
      ca-certificates \
      supervisor \
      libsodium-dev \
      # Install PHP extensions
      && install-php-extensions \
      bz2 \
      pcntl \
      mbstring \
      bcmath \
      sockets \
      pgsql \
      pdo_pgsql \
      opcache \
      exif \
      pdo_mysql \
      zip \
      intl \
      gd \
      redis \
      rdkafka \
      memcached \
      igbinary \
      ldap \
      && apt-get -y autoremove \
      && apt-get clean \
      && docker-php-source delete \
      && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
      && rm /var/log/lastlog /var/log/faillog
    
    
    ################################################################################################
    ## 复制代码文件和部署文件
    ################################################################################################
    COPY  . .
    COPY deployment/supervisord.*.conf /etc/supervisor/conf.d/
    COPY deployment/php.ini ${PHP_INI_DIR}/conf.d/99-octane.ini
    COPY deployment/start-container /usr/local/bin/start-container
    
    ################################################################################################
    ## 安装依赖
    ################################################################################################
    COPY --from=vendor /usr/bin/composer /usr/bin/composer
    RUN composer install \
      --no-dev \
      --no-interaction \
      --no-ansi
    RUN if composer show | grep spiral/roadrunner-cli >/dev/null; then \
      ./vendor/bin/rr get-binary; else \
      echo "`spiral/roadrunner-cli` package is not installed. Exiting..."; exit 1; \
      fi
    
    ################################################################################################
    ## 权限目录设置
    ################################################################################################
    RUN chmod +x rr /usr/local/bin/start-container
    RUN mkdir -p \
      storage/framework/{sessions,views,cache,testing} \
      storage/logs \
      bootstrap/cache && chmod -R a+rw storage
    
    ENTRYPOINT ["start-container"]
    
    HEALTHCHECK --start-period=5s --interval=2s --timeout=5s --retries=8 CMD php artisan octane:status || exit 1
    
    
    php.ini
    [PHP]
    post_max_size = 100M
    upload_max_filesize = 100M
    expose_php = 0
    realpath_cache_size = 16M
    realpath_cache_ttl = 360
    
    ;; 使用 roadrunner 开不开 opcache 影响不大
    [Opcache]
    opcache.enable = 1
    opcache.enable_cli = 0
    opcache.memory_consumption = 128M
    opcache.use_cwd = 0
    opcache.max_file_size = 0
    opcache.max_accelerated_files = 32531
    opcache.validate_timestamps = 0
    opcache.file_update_protection = 0
    opcache.interned_strings_buffer = 16
    opcache.file_cache = 60
    
    [JIT]
    opcache.jit_buffer_size = 64M
    opcache.jit = function
    opcache.jit_prof_threshold = 0.001
    opcache.jit_max_root_traces = 2048
    opcache.jit_max_side_traces = 256
    
    [zlib]
    zlib.output_compression = On
    zlib.output_compression_level = 9
    
    
    start.container
    #!/usr/bin/env bash
    set -e
    
    container_mode=${CONTAINER_MODE:-http}
    octane_server=${OCTANE_SERVER}
    echo "Container mode: $container_mode"
    
    initialStuff() {
        php artisan config:cache;
    }
    
    if [ "$1" != "" ]; then
        exec "$@"
    elif [ ${container_mode} = "http" ]; then
        echo "Octane Server: $octane_server"
        initialStuff
        exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.roadrunner.conf
    elif [ ${container_mode} = "scheduler" ]; then
        initialStuff
        exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.scheduler.conf
    elif [ ${container_mode} = "worker" ]; then
        initialStuff
        exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.worker.conf
    else
        echo "Container mode mismatched."
        exit 1
    fi
    
    
    supervisord.roadrunner.conf
    [supervisord]
    nodaemon=true
    user=root
    logfile=/dev/stdout
    logfile_maxbytes=0
    pidfile=/var/run/supervisord.pid
    
    [supervisorctl]
    serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL  for a unix socket
    
    [unix_http_server]
    file=/var/run/supervisor.sock   ; (the path to the socket file)
    chmod=0700                       ; sockef file mode (default 0700)
    
    [program:octane]
    process_name=%(program_name)s_%(process_num)02d
    command=php %(ENV_ROOT)s/artisan octane:start --server=roadrunner --host=0.0.0.0 --port=8080 --rpc-port=6001 --workers=4 --log-level=warn --max-requests=0 --rr-config=%(ENV_ROOT)s/deployment/.rr.yaml
    autostart=true
    autorestart=true
    environment=LARAVEL_OCTANE="1"
    stdout_logfile=/dev/stdout
    stdout_logfile_maxbytes=0
    stderr_logfile=/dev/stderr
    stderr_logfile_maxbytes=0
    
    

    结束

    • 之后就可以愉快的运行了
    15 条回复    2024-05-03 21:47:07 +08:00
    defunct9
        1
    defunct9  
       14 天前
    疯了吧,还在用 supervisord 这种上古的东西
    pota
        2
    pota  
       14 天前
    @defunct9 #1 有什么好用的替代吗?
    IdJoel
        3
    IdJoel  
       14 天前
    laravel 的版本还是得慢慢升,一下升级这么多版本还是挺麻烦的
    aababc
        4
    aababc  
       14 天前
    @defunct9 我们也使用这个
    seth19960929
        5
    seth19960929  
    OP
       14 天前
    @defunct9 #1 建议说一下你用什么呢? 我猜 linux 很古老, 怎么还有人用
    seth19960929
        6
    seth19960929  
    OP
       14 天前
    @IdJoel #3 暂时没遇到什么大问题, 上了 arms 监控小修小补, 感概 PHP 真的兼容太牛了
    pota
        7
    pota  
       14 天前
    @seth19960929 #6 我把公司的从 laravel5 升级到 8 不敢再升级了
    xiaoriri666
        8
    xiaoriri666  
       14 天前
    @seth19960929 #5 我推荐一个 pm2
    seth19960929
        9
    seth19960929  
    OP
       13 天前 via Android
    @xiaoriri666 pm2 怎么敢出来碰瓷 supervisor 得🤭
    seth19960929
        10
    seth19960929  
    OP
       13 天前 via Android
    我的印象里就只有在 node 会用,有人在其他场景用吗
    fengci
        11
    fengci  
       13 天前
    优秀,supervisord 有什么替换的吗?感觉用这也还好啊
    ywisax
        12
    ywisax  
       10 天前
    octane swoole ,目前能上协程了吗?
    seth19960929
        13
    seth19960929  
    OP
       10 天前
    @ywisax #12 可以, 不过我用的 roadrunner
    ywisax
        14
    ywisax  
       9 天前
    seth19960929
        15
    seth19960929  
    OP
       9 天前
    @ywisax #14 不是 swoole 的写法, octane 有自己的协程写法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   994 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:38 · PVG 06:38 · LAX 15:38 · JFK 18:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.