Docker环境结合whenever使用backup gem的正确配置方法
环境信息
- Docker版本:20.10.10
- Docker基础镜像:Ruby 2.7.2
- 依赖Gem版本:
- Backup: 5.0.0.beta.3
- Rails: 6.1.5
- whenever: 1.0.0
问题现象
在schedule.rb中配置如下定时任务:
every 1.minute do command "/usr/local/bundle/bin/backup perform -t db_backup -c /app/Backup/config.rb" end
在容器交互bash中手动执行上述backup命令可正常运行,但cron定时触发时抛出如下错误:
/usr/local/lib/ruby/2.7.0/rubygems.rb:277:in `find_spec_for_exe': can't find gem backup (>= 0.a) with executable backup (Gem::GemNotFoundException) from /usr/local/lib/ruby/2.7.0/rubygems.rb:296:in `activate_bin_path' from /usr/local/bundle/bin/backup:23:in `<main>'
问题根因
手动进入容器bash时,shell会自动加载/etc/profile、~/.bashrc等初始化配置,Ruby、Gem、Bundler的相关路径已经被注入环境变量,因此可以正常找到backup命令。
而cron执行任务时使用独立的极简运行环境,默认不会加载上述shell初始化文件,缺失GEM_PATH、PATH等关键环境变量,无法定位到已安装的backup gem,因此抛出找不到gem的错误。
正确配置步骤
- 修改
schedule.rb,在文件最开头注入cron运行所需的环境变量,直接读取当前容器环境的对应配置写入crontab:
# 同步必要的运行环境变量到cron env :PATH, ENV['PATH'] env :GEM_HOME, ENV['GEM_HOME'] env :GEM_PATH, ENV['GEM_PATH'] env :BUNDLE_PATH, ENV['BUNDLE_PATH'] every 1.minute do # 先切换到项目根目录,通过bundle exec执行backup命令,确保加载正确的Gem依赖 command "cd /app && bundle exec backup perform -t db_backup -c /app/Backup/config.rb" end
- 重新生成crontab配置,在容器内执行如下命令让whenever更新定时任务:
whenever --update-crontab
- 验证配置是否生效,执行
crontab -l查看生成的定时任务,确认头部已经包含配置的PATH、GEM_HOME等环境变量,任务命令与配置一致即可。
注意:如果容器内使用非root用户运行cron,需要确认该用户对
/usr/local/bundle路径、项目备份路径有读写权限,避免出现权限类错误。
内容的提问来源于stack exchange,提问作者hengsokly
相关产品推荐
相关产品推荐

