diff --git a/.rubocop.yml b/.rubocop.yml index ab65fc2..e224bf5 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,31 +1,32 @@ AllCops: DisplayCopNames: true Exclude: - 'lib/capistrano/**/*' - 'vendor/**/*' + - 'unicorn.conf.rb' Metrics/LineLength: Max: 120 Metrics/AbcSize: Max: 16 Documentation: Enabled: false Style/NegatedIf: Enabled: false Style/Not: Enabled: false Style/WordArray: Enabled: false Style/TrailingComma: Enabled: false Style/BlockDelimiters: Enabled: false Style/TrailingBlankLines: Enabled: false Style/EmptyLinesAroundClassBody: Enabled: false Style/EmptyLinesAroundModuleBody: Enabled: false Lint/HandleExceptions: Enabled: false diff --git a/config/deploy.rb b/config/deploy.rb index 1ec0a16..02701fb 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -1,33 +1,23 @@ # config valid only for Capistrano 3.1 lock '3.2.1' set :application, 'webdns' set :repo_url, 'git@bitbucket.org:xlembouras/webns.git' set :deploy_to, '/srv/webdns' set :linked_files, %w(config/database.yml config/secrets.yml) set :linked_dirs, %w(log tmp/pids tmp/cache tmp/sockets) set :keep_releases, 5 namespace :deploy do desc 'Restart application' task :restart do on roles(:app), in: :sequence, wait: 5 do - # Your restart mechanism here, for example: - # execute :touch, release_path.join('tmp/restart.txt') + execute 'sudo unicornctl respawn' end end after :publishing, :restart - - after :restart, :clear_cache do - on roles(:web), in: :groups, limit: 3, wait: 10 do - # Here we can do anything such as: - # within release_path do - # execute :rake, 'cache:clear' - # end - end - end end diff --git a/contrib/systemd/default_unicorn b/contrib/systemd/default_unicorn new file mode 100644 index 0000000..108a909 --- /dev/null +++ b/contrib/systemd/default_unicorn @@ -0,0 +1,7 @@ +RAILS_ENV=production +APP_ROOT=/srv/webdns/current +UNICORN_CONFIG=/srv/webdns/current/unicorn.conf.rb +UNICORN_LISTEN=/run/unicorn/unicorn.sock +UNICORN_PIDFILE=/run/unicorn/unicorn.pid +UNICORN_TIMEOUT=30 +UNICORN_WORKERS=2 diff --git a/contrib/systemd/sudo_unicorn b/contrib/systemd/sudo_unicorn new file mode 100644 index 0000000..8ff211d --- /dev/null +++ b/contrib/systemd/sudo_unicorn @@ -0,0 +1 @@ +%webdns ALL=(root) NOPASSWD:/usr/local/bin/unicornctl diff --git a/contrib/systemd/unicorn.service b/contrib/systemd/unicorn.service new file mode 100644 index 0000000..98babd6 --- /dev/null +++ b/contrib/systemd/unicorn.service @@ -0,0 +1,18 @@ +[Unit] +Description=Unicorn Server +Wants=network-online.target +After=network-online.target + +[Service] +EnvironmentFile=-/etc/default/unicorn +User=webdns +Group=webdns +ExecStart=/usr/bin/unicorn -c ${UNICORN_CONFIG} --env ${RAILS_ENV} +Type=simple +RuntimeDirectory=unicorn +PIDFile=/run/unicorn/unicorn.pid +KillMode=mixed +KillSignal=SIGQUIT + +[Install] +WantedBy=multi-user.target diff --git a/contrib/systemd/unicornctl b/contrib/systemd/unicornctl new file mode 100755 index 0000000..6e5a856 --- /dev/null +++ b/contrib/systemd/unicornctl @@ -0,0 +1,43 @@ +#!/bin/bash + +usage() { + echo >&2 "Usage: $0 " + exit 1 +} + +cmd="$1"; shift + +[ -z "${cmd}" ] && usage + +service="unicorn" +sig_rotate="USR1" +sig_respawn="USR2" + +get_pid() { + echo $(systemctl show -pMainPID $service|cut -d= -f2) +} + +case "$cmd" in +status|start|stop|restart|enable|disable) + exec systemctl $cmd $service + ;; +rotate|respawn) + pid=$(get_pid) + if [ "${pid}" -eq 0 ]; then + exec systemctl start $service + else + signal="sig_${cmd}" + /sbin/start-stop-daemon --stop --pid "$pid" --signal "${!signal}" --quiet + # Wait for Main PID to change on respawn + while [ "${pid}" -eq $(get_pid) -a "${cmd}" = "respawn" ]; do + sleep 1 + done + fi + ;; +pid) + exec systemctl show -pMainPID $service|cut -d= -f2 + ;; +*) + usage + ;; +esac diff --git a/unicorn.conf.rb b/unicorn.conf.rb new file mode 100644 index 0000000..45d2541 --- /dev/null +++ b/unicorn.conf.rb @@ -0,0 +1,25 @@ +listen ENV['UNICORN_LISTEN'] +working_directory ENV['APP_ROOT'] +worker_processes ENV['UNICORN_WORKERS'].to_i +pid ENV['UNICORN_PIDFILE'] + +preload_app true + +before_fork do |server, worker| + ActiveRecord::Base.connection.disconnect! + + 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 + + sleep 1 +end + +after_fork do |server, worker| + ActiveRecord::Base.establish_connection +end