#ruby-on-rails #nginx #thin
#ruby-on-rails #nginx #тонкий
Вопрос:
Я развернул приложение rails для nginx, используя тонкий capistrano (rails 4, ruby 2.1.2, тонкий 1.6.2, capistrano 2.1.5). Я запустил thin с помощью команды thin start. И просмотрите некоторую ошибку в этом файле thin.log. Кто-нибудь может показать мне, как это исправить?
Большое вам спасибо!
тонкий.yml
pid: /home/deploy/myapp/pids/thin.pid
port: 3000
timeout: 30
wait: 30
log: log/thin.log
max_conns: 1024
require: []
environment: production
max_persistent_conns: 512
threaded: true
no-epoll: true
daemonize: true
socket: /home/deploy/myapp/sockets/thin.sock
chdir: /home/deploy/myapp/current
address: 0.0.0.0
/etc/nginx/sites-availabel/default
upstream myapp{
server 127.0.0.1:3000;
server 127.0.0.1:3001;
server 127.0.0.1:3002;
}
server {
listen 80;
server_name _;
character utf-8;
access_log /home/deploy/myapp/log/access.log;
error_log /home/deploy/myapp/log/error.log;
root /home/deploy/myapp/current/public;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
thin.log
Writing PID to /home/deploy/myapp/pids/thin.pid
Using rack adapter
Thin web server (v1.6.2 codename Doc Brown)
Maximum connections set to 1024
Listening on /home/deploy/myapp/sockets/thin.sock, CTRL C to stop
Exiting!
/home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:528:in `start_unix_server': no unix-domain acceptor (RuntimeError)
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:528:in `start_server'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:548:in `start_unix_domain_server'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/backends/unix_server.rb:19:in `connect'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/backends/base.rb:63:in `block in start'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in `call'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in `run_machine'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in `run'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/backends/base.rb:73:in `start'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/server.rb:162:in `start'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/controllers/controller.rb:87:in `start'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/runner.rb:199:in `run_command'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/runner.rb:155:in `run!'
from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/bin/thin:6:in `<top (required)>'
from /home/deploy/.rvm/gems/ruby-2.1.2/bin/thin:23:in `load'
from /home/deploy/.rvm/gems/ruby-2.1.2/bin/thin:23:in `<main>'
from /home/deploy/.rvm/gems/ruby-2.1.2/bin/ruby_executable_hooks:15:in `eval'
from /home/deploy/.rvm/gems/ruby-2.1.2/bin/ruby_executable_hooks:15:in `<main>'
Комментарии:
1. Когда я использовал thin в рабочей среде, я запускал его в порту 8080 с помощью thin -e production -p 8080, и nginx прослушивал мое приложение на 8080. Я не знаю, делаю ли я это неправильно, но это работает.
2. @Russell Kompinski: Я думаю, мне нужна остановка для тонкого прослушивания в порту 3000 из соображений безопасности. В приведенном выше коде я пытаюсь использовать сервер nginx по умолчанию для прослушивания через порт 80.
3. Я получил ту же ошибку, и для меня изменение имени сокета сработало. Я пока не знаю, почему.
Ответ №1:
Вообще говоря: настройка Thin и Nginx для совместной работы
У меня только что была почти такая же проблема на моем VPS. Чего я не понимаю, так это того, что ваша тонкая конфигурация объединяет порт и сокет. Я не знаю, хороший ли это путь.
Но в любом случае, вот что я предлагаю :
На тонкой стороне
Вы просто указываете тонкому использовать /home/deploy/myapp/sockets/thin.sock
сокет. Хорошо, у нас все хорошо. Я бы использовал другой каталог для сокета (скажем, /tmp
или tmp
каталог вашего приложения), но я не эксперт, и это ваше дело.
На стороне Nginx
Затем, если вы хотите, чтобы Thin и Nginx обменивались данными, вы должны сообщить Nginx, что Thin прослушивает входящий запрос в этом конкретном сокете. Здесь, в вашем upstream
блоке, вы сообщаете Nginx, что Thin прослушивает входящие запросы на localhost:3000. Опять же, поскольку вы используете как порт, так и сокет в вашем Thin conf, я не уверен, может ли это быть проблемой (но, по крайней мере, один из этих параметров кажется мне бесполезным, поскольку речь идет о связи Thin-Nginx). Если и Nginx, и Thin используются на одном компьютере, я думаю, что сокеты — лучший способ сделать это, поскольку они заставляют связь полагаться на файловую систему вместо HTTP-запросов, что должно быть более эффективным. Чтобы сообщить Nginx, что Thin прослушивает сокет, вы должны использовать upstream
блок, подобный этому :
upstream myapp {
server unix:/home/deploy/myapp/sockets/thin.sock;
}
Судя по вашему тонкому конфигурационному файлу, у вас есть только один экземпляр Thin, запущенный для этого проекта, поэтому вам нужна только одна server
строка. Если бы вы использовали, скажем, 2 тонких экземпляра (с servers: 2
в вашей тонкой конфигурации yml), вы бы сделали что-то подобное на стороне nginx :
upstream myapp {
server unix:/home/deploy/myapp/sockets/thin.0.sock;
server unix:/home/deploy/myapp/sockets/thin.1.sock;
}
«Нет акцептора unix-домена (ошибка выполнения)»
Что касается ошибки «нет акцептора unix-домена (RuntimeError)», это может быть связано с проблемой с разрешениями в каталоге сокетов, по крайней мере, так было, когда я только что столкнулся с этой проблемой (не знаю почему, мой sockets
каталог исчез, и когда я создал его снова, у него должны были быть правильные разрешения, чтобы избежать этой ошибки). Итак, я бы сказал, проверьте это;)
Комментарии:
1. Я пытаюсь использовать сокет Unix, потому что я думаю, что открытие порта (например, порта 3000) является дырой в безопасности.
Ответ №2:
Для меня эта ошибка была вызвана отсутствующим каталогом сокетов (в вашем случае это было бы /home/deploy/myapp/sockets
).
Ответ №3:
Вот как выглядит мой nginx с использованием thin. Возможно, это может помочь.
upstream thin_server {
server 0.0.0.0:8080 fail_timeout=0;
}
server {
listen 80 defau<
root /home/example/public;
server_name example.com www.example.com;
index index.htm index.html;
location / {
try_files $uri/index.html $uri.html $uri @app;
}
location ~* ^. .(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|mp3|flv|mpeg|avi)$ {
try_files $uri @app;
}
location @app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://thin_server;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
Комментарии:
1. Я пытался использовать сокет, но он не работал. Можете ли вы показать мне, почему? Я не понимаю, в чем разница между socket: /home /deploy/myapp/sockets/thin.sock и сервером 0.0.0.0:8080. :(. Спасибо.
2. @PhuongTT Я не уверен, как ответить на это, и у меня нет глубокого понимания различных типов сокетов. Вы спрашиваете об адресе сокета? Мы используем адрес сокета, который является IP-адресом и портом, объединенным с localhost и портом 8080, который равен 0.0.0.0:8080. Можете ли вы уточнить? Кроме того, это сработало для вас?
3. Этот способ сработал для меня. Я просто задаю вам вопрос, чтобы узнать больше об этом. 😀