在飞牛NAS的Docker图形界面里把PHP+Nginx+Mysql结合起来,核心就是解决两件事:让两个容器能互相通信,并且把处理PHP动态请求的任务交给PHP容器。
为了让Nginx和PHP能读到同一份代码,需要把飞牛NAS上的项目文件夹分别挂载到两个容器的指定位置。
要让Nginx能找到PHP,PHP能找到Mysql,它们必须在同一个Docker网络下。

⚠️ 注意: 不要使用默认的 bridge 网络,因为默认网络下容器之间不能通过容器名自动解析。

/vol1/1000/docker/www/dfsx168/var/www/html在飞牛的Docker"容器"列表里,找到你的PHP容器并点进去查看。
确保:
如果你的PHP容器是基于 php:fpm 镜像的,它默认就会开启9000端口来处理请求。
⚠️ 关键点: 两个容器挂载的是NAS上同一份代码,容器内部的访问路径统一使用了
/var/www/html。
这是最关键的一步。你需要修改Nginx的配置文件,告诉它当遇到.php结尾的请求时,应该转发给PHP容器处理。
在/vol1/1000/docker/nginx里,新建一个 default.conf 文件:
server {
listen 80;
server_name localhost;
# 这里的根目录必须和Nginx容器内挂载的路径一致
root /var/www/html/public;
index index.php index.html;
location / {
#try_files $uri $uri/ /index.php?$query_string;
if (!-f $request_filename) {
rewrite ^(.*)$ /index.php?s=/$1 last;
}
}
location ~ \.php$ {
# 重点:转发到PHP容器。'php'是容器名,'9000'是PHP-FPM端口
fastcgi_pass php:9000;
fastcgi_index index.php;
# 这里的 $document_root 就是上面root定义的路径
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
}
}进入容器终端执行(临时安装,重启会丢失):
docker-php-ext-install pdo_mysql
root@nas:/vol1/1000/docker/php/php-custom# chmod -R 755 /vol1/1000/docker/www/dfsx168/ root@nas:/vol1/1000/docker/php/php-custom# chmod -R 777 /vol1/1000/docker/www/dfsx168/runtime这样Thinkphp项目就可以访问了,但是pdo_mysql是临时的,还是需要完成永久方案,构建自己的PHP镜像才行
飞牛上构建自定义 PHP 镜像的完整步骤
飞牛 NAS 基于 Linux,完全支持 Docker 命令行。我们通过 SSH 连接后,用 docker build 来构建自己的镜像。
ssh 你的飞牛用户名@飞牛IP地址 # 例如:ssh admin@192.168.1.100 sudo -i # 切换到root用户
mkdir -p /vol1/1000/docker/php-customcd /vol1/1000/docker/php-customnano Dockerfile
粘贴以下内容(带pdo_mysql扩展的PHP 8.5 FPM镜像):
FROM php:8.5.4RC1-fpm-alpine3.22 # 安装pdo_mysql扩展 RUN docker-php-ext-install pdo_mysql # 如果还需要其他扩展,可以继续添加: RUN docker-php-ext-install bcmath opcache
docker build -t my-php:8.5-fpm .
构建过程会从 Docker Hub 拉取基础镜像(首次较慢),然后安装扩展。完成后可以用 docker images 查看。
php -m | grep pdo_mysql
如果输出 pdo_mysql,就成功了!你的 ThinkPHP 项目现在可以正常连接数据库了。
如果你还需要其他扩展(比如 bcmath、opcache、gd 等),可以一次性全部装上。
FROM php:8.5-fpm ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources RUN apt-get update && \ apt-get install -y --no-install-recommends \ libpng-dev \ libjpeg-dev \ libfreetype6-dev \ zlib1g-dev \ libzip-dev \ libonig-dev \ libicu-dev \ libxml2-dev \ libcurl4-openssl-dev \ libssl-dev && \ docker-php-ext-configure gd --with-freetype --with-jpeg && \ docker-php-ext-install -j$(nproc) \ gd \ pdo_mysql \ mbstring \ xml \ curl \ zip \ exif \ fileinfo \ intl \ bcmath \ opcache && \ pecl install redis && \ docker-php-ext-enable redis && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* COPY --from=composer:latest /usr/bin/composer /usr/bin/composer WORKDIR /var/www/html EXPOSE 9000 CMD ["php-fpm"]
然后重新构建:
docker build -t my-php:8.5-fpm .
这样构建出来的镜像就自带了所有需要的扩展,以后每次用这个镜像创建容器,扩展都在。
飞牛上Docder里面下载好Mysql 镜像步骤,在NAS的docker目录里新建mysql目录,用于存放所有mysql相关的文件
Mysql目录里面新建三个目录conf.d data log 三个子目录,用于存放配置文件,数据文件,日志文件
环境变量里增加两项,一个是时区,一个是需要设置下默认root用户的密码,部署好后登录用

