统信UOS服务器版 PHP全版本兼容部署教程

  一、先搞清楚统信UOS是什么
                                                                                                                          统信UOS = 统信软件开发的国产Linux系统,分几个版本:
                                                                                                                          统信UOS家族
  ├── 桌面版(个人/企业桌面)
  ├── 服务器版 V20(生产环境用这个)
  │   ├── 基于 Debian 系(amd64/arm64/mips64el/loongarch64)
  │   └── 包管理器用 apt,不是 yum!
  └── 专业版

  和麒麟的区别:
  - 麒麟 = 基于RHEL/CentOS系,用 yum/dnf
  - 统信UOS = 基于Debian系,用 apt
  - 这个区别非常重要,装软件命令完全不同

  ---
  二、系统初始化

  2.1 查看系统基本信息

  # 查看系统版本
  cat /etc/os-release
  # 输出类似:
  # NAME="UnionTech OS Server 20"
  # VERSION="20"

  # 查看CPU架构(信创关键)
  uname -m
  # aarch64  = 鲲鹏/飞腾(ARM64)
  # x86_64   = 普通Intel/AMD
  # mips64el = 龙芯老架构
  # loongarch64 = 龙芯新架构

  # 查看内核版本
  uname -r

  # 查看内存和CPU
  free -h
  nproc
  lscpu

  2.2 配置apt源(这是统信UOS最关键的一步)

  # 备份原有源
  cp /etc/apt/sources.list /etc/apt/sources.list.bak

  # 查看当前源
  cat /etc/apt/sources.list

  统信UOS服务器版官方源配置(根据架构选择):

  # x86_64 架构
  cat > /etc/apt/sources.list << 'EOF'
  deb [by-hash=force] https://professional-packages.chinauos.com/server-enterprise/eagle/sp3 eagle/sp3 main contrib
  non-free
  deb [by-hash=force] https://professional-packages.chinauos.com/server-enterprise/eagle/sp3 eagle/sp3-security main
  contrib non-free
  deb [by-hash=force] https://professional-packages.chinauos.com/server-enterprise/eagle/sp3 eagle/sp3-updates main
  contrib non-free
  EOF

  # ARM64 架构(鲲鹏/飞腾)
  cat > /etc/apt/sources.list << 'EOF'
  deb [by-hash=force] https://professional-packages.chinauos.com/server-enterprise-arm/eagle/sp3 eagle/sp3 main contrib
  non-free
  deb [by-hash=force] https://professional-packages.chinauos.com/server-enterprise-arm/eagle/sp3 eagle/sp3-security main
   contrib non-free
  deb [by-hash=force] https://professional-packages.chinauos.com/server-enterprise-arm/eagle/sp3 eagle/sp3-updates main
  contrib non-free
  EOF

  # 更新软件包列表
  apt update

  # 升级系统(可选,生产环境谨慎)
  apt upgrade -y

  2.3 安装基础工具

  apt install -y \
      curl wget git vim \
      build-essential \
      software-properties-common \
      apt-transport-https \
      ca-certificates \
      gnupg2 \
      lsb-release \
      net-tools \
      htop \
      unzip

  2.4 关闭不必要的服务

  # 统信UOS默认没有firewalld,用的是ufw或iptables
  # 查看防火墙状态
  ufw status

  # 开发阶段可以关闭
  ufw disable

  # 生产环境按需开放端口
  ufw allow 80/tcp
  ufw allow 443/tcp
  ufw allow 22/tcp
  ufw enable

  ---
  三、PHP全版本兼容方案设计

  核心思路:用 ondrej/php PPA源,可以同时安装 PHP 5.6 / 7.0 / 7.1 / 7.2 / 7.3 / 7.4 / 8.0 / 8.1 / 8.2 / 8.3,通过
  update-alternatives 或 php-fpm 多实例切换。

  服务器上同时运行:
  ├── PHP 7.4-FPM  监听 9074端口  → 老项目A
  ├── PHP 8.1-FPM  监听 9081端口  → 新项目B
  ├── PHP 8.2-FPM  监听 9082端口  → 新项目C
  └── Nginx 根据域名/路径分发到不同PHP版本

  ---
  四、添加PHP多版本源

  方案A:ondrej PPA源(推荐,版本最全)

  # 添加ondrej PHP源的GPG密钥
  curl -fsSL https://packages.sury.org/php/apt.gpg | gpg --dearmor -o /usr/share/keyrings/php-archive-keyring.gpg

  # 添加源(统信UOS基于Debian,用debian的源)
  echo "deb [signed-by=/usr/share/keyrings/php-archive-keyring.gpg] https://packages.sury.org/php/ $(lsb_release -sc)
  main" \
      > /etc/apt/sources.list.d/php.list

  # 更新
  apt update

  ▎ 网络不通怎么办? 统信UOS内网环境常见,用下面的离线方案

  方案B:离线安装(内网/断网环境)

  # 在有网络的同架构机器上下载deb包
  # 以PHP8.1为例
  apt-get download php8.1 php8.1-fpm php8.1-cli php8.1-common \
      php8.1-mysql php8.1-curl php8.1-gd php8.1-mbstring \
      php8.1-xml php8.1-zip php8.1-redis php8.1-opcache

  # 打包传到目标服务器
  tar -czf php81_packages.tar.gz *.deb
  scp php81_packages.tar.gz user@target-server:/tmp/

  # 在目标服务器上安装
  cd /tmp
  tar -xzf php81_packages.tar.gz
  dpkg -i *.deb
  # 修复依赖
  apt-get install -f

  方案C:编译安装(架构兼容性最强,龙芯/飞腾推荐)

  # 安装编译依赖
  apt install -y \
      gcc g++ make cmake autoconf \
      libxml2-dev libssl-dev libcurl4-openssl-dev \
      libjpeg-dev libpng-dev libfreetype6-dev \
      libzip-dev libonig-dev libsqlite3-dev \
      libbz2-dev libreadline-dev libxslt1-dev \
      pkg-config re2c bison

  # 下载PHP源码
  PHP_VERSION="8.1.28"
  cd /usr/local/src
  wget https://www.php.net/distributions/php-${PHP_VERSION}.tar.gz
  tar -zxvf php-${PHP_VERSION}.tar.gz
  cd php-${PHP_VERSION}

  # 编译配置(生产环境推荐配置)
  ./configure \
      --prefix=/usr/local/php81 \
      --with-config-file-path=/usr/local/php81/etc \
      --with-config-file-scan-dir=/usr/local/php81/etc/conf.d \
      --enable-fpm \
      --with-fpm-user=www-data \
      --with-fpm-group=www-data \
      --enable-mysqlnd \
      --with-pdo-mysql=mysqlnd \
      --with-mysqli=mysqlnd \
      --with-openssl \
      --with-curl \
      --with-zlib \
      --with-zip \
      --enable-mbstring \
      --enable-opcache \
      --enable-bcmath \
      --enable-intl \
      --enable-sockets \
      --enable-pcntl \
      --enable-xml \
      --with-xsl \
      --enable-gd \
      --with-jpeg \
      --with-freetype \
      --with-bz2 \
      --enable-calendar \
      --enable-exif \
      --disable-debug

  # 编译(用所有CPU核心)
  make -j$(nproc)
  make install

  # 配置文件
  cp php.ini-production /usr/local/php81/etc/php.ini
  cp /usr/local/php81/etc/php-fpm.conf.default /usr/local/php81/etc/php-fpm.conf
  cp /usr/local/php81/etc/php-fpm.d/www.conf.default /usr/local/php81/etc/php-fpm.d/www.conf

  # 创建软链接
  ln -sf /usr/local/php81/bin/php /usr/local/bin/php81
  ln -sf /usr/local/php81/sbin/php-fpm /usr/local/sbin/php81-fpm

  ---
  五、安装多个PHP版本

  # 一次性安装多个版本(apt方式)
  apt install -y \
      php7.4 php7.4-fpm php7.4-cli php7.4-common \
      php7.4-mysql php7.4-curl php7.4-gd php7.4-mbstring \
      php7.4-xml php7.4-zip php7.4-bcmath php7.4-opcache \
      php7.4-redis php7.4-intl

  apt install -y \
      php8.1 php8.1-fpm php8.1-cli php8.1-common \
      php8.1-mysql php8.1-curl php8.1-gd php8.1-mbstring \
      php8.1-xml php8.1-zip php8.1-bcmath php8.1-opcache \
      php8.1-redis php8.1-intl

  apt install -y \
      php8.2 php8.2-fpm php8.2-cli php8.2-common \
      php8.2-mysql php8.2-curl php8.2-gd php8.2-mbstring \
      php8.2-xml php8.2-zip php8.2-bcmath php8.2-opcache \
      php8.2-redis php8.2-intl

  # 验证安装
  php7.4 -v
  php8.1 -v
  php8.2 -v

  ---
  六、配置多版本PHP-FPM(核心)

  每个PHP版本的FPM监听不同端口或Socket,互不干扰。

  PHP 7.4 FPM配置

  /etc/php/7.4/fpm/pool.d/www.conf:

  [www]
  user = www-data
  group = www-data

  ; 方式1:Unix Socket(推荐,性能更好)
  listen = /run/php/php7.4-fpm.sock
  listen.owner = www-data
  listen.group = www-data
  listen.mode = 0660

  ; 方式2:TCP端口(多服务器时用)
  ; listen = 127.0.0.1:9074

  pm = dynamic
  pm.max_children = 30
  pm.start_servers = 5
  pm.min_spare_servers = 3
  pm.max_spare_servers = 10
  pm.max_requests = 500

  ; 慢日志
  slowlog = /var/log/php7.4-fpm-slow.log
  request_slowlog_timeout = 3s

  ; 环境变量
  clear_env = no

  PHP 8.1 FPM配置

  /etc/php/8.1/fpm/pool.d/www.conf:

  [www]
  user = www-data
  group = www-data

  listen = /run/php/php8.1-fpm.sock
  listen.owner = www-data
  listen.group = www-data
  listen.mode = 0660

  ; TCP方式
  ; listen = 127.0.0.1:9081

  pm = dynamic
  pm.max_children = 50
  pm.start_servers = 10
  pm.min_spare_servers = 5
  pm.max_spare_servers = 20
  pm.max_requests = 500

  slowlog = /var/log/php8.1-fpm-slow.log
  request_slowlog_timeout = 3s

  clear_env = no

  PHP 8.2 FPM配置

  /etc/php/8.2/fpm/pool.d/www.conf:

  [www]
  user = www-data
  group = www-data

  listen = /run/php/php8.2-fpm.sock
  listen.owner = www-data
  listen.group = www-data
  listen.mode = 0660

  ; listen = 127.0.0.1:9082

  pm = dynamic
  pm.max_children = 50
  pm.start_servers = 10
  pm.min_spare_servers = 5
  pm.max_spare_servers = 20
  pm.max_requests = 500

  slowlog = /var/log/php8.2-fpm-slow.log
  request_slowlog_timeout = 3s

  clear_env = no

  启动所有FPM服务

  # 启动
  systemctl start php7.4-fpm
  systemctl start php8.1-fpm
  systemctl start php8.2-fpm

  # 开机自启
  systemctl enable php7.4-fpm
  systemctl enable php8.1-fpm
  systemctl enable php8.2-fpm

  # 查看状态
  systemctl status php7.4-fpm
  systemctl status php8.1-fpm
  systemctl status php8.2-fpm

  # 查看socket文件是否创建成功
  ls -la /run/php/
  # 应该看到:
  # php7.4-fpm.sock
  # php8.1-fpm.sock
  # php8.2-fpm.sock

  ---
  七、配置PHP.ini(每个版本单独配置)

  /etc/php/8.1/fpm/php.ini 和 /etc/php/8.1/cli/php.ini:

  ; ===== 基础配置 =====
  date.timezone = Asia/Shanghai
  default_charset = "UTF-8"

  ; ===== 内存和超时 =====
  memory_limit = 256M
  max_execution_time = 60
  max_input_time = 60
  max_input_vars = 3000

  ; ===== 文件上传 =====
  file_uploads = On
  upload_max_filesize = 100M
  post_max_size = 100M
  max_file_uploads = 20

  ; ===== 错误处理(生产环境) =====
  display_errors = Off
  display_startup_errors = Off
  log_errors = On
  error_log = /var/log/php/php8.1-error.log
  error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

  ; ===== 安全配置 =====
  expose_php = Off          ; 隐藏PHP版本
  allow_url_fopen = On
  allow_url_include = Off   ; 禁止远程包含(安全)
  disable_functions = exec,passthru,shell_exec,system,proc_open,popen

  ; ===== Session配置 =====
  session.save_handler = redis
  session.save_path = "tcp://127.0.0.1:6379?auth=YourRedisPassword"
  session.gc_maxlifetime = 7200
  session.cookie_httponly = 1
  session.cookie_secure = 0   ; HTTPS时改为1
  session.use_strict_mode = 1

  ; ===== OPcache配置(性能关键) =====
  [opcache]
  opcache.enable = 1
  opcache.enable_cli = 0
  opcache.memory_consumption = 256
  opcache.interned_strings_buffer = 16
  opcache.max_accelerated_files = 20000
  opcache.revalidate_freq = 60
  opcache.validate_timestamps = 1   ; 生产环境可改为0
  opcache.fast_shutdown = 1
  opcache.enable_file_override = 0

  # 创建日志目录
  mkdir -p /var/log/php
  chown www-data:www-data /var/log/php

  # 重启FPM使配置生效
  systemctl restart php8.1-fpm

  ---
  八、安装Nginx

  apt install -y nginx

  # 查看版本
  nginx -v

  # 启动
  systemctl start nginx
  systemctl enable nginx

  Nginx主配置 /etc/nginx/nginx.conf:

  user www-data;
  worker_processes auto;
  pid /run/nginx.pid;
  error_log /var/log/nginx/error.log warn;

  events {
      worker_connections 1024;
      use epoll;
      multi_accept on;
  }

  http {
      include /etc/nginx/mime.types;
      default_type application/octet-stream;

      log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

      access_log /var/log/nginx/access.log main;

      sendfile on;
      tcp_nopush on;
      tcp_nodelay on;
      keepalive_timeout 65;
      types_hash_max_size 2048;
      client_max_body_size 100M;

      # 安全
      server_tokens off;

      # Gzip压缩
      gzip on;
      gzip_vary on;
      gzip_proxied any;
      gzip_comp_level 6;
      gzip_types text/plain text/css text/xml application/json
                 application/javascript application/xml+rss
                 application/atom+xml image/svg+xml;

      include /etc/nginx/conf.d/*.conf;
      include /etc/nginx/sites-enabled/*;
  }

  ---
  九、Nginx多版本PHP站点配置

  9.1 PHP 7.4 老项目站点

  /etc/nginx/sites-available/project-php74.conf:

  server {
      listen 80;
      server_name php74.yourdomain.com;
      root /var/www/project-php74/public;
      index index.php index.html;

      charset utf-8;
      access_log /var/log/nginx/php74-access.log main;
      error_log  /var/log/nginx/php74-error.log warn;

      location / {
          try_files $uri $uri/ /index.php?$query_string;
      }

      # 使用PHP 7.4
      location ~ \.php$ {
          try_files $uri =404;
          fastcgi_pass unix:/run/php/php7.4-fpm.sock;
          fastcgi_index index.php;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          include fastcgi_params;
          fastcgi_read_timeout 60;
      }

      location ~ /\.(env|git|svn|htaccess) {
          deny all;
      }
  }

  9.2 PHP 8.1 新项目站点

  /etc/nginx/sites-available/project-php81.conf:

  server {
      listen 80;
      server_name php81.yourdomain.com;
      root /var/www/project-php81/public;
      index index.php index.html;

      charset utf-8;
      access_log /var/log/nginx/php81-access.log main;
      error_log  /var/log/nginx/php81-error.log warn;

      location / {
          try_files $uri $uri/ /index.php?$query_string;
      }

      # 使用PHP 8.1
      location ~ \.php$ {
          try_files $uri =404;
          fastcgi_pass unix:/run/php/php8.1-fpm.sock;
          fastcgi_index index.php;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          include fastcgi_params;
          fastcgi_read_timeout 60;
      }

      location ~ /\.(env|git|svn|htaccess) {
          deny all;
      }
  }

  9.3 同一域名不同路径用不同PHP版本

  /etc/nginx/sites-available/mixed-php.conf:

  server {
      listen 80;
      server_name mixed.yourdomain.com;
      root /var/www/mixed;
      index index.php index.html;

      charset utf-8;

      # /api 路径用PHP 8.2
      location /api {
          root /var/www/mixed;
          try_files $uri $uri/ /api/index.php?$query_string;

          location ~ \.php$ {
              fastcgi_pass unix:/run/php/php8.2-fpm.sock;
              fastcgi_index index.php;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              include fastcgi_params;
          }
      }

      # /legacy 路径用PHP 7.4
      location /legacy {
          root /var/www/mixed;
          try_files $uri $uri/ /legacy/index.php?$query_string;

          location ~ \.php$ {
              fastcgi_pass unix:/run/php/php7.4-fpm.sock;
              fastcgi_index index.php;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              include fastcgi_params;
          }
      }

      # 默认用PHP 8.1
      location ~ \.php$ {
          try_files $uri =404;
          fastcgi_pass unix:/run/php/php8.1-fpm.sock;
          fastcgi_index index.php;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          include fastcgi_params;
      }
  }

  # 启用站点(统信UOS/Debian方式)
  ln -s /etc/nginx/sites-available/project-php74.conf /etc/nginx/sites-enabled/
  ln -s /etc/nginx/sites-available/project-php81.conf /etc/nginx/sites-enabled/
  ln -s /etc/nginx/sites-available/mixed-php.conf /etc/nginx/sites-enabled/

  # 测试配置
  nginx -t

  # 重载
  systemctl reload nginx

  ---
  十、命令行切换默认PHP版本

  # 查看当前默认PHP版本
  php -v

  # 查看所有已安装的PHP版本
  update-alternatives --list php

  # 切换默认版本(交互式)
  update-alternatives --config php

  # 直接切换到指定版本
  update-alternatives --set php /usr/bin/php8.1

  # 同时切换php-config和phpize(编译扩展时需要)
  update-alternatives --set php-config /usr/bin/php-config8.1
  update-alternatives --set phpize /usr/bin/phpize8.1

  # 验证
  php -v

  ---
  十一、安装数据库

  MySQL 8.0

  # 统信UOS直接安装
  apt install -y mysql-server mysql-client

  # 启动
  systemctl start mysql
  systemctl enable mysql

  # 安全初始化
  mysql_secure_installation

  # 创建项目数据库
  mysql -u root -p << 'EOF'
  CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  CREATE USER 'myapp'@'localhost' IDENTIFIED BY 'StrongPass123!';
  GRANT ALL PRIVILEGES ON myapp.* TO 'myapp'@'localhost';
  FLUSH PRIVILEGES;
  EOF

  PostgreSQL(信创项目也常用)

  apt install -y postgresql postgresql-contrib

  systemctl start postgresql
  systemctl enable postgresql

  # 切换到postgres用户操作
  sudo -u postgres psql << 'EOF'
  CREATE DATABASE myapp ENCODING 'UTF8';
  CREATE USER myapp_user WITH PASSWORD 'StrongPass123!';
  GRANT ALL PRIVILEGES ON DATABASE myapp TO myapp_user;
  \q
  EOF

  达梦数据库(信创必备)

  # 达梦需要官网下载,以DM8为例
  # 创建安装用户
  useradd -m -s /bin/bash dmdba
  echo "dmdba:Dmdba123456" | chpasswd

  # 设置系统参数(达梦要求)
  cat >> /etc/sysctl.conf << 'EOF'
  kernel.shmmax = 536870912
  kernel.shmall = 131072
  kernel.shmmni = 4096
  kernel.sem = 250 32000 100 128
  fs.file-max = 6815744
  net.ipv4.ip_local_port_range = 9000 65500
  EOF
  sysctl -p

  # 设置用户限制
  cat >> /etc/security/limits.conf << 'EOF'
  dmdba soft nofile 65536
  dmdba hard nofile 65536
  dmdba soft nproc 16384
  dmdba hard nproc 16384
  EOF

  # 挂载安装包并安装(图形化)
  mount -o loop dm8_xxx_ent_x86_64.iso /mnt/dm
  su - dmdba
  /mnt/dm/DMInstall.bin

  # 初始化实例
  /opt/dmdbms/bin/dminit \
      PATH=/opt/dmdbms/data \
      DB_NAME=DAMENG \
      INSTANCE_NAME=DMSERVER \
      PORT_NUM=5236 \
      CHARSET=1 \
      PAGE_SIZE=16 \
      EXTENT_SIZE=32 \
      LOG_SIZE=512 \
      CASE_SENSITIVE=Y

  # 注册并启动服务
  /opt/dmdbms/script/root/dm_service_installer.sh \
      -t dmserver -p DMSERVER \
      -dm_ini /opt/dmdbms/data/DAMENG/dm.ini

  systemctl start DmServiceDMSERVER
  systemctl enable DmServiceDMSERVER

  ---
  十二、安装Redis

  apt install -y redis-server

  # 配置
  vim /etc/redis/redis.conf

  # 只监听本机
  bind 127.0.0.1 ::1

  # 设置密码
  requirepass YourRedisPassword123

  # 最大内存
  maxmemory 512mb
  maxmemory-policy allkeys-lru

  # 持久化
  appendonly yes
  appendfsync everysec

  # 日志
  loglevel notice
  logfile /var/log/redis/redis-server.log

  systemctl restart redis-server
  systemctl enable redis-server

  # 测试
  redis-cli -a YourRedisPassword123 ping

  ---
  十三、安装Composer

  # 下载安装
  php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
  php composer-setup.php --install-dir=/usr/local/bin --filename=composer
  rm composer-setup.php

  # 验证
  composer --version

  # 配置国内镜像(内网/断网环境必配)
  composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
  # 或腾讯云镜像
  composer config -g repo.packagist composer https://mirrors.cloud.tencent.com/composer/

  ---
十四、部署Laravel项目

  # 创建目录
  mkdir -p /var/www/myapp
  cd /var/www/myapp

  # 拉取代码
  git clone https://your-repo.git .

  # 安装依赖(指定PHP版本)
  php8.1 /usr/local/bin/composer install --no-dev --optimize-autoloader

  # 配置环境
  cp .env.example .env

  .env 配置:

  APP_NAME="信创项目"
  APP_ENV=production
  APP_KEY=
  APP_DEBUG=false
  APP_URL=https://yourdomain.com

  # 数据库
  DB_CONNECTION=mysql
  DB_HOST=127.0.0.1
  DB_PORT=3306
  DB_DATABASE=myapp
  DB_USERNAME=myapp
  DB_PASSWORD=StrongPass123!
  DB_CHARSET=utf8mb4
  DB_COLLATION=utf8mb4_unicode_ci

  # Redis
  REDIS_HOST=127.0.0.1
  REDIS_PASSWORD=YourRedisPassword123
  REDIS_PORT=6379

  # 缓存和Session用Redis
  CACHE_DRIVER=redis
  SESSION_DRIVER=redis
  QUEUE_CONNECTION=redis

  # 日志
  LOG_CHANNEL=daily
  LOG_LEVEL=error

  # 生成密钥
  php8.1 artisan key:generate

  # 数据库迁移
  php8.1 artisan migrate --force

  # 设置权限
  chown -R www-data:www-data /var/www/myapp
  chmod -R 755 /var/www/myapp
  chmod -R 775 /var/www/myapp/storage
  chmod -R 775 /var/www/myapp/bootstrap/cache

  # 生产环境缓存(提升性能)
  php8.1 artisan config:cache
  php8.1 artisan route:cache
  php8.1 artisan view:cache
  php8.1 artisan event:cache

  ---
  十五、ThinkPHP项目部署

  mkdir -p /var/www/thinkphp-app
  cd /var/www/thinkphp-app
  git clone https://your-tp-repo.git .

  # ThinkPHP6用PHP7.4也完全兼容
  php7.4 /usr/local/bin/composer install --no-dev

  chown -R www-data:www-data /var/www/thinkphp-app
  chmod -R 755

✻ Cogitated for 1m 41s

> 继续                                                                                                                  
✻ Mulling…                                                                                                             ●Mchmod -R 755 /var/www/thinkphp-app
  chmod -R 777 /var/www/thinkphp-app/runtime

  ThinkPHP6 .env 配置:                                                                                                 
  APP_DEBUG = false                                                                                                     
  [APP]
  DEFAULT_TIMEZONE = Asia/Shanghai

  [DATABASE]
  TYPE = mysql
  HOSTNAME = 127.0.0.1
  DATABASE = myapp
  USERNAME = myapp
  PASSWORD = StrongPass123!
  HOSTPORT = 3306
  CHARSET = utf8mb4
  PREFIX = tp_

  [CACHE]
  DRIVER = redis
  HOST = 127.0.0.1
  PORT = 6379
  PASSWORD = YourRedisPassword123
  PREFIX = tp_cache_
  EXPIRE = 3600

  [SESSION]
  DRIVER = redis
  HOST = 127.0.0.1
  PORT = 6379
  PASSWORD = YourRedisPassword123
  PREFIX = tp_session_

  ThinkPHP连接达梦数据库 config/database.php:

  <?php
  return [
      'default' => env('DATABASE.TYPE', 'mysql'),

      'connections' => [
          'mysql' => [
              'type'      => 'mysql',
              'hostname'  => env('DATABASE.HOSTNAME', '127.0.0.1'),
              'database'  => env('DATABASE.DATABASE', ''),
              'username'  => env('DATABASE.USERNAME', 'root'),
              'password'  => env('DATABASE.PASSWORD', ''),
              'hostport'  => env('DATABASE.HOSTPORT', '3306'),
              'charset'   => env('DATABASE.CHARSET', 'utf8mb4'),
              'prefix'    => env('DATABASE.PREFIX', ''),
              'options'   => [
                  PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                  PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                  PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4',
              ],
          ],

          // 达梦数据库
          'dm' => [
              'type'     => 'pdo',
              'dsn'      => 'dm:host=127.0.0.1;port=5236;dbname=DAMENG',
              'username' => 'SYSDBA',
              'password' => 'SYSDBA001',
              'charset'  => 'utf8',
              'prefix'   => '',
              'options'  => [
                  PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                  PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
              ],
          ],

          // PostgreSQL(人大金仓兼容)
          'pgsql' => [
              'type'     => 'pgsql',
              'hostname' => '127.0.0.1',
              'database' => 'myapp',
              'username' => 'myapp_user',
              'password' => 'StrongPass123!',
              'hostport' => '5432',
              'charset'  => 'utf8',
              'prefix'   => '',
          ],
      ],
  ];

  ---
  十六、Nginx完整HTTPS站点配置

  # 创建SSL目录
  mkdir -p /etc/nginx/ssl

  # 生成自签证书(内网环境)
  openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
      -keyout /etc/nginx/ssl/server.key \
      -out /etc/nginx/ssl/server.crt \
      -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=IT/CN=yourdomain.com"

  chmod 600 /etc/nginx/ssl/server.key

  /etc/nginx/sites-available/myapp-ssl.conf:

  # HTTP强制跳转HTTPS
  server {
      listen 80;
      server_name yourdomain.com www.yourdomain.com;
      return 301 https://$host$request_uri;
  }

  server {
      listen 443 ssl http2;
      server_name yourdomain.com www.yourdomain.com;
      root /var/www/myapp/public;
      index index.php index.html;

      charset utf-8;
      access_log /var/log/nginx/myapp-access.log main;
      error_log  /var/log/nginx/myapp-error.log warn;

      # SSL证书
      ssl_certificate     /etc/nginx/ssl/server.crt;
      ssl_certificate_key /etc/nginx/ssl/server.key;

      # SSL协议(只允许TLS1.2和1.3)
      ssl_protocols TLSv1.2 TLSv1.3;
      ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305;
      ssl_prefer_server_ciphers off;

      # SSL会话缓存
      ssl_session_cache shared:SSL:10m;
      ssl_session_timeout 1d;
      ssl_session_tickets off;

      # 安全响应头
      add_header X-Frame-Options "SAMEORIGIN" always;
      add_header X-Content-Type-Options "nosniff" always;
      add_header X-XSS-Protection "1; mode=block" always;
      add_header Referrer-Policy "strict-origin-when-cross-origin" always;
      add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

      # 静态资源缓存
      location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
          expires 30d;
          add_header Cache-Control "public, immutable";
          access_log off;
      }

      # 禁止访问敏感文件
      location ~ /\.(env|git|svn|htaccess|DS_Store) {
          deny all;
          return 404;
      }

      location ~ /(composer\.(json|lock)|package\.json|\.editorconfig) {
          deny all;
          return 404;
      }

      # PHP处理(使用PHP 8.1)
      location ~ \.php$ {
          try_files $uri =404;
          fastcgi_pass unix:/run/php/php8.1-fpm.sock;
          fastcgi_index index.php;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          fastcgi_param HTTPS on;
          include fastcgi_params;

          fastcgi_connect_timeout 60;
          fastcgi_send_timeout 120;
          fastcgi_read_timeout 120;
          fastcgi_buffer_size 128k;
          fastcgi_buffers 4 256k;
      }

      # 路由重写
      location / {
          try_files $uri $uri/ /index.php?$query_string;
      }
  }

  ln -s /etc/nginx/sites-available/myapp-ssl.conf /etc/nginx/sites-enabled/
  nginx -t
  systemctl reload nginx

  ---
  十七、进程守护(Supervisor)

  apt install -y supervisor

  systemctl start supervisor
  systemctl enable supervisor

  /etc/supervisor/conf.d/laravel-worker.conf:

  [program:laravel-worker]
  process_name=%(program_name)s_%(process_num)02d
  ; 指定PHP版本运行
  command=/usr/bin/php8.1 /var/www/myapp/artisan queue:work redis \
      --sleep=3 \
      --tries=3 \
      --max-time=3600 \
      --memory=128
  autostart=true
  autorestart=true
  stopasgroup=true
  killasgroup=true
  user=www-data
  numprocs=4
  redirect_stderr=true
  stdout_logfile=/var/log/supervisor/laravel-worker.log
  stdout_logfile_maxbytes=50MB
  stdout_logfile_backups=5
  stopwaitsecs=3600

  /etc/supervisor/conf.d/laravel-horizon.conf(如果用Horizon):

  [program:laravel-horizon]
  process_name=%(program_name)s
  command=/usr/bin/php8.1 /var/www/myapp/artisan horizon
  autostart=true
  autorestart=true
  user=www-data
  redirect_stderr=true
  stdout_logfile=/var/log/supervisor/horizon.log
  stopwaitsecs=3600

  # 重载配置
  supervisorctl reread
  supervisorctl update

  # 启动
  supervisorctl start laravel-worker:*

  # 查看状态
  supervisorctl status

  ---
  十八、定时任务

  # 编辑www-data用户的crontab
  crontab -u www-data -e

  # Laravel调度器(每分钟)
  * * * * * /usr/bin/php8.1 /var/www/myapp/artisan schedule:run >> /dev/null 2>&1

  # ThinkPHP定时任务示例
  # 每天凌晨2点清理日志
  0 2 * * * /usr/bin/php7.4 /var/www/thinkphp-app/think clear >> /dev/null 2>&1

  # 每5分钟检查队列
  */5 * * * * /usr/bin/php8.1 /var/www/myapp/artisan queue:restart >> /dev/null 2>&1

  ---
  十九、日志管理

  /etc/logrotate.d/php-nginx:

  # Nginx日志
  /var/log/nginx/*.log {
      daily
      missingok
      rotate 30
      compress
      delaycompress
      notifempty
      create 0640 www-data adm
      sharedscripts
      postrotate
          if [ -f /run/nginx.pid ]; then
              kill -USR1 $(cat /run/nginx.pid)
          fi
      endscript
  }

  # PHP错误日志
  /var/log/php/*.log {
      daily
      missingok
      rotate 14
      compress
      delaycompress
      notifempty
      create 0640 www-data adm
  }

  # PHP-FPM慢日志
  /var/log/php*-fpm-slow.log {
      weekly
      missingok
      rotate 8
      compress
      delaycompress
      notifempty
  }

  # Laravel应用日志
  /var/www/myapp/storage/logs/*.log {
      daily
      missingok
      rotate 14
      compress
      delaycompress
      notifempty
      create 0664 www-data www-data
  }

  ---
  二十、PHP扩展管理

  安装额外扩展

  # 查看已安装扩展
  php8.1 -m

  # 安装扩展(apt方式)
  apt install -y php8.1-imagick    # 图片处理(比GD强)
  apt install -y php8.1-mongodb    # MongoDB
  apt install -y php8.1-swoole     # 协程/高性能
  apt install -y php8.1-xdebug    # 调试(生产环境不装)

  # 编译安装扩展(以swoole为例)
  apt install -y php8.1-dev
  pecl install swoole

  # 启用扩展
  echo "extension=swoole.so" > /etc/php/8.1/mods-available/swoole.ini
  phpenmod -v 8.1 swoole

  # 验证
  php8.1 -m | grep swoole

  不同版本单独管理扩展

  # 为PHP7.4安装扩展
  apt install -y php7.4-redis php7.4-imagick

  # 为PHP8.2安装扩展
  apt install -y php8.2-redis php8.2-imagick

  # 查看某版本加载的扩展配置目录
  php8.1 --ini
  # 输出类似:
  # Loaded Configuration File: /etc/php/8.1/cli/php.ini
  # Scan for additional .ini files in: /etc/php/8.1/cli/conf.d

  ---
  二十一、性能调优

  PHP-FPM进程数计算

  # 查看单个php-fpm进程内存占用
  ps aux | grep php-fpm | awk '{print $6}' | sort -n | tail -5
  # 单位KB,假设平均50MB = 51200KB

  # 计算公式
  # 可用内存 = 总内存 × 0.7(留30%给系统和其他服务)
  # 最大进程数 = 可用内存 / 单进程内存

  # 8GB内存服务器示例:
  # 可用 = 8192MB × 0.7 = 5734MB
  # 最大进程数 = 5734 / 50 ≈ 114
  # 多版本共存时按比例分配,比如 7.4:30个 + 8.1:50个 + 8.2:30个

  OPcache调优

  # 查看OPcache状态
  php8.1 -r "print_r(opcache_get_status());" | head -30

  # 查看命中率(应该在95%以上)
  php8.1 -r "
  \$s = opcache_get_status();
  \$hit = \$s['opcache_statistics']['hits'];
  \$miss = \$s['opcache_statistics']['misses'];
  echo 'Hit rate: ' . round(\$hit/(\$hit+\$miss)*100, 2) . '%\n';
  "

  Nginx调优

  # 查看CPU核心数
  nproc

  # 调整worker进程数(等于CPU核心数)
  # /etc/nginx/nginx.conf
  # worker_processes auto;  # 自动设置,推荐

  # 查看nginx连接数
  ss -s

  ---
  二十二、一键部署脚本

  #!/bin/bash
  # deploy.sh - 统信UOS PHP项目一键部署脚本

  set -e  # 遇到错误立即退出

  # ===== 配置区域(修改这里)=====
  PHP_VERSION="8.1"
  PROJECT_DIR="/var/www/myapp"
  DOMAIN="yourdomain.com"
  DB_NAME="myapp"
  DB_USER="myapp"
  DB_PASS="StrongPass123!"
  REDIS_PASS="YourRedisPassword123"
  # ================================

  echo ">>> [1/8] 检查系统环境"
  OS=$(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)
  ARCH=$(uname -m)
  echo "系统: $OS"
  echo "架构: $ARCH"

  echo ">>> [2/8] 更新系统包"
  apt update -qq

  echo ">>> [3/8] 安装基础依赖"
  apt install -y -qq nginx mysql-server redis-server supervisor curl git unzip

  echo ">>> [4/8] 安装PHP ${PHP_VERSION}"
  apt install -y -qq \
      php${PHP_VERSION} php${PHP_VERSION}-fpm php${PHP_VERSION}-cli \
      php${PHP_VERSION}-mysql php${PHP_VERSION}-redis \
      php${PHP_VERSION}-curl php${PHP_VERSION}-gd \
      php${PHP_VERSION}-mbstring php${PHP_VERSION}-xml \
      php${PHP_VERSION}-zip php${PHP_VERSION}-bcmath \
      php${PHP_VERSION}-opcache php${PHP_VERSION}-intl

  echo ">>> [5/8] 配置服务"
  # 设置时区
  sed -i 's/;date.timezone =/date.timezone = Asia\/Shanghai/' \
      /etc/php/${PHP_VERSION}/fpm/php.ini
  sed -i 's/;date.timezone =/date.timezone = Asia\/Shanghai/' \
      /etc/php/${PHP_VERSION}/cli/php.ini

  # 关闭错误显示
  sed -i 's/display_errors = On/display_errors = Off/' \
      /etc/php/${PHP_VERSION}/fpm/php.ini

  # 隐藏PHP版本
  sed -i 's/expose_php = On/expose_php = Off/' \
      /etc/php/${PHP_VERSION}/fpm/php.ini

  echo ">>> [6/8] 配置数据库"
  systemctl start mysql
  mysql -u root << EOF
  CREATE DATABASE IF NOT EXISTS ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
  GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';
  FLUSH PRIVILEGES;
  EOF

  echo ">>> [7/8] 配置Redis"
  sed -i "s/# requirepass foobared/requirepass ${REDIS_PASS}/" /etc/redis/redis.conf
  systemctl restart redis-server

  echo ">>> [8/8] 启动所有服务"
  systemctl enable --now nginx
  systemctl enable --now php${PHP_VERSION}-fpm
  systemctl enable --now mysql
  systemctl enable --now redis-server
  systemctl enable --now supervisor

  echo ""
  echo "===== 部署完成 ====="
  echo "PHP版本: $(php${PHP_VERSION} -v | head -1)"
  echo "Nginx: $(nginx -v 2>&1)"
  echo "MySQL: $(mysql --version)"
  echo ""
  echo "服务状态:"
  for svc in nginx php${PHP_VERSION}-fpm mysql redis-server; do
      status=$(systemctl is-active $svc)
      echo "  $svc: $status"
  done

  chmod +x deploy.sh
  bash deploy.sh

  ---
  二十三、环境检查脚本

  #!/bin/bash
  # check_uos_php.sh - 统信UOS PHP环境全面检查

  echo "============================================"
  echo "  统信UOS PHP环境检查报告"
  echo "  时间: $(date '+%Y-%m-%d %H:%M:%S')"
  echo "============================================"

  echo ""
  echo "【系统信息】"
  echo "  OS     : $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
  echo "  架构   : $(uname -m)"
  echo "  内核   : $(uname -r)"
  echo "  内存   : $(free -h | awk '/^Mem/{print $2}') 总 / $(free -h | awk '/^Mem/{print $7}') 可用"
  echo "  CPU    : $(nproc) 核"
  echo "  磁盘   : $(df -h / | awk 'NR==2{print $4}') 可用"

  echo ""
  echo "【PHP版本】"
  for ver in 5.6 7.0 7.1 7.2 7.3 7.4 8.0 8.1 8.2 8.3; do
      if command -v php${ver} &>/dev/null; then
          echo "  PHP ${ver}: 已安装 ($(php${ver} -v | head -1 | awk '{print $2}'))"
      fi
  done
  echo "  默认版本: $(php -v | head -1 | awk '{print $2}')"

  echo ""
  echo "【PHP-FPM状态】"
  for ver in 7.4 8.0 8.1 8.2 8.3; do
      if systemctl list-units --type=service | grep -q "php${ver}-fpm"; then
          status=$(systemctl is-active php${ver}-fpm 2>/dev/null)
          sock="/run/php/php${ver}-fpm.sock"
          sock_status="socket不存在"
          [ -S "$sock" ] && sock_status="socket正常"
          echo "  PHP ${ver}-FPM: ${status} | ${sock_status}"
      fi
  done

  echo ""
  echo "【关键扩展(PHP默认版本)】"
  for ext in opcache redis pdo_mysql mbstring gd curl zip bcmath intl; do
      if php -m 2>/dev/null | grep -qi "^${ext}$"; then
          echo "  ${ext}: 已加载"
      else
          echo "  ${ext}: 未加载 !!!"
      fi
  done

  echo ""
  echo "【服务状态】"
  for svc in nginx mysql mariadb redis-server postgresql supervisor; do
      if systemctl list-units --type=service 2>/dev/null | grep -q "${svc}"; then
          status=$(systemctl is-active ${svc} 2>/dev/null)
          echo "  ${svc}: ${status}"
      fi
  done

  echo ""
  echo "【端口监听】"
  ss -tlnp 2>/dev/null | grep -E ":(80|443|3306|5432|6379|5236|9074|9081|9082)\s" | \
      awk '{print "  " $4 " -> " $1}'

  echo ""
  echo "【OPcache状态】"
  php -r "
  if (function_exists('opcache_get_status')) {
      \$s = opcache_get_status(false);
      if (\$s && \$s['opcache_enabled']) {
          \$hit = \$s['opcache_statistics']['hits'];
          \$miss = \$s['opcache_statistics']['misses'];
          \$total = \$hit + \$miss;
          \$rate = \$total > 0 ? round(\$hit/\$total*100, 2) : 0;
          echo '  状态: 已启用' . PHP_EOL;
          echo '  命中率: ' . \$rate . '%' . PHP_EOL;
          echo '  已缓存文件: ' . \$s['opcache_statistics']['num_cached_scripts'] . PHP_EOL;
          echo '  内存使用: ' . round(\$s['memory_usage']['used_memory']/1024/1024, 2) . 'MB' . PHP_EOL;
      } else {
          echo '  状态: 未启用 !!!' . PHP_EOL;
      }
  } else {
      echo '  OPcache扩展未安装 !!!' . PHP_EOL;
  }
  " 2>/dev/null

  echo ""
  echo "【SELinux/AppArmor】"
  if command -v getenforce &>/dev/null; then
      echo "  SELinux: $(getenforce)"
  elif command -v aa-status &>/dev/null; then
      echo "  AppArmor: $(aa-status --enabled 2>/dev/null && echo '启用' || echo '未启用')"
  else
      echo "  未检测到SELinux/AppArmor"
  fi

  echo ""
  echo "============================================"
  echo "  检查完成"
  echo "============================================"

  chmod +x check_uos_php.sh
  bash check_uos_php.sh

  ---
  二十四、常见问题速查

  ┌───────────────────┬───────────────────────────────┬──────────────────────────────────────────────────────────────┐
  │     问题现象      │           根本原因            │                           解决命令                           │
  ├───────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
  │ 502 Bad Gateway   │ php-fpm未启动或socket路径不对 │ systemctl restart php8.1-fpm 并检查nginx配置中socket路径     │
  ├───────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
  │ Permission denied │ socket文件权限问题            │ chown www-data:www-data /run/php/php8.1-fpm.sock             │
  ├───────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
  │ 中文乱码          │ 字符集不统一                  │ 数据库、PHP、Nginx统一设置 utf8mb4                           │
  ├───────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
  │ 上传文件失败      │ php.ini限制                   │ 修改 upload_max_filesize 和 post_max_size                    │
  ├───────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
  │ composer超时      │ 网络问题                      │ composer config -g repo.packagist composer                   │
  │                   │                               │ https://mirrors.aliyun.com/composer/                         │
  ├───────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
  │ PHP版本切换不生效 │ CLI和FPM是独立的              │ CLI用 update-alternatives,FPM改nginx配置里的socket          │
  ├───────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
  │ 扩展安装后不生效  │ 没有重启FPM                   │ systemctl restart php8.1-fpm                                 │
  ├───────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
  │ 达梦连接乱码      │ 建库字符集错误                │ 重建数据库时指定 CHARSET=1(UTF-8)                          │
  ├───────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
  │ ARM64找不到包     │ 源配置错误                    │ 确认sources.list里用的是arm64对应的源地址                    │
  ├───────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
  │ OPcache命中率低   │ revalidate_freq 太低          │ 生产环境设为 opcache.revalidate_freq=60                      │
  └───────────────────┴───────────────────────────────┴──────────────────────────────────────────────────────────────┘

  ---
  总结

  统信UOS和麒麟的核心区别就一句话:统信用 apt,麒麟用 yum,其他PHP配置逻辑完全一样。

  多版本共存的关键是:
  1. 每个PHP-FPM版本监听不同的 socket文件
  2. Nginx根据域名或路径把请求转发到对应的 socket
  3. 命令行用 php7.4 / php8.1 这样的带版本号命令区分
  4. update-alternatives --config php 控制 php 命令指向哪个版本

更多推荐