sudo adduser deploy
sudo adduser deploy sudo
visudo
deploy ALL=(ALL:ALL) ALL
su deploy
generate ssh key
ssh-keygen -t rsa -b 4096 -C "xingyu.ye@outlook.com"
copy .ssh/id_rsa.pub to server .ssh/id_rsa.pub
cd ~
cat .ssh/id_rsa.pub
vi .ssh/authorized_keys
chmod 600 .ssh/authorized_keys
vim ~/.ssh/config
Host bitbucket.org
Hostname altssh.bitbucket.org
Port 443
ssh -T git@bitbucket.org
sudo apt-get update
sudo apt-get upgrade -y && sudo apt full-upgrade -y
sudo apt-get install -y fail2ban
cd /etc/fail2ban
sudo vi jail.local
[DEFAULT]
bantime = 3600
banaction = iptables-multiport
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 9
sudo apt install -y iptables-persistent
sudo service fail2ban start
sudo fail2ban-client status sshd # check fail2ban status
sudo ufw status
sudo cp /etc/default/ufw /etc/default/ufw.0
cat /etc/default/ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
sudo ufw status
sudo apt-get install -y curl imagemagick
sudo apt-get install -y git
sudo apt install -y curl wget git zsh
echo $SHELL
chsh -s $(which zsh)
logout
log back in
choose 2
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
# server side
ZSH_THEME="simple"
# pve
wget -O $ZSH_CUSTOM/themes/hyperzsh.zsh-theme https://raw.githubusercontent.com/tylerreckart/hyperzsh/master/hyperzsh.zsh-theme
ZSH_THEME="hyperzsh"
vi $ZSH_CUSTOM/themes/hyperzsh.zsh-theme
ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[magenta]%}"
ZSH_THEME_GIT_PROMPT_CLEAN=" %{$fg[green]%}✓%{$reset_color%} "
source .zshrc
sudo apt install -y gnupg2
curl -sSL https://rvm.io/mpapis.asc | gpg2 --import
curl -sSL https://rvm.io/pkuczynski.asc | gpg2 --import
cd /tmp
curl -sSL https://get.rvm.io -o rvm.sh
cat /tmp/rvm.sh | bash -s stable --rails
source /home/{{user}}/.rvm/scripts/rvm
rvm install 2.6.3
rvm use 2.6.3
rvm list
ruby -v
ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
gem install bundler
set bundle config. ex.sidekiq account
sudo apt-get install -y postgresql postgresql-contrib libpq-dev
sudo su - postgres
createuser deploy --pwprompt
exit
sudo su
su postgres
psql
create database {{database_name}} with owner = deploy;
ALTER ROLE deploy WITH CREATEDB;
ALTER ROLE deploy SUPERUSER; //to use uuid
\q
exit
exit
If there is an error regarding to encoding(utf8) compatibility. check link below https://gist.github.com/Sunnyztj/14c554e5694711433c5a1fad4e10892b
test the database with
psql --user deploy --password [database_name]
\q
sudo apt-get install -y nginx
sudo service nginx start
# Ignore bundler config.
/.bundle
# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
# Ignore uploaded files in development
/storage/*
!/storage/.keep
/node_modules
/yarn-error.log
/public/assets
.byebug_history
# Ignore master key for decrypting credentials and more.
/config/master.key
/config/database.yml
/config/secrets.yml
/config/application.yml
/config/racecar.yml
/config/racecar.rb
/config/sidekiq.yml
/config/kafka_ssl/*
.idea/*
dump.rdb
/db/*.sql
/spec/public/system/
/public/system/
.DS_Store
gem "capistrano-db-tasks", require: false
gem 'mini_racer', platforms: :ruby
group :development do
gem 'capistrano', '~> 3.10'
gem 'capistrano-rails', '~> 1.4'
gem 'capistrano-rvm'
gem 'capistrano-bundler'
gem 'capistrano3-unicorn'
gem 'capistrano-sidekiq'
end
gem 'unicorn'
create config/unicorn/production.rb
root = "/home/deploy/{{project_name}}/current"
working_directory root
pid "#{root}/tmp/pids/unicorn.pid"
stderr_path "#{root}/log/unicorn_error.log"
stdout_path "#{root}/log/unicorn_output.log"
# worker_processes Integer(ENV['WEB_CONCURRENCY'])
worker_processes 2
timeout 10
preload_app true
listen "#{root}/tmp/sockets/unicorn.edocapi.sock", backlog: 64
before_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
Process.kill 'QUIT', Process.pid
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
# Force the bundler gemfile environment variable to
# reference the capistrano "current" symlink
before_exec do |_|
ENV['BUNDLE_GEMFILE'] = File.join(root, 'Gemfile')
end
bundle exec cap install
config/deploy/production.rb
set :port, 22
set :user, 'deploy'
set :deploy_via, :remote_cache
set :use_sudo, false
server '{{server_ip}}', port: fetch(:port), user: fetch(:user), roles: %w{app db web}
set :stage, :production
set :rails_env, :production
set :unicorn_env, :production
set :unicorn_rack_env, 'production'
set :branch, "master"
config/deploy.rb
# config valid for current version and patch releases of Capistrano
lock "~> 3.11.0"
# if you want to remove the local dump file after loading
set :db_local_clean, true
# if you want to remove the dump file from the server after downloading
set :db_remote_clean, true
# if you want to exclude table from dump
set :db_ignore_tables, []
# if you want to exclude table data (but not table schema) from dump
set :db_ignore_data_tables, []
# if you are highly paranoid and want to prevent any push operation to the server
set :disallow_pushing, true
set :rvm_map_bins, %w{gem rake ruby rails bundle}
# configure location where the dump file should be created
set :db_dump_dir, -> { File.join(current_path, 'db') }
set :application, "{{project_name_in_lower_case}}"
set :repo_url, "{{project_remote_git_url}}"
set :branch, 'master'
set :deploy_to, "/home/deploy/{{project_name}}"
# Default value for :pty is false
# set :pty, true
append :linked_files, "config/database.yml", "config/application.yml", "config/secrets.yml", "config/sidekiq.yml"
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system", "public/uploads"
set :keep_releases, 5
set :assets_manifests, ['app/assets/config/manifest.js']
set :rails_assets_groups, :assets
set :keep_assets, 2
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:web), in: :sequence, wait: 5 do
execute :touch, release_path.join('tmp/restart.txt')
end
end
end
# after 'deploy:restart', 'unicorn:duplicate'
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
begin
invoke! 'unicorn:stop'
rescue
p 'unicorn stop error'
end
begin
invoke! 'unicorn:stop'
rescue
p 'unicorn stop error'
end
invoke 'unicorn:start'
end
end
# Load DSL and set up stages
require "capistrano/setup"
# Include default deployment tasks
require "capistrano/deploy"
# Load the SCM plugin appropriate to your project:
#
# require "capistrano/scm/hg"
# install_plugin Capistrano::SCM::Hg
# or
# require "capistrano/scm/svn"
# install_plugin Capistrano::SCM::Svn
# or
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
# Include tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
# https://github.com/capistrano/rvm
# https://github.com/capistrano/rbenv
# https://github.com/capistrano/chruby
# https://github.com/capistrano/bundler
# https://github.com/capistrano/rails
# https://github.com/capistrano/passenger
#
require "capistrano/rvm"
# require "capistrano/rbenv"
# require "capistrano/chruby"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
# require "capistrano/passenger"
require 'capistrano3/unicorn'
require 'capistrano-db-tasks'
require 'capistrano/sidekiq'
#require 'capistrano/sidekiq/monit'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
cap production deploy:check
it will generate all the folders cd into config create database.yml, application.yml
vi application.yml
vi databse.yml
vi sidekiq.yml
rake secret
vi secrets.yml
check cap deploy again, it should all pass the list
go to server
cd /etc/nginx/sites-available
sudo vi default
change the default to the following
upstream unicorn {
server unix:/home/deploy/{{project_name}}/current/tmp/sockets/unicorn.edocapi.sock fail_timeout=0;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /home/deploy/{{project_name}}/current/public;
server_name {{project_server_name}};
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location ~ ^/(robots.txt|sitemap.xml.gz)/ {
root /home/deploy/{{project_name}}/current/public;
}
try_files $uri/index.html $uri @unicorn;
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
stop and restart the nginx service
sudo service nginx stop
sudo service nginx start
sudo apt-get -y install redis-server
sudo systemctl enable redis-server.service
change :pty in deploy.rb to true when first setup sidekiq, after first time set it back to false
set :pty, true
cap production deploy
set :pty, false
//? multi process sidekiq? https://github.com/seuros/capistrano-sidekiq
deploy the project with
cap production deploy
useful command
cap production unicorn:start
cap production unicorn:stop
cap production sidekiq:start
cap production sidekiq:stop
sudo wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.bionic_amd64.deb
sudo dpkg -i wkhtmltox_0.12.5-1.bionic_amd64.deb
sudo apt-get install -f
sudo ln -s /usr/local/bin/wkhtmltopdf /usr/bin
sudo ln -s /usr/local/bin/wkhtmltoimage /usr/bin
https://dev.to/kevinluo201/start-sidekiq-6-as-daemon-in-production-environment-on-ubuntu-20-04-4m7b
cd ~
mkdir -p .config/systemd/user
cd .config/systemd/user
vi sidekiq.service
[Unit]
Description=sidekiq
After=syslog.target network.target
[Service]
# notify can be used only after Sidekiq 6.0.6
# if the version is under 6.0.6, use Type=simple
Type=notify
WatchdogSec=10
WorkingDirectory=/path/to/your/app/current
# If you use rbenv:
# ExecStart=/bin/bash -lc 'exec /home/deploy/.rbenv/shims/bundle exec sidekiq -e production'
# If you use the system's ruby:
# ExecStart=/usr/local/bin/bundle exec sidekiq -e production
# If you use rvm in production without gemset and your ruby version is 2.6.5
# ExecStart=/home/deploy/.rvm/gems/ruby-2.6.5/wrappers/bundle exec sidekiq -e production
# If you use rvm in production with gemset and your ruby version is 2.6.5
# ExecStart=/home/deploy/.rvm/gems/ruby-2.6.5@gemset-name/wrappers/bundle exec sidekiq -e production
# If you use rvm in production with gemset and ruby version/gemset is specified in .ruby-version,
# .ruby-gemsetor or .rvmrc file in the working directory
ExecStart=/home/deploy/.rvm/bin/rvm in /path/to/your/app/current do bundle exec sidekiq -e production
ExecReload=/usr/bin/kill -TSTP $MAINPID
# Greatly reduce Ruby memory fragmentation and heap usage
# https://www.mikeperham.com/2018/04/25/taming-rails-memory-bloat/
Environment=MALLOC_ARENA_MAX=2
# if we crash, restart
RestartSec=1
Restart=on-failure
# output goes to /var/log/syslog
StandardOutput=syslog
StandardError=syslog
# This will default to "bundler" if we don't specify it
SyslogIdentifier=sidekiq
[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable sidekiq.service
# you can use systemctl to control sidekiq
systemctl --user {start,stop,restart} sidekiq
sudo cat /var/log/syslog
# Gemfile
gem 'capistrano-sidekiq', group: :development
# Capfile
require 'capistrano/sidekiq'
# Default sidekiq tasks
install_plugin Capistrano::Sidekiq
# We specify that we want to use systemd to control sidekiq
install_plugin Capistrano::Sidekiq::Systemd