Install ubuntu 18.04 LTS
Guide: default version is 10, we use the latest
sudo apt-get install wget ca-certificates
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'
sudo apt-get install postgresql postgresql-contrib libpq-dev
sudo -u postgres createuser db_user -s
sudo -u postgres psql
postgres=# \password (db_user)
By default, psql use peer neection (login by linux user, no password).
To change it, modify /etc/postgresql/9.5/main/pg_hba.conf
from:
local all all peer
to:
local all all md5
then restart by
sudo service postgresql restart
Command to login:
psql -U db_user -d postgres # must specify db
Rails
sudo apt install curl
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update
sudo apt-get install git-core zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev software-properties-common libffi-dev nodejs yarn
cd
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL
rbenv install 2.6.5
rbenv global 2.6.5
ruby -v
gem install bundler
gem install rails -v 6.0.0
rbenv rehash
rails -v
Rails app
rails new my_site -d postgresql
# configure db database.yml
# add domain
add config.hosts << "yourdomain.com" to config/environments/development.rb
# config generator in application.rb
config.generators do |g|
# Disable jbuilder as we use JR
# g.jbuilder false
## Disable empty files
# helper files
g.helper false
# assets files
g.assets false
end
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update
sudo apt-get install -y nginx-extras libnginx-mod-http-passenger
if [ ! -f /etc/nginx/modules-enabled/50-mod-http-passenger.conf ]; then sudo ln -s /usr/share/nginx/modules-available/mod-http-passenger.load /etc/nginx/modules-enabled/50-mod-http-passenger.conf ; fi
sudo ls /etc/nginx/conf.d/mod-http-passenger.conf
sudo vim /etc/nginx/conf.d/mod-http-passenger.conf
# We simply want to change the passenger_ruby line to match the following:
passenger_ruby /home/<deploy_user>/.rbenv/shims/ruby;
sudo service nginx start
Add the following gems to our Gemfile
gem 'capistrano', '~> 3.11'
gem 'capistrano-rails', '~> 1.4'
gem 'capistrano-passenger', '~> 0.2.0'
gem 'capistrano-rbenv', '~> 2.1', '>= 2.1.4'
Generate template
bundle
# use cap in rbenv, source ~/.bashrc if cap not found
cap install STAGES=production
Edit Capfile
Capfile:
require 'capistrano/rails'
require 'capistrano/passenger'
require 'capistrano/rbenv'
set :rbenv_type, :user
set :rbenv_ruby, '2.6.5'
deploy.rb
set :application, "my_site"
set :repo_url, "/home/web/codes/rails"
set :deploy_to, "/var/www/my_site"
append :linked_files, 'config/database.yml', 'config/master.key'
append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', '.bundle', 'public/system', 'public/uploads'
set :keep_releases, 5
deploy/production.rb
server 'yourdomain.com', user: 'web', roles: %w{app db web}
Prepare
RAILS_ENV=production rails db:create # create db
sudo mkdir /var/www/my_site
sudo chown -R web:web /var/www/my_site
cp master.key database.yml to /varw/www/my_site/shared/config
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # Otherwise, ask for password when deploy
Nginx config: /etc/nginx/site-available/default
listen 80;
listen [::]:80;
server_name my_site.com;
passenger_enabled on;
rails_env production;
# Because of incorrect path in /etc/nginx/conf.d/mod-http-passenger.conf, we have to set it again here. It's optional if it's right above.
#pssenger_ruby /home/web/.rbenv/shims/ruby;
root /var/www/my_site/current/public;
Make swap, otherwise, too slow.
cap production deploy
Install certbot
By snapd:
sudo snap install core; sudo snap refresh core
sudo apt-get remove certbot
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
By APT:
sudo apt-get install certbot python-certbot-nginx
sudo certbot --nginx (choose direct, disable http)
usage:
sudo certbot renew # for renew
sudo certbot renew --webroot-path /var/www/xxx # renew with webroot path
sudo certbot certonly -a webroot --webroot-path=/var/www/<your site>/current/public -d www.example.com -d example.com -d api.example.com. # multiple sub-domain
sudo certbot certificates # expiration day
sudo certbot delete --cert-name # remove unused domain
It seems the auto cron will renew the certification once per two months. But Ngnix should be restarted to load the new file.
Config generator in application.rb
config.generators.test_framework false
config.generators do |g|
# Disable jbuilder as we use JR
# g.jbuilder false
# Disable empty files
# helper files
g.helper false
# assets files
g.assets false
end
in config/application.rb
config.middleware.use Rack::Deflater
not working by https://gtmetrix.com/
compress js/css by Nginx
Leverage browser caching for Nginx
jQuery: follow guide
yarn add jquery
config/webpack/environment.js
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery/src/jquery',
jQuery: 'jquery/src/jquery'
})
)
app/javascript/packs/application.js
require('jquery')
webpack-dev-server
to make sure no errorsupport coffee files: follow guide
config/webpack/environment.js
config/webpacker.yml
config/webpack/loaders/coffee.js
rm app/javascript/packs/hello_coffee.coffee
app/javascript/coffee
require('../coffee/application.coffee')
Install
yarn add bootstrap popper.js jquery
In app/javascript/stylesheets/application.scss
@import 'bootstrap/scss/bootstrap';
In app/javascript/packs/application.js
import 'stylesheets/application' # include scss above
import 'bootstrap/dist/js/bootstrap';
On-the-fly build for dev:
bin/webpack-dev-server
rails g mailer admin_mailer send_passwd
Email configuration for sending emails
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
# NOTE: Please use 587 not 465. Details: https://github.com/rails/rails/issues/27298
#:port => 465, # EOF error
# Remember to enable less secure apps, otherwise Net::SMTPAuthenticationError
:port => 587,
:domain => "my_site.com", # does it matter?
:user_name => "my_site@gmail.com",
:password => "my_password",
# Plain vs Login, encry username and password together or separately.
# Details: http://www.samlogic.net/articles/smtp-commands-reference-auth.htm
#:authentication => "plain",
:authentication => "login",
:enable_starttls_auto => true
}
Check your email, Gmail may still block your access. You may need to use server to login your gmail account, then unlock, following the guide
ssh -Y
in Mac to connect server, ssh -X not workzh.yml
file under lib/locale
(default config/locales)config in config/initializers/locale.rb
I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]
I18n.available_locales = [:en, :zh]
I18n.default_locale = :zh
In application.rb
around_action :switch_locale
def switch_locale(&action)
locale = params[:locale] || I18n.default_locale
I18n.with_locale(locale, &action)
end
def default_url_options
{ locale: I18n.locale }
end
config/routes.rb
, put everything in
scope "/:locale" do
resources :books
end
Add js to head
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-159082166-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-159082166-1');
</script>
Add js to Rails, NOTE the hack for turbolinks
<!-- Global site tag (gtag.js) - Google Analytics -->
<% if Rails.env.production? %>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-159082166-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-159082166-1');
// turbolinks
document.addEventListener('turbolinks:load', event => {
if (typeof gtag === 'function') {
gtag('config', 'UA-159082166-1', {
'page_location': event.data.url
});
}
});
</script>
<% end %>
gem "recaptcha"
Configure keys in config/initializers/recaptcha.rb
Recaptcha.configure do |config|
config.site_key = 'xxx'
config.secret_key = 'xxxx'
end
Add to views: <%= recaptcha_tags %>
Check in controller
skip_verify = request.format.json?
if (skip_verify || verify_recaptcha(model: @user)) && @user.save
// OK
else
// ERROR
end