Last active
March 16, 2022 06:35
-
-
Save natew/6207594 to your computer and use it in GitHub Desktop.
Puma + Nginx + Capistrano
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'bundler/capistrano' | |
require 'capistrano_colors' | |
load 'deploy/assets' | |
# ssh forwarding and shell | |
set :default_run_options, { :pty => true } | |
set :ssh_options, { :forward_agent => true } | |
set :scm_verbose, true | |
set :scm, :git | |
set :branch, 'master' | |
set :keep_releases, 2 | |
set :use_sudo, false | |
set :deploy_via, :remote_cache | |
set :user, "USERNAME" | |
set :application, "APP_NAME" | |
set :domain, "IP" | |
set :repository, "ssh://#{user}@#{domain}/var/git/#{application}.git" | |
set :deploy_to, "/var/www/#{application}/web" | |
set :rails_env, "production" | |
# chruby | |
# set :bundle_flags, "--verbose" | |
set :ruby_version, "rbx" | |
set :chrub_script, "/usr/local/share/chruby/chruby.sh" | |
set :set_ruby_cmd, ". #{chrub_script} && chruby #{ruby_version}" | |
set(:bundle_cmd) { "#{set_ruby_cmd} && RAILS_ENV=#{rails_env} exec bundle" } | |
# Roles | |
role :web, domain | |
role :app, domain | |
role :db, domain, :primary => true # This is where Rails migrations will run | |
after 'deploy:update_code', 'deploy:migrate' | |
after 'deploy:update', 'deploy:symlink_attachments' | |
after 'deploy:update', 'deploy:symlink_tmp' | |
after 'deploy:update', 'deploy:clear_caches' | |
after 'deploy:update', 'deploy:cleanup' | |
# Run rake tasks | |
def run_rake(task, options={}, &block) | |
command = "cd #{latest_release} && #{bundle_cmd} rake #{task}" | |
run(command, options, &block) | |
end | |
namespace :puma do | |
task :start, :except => { :no_release => true } do | |
run "/etc/init.d/puma start #{application}" | |
end | |
after "deploy:start", "puma:start" | |
task :stop, :except => { :no_release => true } do | |
run "/etc/init.d/puma stop #{application}" | |
end | |
after "deploy:stop", "puma:stop" | |
task :restart, roles: :app do | |
run "/etc/init.d/puma restart #{application}" | |
end | |
after "deploy:restart", "puma:restart" | |
end | |
namespace :deploy do | |
task :symlink_attachments do | |
run "ln -nfs #{shared_path}/attachments #{release_path}/public/attachments" | |
end | |
task :symlink_tmp do | |
run "rm -rf #{release_path}/tmp" | |
run "ln -nfs #{shared_path}/tmp #{release_path}/tmp" | |
run "chmod 775 #{shared_path}/tmp" | |
end | |
task :clear_caches do | |
run "echo 'flush_all' | nc localhost 11211" # memcached | |
run_rake "tmp:cache:clear >/dev/null 2>&1" | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
upstream APP_puma { | |
server unix:///var/www/APP/web/current/tmp/puma/puma.sock; | |
} | |
server { | |
listen 80 default; | |
server_name APP.com www.APP.com; | |
root /var/www/APP/web/current/public; | |
location ~ ^/(assets|fonts|images|attachments)/?|favicon.ico { | |
root /var/www/APP/web/current/public; | |
expires max; | |
break; | |
} | |
location / { | |
proxy_set_header Host $host; | |
proxy_set_header X-Real-IP $remote_addr; | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
proxy_redirect off; | |
proxy_pass http://APP_puma; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/bash | |
### BEGIN INIT INFO | |
# Provides: puma | |
# Required-Start: $remote_fs $syslog | |
# Required-Stop: $remote_fs $syslog | |
# Default-Start: 2 3 4 5 | |
# Default-Stop: 0 1 6 | |
# Short-Description: Example initscript | |
# Description: This file should be used to construct scripts to be | |
# placed in /etc/init.d. | |
### END INIT INFO | |
# Author: Darío Javier Cravero <[email protected]> | |
# | |
# Do NOT "set -e" | |
# PATH should only include /usr/* if it runs after the mountnfs.sh script | |
PATH=/usr/local/bin:/usr/local/sbin/:/sbin:/usr/sbin:/bin:/usr/bin | |
DESC="Puma rack web server" | |
NAME=puma | |
DAEMON=$NAME | |
SCRIPTNAME=/etc/init.d/$NAME | |
CONFIG=/etc/puma.conf | |
JUNGLE=`cat $CONFIG` | |
RUNPUMA=/usr/local/bin/run-puma | |
do_chruby() { | |
. /usr/local/share/chruby/chruby.sh && chruby rbx | |
} | |
# Load the VERBOSE setting and other rcS variables | |
. /lib/init/vars.sh | |
# Define LSB log_* functions. | |
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. | |
. /lib/lsb/init-functions | |
# | |
# Function that starts the jungle | |
# | |
do_start() { | |
log_daemon_msg "=> Running the jungle..." | |
for i in $JUNGLE; do | |
dir=`echo $i | cut -d , -f 1` | |
user=`echo $i | cut -d , -f 2` | |
config_file=`echo $i | cut -d , -f 3` | |
if [ "$config_file" = "" ]; then | |
config_file="$dir/config/puma.rb" | |
fi | |
log_file=`echo $i | cut -d , -f 4` | |
if [ "$log_file" = "" ]; then | |
log_file="$dir/log/puma.log" | |
fi | |
do_start_one $dir $user $config_file $log_file | |
done | |
} | |
do_start_one() { | |
PIDFILE=$1/tmp/puma/pid | |
if [ -e $PIDFILE ]; then | |
PID=`cat $PIDFILE` | |
# If the puma isn't running, run it, otherwise restart it. | |
if [ "`ps -A -o pid= | grep -c $PID`" -eq 0 ]; then | |
do_start_one_do $1 $2 $3 $4 | |
else | |
do_restart_one $1 | |
fi | |
else | |
do_start_one_do $1 $2 $3 $4 | |
fi | |
} | |
do_start_one_do() { | |
log_daemon_msg "--> Woke up puma $1" | |
log_daemon_msg "user $2" | |
log_daemon_msg "log to $4" | |
start-stop-daemon --verbose --start --chdir $1 --chuid $2 --background --exec $RUNPUMA -- $1 $3 $4 | |
} | |
# | |
# Function that stops the jungle | |
# | |
do_stop() { | |
log_daemon_msg "=> Putting all the beasts to bed..." | |
for i in $JUNGLE; do | |
dir=`echo $i | cut -d , -f 1` | |
do_stop_one $dir | |
done | |
} | |
# | |
# Function that stops the daemon/service | |
# | |
do_stop_one() { | |
log_daemon_msg "--> Stopping $1" | |
PIDFILE=$1/tmp/puma/pid | |
STATEFILE=$1/tmp/puma/state | |
if [ -e $PIDFILE ]; then | |
PID=`cat $PIDFILE` | |
if [ "`ps -A -o pid= | grep -c $PID`" -eq 0 ]; then | |
log_daemon_msg "---> Puma $1 isn't running." | |
else | |
log_daemon_msg "---> About to kill PID `cat $PIDFILE`" | |
do_chruby | |
pumactl --state $STATEFILE stop | |
# Many daemons don't delete their pidfiles when they exit. | |
rm -f $PIDFILE $STATEFILE | |
fi | |
else | |
log_daemon_msg "---> No puma here..." | |
fi | |
return 0 | |
} | |
# | |
# Function that restarts the jungle | |
# | |
do_restart() { | |
for i in $JUNGLE; do | |
dir=`echo $i | cut -d , -f 1` | |
do_restart_one $dir | |
done | |
} | |
# | |
# Function that sends a SIGUSR2 to the daemon/service | |
# | |
do_restart_one() { | |
PIDFILE=$1/tmp/puma/pid | |
i=`grep $1 $CONFIG` | |
dir=`echo $i | cut -d , -f 1` | |
if [ -e $PIDFILE ]; then | |
log_daemon_msg "--> About to restart puma $1" | |
do_chruby | |
pumactl --state $dir/tmp/puma/state restart | |
# kill -s USR2 `cat $PIDFILE` | |
# TODO Check if process exist | |
else | |
log_daemon_msg "--> Your puma was never playing... Let's get it out there first" | |
user=`echo $i | cut -d , -f 2` | |
config_file=`echo $i | cut -d , -f 3` | |
if [ "$config_file" = "" ]; then | |
config_file="$dir/config/puma.rb" | |
fi | |
log_file=`echo $i | cut -d , -f 4` | |
if [ "$log_file" = "" ]; then | |
log_file="$dir/log/puma.log" | |
fi | |
do_start_one $dir $user $config_file $log_file | |
fi | |
return 0 | |
} | |
# | |
# Function that statuss the jungle | |
# | |
do_status() { | |
for i in $JUNGLE; do | |
dir=`echo $i | cut -d , -f 1` | |
do_status_one $dir | |
done | |
} | |
# | |
# Function that sends a SIGUSR2 to the daemon/service | |
# | |
do_status_one() { | |
PIDFILE=$1/tmp/puma/pid | |
i=`grep $1 $CONFIG` | |
dir=`echo $i | cut -d , -f 1` | |
if [ -e $PIDFILE ]; then | |
log_daemon_msg "--> About to status puma $1" | |
do_chruby | |
pumactl --state $dir/tmp/puma/state stats | |
# kill -s USR2 `cat $PIDFILE` | |
# TODO Check if process exist | |
else | |
log_daemon_msg "--> $1 isn't there :(..." | |
fi | |
return 0 | |
} | |
do_add() { | |
str="" | |
# App's directory | |
if [ -d "$1" ]; then | |
if [ "`grep -c "^$1" $CONFIG`" -eq 0 ]; then | |
str=$1 | |
else | |
echo "The app is already being managed. Remove it if you want to update its config." | |
exit 1 | |
fi | |
else | |
echo "The directory $1 doesn't exist." | |
exit 1 | |
fi | |
# User to run it as | |
if [ "`grep -c "^$2:" /etc/passwd`" -eq 0 ]; then | |
echo "The user $2 doesn't exist." | |
exit 1 | |
else | |
str="$str,$2" | |
fi | |
# Config file | |
if [ "$3" != "" ]; then | |
if [ -e $3 ]; then | |
str="$str,$3" | |
else | |
echo "The config file $3 doesn't exist." | |
exit 1 | |
fi | |
fi | |
# Log file | |
if [ "$4" != "" ]; then | |
str="$str,$4" | |
fi | |
# Add it to the jungle | |
echo $str >> $CONFIG | |
log_daemon_msg "Added a Puma to the jungle: $str. You still have to start it though." | |
} | |
do_remove() { | |
if [ "`grep -c "^$1" $CONFIG`" -eq 0 ]; then | |
echo "There's no app $1 to remove." | |
else | |
# Stop it first. | |
do_stop_one $1 | |
# Remove it from the config. | |
sed -i "\\:^$1:d" $CONFIG | |
log_daemon_msg "Removed a Puma from the jungle: $1." | |
fi | |
} | |
case "$1" in | |
start) | |
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" | |
if [ "$#" -eq 1 ]; then | |
do_start | |
else | |
i=`grep $2 $CONFIG` | |
dir=`echo $i | cut -d , -f 1` | |
user=`echo $i | cut -d , -f 2` | |
config_file=`echo $i | cut -d , -f 3` | |
if [ "$config_file" = "" ]; then | |
config_file="$dir/config/puma.rb" | |
fi | |
log_file=`echo $i | cut -d , -f 4` | |
if [ "$log_file" = "" ]; then | |
log_file="$dir/log/puma.log" | |
fi | |
do_start_one $dir $user $config_file $log_file | |
fi | |
case "$?" in | |
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; | |
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; | |
esac | |
;; | |
stop) | |
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" | |
if [ "$#" -eq 1 ]; then | |
do_stop | |
else | |
i=`grep $2 $CONFIG` | |
dir=`echo $i | cut -d , -f 1` | |
do_stop_one $dir | |
fi | |
case "$?" in | |
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; | |
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; | |
esac | |
;; | |
status) | |
# TODO Implement. | |
log_daemon_msg "Status $DESC" "$NAME" | |
if [ "$#" -eq 1 ]; then | |
do_status | |
else | |
i=`grep $2 $CONFIG` | |
dir=`echo $i | cut -d , -f 1` | |
do_status_one $dir | |
fi | |
case "$?" in | |
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; | |
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; | |
esac | |
;; | |
restart) | |
log_daemon_msg "Restarting $DESC" "$NAME" | |
if [ "$#" -eq 1 ]; then | |
do_restart | |
else | |
i=`grep $2 $CONFIG` | |
dir=`echo $i | cut -d , -f 1` | |
do_restart_one $dir | |
fi | |
case "$?" in | |
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; | |
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; | |
esac | |
;; | |
add) | |
if [ "$#" -lt 3 ]; then | |
echo "Please, specifiy the app's directory and the user that will run it at least." | |
echo " Usage: $SCRIPTNAME add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log" | |
echo " config and log are optionals." | |
exit 1 | |
else | |
do_add $2 $3 $4 $5 | |
fi | |
case "$?" in | |
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; | |
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; | |
esac | |
;; | |
remove) | |
if [ "$#" -lt 2 ]; then | |
echo "Please, specifiy the app's directory to remove." | |
exit 1 | |
else | |
do_remove $2 | |
fi | |
case "$?" in | |
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; | |
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; | |
esac | |
;; | |
*) | |
echo "Usage:" >&2 | |
echo " Run the jungle: $SCRIPTNAME {start|stop|status|restart}" >&2 | |
echo " Add a Puma: $SCRIPTNAME add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log" | |
echo " config and log are optionals." | |
echo " Remove a Puma: $SCRIPTNAME remove /path/to/app" | |
echo " On a Puma: $SCRIPTNAME {start|stop|status|restart} PUMA-NAME" >&2 | |
exit 3 | |
;; | |
esac | |
: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env puma | |
basedir = '/var/www/2u/web/current' | |
directory "#{basedir}" | |
environment 'production' | |
daemonize true | |
bind "unix://#{basedir}/tmp/puma/puma.sock" | |
pidfile "#{basedir}/tmp/puma/pid" | |
state_path "#{basedir}/tmp/puma/state" | |
threads 4, 48 | |
# stdout_redirect "#{basedir}/shared/log/stdout", "#{basedir}/shared/log/stderr" | |
# workers 2 | |
# on_worker_boot do | |
# ActiveSupport.on_load(:active_record) do | |
# ActiveRecord::Base.establish_connection | |
# end | |
# end | |
preload_app! | |
activate_control_app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/zsh | |
app=$1; config=$2; log=$3; | |
source /usr/local/share/chruby/chruby.sh && chruby rbx && cd $app && puma --debug -C $config 2>&1 >> $log |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi Nate,
Could you please help me to configure using capistrano 3?
Here are my application information
I was manually deploying the changes to ec2, but now I want to use capistrano 3 for auto deployment.
Best,
Suman