Skip to content

Instantly share code, notes, and snippets.

@JeanMertz
Last active September 9, 2020 21:03
Show Gist options
  • Save JeanMertz/4360598 to your computer and use it in GitHub Desktop.
Save JeanMertz/4360598 to your computer and use it in GitHub Desktop.
Snippets for article "debian + chruby + postgres + nginx + unicorn + rails and friends…"
source /usr/local/share/chruby/chruby.sh
source /usr/local/share/chruby/auto.sh
chruby 2 &>/dev/null
if [ "$?" -eq "1" ]
then
chruby 1 &>/dev/null
fi
deb http://packages.dotdeb.org wheezy all
deb-src http://packages.dotdeb.org wheezy all
---
gem: --no-ri --no-rdoc
#! /bin/sh
### BEGIN INIT INFO
# Provides: unicorn
# Required-Start: $all
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Control unicorn server
# Description: This command controls the unicorn servers
### END INIT INFO
# Author: Jean Mertz <jean@mertz.fm>
sig () {
test -s "$PID" && kill -$1 `cat "$PID"`
}
oldsig () {
test -s "$OLD_PID" && kill -$1 `cat "$OLD_PID"`
}
cmd () {
case $1 in
start)
sig 0 && echo >&2 "Already running" && exit 0
echo "Starting: $CMD"
$CMD
;;
stop)
sig QUIT && echo "Stopping" && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && echo "Forcing a stop" && exit 0
echo >&2 "Not running"
;;
restart|reload)
sig USR2 && sleep 5 && oldsig QUIT && echo "Killing old master" `cat $OLD_PID` && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
$CMD
;;
upgrade)
sig USR2 && echo Upgraded && exit 0
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
$CMD
;;
rotate)
sig USR1 && echo rotated logs OK && exit 0
echo >&2 "Couldn't rotate logs" && exit 1
;;
*)
echo >&2 "Usage: $0 <start|stop|restart|upgrade|rotate|force-stop> <application directory name>"
exit 1
;;
esac
}
setup () {
APPLICATION_ROOT="/var/www/$2/current"
PID="$APPLICATION_ROOT/tmp/pids/unicorn.pid"
OLD_PID="$PID.oldbin"
UNICORN_CONFIG="$APPLICATION_ROOT/config/unicorn.rb"
[ "$WORKERS" ] || { WORKERS=3; }
[ "$RACK_ENV" ] && { ENVIRONMENT="-E $RACK_ENV"; }
[ "$RAILS_ENV" ] || { RAILS_ENV=staging; }
# Verify existence of chruby-exec
command -v /usr/local/bin/chruby-exec >/dev/null 2>&1 || {
echo >&2 "`/usr/local/bin/chruby-exec` command could not be found"
exit 1
}
# Verify existence of application directory
cd $APPLICATION_ROOT || {
echo >&2 "$APPLICATION_ROOT could not be found"
exit 1
}
# Verify existence of config/unicorn.rb
if [ ! -f "$UNICORN_CONFIG" ]; then
echo >&2 "$UNICORN_CONFIG could not be found"
exit 1
fi
# Get ruby version
RUBY_VERSION="$(cat $APPLICATION_ROOT/Gemfile 2>/dev/null | sed -n "s/^[ ]*ruby [\"']\(.*\)[\"'][ ]*$/\1/p")"
if [ ! "$RUBY_VERSION" ]; then
if [ -f "$APPLICATION_ROOT/.ruby-version" ]; then
RUBY_VERSION="$(cat $APPLICATION_ROOT/.ruby-version)"
else
echo -e >&2 "Bundler: No ruby version specified\n$APPLICATION_ROOT/.ruby-version: Does not exist"
exit 1
fi
fi
RUBY_VERSION_CMD="sudo -u deployer -- /usr/local/bin/chruby-exec $RUBY_VERSION"
# Verify existence of ruby version
$RUBY_VERSION_CMD -- test >/dev/null 2>&1
if [ ! $? ]; then
echo >&2 "chruby: unknown Ruby: $RUBY_VERSION"
exit 1
fi
# Use bin/unicorn if available, otherwise use `bundle exec`
if [ -f "$APPLICATION_ROOT/bin/unicorn" ]; then
START_CMD="$APPLICATION_ROOT/bin/unicorn"
else
START_CMD="cd $APPLICATION_ROOT && bundle exec unicorn"
fi
CMD="$RUBY_VERSION_CMD -- WORKERS=$WORKERS RAILS_ENV=$RAILS_ENV $START_CMD -c $UNICORN_CONFIG $ENVIRONMENT -D"
}
runner () {
# $1 contains the start/stop/etc command
# $2 if it exists, should be the application directory name (/var/www/$2)
if [ "$2" ]; then
setup $ARGS
cmd $ARGS
else
for APP in /var/www/*; do
setup $1 $(basename $APP)
cmd $1 $(basename $APP)
done
fi
}
ARGS="$1 $2"
runner $ARGS
#!/bin/sh
iptables-restore < /etc/iptables.up.rules
# Users are strongly encouraged to refer to nginx documentation for more
# details and search for other example configs.
# you generally only need one nginx worker unless you're serving
# large amounts of static files which require blocking disk reads
worker_processes 1;
# drop privileges, root is needed on most systems for binding to port 80
# (or anything < 1024). Capability-based security may be available for
# your system and worth checking out so you won't need to be root to
# start nginx to bind on 80
user deployer staff;
# Feel free to change all paths to suite your needs here, of course
pid /var/run/nginx.pid;
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+
}
http {
# nginx will find this file in the config directory set at nginx build time
include mime.types;
# fallback in case we can't determine a type
default_type application/octet-stream;
# 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
# also see: http://wiki.linuxwall.info/doku.php/en:ressources:dossiers:nginx:nginx_performance_tuning
gzip on;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_proxied any;
gzip_min_length 1400;
gzip_disable "MSIE [1-6]\.";
gzip_types text/plain text/xml text/css
text/comma-separated-values
text/javascript application/x-javascript
application/atom+xml;
# include custom configurations
include /etc/nginx/conf.d/*.conf;
# include activated website
include /etc/nginx/sites-enabled/*;
}
deb http://nginx.org/packages/debian/ wheezy nginx
deb-src http://nginx.org/packages/debian/ wheezy nginx
log_facility=daemon
pid_file=/var/run/nrpe.pid
server_port=5666
nrpe_user=nagios
nrpe_group=nagios
allowed_hosts=31.222.157.83
dont_blame_nrpe=1
debug=0
command_timeout=60
connection_timeout=300
command[check_users]=/usr/lib/nagios/plugins/check_users -w $ARG1$ -c $ARG2$
command[check_load]=/usr/lib/nagios/plugins/check_load -w $ARG1$ -c $ARG2$
command[check_disk]=/usr/lib/nagios/plugins/check_disk -w $ARG1$ -c $ARG2$ -p $ARG3$
command[check_procs]=/usr/lib/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -s $ARG3$
command[check_proc_name]=/usr/lib/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -a $ARG3$
include=/etc/nagios/nrpe_local.cfg
include_dir=/etc/nagios/nrpe.d/
deb http://apt.postgresql.org/pub/repos/apt/ wheezy-pgdg main
export RBENV_ROOT=/usr/local/rbenv
export PATH="$RBENV_ROOT/bin:$RBENV_ROOT/shims:$PATH"
eval "$(rbenv init -)"
upstream appname {
server unix:///var/www/YOUR_APP/shared/tmp/puma/puma.sock;
}
server {
listen 80;
server_name www.YOUR_APP.com YOUR_APP.com;
keepalive_timeout 5;
root /var/www/YOUR_APP/current/public;
access_log /var/www/YOUR_APP/shared/log/nginx/nginx.access.log;
error_log /var/www/YOUR_APP/shared/log/nginx/nginx.error.log info;
if (-f $document_root/maintenance.html) {
rewrite ^(.*)$ /maintenance.html last;
break;
}
location ~ ^/(assets)/ {
root /var/www/YOUR_APP/current/public;
expires max;
add_header Cache-Control public;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
if (-f $request_filename) {
break;
}
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (!-f $request_filename) {
proxy_pass http://YOUR_APP;
break;
}
}
# Now this supposedly should work as it gets the filenames
# with querystrings that Rails provides.
# BUT there's a chance it could break the ajax calls.
location ~* \.(ico|css|gif|jpe?g|png)(\?[0-9]+)?$ {
expires max;
break;
}
location ~ ^/javascripts/.*\.js(\?[0-9]+)?$ {
expires max;
break;
}
# Error pages
# error_page 500 502 503 504 /500.html;
location = /500.html {
root /var/www/YOUR_APP/current/public;
}
}
upstream YOUR_APP {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response (in case the Unicorn master nukes a
# single worker for timing out).
server unix:/var/www/YOUR_APP/shared/sockets/unicorn.socket fail_timeout=0;
}
server {
listen 80 default deferred;
# 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;
client_max_body_size 4G;
server_name YOUR_APP_HOST;
# ~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/YOUR_APP/current/public;
# application logs
access_log /var/www/YOUR_APP/shared/log/nginx/access.log;
error_log /var/www/YOUR_APP/shared/log/nginx/error.log;
rewrite_log on;
# only accept request methods supported by Ruby on Rails
if ($request_method !~ ^(GET|HEAD|PUT|POST|DELETE|OPTIONS|PATCH)$ ){
return 405;
}
# If the request is for a static resource, nginx should serve it directly
# and add a far future expires header to it, making the browser
# cache the resource and navigate faster over the website.
location ~ ^/(assets)/.+-([0-9a-zA-Z])+\. {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location / {
try_files $uri/index.html $uri.html $uri @YOUR_APP;
# rails error pages
error_page 404 /404.html;
error_page 422 /422.html;
error_page 500 502 503 504 /500.html;
error_page 403 /403.html;
}
location @YOUR_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;
# 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;
# Pass the X-Real-IP: header from the client right along
proxy_set_header X-Real-IP $remote_addr;
# 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;
# Set correct package sizes and timeouts
client_max_body_size 100m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
# This directive sets the address of the proxied server and the URI
# to which location will be mapped. Address may be given as hostname
# or address and port.
proxy_pass http://YOUR_APP;
}
location = /favicon.ico {
expires max;
add_header Cache-Control public;
}
location ~ \.php$ {
deny all;
}
}
deb http://backports.debian.org/debian-backports squeeze-backports main
Defaults!/etc/init.d/unicorn env_keep="RACK_ENV WORKERS"
Defaults:deployer env_keep="RACK_ENV WORKERS"
deployer ALL=NOPASSWD: /etc/init.d/unicorn
deployer ALL=NOPASSWD: /usr/sbin/service nginx *
deployer ALL=NOPASSWD: /usr/sbin/service passenger *
deployer ALL=NOPASSWD: /usr/sbin/service postgres *
upstream <%= application %> {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response (in case the Unicorn master nukes a
# single worker for timing out).
server <%= "unix:#{shared_path}/sockets/unicorn.socket fail_timeout=0" %>;
}
server {
listen 80 default deferred;
# 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;
client_max_body_size 4G;
server_name <%= [app_host].flatten.split(' ') %>;
# ~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 <%= "#{current_path}/public" %>;
# application logs
access_log <%= "#{shared_path}/log/nginx/access.log" %>;
error_log <%= "#{shared_path}/log/nginx/error.log" %>;
rewrite_log on;
# only accept request methods supported by Ruby on Rails
if ($request_method !~ ^(GET|HEAD|PUT|POST|DELETE|OPTIONS|PATCH)$ ){
return 405;
}
# If the request is for a static resource, nginx should serve it directly
# and add a far future expires header to it, making the browser
# cache the resource and navigate faster over the website.
location ~ ^/(assets)/.+-([0-9a-zA-Z])+\. {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location / {
try_files $uri/index.html $uri.html $uri @<%= application %>;
# rails error pages
error_page 404 /404.html;
error_page 422 /422.html;
error_page 500 502 503 504 /500.html;
error_page 403 /403.html;
}
location @<%= application %> {
# 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;
# 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;
# Pass the X-Real-IP: header from the client right along
proxy_set_header X-Real-IP $remote_addr;
# 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;
# Set correct package sizes and timeouts
client_max_body_size 100m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
# This directive sets the address of the proxied server and the URI
# to which location will be mapped. Address may be given as hostname
# or address and port.
proxy_pass http://<%= application %>;
}
location = /favicon.ico {
expires max;
add_header Cache-Control public;
}
location ~ \.php$ {
deny all;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment