如何让AWS CodeDeploy在钩子间保持环境状态?
问题根源
AWS CodeDeploy的每个钩子脚本都是在独立的Shell会话中执行的,所以AfterInstall阶段里设置的RVM、Ruby环境变量不会自动传递到后续的ApplicationStart脚本中。这就是为什么你在AfterInstall里能正常运行bundle install,但ApplicationStart里找不到bundle命令的原因。
解决方案
要让ApplicationStart脚本能识别RVM和Ruby环境,需要做以下调整:
1. 修正RVM的安装方式(以普通用户ec2-user安装)
RVM推荐以普通用户身份安装,避免root权限带来的环境变量问题。修改你的install脚本,用ec2-user执行RVM和Ruby的安装步骤:
#!/bin/bash set -e # exit on error # 安装系统依赖(root权限执行) sudo yum install postgresql-devel -y sudo amazon-linux-extras install postgresql13 -y # 创建部署目录并设置权限 mkdir -p /var/www/timesheets chown ec2-user:ec2-user /var/www/timesheets # 以ec2-user身份安装RVM、Ruby和Bundler sudo -u ec2-user bash << EOF cd /var/www/timesheets curl -sSL https://rvm.io/mpapis.asc | gpg2 --import - curl -sSL https://rvm.io/pkuczynski.asc | gpg2 --import - curl -L get.rvm.io | bash -s stable # 加载RVM环境 source /home/ec2-user/.rvm/scripts/rvm # 安装指定Ruby版本并设为默认 rvm install ruby-3.1.0 --default gem install bundler EOF # 以ec2-user身份执行bundle install sudo -u ec2-user bash << EOF cd /var/www/timesheets/deployment bundle install EOF
2. 修改appspec.yml,让ApplicationStart以ec2-user运行
在ApplicationStart钩子中添加runas: ec2-user,确保脚本用安装RVM的用户执行:
version: 0.0 os: linux files: # copy files - source: / destination: /var/www/timesheets/deployment permissions: - object: /var/www/timesheets/deployment owner: ec2-user group: ec2-user hooks: BeforeInstall: - location: deploy/arrange_folders runas: root AfterInstall: - location: deploy/install timeout: 900 ApplicationStart: - location: deploy/start runas: ec2-user # 新增这一行
3. 在start脚本中显式加载RVM环境
因为每个钩子是独立进程,必须在start脚本开头手动加载RVM的初始化脚本:
#!/bin/bash set -e # exit on error # 加载ec2-user的RVM环境 source /home/ec2-user/.rvm/scripts/rvm # 若安装时未设默认版本,需手动切换 # rvm use ruby-3.1.0 cd /var/www/timesheets/deployment source /home/ec2-user/.env bundle exec puma -C config/puma.rb
补充建议
- 安装Ruby时加上
--default参数,后续无需手动执行rvm use即可直接使用对应版本。 - 生产环境中可使用RVM的
wrapper功能生成独立可执行文件路径,比如rvm wrapper ruby-3.1.0 puma,之后直接用/home/ec2-user/.rvm/wrappers/ruby-3.1.0/puma启动服务,彻底摆脱shell环境依赖。 - 预先在EC2实例的
ec2-user家目录配置好GPG密钥,避免每次部署重复下载导入,提升部署效率。
内容的提问来源于stack exchange,提问作者Toby
相关产品推荐
相关产品推荐

