Last active
August 19, 2024 15:09
-
-
Save PavloBezpalov/6525017b7ab61c843264a0b544acfdd6 to your computer and use it in GitHub Desktop.
Deploy Rails 5.1.1 to VPS(Ubuntu 16.04.2 LTS). Nginx mainline + pagespeed, Puma with Jungle, Capistrano3, PostgreSQL 9.6, RVM, Certbot
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
root# apt-get update | |
root# apt-get upgrade | |
// dependencies for Ruby | |
root# apt-get install -y git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev \ | |
libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev \ | |
libpcre3-dev unzip | |
// Node.js v7 | |
root# curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash - | |
root# apt-get install -y nodejs | |
// Yarn | |
root# curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - | |
root# echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list | |
root# sudo apt-get update && sudo apt-get install yarn | |
// Postgresql 9.6 | |
root# echo 'deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main' > /etc/apt/sources.list.d/pgdg.list | |
root# wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - | |
root# apt-get update && apt-get install -y postgresql-9.6 libpq-dev | |
// fix perl: warning: Setting locale failed. | |
root# echo -e 'LANG="en_US.UTF-8"\nLC_ALL="en_US.UTF-8"\nLANGUAGE="en_US:en"' > /etc/default/locale | |
// mainline nginx with stable ngx_pagespeed | |
root# bash <(curl -f -L -sS https://ngxpagespeed.com/install) -y --nginx-version latest -a ' \ | |
--prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf \ | |
--error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid \ | |
--lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp \ | |
--http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \ | |
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx \ | |
--group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module \ | |
--with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module \ | |
--with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module \ | |
--with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module \ | |
--with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module \ | |
--with-stream_ssl_module --with-stream_ssl_preread_module' | |
root# adduser --system --no-create-home --shell /bin/false --group --disabled-login nginx | |
root# wget -O /etc/nginx/nginx.conf https://gist.githubusercontent.com/PavelBezpalov/6525017b7ab61c843264a0b544acfdd6/raw/nginx.conf | |
root# mkdir /etc/nginx/sites-enabled | |
root# mkdir /etc/nginx/sites-available | |
root# mkdir /var/cache/nginx | |
root# mkdir -p /var/ngx_pagespeed_cache | |
root# chown nginx:nginx /var/ngx_pagespeed_cache | |
root# wget -O /etc/init.d/nginx https://gist.githubusercontent.com/PavelBezpalov/6525017b7ab61c843264a0b544acfdd6/raw/nginx | |
root# chmod +x /etc/init.d/nginx | |
root# systemctl enable nginx.service | |
// certbot | |
root# apt-get install software-properties-common | |
root# add-apt-repository ppa:certbot/certbot | |
root# apt-get update | |
root# apt-get install certbot | |
// deployer user in sudo group | |
root# adduser deployer | |
root# gpasswd -a deployer sudo | |
// disable ssh root login, permit password login | |
root# nano /etc/ssh/sshd_config | |
EDIT: | |
PermitRootLogin no | |
PasswordAuthentication yes | |
SAVE: | |
ctrl + x | |
y | |
enter | |
root# service ssh restart | |
root# exit | |
ssh deployer@server | |
// rvm, ruby 2.4.1, bundler | |
deployer$ sudo apt-get install libgdbm-dev libncurses5-dev automake libtool bison libffi-dev | |
deployer$ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 | |
deployer$ curl -sSL https://get.rvm.io | bash -s stable | |
deployer$ echo "gem: --no-document" > ~/.gemrc | |
deployer$ source ~/.rvm/scripts/rvm | |
deployer$ rvm install 2.4.1 && rvm use 2.4.1 --default | |
deployer$ gem install bundler | |
// postgresql deployer user, project db | |
deployer$ sudo su - postgres | |
deployer$ createuser --pwprompt deployer | |
deployer$ createdb -O deployer <<APP_DB_NAME>> | |
deployer$ exit |
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
ADD TO Gemfile: | |
group :development do | |
gem 'capistrano', '~> 3.8', '>= 3.8.1' | |
gem 'capistrano-rvm', '~> 0.1.2' | |
gem 'capistrano-rails', '~> 1.2', '>= 1.2.3' | |
gem 'capistrano3-puma', git: 'https://github.com/seuros/capistrano-puma.git', ref: '00708fa' | |
gem 'capistrano-nginx', '~> 1.0' | |
gem 'capistrano-upload-config', '~> 0.7.0' | |
gem 'sshkit-sudo', '~> 0.1.0' | |
end | |
RUN: | |
your_app$ bundle install | |
your_app$ cap install | |
EDIT Capfile AS ATTACHED Capfile | |
EDIT config/deploy.rb AS ATTACHED deploy.rb AND CHANGE VARIABLES IN IT | |
RUN: | |
your_app$ cp config/database.yml config/database.yml.example | |
your_app$ cp config/secrets.yml config/secrets.yml.example | |
your_app$ cap production config:init | |
your_app$ echo '/config/database.production.yml' >> .gitignore | |
your_app$ echo '/config/secrets.production.yml' >> .gitignore | |
EDIT WITH YOUR PARAMETERS: | |
/config/database.production.yml | |
/config/secrets.production.yml | |
RUN: | |
your_app$ rails g capistrano:nginx_puma:config | |
EDIT OR LEAVE AS IS: | |
config/deploy/templates/nginx_conf.erb | |
config/deploy/templates/puma.rb.erb | |
ADD RUBY-VERSION FILE FOR PUMA JUNGLE: | |
your_app$ echo 'ruby-2.4.1' > .ruby-version | |
GIT COMMIT AND PUSH CHANGES | |
RUN: | |
your_app$ cap production deploy | |
CONGRATULATION! ALL DONE! | |
CHECK YOUR RUNNIG SERVER! |
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
Using ENV variables: | |
store variables in /etc/environment like: | |
export VAR_NAME=value |
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 'capistrano/setup' | |
require 'capistrano/deploy' | |
require 'capistrano/scm/git' | |
install_plugin Capistrano::SCM::Git | |
require 'capistrano/rvm' | |
require 'capistrano/rails' | |
require 'capistrano/puma' | |
install_plugin Capistrano::Puma | |
install_plugin Capistrano::Puma::Nginx | |
install_plugin Capistrano::Puma::Jungle | |
require 'capistrano/nginx' | |
require 'capistrano/upload-config' | |
require 'sshkit/sudo' | |
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r } |
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
# config valid only for current version of Capistrano | |
lock '3.8.1' | |
set :application, '<<YOUR APPNAME>>' | |
set :repo_url, '<<YOUR APP REPO>>' | |
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp | |
set :user, 'deployer' | |
server '<<YOUR SERVER>>', user: "#{fetch(:user)}", roles: %w{app db web}, primary: true | |
set :deploy_to, "/home/#{fetch(:user)}/apps/#{fetch(:application)}" | |
set :pty, true | |
set :rvm_ruby_version, '2.4.1' | |
append :linked_files, 'config/database.yml', 'config/secrets.yml', 'config/puma.rb' | |
append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads' | |
set :config_example_suffix, '.example' | |
set :config_files, %w{config/database.yml config/secrets.yml} | |
set :puma_conf, "#{shared_path}/config/puma.rb" | |
namespace :deploy do | |
before 'check:linked_files', 'config:push' | |
before 'check:linked_files', 'puma:jungle:setup' | |
before 'check:linked_files', 'puma:nginx_config' | |
after 'puma:smart_restart', 'nginx:restart' | |
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
#!/bin/sh | |
### BEGIN INIT INFO | |
# Provides: nginx | |
# Required-Start: $network $remote_fs $local_fs | |
# Required-Stop: $network $remote_fs $local_fs | |
# Default-Start: 2 3 4 5 | |
# Default-Stop: 0 1 6 | |
# Short-Description: Stop/start nginx | |
### END INIT INFO | |
# Author: Sergey Budnevitch <[email protected]> | |
PATH=/sbin:/usr/sbin:/bin:/usr/bin | |
if [ -L $0 ]; then | |
SCRIPTNAME=`/bin/readlink -f $0` | |
else | |
SCRIPTNAME=$0 | |
fi | |
sysconfig=`/usr/bin/basename $SCRIPTNAME` | |
[ -r /etc/default/$sysconfig ] && . /etc/default/$sysconfig | |
DESC=${DESC:-nginx} | |
NAME=${NAME:-nginx} | |
CONFFILE=${CONFFILE:-/etc/nginx/nginx.conf} | |
DAEMON=${DAEMON:-/usr/sbin/nginx} | |
PIDFILE=${PIDFILE:-/var/run/nginx.pid} | |
SLEEPSEC=${SLEEPSEC:-1} | |
UPGRADEWAITLOOPS=${UPGRADEWAITLOOPS:-5} | |
CHECKSLEEP=${CHECKSLEEP:-3} | |
[ -x $DAEMON ] || exit 0 | |
DAEMON_ARGS="-c $CONFFILE $DAEMON_ARGS" | |
. /lib/init/vars.sh | |
. /lib/lsb/init-functions | |
do_start() | |
{ | |
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ | |
$DAEMON_ARGS | |
RETVAL="$?" | |
return "$RETVAL" | |
} | |
do_stop() | |
{ | |
# Return | |
# 0 if daemon has been stopped | |
# 1 if daemon was already stopped | |
# 2 if daemon could not be stopped | |
# other if a failure occurred | |
start-stop-daemon --stop --quiet --oknodo --retry=TERM/30/KILL/5 --pidfile $PIDFILE | |
RETVAL="$?" | |
rm -f $PIDFILE | |
return "$RETVAL" | |
} | |
do_reload() { | |
# | |
start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE | |
RETVAL="$?" | |
return "$RETVAL" | |
} | |
do_configtest() { | |
if [ "$#" -ne 0 ]; then | |
case "$1" in | |
-q) | |
FLAG=$1 | |
;; | |
*) | |
;; | |
esac | |
shift | |
fi | |
$DAEMON -t $FLAG -c $CONFFILE | |
RETVAL="$?" | |
return $RETVAL | |
} | |
do_upgrade() { | |
OLDBINPIDFILE=$PIDFILE.oldbin | |
do_configtest -q || return 6 | |
start-stop-daemon --stop --signal USR2 --quiet --pidfile $PIDFILE | |
RETVAL="$?" | |
for i in `/usr/bin/seq $UPGRADEWAITLOOPS`; do | |
sleep $SLEEPSEC | |
if [ -f $OLDBINPIDFILE -a -f $PIDFILE ]; then | |
start-stop-daemon --stop --signal QUIT --quiet --pidfile $OLDBINPIDFILE | |
RETVAL="$?" | |
return | |
fi | |
done | |
echo $"Upgrade failed!" | |
RETVAL=1 | |
return $RETVAL | |
} | |
do_checkreload() { | |
templog=`/bin/mktemp --tmpdir nginx-check-reload-XXXXXX.log` | |
trap '/bin/rm -f $templog' 0 | |
/usr/bin/tail --pid=$$ -n 0 --follow=name /var/log/nginx/error.log > $templog & | |
/bin/sleep 1 | |
start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE | |
/bin/sleep $CHECKSLEEP | |
/bin/grep -E "\[emerg\]|\[alert\]" $templog | |
} | |
case "$1" in | |
start) | |
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME" | |
do_start | |
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" | |
do_stop | |
case "$?" in | |
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; | |
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; | |
esac | |
;; | |
status) | |
status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME" && exit 0 || exit $? | |
;; | |
configtest) | |
do_configtest | |
;; | |
upgrade) | |
do_upgrade | |
;; | |
reload|force-reload) | |
log_daemon_msg "Reloading $DESC" "$NAME" | |
do_reload | |
log_end_msg $? | |
;; | |
restart|force-reload) | |
log_daemon_msg "Restarting $DESC" "$NAME" | |
do_configtest -q || exit $RETVAL | |
do_stop | |
case "$?" in | |
0|1) | |
do_start | |
case "$?" in | |
0) log_end_msg 0 ;; | |
1) log_end_msg 1 ;; # Old process is still running | |
*) log_end_msg 1 ;; # Failed to start | |
esac | |
;; | |
*) | |
# Failed to stop | |
log_end_msg 1 | |
;; | |
esac | |
;; | |
check-reload) | |
do_checkreload | |
RETVAL=0 | |
;; | |
*) | |
echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload|upgrade|configtest|check-reload}" >&2 | |
exit 3 | |
;; | |
esac | |
exit $RETVAL |
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
user nginx; | |
worker_processes 1; | |
error_log /var/log/nginx/error.log warn; | |
pid /var/run/nginx.pid; | |
events { | |
worker_connections 1024; | |
} | |
http { | |
include /etc/nginx/mime.types; | |
default_type application/octet-stream; | |
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' | |
'$status $body_bytes_sent "$http_referer" ' | |
'"$http_user_agent" "$http_x_forwarded_for"'; | |
access_log /var/log/nginx/access.log main; | |
sendfile on; | |
#tcp_nopush on; | |
keepalive_timeout 65; | |
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | |
ssl_prefer_server_ciphers on; | |
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; | |
ssl_ecdh_curve prime256v1:secp384r1; | |
ssl_session_cache shared:SSL:10m; | |
ssl_session_tickets off; # Requires nginx >= 1.5.9 | |
ssl_stapling on; # Requires nginx >= 1.3.7 | |
ssl_stapling_verify on; # Requires nginx => 1.3.7 | |
resolver 8.8.8.8 8.8.4.4 valid=300s; | |
resolver_timeout 5s; | |
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; | |
add_header X-Frame-Options DENY; # change to SAMEORIGIN for iframes | |
add_header X-Content-Type-Options nosniff; | |
gzip on; | |
gzip_vary on; | |
gzip_types application/ecmascript; | |
gzip_types application/javascript; | |
gzip_types application/json; | |
gzip_types application/pdf; | |
gzip_types application/postscript; | |
gzip_types application/x-javascript; | |
gzip_types image/svg+xml; | |
gzip_types text/css; | |
gzip_types text/csv; | |
gzip_types text/javascript; | |
gzip_types text/plain; | |
gzip_types text/xml; | |
gzip_http_version 1.0; | |
pagespeed on; | |
pagespeed FetchWithGzip on; | |
# Needs to exist and be writable by nginx. Use tmpfs for best performance. | |
pagespeed FileCachePath /var/ngx_pagespeed_cache; | |
pagespeed ModPagespeedCreateSharedMemoryMetadataCache "/var/ngx_pagespeed_cache" 51200; | |
pagespeed ModPagespeedFileCacheSizeKb 1024000; | |
pagespeed LRUCacheKbPerProcess 8192; | |
pagespeed LRUCacheByteLimit 16384; | |
#pagespeed Disallow "*.svg*"; | |
include /etc/nginx/sites-enabled/*; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If your server have less 1 GB RAM you must have swapfile or swapdisk, because https://gist.github.com/PavelBezpalov/6525017b7ab61c843264a0b544acfdd6#file-1-setup-vps-L27 need huge RAM for executing