部署 Rails4:/socket/.unicorn.sock 在连接上游时失败(2:没有这样的文件或目录)

Posted

技术标签:

【中文标题】部署 Rails4:/socket/.unicorn.sock 在连接上游时失败(2:没有这样的文件或目录)【英文标题】:Deploy Rails4: /socket/.unicorn.sock failed (2: No such file or directory) while connecting to upstream 【发布时间】:2014-10-25 10:18:12 【问题描述】:

nginx.conf

user nginx web; 

pid /var/run/nginx.pid;
error_log /var/www/log/nginx.error.log;

events 
  worker_connections 1024; # increase if you have lots of clients
  accept_mutex off; # "on" if nginx worker_processes > 1
  use epoll; # enable for Linux 2.6+
  # use kqueue; # enable for FreeBSD, OSX


http 
  # nginx will find this file in the config directory set at nginx build time
  include mime.types;
  types_hash_max_size 2048;
  server_names_hash_bucket_size 64;
  # fallback in case we can't determine a type
  default_type application/octet-stream;

  # click tracking!
  access_log /var/www/log/nginx.access.log combined;

  # you generally want to serve static files with nginx since neither
  # Unicorn nor Rainbows! is optimized for it at the moment
  sendfile on;

  tcp_nopush on; # off may be better for *some* Comet/long-poll stuff
  tcp_nodelay off; # on may be better for some Comet/long-poll stuff

  # we haven't checked to see if Rack::Deflate on the app server is
  # faster or not than doing compression via nginx.  It's easier
  # to configure it all in one place here for static files and also
  # to disable gzip for clients who don't get gzip/deflate right.
  # There are other gzip settings that may be needed used to deal with
  # bad clients out there, see http://wiki.nginx.org/NginxHttpGzipModule
  gzip on;
  gzip_http_version 1.0;
  gzip_proxied any;
  gzip_min_length 0;
  gzip_vary on;
  gzip_disable "MSIE [1-6]\.";
  gzip_proxied expired no-cache no-store private auth;
  gzip_comp_level 9;
  gzip_types text/plain text/xml text/css
             text/comma-separated-values
             text/javascript application/x-javascript
             application/atom+xml;

  # this can be any application server, not just Unicorn/Rainbows!
  upstream app_server 
    server unix:/var/www/apps/photoreal/socket/.unicorn.sock fail_timeout=0;
  

  server 
    # PageSpeed
    pagespeed on;
    pagespeed FileCachePath /var/ngx_pagespeed_cache;
    location ~ "\.pagespeed\.([a-z]\.)?[a-z]2\.[^.]10\.[^.]+"  
      add_header "" ""; 
    
    location ~ "^/ngx_pagespeed_static/"  
    location ~ "^/ngx_pagespeed_beacon$"  
    location /ngx_pagespeed_statistics  
      allow 127.0.0.1; allow 5.228.169.73; deny all; 
    
    location /ngx_pagespeed_global_statistics  
      allow 127.0.0.1; allow 5.228.169.73; deny all; 
    
    pagespeed MessageBufferSize 100000;
    location /ngx_pagespeed_message  
      allow 127.0.0.1; allow 5.228.169.73; deny all; 
    
    location /pagespeed_console  
      allow 127.0.0.1; allow 5.228.169.73; deny all; 
    






    charset utf-8;
    # enable one of the following if you're on Linux or FreeBSD
    listen 80 default deferred; # for Linux
    # listen 80 default accept_filter=httpready; # for FreeBSD

    # If you have IPv6, you'll likely want to have two separate listeners.
    # One on IPv4 only (the default), and another on IPv6 only instead
    # of a single dual-stack listener.  A dual-stack listener will make
    # for ugly IPv4 addresses in $remote_addr (e.g ":ffff:10.0.0.1"
    # instead of just "10.0.0.1") and potentially trigger bugs in
    # some software.
    # listen [::]:80 ipv6only=on; # deferred or accept_filter recommended

    client_max_body_size 4G;
    server_name _;

    # ~2 seconds is often enough for most folks to parse html/CSS and
    # retrieve needed images/icons/frames, connections are cheap in
    # nginx so increasing this is generally safe...
    keepalive_timeout 5;

    # path for static files
    root /var/www/apps/photoreal/current/public;

    # Prefer to serve static files directly from nginx to avoid unnecessary
    # data copies from the application server.
    #
    # try_files directive appeared in in nginx 0.7.27 and has stabilized
    # over time.  Older versions of nginx (e.g. 0.6.x) requires
    # "if (!-f $request_filename)" which was less efficient:
    # http://bogomips.org/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
    try_files $uri/index.html $uri.html $uri @app;

    location ~ ^/(assets)/  
      root /var/www/apps/photoreal/current/public;

      expires max;
      add_header Cache-Control public;
    
    location @app 
      # an HTTP header important enough to have its own Wikipedia entry:
      #   http://en.wikipedia.org/wiki/X-Forwarded-For
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

      # enable this if you forward HTTPS traffic to unicorn,
      # this helps Rack set the proper URL scheme for doing redirects:
      # proxy_set_header X-Forwarded-Proto $scheme;

      # pass the Host: header from the client right along so redirects
      # can be set properly within the Rack application
      proxy_set_header Host $http_host;

      # we don't want nginx trying to do something clever with
      # redirects, we set the Host: header above already.
      proxy_redirect off;

      # set "proxy_buffering off" *only* for Rainbows! when doing
      # Comet/long-poll/streaming.  It's also safe to set if you're using
      # only serving fast clients with Unicorn + nginx, but not slow
      # clients.  You normally want nginx to buffer responses to slow
      # clients, even with Rails 3.1 streaming because otherwise a slow
      # client can become a bottleneck of Unicorn.
      #
      # The Rack application may also set "X-Accel-Buffering (yes|no)"
      # in the response headers do disable/enable buffering on a
      # per-response basis.
      # proxy_buffering off;

      proxy_pass http://app_server;
    

    # Rails error pages
    error_page 500 502 503 504 /500.html;
    location = /500.html 
      root /var/www/apps/photoreal/current/public;
    
  

