首页主机资讯ThinkPHP在Linux如何实现容器化部署

ThinkPHP在Linux如何实现容器化部署

时间2026-01-20 09:04:04发布访客分类主机资讯浏览460
导读:在 Linux 上容器化部署 ThinkPHP 的可落地方案 一、方案选型与架构 方案一 全容器化 LNMP:使用 Nginx + PHP-FPM + MySQL 全部容器化,数据卷持久化,适合从零搭建、环境一致性要求高的场景。 方案二...

在 Linux 上容器化部署 ThinkPHP 的可落地方案


一、方案选型与架构

  • 方案一 全容器化 LNMP:使用 Nginx + PHP-FPM + MySQL 全部容器化,数据卷持久化,适合从零搭建、环境一致性要求高的场景。
  • 方案二 部分容器化(混合部署):仅容器化 PHP-FPM,复用宿主机 Nginx/MySQL,避免端口冲突与资源浪费,适合已有宝塔/Nginx/MySQL 的存量环境。
  • 关键原则:目录挂载实现代码热更新;端口不与宿主机已有服务冲突;通过内网地址打通容器与数据库;权限与运行用户保持一致以减少文件权限问题。

二、方案一 全容器化 LNMP 快速落地

  • 目录结构

    tp6/
    ├─ docker-compose.yml
    ├─ nginx/
    │  └─ default.conf
    ├─ php/
    │  └─ Dockerfile
    └─ mysql/
       └─ init.sql
    
  • docker-compose.yml

    version: "3.8"
    services:
      app:
        build: ./php
        container_name: tp6_app
        volumes:
          - ./:/var/www/html
          - ./runtime:/var/www/html/runtime
          - ./public/uploads:/var/www/html/public/uploads
        environment:
          - DB_HOST=mysql
          - DB_PORT=3306
          - DB_NAME=tp6
          - DB_USER=tp6
          - DB_PASS=Tp6@123456
        depends_on:
          mysql:
            condition: service_healthy
    
      web:
        image: nginx:alpine
        container_name: tp6_web
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - ./:/var/www/html
          - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
          - ./runtime:/var/www/html/runtime:ro
          - ./public/uploads:/var/www/html/public/uploads:ro
        depends_on:
          app:
            condition: service_started
    
      mysql:
        image: mysql:8.0
        container_name: tp6_mysql
        environment:
          MYSQL_ROOT_PASSWORD: Root@123456
          MYSQL_DATABASE: tp6
          MYSQL_USER: tp6
          MYSQL_PASSWORD: Tp6@123456
        volumes:
          - mysql_data:/var/lib/mysql
          - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
        healthcheck:
          test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u$$MYSQL_USER", "-p$$MYSQL_PASSWORD"]
          interval: 10s
          timeout: 5s
          retries: 5
    
    volumes:
      mysql_data:
    
  • php/Dockerfile(TP6 常用扩展)

    FROM php:8.1-fpm
    
    RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list &
        &
         \
        sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list
    
    RUN apt-get update &
        &
         apt-get install -y --no-install-recommends \
        libfreetype6-dev libjpeg62-turbo-dev libpng-dev libzip-dev unzip &
        &
         \
        rm -rf /var/lib/apt/lists/*
    
    RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
        &
        &
         docker-php-ext-install -j$(nproc) gd pdo_mysql mysqli zip opcache
    
    RUN curl -sS https://install.phpcomposer.com/installer | php -- \
        --install-dir=/usr/local/bin --filename=composer \
        &
        &
         composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
    
    RUN usermod -u 1000 www-data &
        &
         groupmod -g 1000 www-data
    
    WORKDIR /var/www/html
    COPY . .
    RUN composer install --no-dev --optimize-autoloader --no-scripts \
        &
        &
         chown -R 1000:1000 /var/www/html \
        &
        &
         chmod -R 755 /var/www/html \
        &
        &
         chmod -R 777 /var/www/html/runtime /var/www/html/public/uploads
    
    RUN echo "date.timezone=Asia/Shanghai" >
     /usr/local/etc/php/conf.d/timezone.ini
    
    EXPOSE 9000
    CMD ["php-fpm"]
    
  • nginx/default.conf(PATH_INFO 兼容)

    server {
        
        listen 80;
        
        server_name localhost;
        
        root /var/www/html/public;
        
        index index.php;
    
    
        location / {
        
            try_files $uri $uri/ /index.php?$query_string;
    
        }
    
    
        location ~ \.php$ {
        
            fastcgi_pass app:9000;
        
            fastcgi_index index.php;
        
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        
            include fastcgi_params;
    
        }
    
    
        location ~ /\.ht {
        
            deny all;
    
        }
    
    }
        
    
  • 部署与验证

    docker compose up -d --build
    docker compose ps
    docker compose logs -f app
    curl -I http://localhost
    

    上述组合使用官方 PHP 与 Nginx 镜像,安装 gd/pdo_mysql/zip/opcache 等扩展,并通过 Composer 安装依赖,适合 TP5/TP6 的标准容器化部署。


三、方案二 部分容器化 复用宿主机 Nginx 与 MySQL

  • 适用场景:已有宝塔/Nginx/MySQL,避免端口冲突与重复部署。

  • 核心思路:仅启动 PHP-FPM 容器,将 PHP 请求由宿主机 Nginx 反向代理到容器;数据库通过 docker0 网关 172.18.0.1 或宿主机内网 IP 访问。

  • php/Dockerfile(监听 9003,避免与宿主机 9000 冲突)

    FROM php:8.1-fpm
    
    RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list &
        &
         \
        sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list
    
    RUN apt-get update &
        &
         apt-get install -y --no-install-recommends \
        libfreetype6-dev libjpeg62-turbo-dev libpng-dev libzip-dev &
        &
         \
        rm -rf /var/lib/apt/lists/*
    
    RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
        &
        &
         docker-php-ext-install -j$(nproc) gd pdo_mysql mysqli zip opcache
    
    RUN curl -sS https://install.phpcomposer.com/installer | php -- \
        --install-dir=/usr/local/bin --filename=composer \
        &
        &
         composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
    
    RUN usermod -u 1000 www-data &
        &
         groupmod -g 1000 www-data
    
    RUN echo '[global]' >
         /usr/local/etc/php-fpm.conf &
        &
         \
        echo 'error_log = /proc/self/fd/2' >
        >
         /usr/local/etc/php-fpm.conf &
        &
         \
        echo 'daemonize = no' >
        >
         /usr/local/etc/php-fpm.conf &
        &
         \
        echo 'include=/usr/local/etc/php-fpm.d/*.conf' >
        >
         /usr/local/etc/php-fpm.conf
    
    RUN echo '[www]' >
         /usr/local/etc/php-fpm.d/www.conf &
        &
         \
        echo 'listen = 9003' >
        >
         /usr/local/etc/php-fpm.d/www.conf &
        &
         \
        echo 'user = www-data' >
        >
         /usr/local/etc/php-fpm.d/www.conf &
        &
         \
        echo 'group = www-data' >
        >
         /usr/local/etc/php-fpm.d/www.conf &
        &
         \
        echo 'pm = dynamic' >
        >
         /usr/local/etc/php-fpm.d/www.conf &
        &
         \
        echo 'pm.max_children = 50' >
        >
         /usr/local/etc/php-fpm.d/www.conf &
        &
         \
        echo 'pm.start_servers = 5' >
        >
         /usr/local/etc/php-fpm.d/www.conf &
        &
         \
        echo 'pm.min_spare_servers = 5' >
        >
         /usr/local/etc/php-fpm.d/www.conf &
        &
         \
        echo 'pm.max_spare_servers = 10' >
        >
         /usr/local/etc/php-fpm.d/www.conf
    
    RUN rm -f /usr/local/etc/php-fpm.d/zz-docker.conf
    
    RUN echo "date.timezone=Asia/Shanghai" >
         /usr/local/etc/php/conf.d/timezone.ini
    
    WORKDIR /var/www/html
    COPY . .
    RUN composer install --no-dev --optimize-autoloader --no-scripts \
        &
        &
         chown -R 1000:1000 /var/www/html \
        &
        &
         chmod -R 755 /var/www/html \
        &
        &
     chmod -R 777 /var/www/html/runtime /var/www/html/public/uploads
    
    EXPOSE 9003
    CMD ["php-fpm"]
    
  • docker-compose.yml(仅 PHP-FPM)

    version: "3.8"
    services:
      tp6-php-fpm:
        build: .
        container_name: tp6_php_fpm
        volumes:
          - /www/wwwroot/tp6:/var/www/html
        ports:
          - "9003:9003"
        user: "1000:1000"
    
  • 宿主机宝塔 Nginx 配置片段(反向代理到容器)

    location ~ \.php$ {
        
        fastcgi_pass 127.0.0.1:9003;
        
        fastcgi_index index.php;
        
        fastcgi_param SCRIPT_FILENAME /var/www/html/public$fastcgi_script_name;
        
        include fastcgi_params;
    
    }
    
    
    location / {
        
        root /www/wwwroot/tp6/public;
    
        if (!-e $request_filename) {
        
            rewrite ^(.*)$ /index.php?s=$1 last;
    
        }
    
    }
        
    
  • 数据库授权与连接

    • 在宝塔数据库权限中新增授权主机为 172.18.0.1(docker0 网关)或宿主机内网 IP,允许容器访问 MySQL。
    • .env 示例:
      APP_DEBUG=true
      DB_TYPE=mysql
      DB_HOST=172.18.0.1
      DB_NAME=tp6
      DB_USER=tp6
      DB_PASS=Tp6@123456
      DB_PORT=3306
      DB_CHARSET=utf8mb4
      

    该方案通过挂载代码目录、错开端口、网关访问宿主机数据库,实现与宝塔共存且易于维护的“部分容器化”。


四、关键配置与排错要点

  • 文件权限与运行用户

    • 容器内 PHP-FPM 以 www-data:1000 运行,宿主机项目目录属主建议同为 www:www(1000:1000),避免写入 runtime/uploads 失败。
    • 推荐权限:755 目录、644 文件、777 仅对 runtime/uploads 等可写目录开启。
  • 端口与冲突

    • 宿主机已有 PHP-FPM 占用 9000 时,容器可改用 9003 并在 Nginx 反向代理中指向该端口。
  • 数据库连通性

    • 容器访问宿主机 MySQL 使用 172.18.0.1(docker0 网关)或宿主机内网 IP;宝塔数据库权限需放行对应来源。
  • 路由与重写

    • TP5/TP6 需开启 PATH_INFO,Nginx 配置 try_files $uri $uri/ /index.php?$query_string; ,或 TP5 兼容写法 rewrite ^(.*)$ /index.php?s=$1 last;
  • Composer 与依赖

    • 构建阶段使用 --no-dev --optimize-autoloader 减少镜像体积并提升性能;如需私有包,配置 Composer 镜像与 auth。
  • 时区与 OPCache

    • 建议设置 date.timezone=Asia/Shanghai;开启 OPcache 提升生产性能(开发环境可关闭)。
  • 日志与调试

    • 容器日志:docker logs -f < 容器名> ;FPM 错误日志默认输出到 stderr,便于 docker logs 查看。

五、生产级优化建议

  • 安全

    • 禁止在镜像中硬编码敏感信息,使用 Secrets/环境变量 注入;以非 root 用户运行(已通过 www-data:1000 实现)。
  • 镜像与缓存

    • 分层组织 Dockerfile,将不常变动的层(如依赖安装)放前,常变动的源码放后;使用 多阶段构建 减小镜像体积。
  • 健康检查与可观测性

    • 为关键服务添加 HEALTHCHECK;容器编排中结合 restart 策略与日志采集,提升稳定性与可维护性。
  • 数据与备份

    • MySQL 使用独立卷持久化;定期备份数据与代码,回滚策略纳入发布流程。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: ThinkPHP在Linux如何实现容器化部署
本文地址: https://pptw.com/jishu/786934.html
Linux环境下K8S怎么搭建 Linux下ThinkPHP如何使用缓存

游客 回复需填写必要信息