在conf.d目录里新建文件custom.cnf ,你需要自定义的配置都写在里面,保存后记得需要设置文件权限,在NAS系统SSH里面设置
[mysqld] # 字符集 character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci # 时区 default-time-zone='+08:00' # 跳过域名解析 skip-name-resolve # 禁止本地文件导入 local_infile=0 # 连接配置 max_connections=500 max_connect_errors=1000 wait_timeout=28800 # 缓冲区(根据 NAS 内存调整) innodb_buffer_pool_size=1G innodb_redo_log_capacity=128M innodb_log_buffer_size=64M innodb_flush_log_at_trx_commit=2 # 日志 log_error=/var/log/mysql/error.log slow_query_log=1 slow_query_log_file=/var/log/mysql/slow.log long_query_time=2 # ========== 二进制日志配置 ========== # MySQL 9.x 使用 binlog_expire_logs_seconds(替代 expire_logs_days) # 604800 秒 = 7 天 binlog_expire_logs_seconds=604800 [client] default-character-set=utf8mb4
关于权限设置,999是mysql用户
chmod 644 vol1/1000/docker/mysql/conf.d/custom.cnf chown -R 999:999 /vol1/1000/docker/mysql/logs chown -R 999:999 /vol1/1000/docker/mysql/data chmod -R 777 /vol1/1000/docker/mysql/data chmod -R 755 /vol1/1000/docker/mysql/logs
在NAS系统SSH里面进数据库
root@nas:/vol1/1000/docker/nginx# docker exec -it mysql mysql -uroot -p
登录进MYSQL 后创建个新用户用于远程登录管理MYSQL
CREATE USER 'sjd'@'%' IDENTIFIED BY 'password'; # 授予所有权限(类似 root) GRANT ALL PRIVILEGES ON *.* TO 'sjd'@'%' WITH GRANT OPTION; # 刷新权限 FLUSH PRIVILEGES;
在ThinkPHP项目里面连接Mysql时,连接地址填写Mysql容器的名称即可,不用填写IP地址,因为它们在同一个网络里
Mysql设置自动备份脚本,新建setup-mysql-separate-backup.sh
#!/bin/bash
# setup-mysql-separate-backup.sh
echo "=== 设置 MySQL 单独备份(每个数据库独立备份) ==="
# 配置变量
MYSQL_DIR="/vol1/1000/docker/mysql/"
BACKUP_DIR="$MYSQL_DIR/backup/separate"
SCRIPTS_DIR="$MYSQL_DIR/scripts"
MYSQL_CONTAINER="mysql"
MYSQL_ROOT_PASSWORD="SJDxx2030../"
# 系统数据库(不备份)
SKIP_DBS="information_schema performance_schema mysql sys"
# 1. 创建目录
echo "1. 创建目录结构..."
mkdir -p "$BACKUP_DIR"
mkdir -p "$SCRIPTS_DIR"
chmod -R 755 "$BACKUP_DIR"
# 2. 创建单独备份脚本
echo "2. 创建单独备份脚本..."
cat > "$SCRIPTS_DIR/backup-separate.sh" << 'EOF'
#!/bin/bash
# MySQL 单独备份脚本(每个数据库独立备份)
# ========== 配置 ==========
MYSQL_CONTAINER="mysql"
MYSQL_ROOT_PASSWORD="SJDxx2030../"
BACKUP_DIR="/vol1/1000/docker/mysql/backup/separate"
KEEP_DAYS=30
LOG_FILE="/vol1/1000/docker/mysql/logs/backup-separate.log"
# 排除的系统数据库
SKIP_DBS="information_schema|performance_schema|mysql|sys"
# 获取当前日期和时间
DATE=$(date +%Y%m%d)
TIME=$(date +%H%M%S)
# ========== 日志函数 ==========
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# ========== 检查容器 ==========
if ! docker ps | grep -q "$MYSQL_CONTAINER"; then
log "❌ MySQL 容器未运行"
exit 1
fi
# ========== 开始备份 ==========
log " 本文为 小风原创文章,转载无需和我联系,但请注明来自 小风博客www.hotxf.com