部署.rb:

# config valid only for Capistrano 3.1
lock '3.2.1'

set :repo_url, '...'
set :application, 'photoreal'
application = 'photoreal'
set :rvm_type, :user
set :rvm_ruby_version, ' 2.0.0'
set :deploy_to, '/var/www/apps/photoreal'

set :rails_env, 'production'

namespace :foreman do
  desc 'Start server'
  task :start do
    on roles(:all) do
      sudo "start #application"
    end
  end

  desc 'Stop server'
  task :stop do
    on roles(:all) do
      sudo "stop #application"
    end
  end

  desc 'Restart server'
  task :restart do
    on roles(:all) do
      sudo "restart #application"
    end
  end

  desc 'Server status'
  task :status do
    on roles(:all) do
      execute "initctl list | grep #application"
    end
  end
end

namespace :git do
  desc 'Deploy'
  task :deploy do
    ask(:message, "Commit message?")
    run_locally do
      execute "git add -A"
      execute "git commit -m '#fetch(:message)'"
      execute "git push"
    end
  end
end




# Default branch is :master
# ask :branch, proc  `git rev-parse --abbrev-ref HEAD`.chomp .call

# Default deploy_to directory is /var/www/my_app
# set :deploy_to, '/var/www/my_app'

# Default value for :scm is :git
# set :scm, :git

# Default value for :format is :pretty
# set :format, :pretty

# Default value for :log_level is :debug
# set :log_level, :debug

# Default value for :pty is false
# set :pty, true

# Default value for :linked_files is []
# set :linked_files, %wconfig/database.yml

# Default value for linked_dirs is []
# set :linked_dirs, %wbin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system

# Default value for default_env is 
# set :default_env,  path: "/opt/ruby/bin:$PATH" 

# Default value for keep_releases is 5
# set :keep_releases, 5

namespace :deploy do

  desc 'Setup'
  task :setup do
    on roles(:all) do
      execute "mkdir  #shared_path/config/"
      execute "mkdir  /var/www/apps/#application/run/"
      execute "mkdir  /var/www/apps/#application/log/"
      execute "mkdir  /var/www/apps/#application/socket/"
      execute "mkdir #shared_path/system"
      sudo "ln -s /var/log/upstart /var/www/log/upstart"

      upload!('shared/database.yml', "#shared_path/config/database.yml")

      upload!('shared/Procfile', "#shared_path/Procfile")


      upload!('shared/nginx.conf', "#shared_path/nginx.conf")
      #sudo 'sudo initctl stop nginx'
      sudo "rm -f /usr/local/nginx/conf/nginx.conf"
      sudo "ln -s #shared_path/nginx.conf /usr/local/nginx/conf/nginx.conf"
      #sudo 'sudo initctl start nginx'

      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, "db:create"
        end
      end



    end
  end

  desc 'Create symlink'
  task :symlink do
    on roles(:all) do
      execute "ln -s #shared_path/config/database.yml #release_path/config/database.yml"
      execute "ln -s #shared_path/Procfile #release_path/Procfile"
      execute "ln -s #shared_path/system #release_path/public/system"
    end
  end

  desc 'Foreman init'
  task :foreman_init do
    on roles(:all) do
      foreman_temp = "/var/www/tmp/foreman"
      execute  "mkdir -p #foreman_temp"
      # Создаем папку current для того, чтобы foreman создавал upstart файлы с правильными путями
      execute "ln -s #release_path #current_path"

      within current_path do
        execute "cd #current_path"
        execute :bundle, "exec foreman export upstart #foreman_temp -a #application -u deployer -l /var/www/apps/#application/log -d #current_path"
      end
      sudo "mv #foreman_temp/* /etc/init/"
      sudo "rm -r #foreman_temp"
    end
  end


  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      sudo "restart #application"
    end
  end

  after :finishing, 'deploy:cleanup'
  after :finishing, 'deploy:restart'

  after :updating, 'deploy:symlink'

  after :setup, 'deploy:foreman_init'

  after :foreman_init, 'foreman:start'

  before :foreman_init, 'rvm:hook'

  before :setup, 'deploy:starting'
  before :setup, 'deploy:updating'
  before :setup, 'bundler:install'
