Files
shop-platform/docker/php/entrypoint.sh

237 lines
6.8 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
set -e
echo "=== ThinkPHP Docker权限初始化 ==="
# 定义应用根目录,优先使用环境变量,否则使用默认值
APP_ROOT="${PHP_APP_ROOT:-/var/www/html}"
echo "使用应用根目录: $APP_ROOT"
# 获取正确的用户和组
if [ -n "$USER_ID" ] && [ -n "$GROUP_ID" ]; then
# 如果指定了用户ID修改www-data
usermod -u $USER_ID www-data
groupmod -g $GROUP_ID www-data
fi
echo "当前用户: $(whoami)"
echo "UID: $(id -u), GID: $(id -g)"
# 修复目录所有权和权限
fix_directory_permissions() {
local dir=$1
echo "修复PHP目录权限: $dir"
# 确保目录存在
mkdir -p "$dir"
# 设置所有权
chown -R www-data:www-data "$dir"
# 设置权限
chmod -R 775 "$dir"
# 设置setgid权限
chmod g+s "$dir"
# 尝试设置ACL如果支持
if command -v setfacl >/dev/null 2>&1; then
setfacl -dR -m u:www-data:rwx "$dir"
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 "$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用户]"
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 "=== 启动应用 ==="
# 执行原有的启动命令
exec "$@"