Files
shop-platform/docs/CRON_ENV_SETUP.md

7.0 KiB
Raw Permalink Blame History

Cron 任务环境变量配置指南

🎯 问题:如何为 nohup php think cron:schedule 指定 .env 文件

解决方案

最重要的部分

我们修改了项目目录下的 think 文件的内容,增加了读取环境变量的代码

#!/usr/bin/env php
<?php
namespace think;

// 命令行入口文件
// 加载基础文件
require __DIR__ . '/vendor/autoload.php';

// 创建应用程序
$app = new App();

// 您的代码使用APP_ENV
$appEnv = getenv('APP_ENV') ?: '';
if ($appEnv) {
    $envFile = __DIR__ . '/.env.' . $appEnv;
    if (is_file($envFile)) {
        $app->env->load($envFile);
    }
}

// 应用初始化
$app->console->run();

方案一:使用环境变量(推荐)

# 1. 临时设置环境变量(当前会话有效)
export THINK_ENV=production
nohup php think cron:schedule > /dev/null 2>&1 &

# 2. 永久设置环境变量(写入 ~/.bashrc
echo 'export THINK_ENV=production' >> ~/.bashrc
source ~/.bashrc
nohup php think cron:schedule > /dev/null 2>&1 &

# 3. 直接传递环境变量
THINK_ENV=production nohup php think cron:schedule > /dev/null 2>&1 &

方案二:指定不同的 .env 文件

# 1. 复制环境配置文件
cp .env .env.production
# 编辑 .env.production 修改相应配置

# 2. 使用 APP_ENV 指定环境
APP_ENV=production nohup php think cron:schedule > /dev/null 2>&1 &

# 3. 或者在运行时指定
php think cron:schedule --env=production

方案三:自定义启动脚本(最佳实践)

创建专用启动脚本 start_cron.sh

#!/bin/bash

# 设置环境变量
export THINK_ENV=${1:-production}

# 设置工作目录
cd /path/to/your/project

# 日志文件路径
LOG_FILE="/var/log/cron_${THINK_ENV}.log"

# 启动 cron 任务
echo "Starting cron with environment: $THINK_ENV"
nohup php think cron:schedule > $LOG_FILE 2>&1 &

# 记录进程ID
echo $! > /var/run/cron_${THINK_ENV}.pid

echo "Cron started with PID: $(cat /var/run/cron_${THINK_ENV}.pid)"

使用方法:

chmod +x start_cron.sh

# 启动生产环境 cron
./start_cron.sh production

# 启动开发环境 cron  
./start_cron.sh development

🔧 ThinkPHP 6.x 环境变量加载机制

ThinkPHP 自动加载顺序:

  1. 服务器环境变量: $_SERVER['APP_ENV']
  2. 系统环境变量: getenv('APP_ENV')
  3. .env 文件: 根据环境变量加载对应的 .env.* 文件

支持的环境变量:

变量名 作用 示例
APP_ENV 指定运行环境 production
THINK_ENV ThinkPHP 6.x 环境标识 production
ENV_PATH 自定义 .env 文件路径 /custom/path/.env

📁 环境配置文件结构

project/
├── .env                    # 默认配置
├── .env.development        # 开发环境
├── .env.testing          # 测试环境
├── .env.staging          # 预发布环境
└── .env.production      # 生产环境

🚀 实际使用示例

Docker 环境中的使用

# Dockerfile 中设置环境变量
ENV THINK_ENV=production

# 或者在 docker-compose.yml 中
environment:
  - THINK_ENV=production
  - MYSQL_HOST=mysql
  - MYSQL_PORT=3306

Supervisor 配置

[program:cron-production]
command=/usr/bin/php /var/www/html/think cron:schedule
environment=THINK_ENV=production
directory=/var/www/html
autostart=true
autorestart=true
user=www-data
stdout_logfile=/var/log/supervisor/cron-production.log
stderr_logfile=/var/log/supervisor/cron-production-error.log

[program:cron-development]  
command=/usr/bin/php /var/www/html/think cron:schedule
environment=THINK_ENV=development
directory=/var/www/html
autostart=false
autorestart=true
user=www-data
stdout_logfile=/var/log/supervisor/cron-development.log
stderr_logfile=/var/log/supervisor/cron-development-error.log

系统服务配置

# 创建 systemd 服务文件
sudo tee /etc/systemd/system/think-cron.service > /dev/null <<EOF
[Unit]
Description=ThinkPHP Cron Scheduler
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/html
Environment=THINK_ENV=production
ExecStart=/usr/bin/php /var/www/html/think cron:schedule
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

# 启用并启动服务
sudo systemctl enable think-cron
sudo systemctl start think-cron

🔍 验证配置

检查当前环境

# 1. 在 cron 任务中添加日志
php think cron:schedule --verbose

# 2. 检查环境变量
php -r "echo 'APP_ENV: ' . getenv('APP_ENV') . PHP_EOL;"
php -r "echo 'THINK_ENV: ' . getenv('THINK_ENV') . PHP_EOL;"

# 3. 检查 ThinkPHP 加载的配置
php think config:get app.env

测试不同环境

# 测试生产环境
APP_ENV=production php think cron:schedule --verbose

# 测试开发环境  
APP_ENV=development php think cron:schedule --verbose

# 使用指定配置文件
THINK_ENV=staging php think cron:schedule --verbose

📝 日志和监控

日志配置

# 按环境分离日志
nohup php think cron:schedule > logs/cron_${APP_ENV:-default}.log 2>&1 &

# 带时间戳的日志
nohup php think cron:schedule > logs/cron_$(date +%Y%m%d).log 2>&1 &

进程监控

# 检查 cron 进程
ps aux | grep "think cron:schedule" | grep -v grep

# 使用 pgrep 查找进程ID
pgrep -f "think cron:schedule"

# 监控脚本
#!/bin/bash
while true; do
    if ! pgrep -f "think cron:schedule"; then
        echo "$(date): Cron process died, restarting..."
        nohup php think cron:schedule > logs/cron.log 2>&1 &
    fi
    sleep 30
done

🎯 推荐配置

生产环境最佳实践

# 1. 使用环境变量指定配置
export APP_ENV=production

# 2. 设置适当的日志级别
nohup php think cron:schedule --quiet > /var/log/cron.log 2>&1 &

# 3. 定期检查进程状态
*/5 * * * * * /usr/bin/pgrep -f "think cron:schedule" || /usr/bin/nohup /usr/bin/php /var/www/html/think cron:schedule > /var/log/cron.log 2>&1 &

开发环境配置

# 1. 使用开发环境配置
export APP_ENV=development

# 2. 显示详细输出用于调试
nohup php think cron:schedule > /dev/null 2>&1 &

# 3. 实时查看日志
tail -f logs/cron_dev.log

本地开发环境配置

# 1. 使用开发环境配置
export APP_ENV=local

# 2. 显示详细输出用于调试
nohup php think cron:schedule > /dev/null 2>&1 &

# 3. 实时查看日志
tail -f logs/cron_dev.log

总结

答案:是的,可以为 nohup php think cron:schedule 指定 .env 文件!

推荐方法:

  1. 使用 APP_ENV=production 环境变量
  2. 创建对应的 .env.production 文件
  3. 使用自定义启动脚本管理不同环境

这样可以让同一套代码在不同环境中使用不同的数据库配置、缓存配置等。