end

独角兽.rb:

worker_processes 2

working_directory "/var/www/apps/photoreal/current" # available in 0.94.0+

# listen on both a Unix domain socket and a TCP port,
# we use a shorter backlog for quicker failover when busy
listen "/var/www/apps/photoreal/socket/.unicorn.sock", :backlog => 64
listen 8080, :tcp_nopush => true

# nuke workers after 30 seconds instead of 60 seconds (the default)
timeout 30

# feel free to point this anywhere accessible on the filesystem
pid "/var/www/apps/photoreal/run/unicorn.pid"

# By default, the Unicorn logger will write to stderr.
# Additionally, ome applications/frameworks log to stderr or stdout,
# so prevent them from going to /dev/null when daemonized here:
stderr_path "/var/www/apps/photoreal/log/unicorn.stderr.log"
stdout_path "/var/www/apps/photoreal/log/unicorn.stdout.log"

# combine Ruby 2.0.0dev or REE with "preload_app true" for memory savings
# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
  GC.copy_on_write_friendly = true

# Enable this flag to have unicorn test client connections by writing the
# beginning of the HTTP headers before calling the application.  This
# prevents calling the application for connections that have disconnected
# while queued.  This is only guaranteed to detect clients on the same
# host unicorn runs on, and unlikely to detect disconnects even on a
# fast LAN.
check_client_connection false

before_fork do |server, worker|



  # the following is highly recomended for Rails + "preload_app true"
  # as there's no need for the master process to hold a connection

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!

  # The following is only recommended for memory/DB-constrained
  # installations.  It is not needed if your system can house
  # twice as many worker_processes as you have configured.
  #
  # # This allows a new master process to incrementally
  # # phase out the old master process with SIGTTOU to avoid a
  # # thundering herd (especially in the "preload_app false" case)
  # # when doing a transparent upgrade.  The last worker spawned
  # # will then kill off the old master process with a SIGQUIT.
  old_pid = "#server.config[:pid].oldbin"
  if old_pid != server.pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
  #
  # Throttle the master from forking too quickly by sleeping.  Due
  # to the implementation of standard Unix signal handlers, this
  # helps (but does not completely) prevent identical, repeated signals
  # from being lost when the receiving process is busy.
  # sleep 1
end

after_fork do |server, worker|
  # per-process listener ports for debugging/admin/migrations
  # addr = "127.0.0.1:#9293 + worker.nr"
  # server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)

  # the following is *required* for Rails + "preload_app true",
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection


  # if preload_app is true, then you may also want to check and
  # restart any other shared sockets/descriptors such as Memcached,
  # and Redis.  TokyoCabinet file handles are safe to reuse
  # between any number of forked children (assuming your kernel
  # correctly implements pread()/pwrite() system calls)
end

nginx.error:

2014/09/01 08:02:46 [crit] 4697#0: *1 connect() to unix :/var/www/apps/photoreal/socket/.unicorn.sock 失败(2:没有这样的文件或目录)同时连接到上游,客户端:178.76.217.203,服务器:_,请求:“GET / HTTP/1.1”,上游:“http:// unix :/var/www/apps/photoreal/socket/.unicorn .sock:/",主机:"45.65.32.1"

控制台:

$ netstat -an | grep unicorn
$ ps aux | grep unicorn
deployer  5061  0.0  0.0   2268   660 pts/0    S+   08:12   0:00 grep --color=auto unicorn

【问题讨论】:

【参考方案1】:

好的配置,但是日志呢? :) 你在 deploy.rb 中有独角兽启动(upstart)的命令,检查这些命令的部署日志(sudo "start #application")

我想在“sudo start photoreal”期间出了点问题

ps 显示没有活动的独角兽进程,因此套接字不存在,nginx 尝试连接套接字时出错(app_server;)

【讨论】:

以上是关于部署 Rails4:/socket/.unicorn.sock 在连接上游时失败(2:没有这样的文件或目录)的主要内容,如果未能解决你的问题,请参考以下文章

Rails 4 + Capistrano + AWS Net::SSH::AuthenticationFailed: 部署

在 Windows Apache MySQL 上的生产环境中部署 Rails 4

Rails 4 Elastic Beanstalk 部署错误

rails 4.1 无法通过 capistrano 3 部署

rails4 rake assets 在生产环境中预编译生成错误的javascript文件

Rails 4,Capistrano 3.0.0,无法加载这样的文件——部署