Nginx – Multiple Unicorns/Rails Apps, Nginx, One User

nginxunicorn

  1. I successfully deployed a Rails app using Capistrano, Unicorn, Nginx using the following unicorn configuration:

    env = ENV["RAILS_ENV"] || "development"
    
    worker_processes 4
    
    listen "/tmp/app_one.socket", :backlog => 64
    
    preload_app true
    
    timeout 60
    
    pid "/tmp/unicorn.app_one.pid"
    
    if env == "production"
      working_directory "/home/single_user/app_one/current"
    
      user 'single_user'
    
      shared_path = "/home/single_user/app_one/shared"
    
      stderr_path "#{shared_path}/log/unicorn.stderr.log"
      stdout_path "#{shared_path}/log/unicorn.stdout.log"
    end
    
    before_fork do |server, worker|
      if defined?(ActiveRecord::Base)
        ActiveRecord::Base.connection.disconnect!
      end
    
      old_pid = "/tmp/unicorn.app_one.pid.oldbin"
      if File.exists?(old_pid) && server.pid != old_pid
        begin
          Process.kill("QUIT", File.read(old_pid).to_i)
        rescue Errno::ENOENT, Errno::ESRCH
          # already dead
        end
      end
    end
    
    after_fork do |server, worker|
      if defined?(ActiveRecord::Base)
        ActiveRecord::Base.establish_connection
      end
    end
    
  2. Under the same single_user, I added a second Rails app, a second Nginx virtual server, and used the exact same Unicorn config, replacing app_one with app_two in all the appropriate places.

  3. My second app deployed just fine, but now I am having trouble deploying app one. The /tmp/unicorn.app_one.pid does not exist, but the site still works fine (top showing ten processes as expected). However /tmp/app_one.socket does exist, which prevents me from starting Unicorn by hand.

So is this the appropriate practice, to run multiple Rails/Unicorn/Nginx under the same user? Have I caused some kind of conflict in my deployment process? How should I proceed without breaking app_one, which is live and in use?

Best Answer

Why don't you use an app-specific tmp directory, and put the unicorn.pid into there, like "#{working_directory}/tmp/unicorn.pid". Similarly for any app-specific files like the socket. If you don't want to put it in working_directory, use shared_path. Keep everything specific to app1 in an app1-specific location, and everything related to app2 in an app2-specific directory.

Related Topic