以前一直是前后端分离,最近实在是受不了 react 和 rails api 切来切去的人格分裂,于是退回到 rails 渲染 前端
说实在的,在页面不复杂的情况下 ( 小型内部用邮件,短信,身份核验管理 ),套一个 bootstrap sb2 admin 的模板,turbolinks + SRJ, 比折腾 antd 强很多
很快开发就结束了,就只剩下部署。
我的部署机器是这样规划的:有两台机器 club_001 和 club_002 001 有公网 IP, 002 没有,同时 002 的性能剩余稍多
我的这个小项目就打算部署到 002 上,之后由于 002 上是没有装 nginx 的,直接由 001 upstream 过来
这里遇到了第一个麻烦之处:
由于 nginx 是装在 001 上的,而项目在 002 上,所以 002 生成的静态文件,是没有办法直接被 nginx 访问到的
(下面常规的 nginx 配置是有问题的,因为 nginx 无法访问到 002 的 /var/www/tube_center/current/public)
server {
listen 80;
listen 443 ssl;
ssl_certificate /root/.acme.sh/cer;
ssl_certificate_key /root/.acme.sh/key;
server_name tubecenter.xxxxx.com;
root /var/www/tube_center/current/public;
try_files $uri/index.html $uri @puma_tubecenter_production;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location @puma_tubecenter_production {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_pass http://puma_tubecenter_production;
}
if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){
return 405;
}
}
怎么解决?最简单的 就是在 cap 的 assets:compile after 加上脚本进行拷贝,只不过因为要改 deploy , 遂放弃
我选择了另一种方案,就是在 001 也部署这个项目,但是这个项目仅仅只做 precompile 就好了,以后万一需要也负载到 001 号机器,也修改最少
于是,修改 deploy.rb 文件
server "club-api001", roles: %w{web}
server "club-api002", roles: %w{web app db}
默认 web 会生成 assets, puma 会运行在 app 上
之后执行 cap production deploy
一切正常,但是访问的时候,出现了问题
css 加载不出来,
我看源码,编译正常 css 和 js 都有 fingerprint, 而且 js 的竟然还能访问,
于是我登录两台机器查看究竟,
发现两台机器编译出来的 css fingerprint, 竟然不一致
同时,我又发现另外一个我自己写的 devise.css 的是一致的,
所以推论得出 scss 应该工作的是正常的,
那么问题就出在了 application.css
cat 这两个文件,格式化 放到 text differ 进行对比,发现了一个有意思的地方
看起来似乎是循环下的随机数,于是以 css class name 为搜索条件,去搜索 发现了一个 sb2 admin template 留给我的惊喜
// _error.scss
@keyframes noise-anim {
$steps: 20;
@for $i from 0 through $steps {
#{percentage($i*(1/$steps))} {
clip: rect(random(100)+px,9999px,random(100)+px,0);
}
}
}
这里看到 有一个叫做 random
的函数
在此最终找到原因
scss 在编译的时候,由于使用了随机数,导致了每次编译的 css 文件都 不一样, 所以 css 的最终内容不一致 所以 在 002 号的 puma 就找不到 001 里和自己生成的 assets 一样的文件
解决的办法也很简单,就把 random 函数去掉,用固定值即可
最后在重新编译的时候并未发现 assets 里的文件变化,于是修改 initializers/assets.rb 文件里的
Rails.application.config.assets.version = '2.1' # 新编号
即可重新编译 assets
至此,css 的 fingerprint 不一致的问题 就这样解决了。
其实实际中解决的比较着急,因为太久没有做 rails 的前端了,很多地方都在瞎猜,搞了很多 对比环境的工作,打 docker 什么的,方向走的不对
最后总结下: