如何配置Docker运行Ruby on Rails开发环境 实现容器复用与服务扩展
问题1:Ruby on Rails 开发环境 Docker 最优配置方案
你当前遇到的每次启动都需要重新执行bundle install的问题,核心原因有两个:一是使用docker-compose run命令每次都会创建新容器,二是已安装的gem没有做持久化,容器销毁后依赖就丢失了。优化方案如下:
优化要点
- 优先拷贝Gemfile并执行依赖安装,最大化利用Docker镜像层缓存,只要Gemfile内容不变就不会重复安装依赖
- 新增持久化卷存储已安装的gem,避免容器重建后依赖丢失
- 日常启动使用
docker-compose up而非docker-compose run,需要进入容器执行命令时用docker-compose exec复用现有容器
优化后配置示例
Dockerfile.dev
FROM ruby:2.7.4-bullseye WORKDIR /apps/gaia_api # 提前拷贝Gemfile,利用镜像缓存避免重复安装依赖 COPY Gemfile Gemfile.lock ./ RUN gem install rails bundler # 建议此处指定和项目匹配的bundler版本,避免版本不兼容问题 RUN bundle install COPY . . EXPOSE 3000 # 开发环境默认启动Rails服务,也可根据需求改为/bin/bash CMD ["rails", "s", "-b", "0.0.0.0"]
docker-compose.yml
version: "3.8" # 顶层定义持久化卷,服务销毁后卷内数据不会丢失 volumes: bundle_cache: pg_data: services: gaia_api: build: dockerfile: Dockerfile.dev context: "." volumes: - .:/apps/gaia_api # 挂载gem缓存卷,所有已安装的gem会存在这个卷里 - bundle_cache:/usr/local/bundle environment: - USER_DB_RAILS - PASSWORD_DB_RAILS - DB_HOST=postgres ports: - "3000:3000" depends_on: - postgres
日常使用命令
- 首次启动:
docker-compose up --build自动构建镜像并启动所有服务 - 后续常规启动:
docker-compose up无需重新构建,也不需要重新执行bundle install - 进入运行中的容器执行命令(如生成器、数据库迁移):
docker-compose exec gaia_api bash - 仅当Gemfile改动后需要更新依赖时,执行
docker-compose build即可复用缓存更新依赖
问题2:是否支持扩展添加postgres、Vue项目等其他服务
完全支持,docker-compose本身就是为多服务编排设计的,只需要在配置文件的services字段下新增对应服务即可。
新增PostgreSQL服务示例
在services节点下添加以下配置即可:
postgres: image: postgres:13-alpine volumes: # 持久化数据库数据,避免容器重启后数据丢失 - pg_data:/var/lib/postgresql/data environment: - POSTGRES_USER=${USER_DB_RAILS} - POSTGRES_PASSWORD=${PASSWORD_DB_RAILS} ports: # 开发环境映射端口,可直接用本地数据库客户端连接 - "5432:5432"
新增Vue前端服务示例
在services节点下新增配置即可,容器之间可以直接通过服务名互相访问:
gaia_frontend: build: dockerfile: Dockerfile.frontend context: "./gaia_frontend" # 替换为你的Vue项目实际存放路径 volumes: - ./gaia_frontend:/app # 新增node_modules缓存卷,避免重复安装前端依赖 - node_modules:/app/node_modules ports: - "8080:8080" environment: # 直接通过Rails服务名调用后端接口,无需走公网 - VUE_APP_API_BASE=http://gaia_api:3000
记得在顶层volumes节点补充node_modules卷的声明:
volumes: bundle_cache: pg_data: node_modules:
内容的提问来源于stack exchange,提问作者otavio1992
相关产品推荐
相关产品推荐

