chore(docker): 更新docker配置,解决多余的执行步骤

This commit is contained in:
2025-12-25 09:34:07 +08:00
parent 2eb98efe61
commit f461fe93f0
3 changed files with 27 additions and 211 deletions

View File

@@ -25,9 +25,13 @@ services:
# 不然ThinkPHP 6.x 系列,会只加载 .env 文件,而不会加载 .env.local 文件,导致 .env.local 文件中的配置不会生效
APP_ENV: ${APP_ENV:-development}
APP_DEBUG: ${APP_DEBUG:-true}
# PHP应用根目录可选默认 /var/www/html
PHP_APP_ROOT: ${PHP_APP_ROOT:-/var/www/html}
# 用户ID映射可选用于解决挂载权限问题
USER_ID: ${USER_ID:-33}
GROUP_ID: ${GROUP_ID:-33}
volumes:
- ./:/var/www/all_source
- ./src:/var/www/html
- ./src:/var/www/html:rw
# 更新下载源列表以加速apt-get
- ./docker/debian/sources.list:/etc/apt/sources.list:ro
- ./docker/php/php.ini:/usr/local/etc/php/php.ini:ro

View File

@@ -18,219 +18,40 @@ fi
echo "当前用户: $(whoami)"
echo "UID: $(id -u), GID: $(id -g)"
# 修复目录所有权和权限
fix_directory_permissions() {
local dir=$1
echo "修复PHP目录权限: $dir"
# 确保目录存在
mkdir -p "$dir"
# 修复所有目录权限(处理挂载覆盖问题,一次性处理)
if [ -d "$APP_ROOT" ]; then
echo "修复应用目录权限(处理 Docker 挂载覆盖问题)"
# 设置所有权
chown -R www-data:www-data "$dir"
chown -R www-data:www-data "$APP_ROOT"
# 设置权限
chmod -R 775 "$dir"
# 设置目录权限和setgid
find "$APP_ROOT" -type d -exec chmod 775 {} \;
find "$APP_ROOT" -type f -exec chmod 664 {} \;
find "$APP_ROOT" -type d -exec chmod g+s {} \;
# 设置setgid权限
chmod g+s "$dir"
# 尝试设置ACL如果支持
# 设置ACL如果支持
if command -v setfacl >/dev/null 2>&1; then
setfacl -dR -m u:www-data:rwx "$dir"
setfacl -dR -m u:www-data:rwx "$APP_ROOT" 2>/dev/null || echo "ACL 设置失败,继续执行"
fi
find "$dir" -type d -exec chmod 775 {} \;
find "$dir" -type f -exec chmod 775 {} \;
find "$dir" -type d -exec chmod g+s {} \;
find "$dir" -type f -exec chmod g+s {} \;
# 设置umask
umask 0002
echo "✅ 应用目录权限修复完成"
echo "$dir 权限设置完成, 目录权限: $(stat -c '%a %n' "$dir"), setgid权限: $(stat -c '%a %n' "$dir" | grep 's')"
}
# 处理所有需要权限的目录
directories=("addon" "app" "config" "extend" "public" "runtime" "upload" "runtime/log" "runtime/cache" "runtime/temp")
for dir in "${directories[@]}"; do
fix_directory_permissions "$APP_ROOT/$dir"
done
# 验证权限
echo "=== 权限验证 ==="
echo "当前用户: $(whoami)"
echo "当前UID: $(id -u), GID: $(id -g)"
echo "当前umask: $(umask)"
# 验证www-data用户是否可以在runtime和upload目录下新建子目录
# 方法1使用sudo
if command -v sudo >/dev/null 2>&1; then
echo "使用sudo测试..."
if sudo -u www-data mkdir -p $APP_ROOT/runtime/log/test_dir 2>/dev/null; then
echo "✅ sudo: runtime目录创建子目录成功 [使用www-data用户]"
rm -rf $APP_ROOT/runtime/log/test_dir
else
echo "❌ sudo: runtime目录创建子目录失败 [使用www-data用户]"
# 验证文件权限是否足够
echo "=== 验证文件权限 ==="
test_file="$APP_ROOT/index.php"
if [ -f "$test_file" ]; then
echo "测试文件: $test_file"
echo "文件权限: $(stat -c '%a %n' "$test_file")"
echo "www-data 用户测试读权限: $(su -s /bin/sh -c "cat '$test_file' >/dev/null && echo '✅ 可读' || echo '❌ 不可读'" www-data 2>/dev/null || '无法测试')"
echo "www-data 用户测试写权限: $(su -s /bin/sh -c "echo 'test' >> '$test_file.test' && rm '$test_file.test' && echo '✅ 可写' || echo '❌ 不可写'" www-data 2>/dev/null || '无法测试')"
fi
fi
# 方法2使用su
echo "使用su测试..."
if su -s /bin/sh -c "mkdir -p $APP_ROOT/runtime/log/test_dir" www-data 2>/dev/null; then
echo "✅ su: runtime目录创建子目录成功 [使用www-data用户]"
rm -rf $APP_ROOT/runtime/log/test_dir
else
echo "❌ su: runtime目录创建子目录失败 [使用www-data用户]"
fi
# 方法3使用runuser
if command -v runuser >/dev/null 2>&1; then
echo "使用runuser测试..."
if runuser -u www-data -- mkdir -p $APP_ROOT/runtime/log/test_dir 2>/dev/null; then
echo "✅ runuser: runtime目录创建子目录成功 [使用www-data用户]"
rm -rf $APP_ROOT/runtime/log/test_dir
else
echo "❌ runuser: runtime目录创建子目录失败 [使用www-data用户]"
fi
fi
# 检查www-data用户和组
echo "检查www-data用户..."
id www-data
groups www-data
# 检查目录的实际权限
echo "检查目录权限..."
for dir in "${directories[@]}"; do
echo "检查目录权限: $dir"
ls -ld "$APP_ROOT/$dir"
done
echo "检查setgid权限..."
for dir in "${directories[@]}"; do
echo "检查setgid权限: $dir"
stat -c '%a %n' "$APP_ROOT/$dir" | grep 's'
done
echo "=== 检测 PHP 执行用户 ==="
# 检查命令可用性函数
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# 方法1通过 PHP 脚本检测当前用户
echo "方法1: 通过 PHP 检测当前执行用户"
if command_exists php; then
php -r "
if (function_exists('get_current_user')) {
echo '当前 PHP 执行用户: ' . get_current_user() . PHP_EOL;
} else {
echo 'get_current_user() 函数不可用' . PHP_EOL;
}
if (function_exists('getmyuid')) {
echo '当前用户 ID: ' . getmyuid() . PHP_EOL;
} else {
echo 'getmyuid() 函数不可用' . PHP_EOL;
}
if (function_exists('getmygid')) {
echo '当前组 ID: ' . getmygid() . PHP_EOL;
} else {
echo 'getmygid() 函数不可用' . PHP_EOL;
}
if (function_exists('posix_geteuid') && function_exists('posix_getpwuid')) {
echo '当前进程用户: ' . posix_getpwuid(posix_geteuid())['name'] . PHP_EOL;
} else {
echo 'posix 函数不可用,尝试系统方法' . PHP_EOL;
echo '当前用户: ' . exec('whoami') . PHP_EOL;
}
" 2>/dev/null || echo "PHP 执行检测失败"
else
echo "❌ PHP 命令不可用,跳过检测"
fi
# 方法2通过进程检测 PHP-FPM 运行用户
echo "方法2: 检测 PHP-FPM 进程用户"
if command_exists pgrep; then
if pgrep php-fpm > /dev/null 2>&1; then
if command_exists ps; then
ps aux | grep php-fpm | grep -v grep | head -3 2>/dev/null || echo "进程检测失败"
else
echo "ps 命令不可用,但找到 PHP-FPM 进程"
fi
else
echo "PHP-FPM 进程未运行"
fi
else
echo "pgrep 命令不可用,尝试其他方法"
if command_exists ps; then
echo "使用 ps 直接检测:"
ps aux | grep php-fpm | grep -v grep | head -3 2>/dev/null || echo "未找到 PHP-FPM 进程"
else
echo "ps 和 pgrep 命令都不可用,无法检测进程"
fi
fi
# 方法3检测配置文件中的用户设置
echo "方法3: 检查配置文件中的用户设置"
# PHP-FPM 配置检查
php_fpm_configs=(
"/usr/local/etc/php-fpm.d/www.conf"
"/etc/php-fpm.d/www.conf"
"/usr/local/etc/php-fpm.conf"
"/etc/php-fpm.conf"
)
for config_file in "${php_fpm_configs[@]}"; do
if [ -f "$config_file" ]; then
echo "找到 PHP-FPM 配置: $config_file"
if command_exists grep; then
echo "PHP-FPM 用户配置:"
grep -E "^user|^group" "$config_file" 2>/dev/null || echo "未找到用户配置行"
else
echo "grep 命令不可用,但配置文件存在"
fi
break
fi
done
# Nginx 配置检查
nginx_configs=(
"/etc/nginx/nginx.conf"
"/usr/local/nginx/conf/nginx.conf"
"/etc/nginx/conf/nginx.conf"
)
for config_file in "${nginx_configs[@]}"; do
if [ -f "$config_file" ]; then
echo "找到 Nginx 配置: $config_file"
if command_exists grep; then
echo "Nginx 用户配置:"
grep -E "^user" "$config_file" 2>/dev/null || echo "未找到用户配置行"
else
echo "grep 命令不可用,但配置文件存在"
fi
break
fi
done
# 方法4使用 /proc 文件系统检测(如果其他方法都失败)
echo "方法4: 使用 /proc 文件系统检测"
if [ -d "/proc" ]; then
echo "当前脚本执行用户: $(whoami 2>/dev/null || echo 'whoami 命令不可用')"
echo "当前脚本用户 ID: $(id -u 2>/dev/null || echo 'id 命令不可用')"
else
echo "/proc 目录不可用"
fi
echo "=== 启动应用 ==="
# 执行原有的启动命令

View File

@@ -6,15 +6,6 @@ logfile_backups=10
loglevel=info
pidfile=/var/run/supervisord.pid
[program:php-permission-change]
command=/bin/bash -c "sleep 15 && /usr/local/bin/entrypoint.sh"
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stdout_logfile=/var/log/supervisor/php-permission-change.log
stderr_logfile=/var/log/supervisor/php-permission-change-error.log
[program:php-fpm]
command=php-fpm
autostart=true