Docker化Rails应用中Webpacker编译失败问题求助
我之前在Docker化Rails+Webpacker项目时也踩过几乎一模一样的坑,咱们一步步拆解解决这些问题:
1. 「No such file or directory - yarn (Errno::ENOENT)」报错
原因
你的Rails应用容器里缺少yarn包管理器,Webpacker依赖yarn来管理前端依赖包,所以启动时找不到yarn命令。
解决方案
在你的Dockerfile中添加Node.js和yarn的安装步骤,注意匹配你本地开发环境的版本(Node 12.6.0、npm 6.11.3):
# 安装Node.js 12.x和yarn RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - \ && apt-get install -y nodejs \ && npm install -g npm@6.11.3 \ && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ && apt-get update && apt-get install -y yarn
确保这段代码放在安装Ruby和Bundle之后、复制项目文件之前,这样可以利用Docker缓存,加快构建速度。
2. 「Node Sass could not find a binding for your current environment: Linux 64-bit with Node.js 8.x」报错
原因
这个问题是Node Sass的二进制绑定版本和容器内的Node.js版本不匹配导致的——要么你容器里装的Node.js是8.x(和你声明的12.6.0不符),要么本地开发环境的node_modules被挂载到容器里,里面的Node Sass是针对本地系统编译的,不兼容容器的Linux环境。
解决方案
第一步:确保容器内Node版本正确
检查Dockerfile里的Node安装命令,确认安装的是12.6.0而不是默认的8.x。可以在Dockerfile里添加版本校验:RUN node --version | grep v12.6.0如果不匹配,调整nodesource的安装脚本为
setup_12.x(上面的Dockerfile示例已经包含)。第二步:避免挂载本地node_modules到容器
在docker-compose.yml的web服务volumes中,排除node_modules目录:volumes: - .:/app - /app/node_modules # 添加这一行,让容器使用自己的node_modules - /app/vendor/bundle这样可以防止本地的node_modules干扰容器内的依赖。
第三步:重新编译Node Sass
如果还是报错,进入容器执行重新编译命令:docker-compose exec web npm rebuild node-sass
3. 「ActionView::Template::Error (Webpacker can't find styles/application in /app/public/packs/manifest.json」报错
原因
Webpacker没有成功编译出styles/application对应的pack文件,可能是以下几种情况:
- Webpacker编译服务没有启动
- 编译命令没有执行
- Webpacker配置文件路径错误
解决方案
第一步:配置webpacker服务到docker-compose.yml
添加一个独立的webpacker服务负责前端编译,避免和Rails服务互相阻塞:version: '3' services: web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/app - /app/node_modules - /app/vendor/bundle ports: - "3000:3000" depends_on: - db - webpacker # 依赖webpacker服务 db: image: postgres:10 volumes: - postgres_data:/var/lib/postgresql/data/ webpacker: build: . command: ./bin/webpack-dev-server volumes: - .:/app - /app/node_modules ports: - "3035:3035" # webpack-dev-server默认端口 volumes: postgres_data:第二步:确保Webpacker编译命令执行
在开发环境下,webpack-dev-server会自动监听文件变化并编译,但首次启动时可以手动执行一次编译:docker-compose run web bundle exec rails webpacker:compile第三步:检查Webpacker配置
打开config/webpacker.yml,确认development环境下的配置:development: <<: *default compile: true dev_server: host: webpacker port: 3035 public: localhost:3035 hmr: true确保
dev_server.host指向webpacker服务的名称,这样Rails容器能正确访问webpack-dev-server。
最后检查点
- 确保
config/webpacker.yml里的public_output_path是packs,和报错里的路径一致 - 确认你的视图文件里引用的pack是正确的,比如
<%= stylesheet_pack_tag 'application' %> - 删掉本地的
yarn.lock和node_modules,重新构建容器,避免旧依赖干扰
内容的提问来源于stack exchange,提问作者Jake

