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

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

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

    已有方案

    升级过程

    项目准备
    • 假设我现在的项目名为/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  
       13 天前
    @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
       9 天前
    @ywisax #12 可以, 不过我用的 roadrunner
    ywisax
        14
    ywisax  
       9 天前
    seth19960929
        15
    seth19960929  
    OP
       8 天前
    @ywisax #14 不是 swoole 的写法, octane 有自己的协程写法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2959 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:33 · PVG 20:33 · LAX 05:33 · JFK 08:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.