基于Fargate部署Rails应用:标准方式与Puma配置疑问
在Fargate上部署Rails应用:Puma实践指南
明确说一句:Fargate上完全可以运行Puma,这才是生产环境的标准操作,用rails s只是开发环境图方便的做法,生产环境没人这么玩。
为啥不能用rails s?
rails s默认启动的是WEBrick服务器,这货是单线程单进程的开发专用服务器,确实一次只能处理一个请求,性能差到离谱,根本扛不住生产流量。
在Fargate容器里跑Puma的正确步骤
1. 配置Puma
确保你的Rails项目里有config/puma.rb配置文件,参考示例:
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } threads min_threads_count, max_threads_count # 根据Fargate分配的CPU/内存调worker数,一般1核CPU对应2-4个worker就行 workers ENV.fetch("WEB_CONCURRENCY") { 2 } app_dir = File.expand_path("../..", __FILE__) shared_dir = "#{app_dir}/shared" # 绑定0.0.0.0才能让外部访问到容器里的Puma bind "tcp://0.0.0.0:3000" environment ENV.fetch("RAILS_ENV") { "production" } # 日志和PID文件配置,方便排查问题 stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true pidfile "#{shared_dir}/pids/puma.pid" state_path "#{shared_dir}/pids/puma.state" # 可选:启用Puma控制端,方便管理进程 activate_control_app
2. 编写Dockerfile
在Dockerfile里指定启动命令为Puma,替换掉rails s,示例:
# 这里省略基础镜像安装、bundle install等步骤... # 设置生产环境变量 ENV RAILS_ENV=production ENV RAILS_MAX_THREADS=5 ENV WEB_CONCURRENCY=2 # 预编译静态资产 RUN bundle exec rails assets:precompile # 启动Puma服务 CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
3. Fargate任务配置
- 资源分配:根据Puma的worker和线程数调整CPU/内存,比如1vCPU + 2GB内存足够支撑2-3个worker,每个worker配5个线程,能充分利用资源。
- 端口映射:把容器的3000端口映射到Fargate任务的端口,然后通过AWS ALB(应用负载均衡)对外提供服务——这时候容器里不需要跑Nginx,ALB可以搞定反向代理、负载均衡、SSL终止这些活儿。
- 健康检查:给ALB配置健康检查路径(比如
/health),确保Puma服务正常运行,避免把流量打到挂掉的实例上。
关于Nginx的取舍
如果你确实需要Nginx的某些功能(比如复杂路由、静态文件缓存),有两种方案:
- 多阶段构建Docker镜像:先构建Rails应用,再添加Nginx层,配置Nginx反向代理到Puma的TCP端口或者Unix Socket。
- Sidecar容器模式:在Fargate任务里同时跑Nginx容器和Puma容器,两者通过本地网络通信,ALB流量先到Nginx,再转发给Puma。不过这种方式会占用更多资源,大部分场景下ALB已经够用,没必要多此一举。
总结
Fargate上部署Rails的生产标准方案就是用Puma当应用服务器,搭配ALB做负载均衡,完全没必要用rails s。通过调整Puma的worker和线程数,能充分发挥Fargate的资源优势,实现高并发请求处理。
内容的提问来源于stack exchange,提问作者l33z3r
相关产品推荐
相关产品推荐

