MacBook Pro(M1)本地Docker运行Rails应用性能过慢优化咨询
Rails应用Docker开发性能优化(M1 MacBook Pro)
问题背景
设备:MacBook Pro(M1,2020),系统版本12.0.1
将Rails应用迁移至Docker开发环境后,应用可正常运行,但本地性能极差,寻求优化方案及配置问题排查。
环境配置信息
Rails版本
rails (5.2.8.1)
Dockerfile
FROM ruby:2.5.9 ENV INSTALL_PATH /opt/app RUN mkdir -p $INSTALL_PATH RUN apt-get update && apt-get install -y \ # curl \ # chromium \ build-essential \ libpq-dev \ curl -sL https://deb.nodesource.com/setup_14.x | bash - && \ apt-get update && apt-get install -y nodejs RUN gem install bundler -v 2.3.26 COPY Gemfile Gemfile COPY Gemfile.lock Gemfile.lock RUN bundle config build.nokogiri --use-system-libraries RUN bundle install WORKDIR /opt/app/core-project VOLUME ["$INSTALL_PATH/public"] # For Rails EXPOSE 4000
config/database.yml
development: adapter: postgresql url: postgresql://postgres@host.docker.internal:5432/coredb?encoding=utf8&pool=5&timeout=5000
docker-compose.yml
version: "3.7" services: redis: image: redis:6.2 rails-server: build: context: . args: USER_ID: "${USER_ID:-1000}" GROUP_ID: "${GROUP_ID:-1000}" command: ["bundle", "exec", "rails", "s", "-b", "0.0.0.0"] depends_on: - redis volumes: - type: bind source: ./ target: /opt/app/core-project ports: - '4000:3000' env_file: - .env sidekiq: build: context: . args: USER_ID: "${USER_ID:-1000}" GROUP_ID: "${GROUP_ID:-1000}" command: ["bundle", "exec", "sidekiq"] depends_on: - redis volumes: - type: bind source: ./ target: /opt/app/core-project env_file: - .env
application.rb
# Added to resolve the segmentation issue when running the application in Docker. config.assets.configure do |env| env.export_concurrent = false end
配置问题排查
- Dockerfile路径逻辑混乱:当前在容器根目录执行
bundle install后才切换到项目目录,虽不影响运行,但建议调整为提前切换工作目录再复制Gemfile,避免路径冗余:WORKDIR $INSTALL_PATH COPY Gemfile Gemfile.lock ./ RUN bundle install WORKDIR $INSTALL_PATH/core-project - 端口配置不一致:Dockerfile暴露4000端口,但docker-compose将容器3000端口映射到宿主机4000,属于配置冗余,可统一为一致端口。
- 数据库网络开销:使用
host.docker.internal连接本地PostgreSQL,M1设备上容器与宿主机的网络通信存在额外延迟,建议将PostgreSQL纳入docker-compose服务。
性能优化方案
1. Docker Desktop基础配置优化
- 分配充足资源:打开Docker Desktop偏好设置→资源,分配至少4核CPU、8GB内存(根据设备剩余资源调整),避免资源瓶颈。
- 启用Rosetta模拟:在偏好设置→特性中勾选"使用Rosetta for x86/amd64模拟",
ruby:2.5.9为amd64架构镜像,Rosetta可大幅降低模拟性能损耗。 - 切换文件共享机制:在偏好设置→资源→文件共享中选择
virtiofs(Docker Desktop 4.6+支持),替代默认的gRPC FUSE,提升绑定挂载的文件IO性能。
2. 优化绑定挂载(核心优化点)
Mac的Docker绑定挂载IO性能天生较弱,通过以下方式减少同步开销:
- 隔离高频读写目录:在docker-compose的volumes中添加匿名卷,避免容器内临时目录与宿主机同步:
volumes: - .:/opt/app/core-project - /opt/app/core-project/tmp # 隔离临时文件目录 - /opt/app/core-project/log # 隔离日志目录 - /opt/app/core-project/node_modules # 隔离前端依赖目录 - 用Docker卷替代绑定挂载:对于不需要实时同步的目录(如assets编译产物),改用Docker卷存储,减少宿主机与容器的文件交互。
3. 数据库优化
- 将PostgreSQL纳入docker-compose:避免跨容器-宿主机的网络延迟,添加postgres服务:
同时修改services: postgres: image: postgres:13-alpine volumes: - postgres_data:/var/lib/postgresql/data environment: POSTGRES_USER: postgres POSTGRES_DB: coredb POSTGRES_HOST_AUTH_METHOD: trust volumes: postgres_data:config/database.yml的连接地址:development: adapter: postgresql url: postgresql://postgres@postgres:5432/coredb?encoding=utf8&pool=10&timeout=5000 - 调整连接池大小:将
pool从5调至10-20,适配Rails开发模式下的并发请求。
4. 镜像架构优化
优先使用arm64架构的Ruby镜像,避免Rosetta模拟的性能损耗:
- 检查
ruby:2.5.9是否有arm64版本,若有则直接使用;若没有,改用ruby:2.5.9-alpine(体积更小、性能更优),或基于arm64基础镜像构建自定义Ruby环境。
5. Rails开发模式优化
- 开启开发缓存:执行
bundle exec rails dev:cache,启用开发模式缓存,减少重复的视图渲染、资产编译等操作。 - 用Spring加速启动:修改docker-compose的rails-server命令为
["spring", "bundle", "exec", "rails", "s", "-b", "0.0.0.0"],Spring常驻Ruby进程,大幅缩短应用启动和代码重载时间。 - 关闭不必要的资产编译:在
config/environments/development.rb中设置:
减少开发模式下的资产编译开销。config.assets.debug = true config.assets.compile = false
6. Sidekiq优化
- 与rails-server一致,在volumes中隔离tmp、log等目录;
- 调整Sidekiq并发数:在启动命令中添加
-c 10(建议为CPU核数的2倍),提升任务处理效率:command: ["bundle", "exec", "sidekiq", "-c", "10"]
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

