项目部署到服务器(DigitalOcean), 其它正常,但上传图片会 500。
而我本机操作时,上传图片是正常的。
本来猜想是 capistrano 的问题,想到在不同版本应共享 public/uploads 文件夹下的所有上传文件。所以,我在config/deploy.rb
中设置了
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads}
所以目前,public/uploads 在服务器上是应该是 shared 目录下的。
# 看到当前deploy版本的确链接过去了
root@a_project:/home/a_project/current/public# ls -l
total 3340
-rw-rw-r-- 1 root root 1507 Jan 26 03:11 404.html
-rw-rw-r-- 1 root root 1508 Jan 26 03:11 422.html
-rw-rw-r-- 1 root root 1502 Jan 26 03:11 500.html
drwxrwxr-x 5 root root 4096 Jan 26 03:14 assets
-rw-rw-r-- 1 root root 2550 Jan 26 03:11 favicon.ico
drwxrwxr-x 2 root root 4096 Jan 26 03:11 images
-rw-rw-r-- 1 root root 202 Jan 26 03:11 robots.txt
lrwxrwxrwx 1 root root 33 Jan 26 03:13 system -> /home/a_project/shared/public/system
lrwxrwxrwx 1 root root 34 Jan 26 03:14 uploads -> /home/a_project/shared/public/uploads
# 看到这个目录的权限应该还是root
root@a_project:/home/a_project/shared/public# ls -l
total 8
drwxr-xr-x 2 root root 4096 Jan 21 22:48 system
drwxr-xr-x 2 root root 4096 Jan 26 03:12 uploads
可是,当我上传图片,还是会出错。查看 nginx 出错日志,还是说::Errno::EACCES (Permission denied @ dir_s_mkdir - /home/a_project/releases/20150126081307/public/uploads/tmp):
App 23466 stderr: Started PATCH "/admin/projects/1" for 54.64.229.171 at 2015-01-26 03:36:42 -0500
App 23466 stderr: Processing by Admin::ProjectsController#update as HTML
App 23466 stderr: Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxx", "project"=>{"img_on_homepage"=>#<ActionDispatch::Http::UploadedFile:0x007f7fa0d1d630 @tempfile=#<Tempfile:/tmp/RackMultipart20150126-23483-1nxkjq0.jpg>, @original_filename="1-中国旅游信息化“十二五”发展规划项目.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"project[img_on_homepage]\"; filename=\"1-\xE4\xE5\x88\x92\xE9\xA1\xB9\xE7\x9B\xAE.jpg\"\r\nContent-Type: image/jpeg\r\n">, "img_on_homepage_cache"=>""}, "commit"=>"更新", "id"=>"1"}
App 23466 stderr: ^[[1m^[[35mUser Load (0.7ms)^[[0m SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
App 23466 stderr: ^[[1m^[[36mProject Load (0.4ms)^[[0m ^[[1mSELECT `projects`.* FROM `projects` WHERE `projects`.`id` = 1 LIMIT 1^[[0m
App 23466 stderr: ^[[1m^[[35m (0.2ms)^[[0m BEGIN
App 23466 stderr: ^[[1m^[[36m (0.2ms)^[[0m ^[[1mROLLBACK^[[0m
App 23466 stderr: Completed 500 Internal Server Error in 11ms
App 23466 stderr:
App 23466 stderr: Errno::EACCES (Permission denied @ dir_s_mkdir - /home/a_project/releases/20150126081307/public/uploads/tmp):
App 23466 stderr: app/controllers/admin/projects_controller.rb:29:in `update'
难道意思是,我要把/tmp 目录也放在共享下?可是不对吧?我 public/uploads 都 shared 了,那 public/uploads/tmp 应该就没问题了啊?
如果是权限问题,又在哪部分控制的权限?
在家,小区所谓时代宽带,完全翻不了墙,用不了 google,百度出来的答案全是广告…… 又来求助万能的 ruby-china 啦……
用了 carriewave,在我本机 localhost 上传照片完全没有问题,可是部署完,在正式启用的网上后台操作,却会直接跳转到 500 页面。 我的 Debug 思路是:
log/production.rb
生产日志,一无所获。/tmp# ls
passenger-error-71NFJU.html RackMultipart20150123-26977-1hjx223 RackMultipart20150123-26977-l5zd44.jpg
passenger.1.0.12087 passenger-error-9xT843.html RackMultipart20150123-26977-1mgii56 RackMultipart20150123-26977-nxrc87
passenger-error-2VjmRw.html passenger-error-CzlBbt.html RackMultipart20150123-26977-37vw3t RackMultipart20150123-26977-yhek8w
passenger-error-3Y9ACE.html passenger-error-FCXM6h.html RackMultipart20150123-26977-45020n
passenger-error-68ouMr.html passenger-error-yCMDWp.html RackMultipart20150123-26977-89vtvd.jpg
额,这次出错页面没有提示,我根本不知道是哪一个文件啊!为什么没有时间标记?难道要全部复制到本机才能看?因为 html 文件很长很长,开头是页内 css,结尾是很多参数,只用复制过来打开才能较好地看到……
shell
$ vi + /usr/local/logs/error.log
App 26960 stderr: User Load (0.9ms) SELECT
users.* FROM
usersWHERE
users.
id= 1 ORDER BY
users.
idASC LIMIT 1
App 26960 stderr: Project Load (0.4ms) SELECT
projects.* FROM
projectsWHERE
projects.
id= 1 LIMIT 1
App 26960 stderr: (0.3ms) BEGIN
App 26960 stderr: (0.4ms) ROLLBACK
App 26960 stderr: Completed 500 Internal Server Error in 17ms
App 26960 stderr:
App 26960 stderr: Errno::EACCES (Permission denied @ dir_s_mkdir - /home/a_project/releases/20150123105103/public/uploads):
App 26960 stderr: app/controllers/admin/projects_controller.rb:29:in
update'
App 26960 stderr:
App 26960 stderr:
App 26960 stderr: Started GET "/favicon.ico" for xxx.xxx.xxx.xx at 2015-01-23 09:27:33 -0500
App 26960 stderr:
App 26960 stderr: ActionController::RoutingError (No route matches [GET] "/favicon.ico"):不知道怎么解读……
疑问:
为什么会`Permission denied @ dir_s_mkdir - /home/a_project/releases/20150123105103/public/uploads)`?
我用的是管理员帐号,而且能编辑其它参数,所以不是权限问题。` @ dir_s_mkdir`是什么呢?难道是存储地址有问题?
我是用capistrano一键部署的,那每次部署之后current/public/应该是会变的,这个怎么处理?我是不是应该指明在哪里的public文件夹?
另外,出错了,它为什么要`Started GET "/favicon.ico"`?我平时没用到这个默认的图标,我删了啊!有必要加回来的么?我的500页面是自己写的啊!没用到图标啊!
# 解决方案
- 一方面,需要把uploads目录放在capistrano设置的共享文件夹下
```shell
# config/deploy.rb
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads}
shell
chmod 777 -R /home/a_project/shared/public/uploads