Alibaba Cloud Linux 3 +Docker 部署 ThinkPHP6 (宝塔环境)

在使用 Docker 部署 ThinkPHP6 并适配宝塔环境时,遇到很多问题。本文整理了实战中具体的操作步骤,至于遇到的错误及解决方案后边再补充。(结合实际这种部署有点繁琐,后期维护管理比较复杂,所以这里只用于Docker学习,不建议这样搭建生产环境。)

一、环境说明

  • 宿主机:安装宝塔面板的 Linux 服务器
  • 容器环境:PHP 8.1-FPM
  • 框架:ThinkPHP6
  • 部署方式:Docker + Docker Compose

宿主机已通过宝塔面板安装 Nginx、PHP、MySQL ,我这里并没有重复容器化整套 LNMP 环境(避免端口冲突和资源浪费),采用的是 **"部分容器化"**方案:仅将 ThinkPHP6 应用与 PHP-FPM 容器化,同时复用宿主机宝塔管理的 Nginx(处理反向代理)和 MySQL(数据库)。

容器化需遵循 "不占用宿主机已用端口、通过挂载目录同步代码、配置网络互通" 原则,核心架构如下:

宿主机(安装宝塔面板)

├─ 1. Nginx(占用 80/443 端口,作为前端Web服务器)

├─ 2. MySQL(占用 3306 端口,独立运行在宿主机)

└─ 3. Docker 容器(运行 ThinkPHP6 + PHP-FPM)

├─ 目录挂载:将宿主机项目目录 /www/wwwroot/tp6 挂载到容器内目录(如 /var/www/html),实现代码实时同步

├─ 端口配置:暴露容器内 PHP-FPM 监听端口(如 9003),与宿主机 PHP-FPM 端口(默认 9000)错开,避免冲突

└─ 数据库连接:通过"宿主机内网IP"(如 172.18.0.1,Docker 默认网桥网关)或"宿主机真实内网IP"(如 192.168.1.100)连接宿主机 MySQL

二 、前置准备:宿主机环境检查与配置

1. 确认宝塔服务状态

通过宝塔面板或命令行确认 Nginx、MySQL 正常运行:

bash 复制代码
# 宝塔命令行工具查看服务状态
# 确保 Nginx、MySQL 显示"运行中"
bt status

# 查看宿主机 PHP-FPM 端口(避免容器端口冲突)
# 如显示 9000、9001,容器需用其他端口(如 9002)
netstat -tulnp | grep php-fpm
 

2. 准备 ThinkPHP6 项目目录

在宝塔默认网站目录创建项目(便于宝塔管理):

bash 复制代码
# 1. 创建目录并克隆 ThinkPHP6 源码(Gitee 镜像)
mkdir -p /www/wwwroot/tp6 && cd /www/wwwroot/tp6
git clone https://gitee.com/top-think/think.git .


# 确认 Composer 路径
# 输出可能为 /usr/local/bin/composer
which composer 
#获取composer版本 
#输出结果:Composer version 2.8.11  PHP version 8.1.32 
/usr/bin/composer --version


# 进入项目目录,用 PHP 8.1 执行
cd /www/wwwroot/tp6

#安装ThinkPHP6项目依赖
/www/server/php/81/bin/php $(which composer) install --no-dev

调整目录权限(宝塔默认www用户,避免容器读写权限问题)

bash 复制代码
chown -R www:www /www/wwwroot/tp6
chmod -R 755 /www/wwwroot/tp6
chmod -R 777 /www/wwwroot/tp6/runtime /www/wwwroot/tp6/public/uploads

3. 授权 MySQL 允许容器访问

容器内应用需连接宿主机 MySQL,需通过宝塔授权 "容器所在内网 IP" 访问:

  1. 登录宝塔面板 → 数据库 → 对应数据库(如 tp6_db)→ 权限管理;
  2. 新增授权:
    • 用户名:tp6_user(自定义);
    • 密码:Tp6@123456(自定义);
    • 授权主机:填写 宿主机内网 IP (如 172.18.0.1,Docker 默认网桥网关,可通过 ip addr show docker0 查看);
bash 复制代码
ip addr show docker0
#运行结果
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:3e:7e:6a:ac brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:3eff:fe7e:6aac/64 scope link 
       valid_lft forever preferred_lft forever

使用 172.18.0.1 这个网关地址设置数据库访问权限:

三、容器化配置:仅容器化 ThinkPHP6 + PHP-FPM

在项目目录 /www/wwwroot/tp6 下创建 Docker 相关文件,仅定义 PHP-FPM 容器(复用宿主机 Nginx/MySQL)。

1. 创建 Dockerfile(仅构建 PHP-FPM 环境)

无需包含 Nginx 和 MySQL,仅需适配 ThinkPHP6 所需的 PHP 扩展:

bash 复制代码
# 基础镜像:PHP 8.1-FPM(与宿主机宝塔 PHP 版本一致,避免语法兼容问题)
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

# 修改 www-data 用户的 UID/GID 为 1000(匹配宿主机 www 用户)
RUN usermod -u 1000 www-data && groupmod -g 1000 www-data

# 安装 ThinkPHP6 必需扩展(gd、pdo_mysql 等)
RUN apt-get update && apt-get install -y \
    curl \
    wget \
    iproute2 \
    net-tools \
    procps \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng-dev \
    libzip-dev \
    && rm -rf /var/lib/apt/lists/*  

# 安装 PHP 扩展(分开步骤避免失败)
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install -j$(nproc) gd pdo_mysql mysqli zip opcache

# 安装 Composer(使用国内镜像)
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/

# 配置 PHP-FPM 监听端口(使用自定义配置文件)
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 cp /usr/local/etc/php-fpm.d/www.conf /usr/local/etc/php-fpm.d/www.conf.backup && \
    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

# 配置 PHP 时区
RUN echo 'date.timezone = Asia/Shanghai' > /usr/local/etc/php/conf.d/timezone.ini

# 设置工作目录(与宿主机项目目录对应,后续通过挂载同步代码)
WORKDIR /var/www/html

# 先复制所有项目文件
COPY . .

# 安装 PHP 依赖
RUN composer install --no-dev --optimize-autoloader --no-scripts

# 设置文件权限
RUN chown -R 1000:1000 /var/www/html \
    && chmod -R 755 /var/www/html \
    && chmod 644 /var/www/html/public/index.php \
    && chmod -R 777 /var/www/html/runtime /var/www/html/public/uploads

# 暴露自定义 PHP-FPM 端口(9003)
EXPOSE 9003

CMD ["php-fpm"]

2. 创建 docker-compose.yml(简化版,仅管理 PHP-FPM 容器)

无需定义 Nginx 和 MySQL 服务,仅启动 PHP-FPM 容器,并挂载宿主机项目目录:

bash 复制代码
services:
  tp6-php-fpm:
    build: .  # 基于当前目录 Dockerfile 构建
    restart: no
    volumes:
      # 挂载宿主机项目目录到容器(实时同步代码,宿主机修改后容器立即生效)
      - /www/wwwroot/tp6_study_web:/var/www/html
    ports:
      # 宿主机端口 9003 → 容器端口 9003(避免冲突)
      - "9003:9003"
    # 关键:指定容器运行用户(UID 1000 对应宿主机 www 用户)
    user: "1000:1000"

四、配置宿主机宝塔 Nginx:反向代理到容器

通过宝塔面板配置 Nginx,将请求转发到容器内的 PHP-FPM(无需在容器内启动 Nginx)。

1. 宝塔创建站点

  1. 登录宝塔面板 → 网站 → 添加站点;
  2. 填写基本信息:
    • 域名:如 tp6.example.com(或直接用服务器 IP);
    • 根目录:选择 /www/wwwroot/tp6/public(ThinkPHP 入口目录);
    • PHP 版本:选择 "纯静态"(因为 PHP 解析交给容器,避免宿主机 PHP 干扰);
  3. 点击 "提交",创建站点。

2. 修改 Nginx 配置:反向代理 PHP 请求到容器

  1. 进入站点 → 配置文件 → 修改 "Nginx 配置";
  2. 找到 location ~ \.php$ 块,替换为以下内容(转发到容器 PHP-FPM):
bash 复制代码
# 处理 PHP 请求:转发到容器 PHP-FPM(宿主机 9003 端口)
location ~ \.php$ {
        # 容器 PHP-FPM 地址(替换为你的容器 IP)
        fastcgi_pass 127.0.0.1:9003;
        fastcgi_index index.php;
        # 容器内的项目路径(与 Docker 挂载路径对应)
        fastcgi_param SCRIPT_FILENAME /var/www/html/public$fastcgi_script_name;        
        include fastcgi_params;
}

# 处理静态资源:直接返回(复用宿主机 Nginx 静态资源处理能力)
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ {
    root /www/wwwroot/tp6/public;  # 宿主机静态资源目录
    expires 30d;
    access_log off;
}

# ThinkPHP URL 重写(美化路由)
location / {
    root /www/wwwroot/tp6/public;
    if (!-e $request_filename) {     # 只有文件/目录不存在时,才重写
        rewrite  ^(.*)$  /index.php?s=$1  last;
        break;
   }
}

3、点击 "保存",并重启 Nginx(宝塔面板 → 服务 → Nginx → 重启)。

五、启动容器并测试

1. 启动 PHP-FPM 容器

在项目目录 /www/wwwroot/tp6 执行命令:

构建镜像并启动容器(-d 后台运行)

docker-compose up -d --build

查看容器状态(确保 tp6-php-fpm 为 Up 状态)

docker-compose ps

查看容器日志(排查 PHP 扩展缺失、MySQL 连接失败等问题)

docker logs tp6-tp6-php-fpm-1

2. 测试访问与数据库连接

(1)访问 ThinkPHP6 首页

在浏览器输入站点域名 / IP(如 http://tp6.xiaocaizhang.fun),若看到 ThinkPHP 欢迎页面,说明 Nginx 反向代理和容器 PHP-FPM 正常。

(2)测试数据库连接

修改 ThinkPHP6 配置文件 .env,连接宿主机 MySQL:

bash 复制代码
APP_DEBUG = true

DB_TYPE = mysql
DB_HOST = 172.18.0.1
DB_NAME = tp6_user
DB_USER = tp6_user
DB_PASS = mW3ekrY3MDmTzGzS
DB_PORT = 3306
DB_CHARSET = utf8

DEFAULT_LANG = zh-cn

创建测试控制器 app/controller/Test.php,验证数据库连接:

php 复制代码
<?php
namespace app\controller;

use think\Db;
use app\BaseController;

class Test extends BaseController
{
    public function index()
    {
        // 测试创建表并插入数据
        Db::execute("CREATE TABLE IF NOT EXISTS test (
            id INT AUTO_INCREMENT PRIMARY KEY,
            name VARCHAR(50) NOT NULL,
            create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )");
        Db::name('test')->insert(['name' => '宝塔+容器混合部署测试']);
        $data = Db::name('test')->select();
        
        return json($data);
    }
}

访问 tp6.xiaocaizhang.fun/index/test,若返回 JSON 数据,说明数据库连接成功。

部署中遇到了很多问题,后边我再编写笔记。

相关推荐
骄傲的心别枯萎3 小时前
RV1126 NO.30:RV1126多线程获取音频AI的PCM数据
linux·ffmpeg·音视频·pcm·视频编解码
zz-zjx3 小时前
Apache 生产环境操作与 LAMP 搭建指南
linux·运维·apache
峰顶听歌的鲸鱼3 小时前
29.Linux防火墙管理
linux·运维·网络·笔记·学习方法
长不大的程序员3 小时前
Linux系统-debian系的软件包管理
linux·运维·服务器·debian
jun~3 小时前
SQLMap绕过 Web 应用程序保护靶机(打靶记录)
linux·笔记·学习·安全·web安全
小麦矩阵系统永久免费3 小时前
自动化运营|矩阵系统省心高效
运维·矩阵·自动化
天上的光4 小时前
软件体系结构——负载均衡
运维·负载均衡
每天更新4 小时前
linux驱动开发笔记
linux·驱动开发·笔记
Mr.45674 小时前
Linux安装配置Redis 7.2.3教程
linux·运维·服务器