标签:react

Docker跑NodeJS的同步问题

一直MacOSX本地做开发,没遇到过Watch同步文件不了的问题。最近在skaffold + minikube + React下跑开发环境,居然无法触发WebpackDevServer的Watch刷新,折腾了些时间。

用的是create-react-app建的基于TypeScript的环境,eject了webpack设定,本地跑能watch,在skaffold的manual sync下模式就不行了。skaffold有两个模式,一个是默认模式,一旦有文件修改就重建整个容器,能动但是慢;另一个是manual sync,可以把文件自动同步进容器内,触发容器内的开发服务器重编译或者HotReload,是做本地开发比较现实的方案。

开始以为是skaffold设置问题,但是进容器内能看到文件的确被同步成功;又以为是create-react-app的问题,检查了也是能跑的。奇怪的是明明同样的设置,我的机器却跑不了;明明跑python flask没问题,node却不能动。

后来调试时一不小心触发了提示:

Error: ENOSPC: System limit for number of file watchers reached

ENOSPC指的是没有空间,常见的一般有两种问题:一是真的没空间了,还有一种是inode不足。而这次这个则是file watcher不足。

Webpack官方对这个问题给出了解答:改内核的监视器数目限制。我用的node:10.15.3-alpine,默认数量才8192,对很多Node应用是不够的。其实同样的问题以前用golang在ubuntu做服务器编程,监视log文件时也遇到过,没想到会在写React时再被恶心一次。

因为是内核问题,在Docker容器内部是改不了的,必须进node里改。Production跑的是编译版可以不用动,只改开发用的minikube就可以了。minikube ssh进去

echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p

一下就好,不用重启,连进pod就能看到更新。

不止是docker,理论上来说用ubuntu这类内核默认设定比较保守的linux发行版做开发都应该很容易遇到同样的问题。据说VS Code在Ubuntu跑的时候就会显示:

Visual Studio Code is unable to watch for file changes in this large workspace

新的PC还没到,提早碰上这个问题也是个好事。打算去skaffold开个ticket警告各位。