Record a Rails project deployment

Cloud server

Tencent cloud and Ubuntu Server 16.04.1 LTS 64-bit

Project example

Using a blog demo, Getting Started with Rails from the documentation on the Rails website

Installing the Server Software

Use Ubuntu’s built-in suite management tool apt-get

  1. Update the software list

    sudo apt-get update
    Copy the code
  2. Install the required software for Ruby on Rails

    sudo apt-get install -y build-essential git-core bison openssl libreadline6-dev curl zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 autoconf libc6-dev libpcre3-dev libcurl4-nss-dev libxml2-dev libxslt-dev  imagemagick nodejs libffi-devCopy the code
  3. Install Ruby and use Brighbox’s compiled Ruby

    sudo apt-get install software-properties-common sudo apt-add-repository ppa:brightbox/ruby-ng sudo apt-get update sudo Apt to get the install ruby2.6 ruby2.6 - devCopy the code
  4. Replace the gem source and install the Bundler gem

    gem source
    gem source -r https://rubygems.org/
    gem source -a https://gems.ruby-china.com
    
    sudo gem install bundler
    Copy the code
  5. Install Rails

    Gem install Rails -v 5.1.7Copy the code
  6. Install the database using PostgreSQL or MySQL

    Sudo apt-get install postgresql libpq-dev postgresql-contrib # Modify the password of account postgres sudo -u postgres PSQL Sudo -u postgres createdb blog postgres=#\password # remember the password in database.ymlCopy the code
  7. Install Nginx + Passenger Web server from Installing Passenger + Nginx

    sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
    sudo apt-get install -y apt-transport-https ca-certificates
    sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger xenial main > /etc/apt/sources.list.d/passenger.list'
    sudo apt-get update
    sudo apt-get install -y nginx-extras passenger
    Copy the code
  8. Welcome to Nginx on Ubuntu!

Creating a Deployment User

  1. Adding a Deploy user
Sudo adduser --disabled-password deploy sudo su deploy mkdir ~/. SSH touch ~/. SSH /authorized_keys # Cat ~/.ssh/id_rsa.pub # Paste the public key vi ~/. SSH /authorized_keys chmod 700 ~/. SSH chmod 644 ~/. SSH /authorized_keys # After you exit, the local PC can use SSH to deploy@< host IP address location > to log in without passwordCopy the code

Automated deployment

  1. To install the Capistrano deployment tool, use the blog project

    Modify the blog project Gemfile with #!! , bundle install after modification

    source 'https://gems.ruby-china.com/' git_source(:github) do |repo_name| repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") "https://github.com/#{repo_name}.git" end # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.1.7' # Use sqlite3 as the database for Active Record # Use Puma as the app server gem 'Puma ', '~> 3.7' # Use SCSS for stylesheets gem 'sass-rails', # Use Uglifier as compressor for JavaScript assets gem 'Uglifier ', # '> = 1.3.0 See https://github.com/rails/execjs#readme for more supported runtimes # gem' therubyracer, platforms: :ruby # Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.2' # Turbolinks makes navigating your Web Application faster. Read more: https://github.com/turbolinks/turbolinks gem 'turbolinks', '~> 5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.5' # Use Redis adapter to run Action Cable in production # gem 'Redis' '~> 4.0' # Use ActiveModel has_secure_password # Use Capistrano for deployment # gem 'Capistrano -rails', group: :development #!! group :production do gem 'pg' end #!!! group :development, :test do gem 'sqlite3' # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] # Adds support for Capybara system testing and selenium driver gem 'capybara', '>= 2.15' gem 'selenium-webdriver' gem 'rspec-rails' #!! gem 'capistrano-rails' gem 'capistrano-passenger' end group :development do # Access an IRB console on exception pages Or by using <%= console %> anywhere in the code. gem 'web-console', '>= 3.3.0' gem 'listen', '>= 3.0.5', '< 3.2' # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' gem 'spring-watcher-listen', '~> FFFFFF 'end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', FFFFFF: [:mingw, :mswin, :x64_mingw, :jruby]Copy the code
  2. Capistrano is configured locally and executed in the project directory

    cap install
    Copy the code

    Edit Capfile file with #!!

    # 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 #!!! require 'capistrano/rails' require 'capistrano/passenger' # 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" # Load custom  tasks from `lib/capistrano/tasks` if you have any defined Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }Copy the code
  3. Change config/deploy.rb to #!!

    # config valid for current version and patch releases of Capistrano #!!! Sh "ssh-add" lock "~> 3.16.0" #! set :application, "blog" #!!! Send your project to the remote Github repository, Set: repo_URL, "[email protected]: XXX /blog.git" # Default branch is :master # ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp # Default deploy_to directory is /var/www/my_app_name # set :deploy_to, "/var/www/my_app_name" #!!! set :deploy_to, "/home/deploy/blog" # Default value for :format is :airbrussh. # set :format, :airbrussh # You can configure the Airbrussh format using :format_options. # These are the defaults. # set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto # Default value for :pty is false # set :pty, true # Default value for :linked_files is [] # append :linked_files, "config/database.yml" #!!! append :linked_files, "config/database.yml", "config/secrets.yml" # Default value for linked_dirs is [] # append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system" #!!! append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system" #!!! set :passenger_restart_with_touch, true # Default value for default_env is {} # set :default_env, { path: "/opt/ruby/bin:$PATH" } # Default value for local_user is ENV['USER'] # set :local_user, -> { `git config user.name`.chomp } # Default value for keep_releases is 5 # set :keep_releases, 5 #!!! set :keep_releases, 5 # Uncomment the following to require manually verifying the host key before first deploy. # set :ssh_options, verify_host_key: :secureCopy the code
  4. Modify the config/deploy/production. Rb, attention tag #!!!!!!

    #!!!!!! set :branch, "master" # server-based syntax # ====================== # Defines a single server with a list of roles and multiple properties. # You can define all roles on a single server, or split them: # server "example.com", user: "deploy", roles: %w{app db web}, my_property: :my_value # server "example.com", user: "deploy", roles: %w{app web}, other_property: :other_value # server "db.example.com", user: "deploy", roles: %w{db} #!!! Server "15x.13x.12x.18", user: "deploy", roles: %w{app db web}, my_property: :my_value # role-based syntax # ================== # Defines a role with one or multiple servers. The primary server in each # group is considered to be the first unless any hosts have the primary # property set. Specify the username and a domain or IP for the server. # Don't use `:all`, it's a meta role. # role :app, %w{[email protected]}, my_property: :my_value # role :web, %w{[email protected] [email protected]}, other_property: :other_value # role :db, %w{[email protected]} # Configuration # ============= # You can set any configuration variable like in config/deploy.rb  # These variables are then only loaded and set in this stage. # For available Capistrano configuration variables see the documentation page. # http://capistranorb.com/documentation/getting-started/configuration/ # Feel free to add new variables to customise your setup. # Custom SSH Options # ================== # You may pass any option but keep in mind that net/ssh understands a # limited set of options, consult the Net::SSH documentation. # http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start # # Global options # -------------- # set :ssh_options, { # keys: %w(/home/user_name/.ssh/id_rsa), # forward_agent: false, # auth_methods: %w(password) # } # # The server-based syntax can be used to override options: # ------------------------------------ # server "example.com", # user: "user_name", # roles: %w{web app}, # ssh_options: { # user: "user_name", # overrides user setting above # keys: %w(/home/user_name/.ssh/id_rsa), # forward_agent: false, # auth_methods: %w(publickey password) # # password: "please use keys" # }Copy the code
  5. Execute cap Production deploy: Check in the local project directory, which automatically creates some Capistrano directories and files on the automatic login remote server

    Cap Production deploy:check # will have a missing database.yml file Error, continue to see the next stepCopy the code
  6. The server is set to database.yml and secrets.yml

    # login or switch to deploy users, add/home/deploy/blog/Shared/config/database. Yml production: adapter: postgresql pool: 25 database: blog host: localhost username: postgres password: XXXXXX # execute rake secret under local project Generate random number for later use efab0aae7352a424fae818574934baf1107f96785dbdf6ee5f8e7054399a4bbbb561dfc1183e1f20f2c247d9cd437fa0908d2fcb7517b0d7c34e61b4 59 d5969d # login or switch to deploy users, add/home/deploy/blog/Shared/config/secrets. Yml production: secret_key_base: Paste in the random number we just created, there is a space here, or parse # # # # # # # # #Copy the code
  7. Execute Cap Production deploy in the native blog directory for deployment

    Perform logging into remote servers, pulling code from GitHub repositories, installing gems, migrating databases, compiling assets, and more

    ssh-add
    Identity added: /Users/gekang/.ssh/id_rsa (/Users/gekang/.ssh/id_rsa)
    00:00 git:wrapper
      01 mkdir -p /tmp
    ✔ 01 [email protected] 0.351s
      Uploading /tmp/git-ssh-0633e09da1de2a9e42f4.sh 100.0%
      02 chmod 700 /tmp/git-ssh-0633e09da1de2a9e42f4.sh
    ✔ 02 [email protected] 0.077s
    00:00 git:check
      01 git ls-remote [email protected]:grackanil/blog.git HEAD
      01 ac469184b28aec29e409430ab7bdc0eb6af76e5b	HEAD
    ✔ 01 [email protected] 6.136s
    00:06 deploy:check:directories
      01 mkdir -p /home/deploy/blog/shared /home/deploy/blog/releases
    ✔ 01 [email protected] 0.035s
    00:06 deploy:check:linked_dirs
      01 mkdir -p /home/deploy/blog/shared/log /home/deploy/blog/shared/tmp/pids /home/…
    ✔ 01 [email protected] 0.464s
    00:07 deploy:check:make_linked_dirs
      01 mkdir -p /home/deploy/blog/shared/config
    ✔ 01 [email protected] 0.031s
    00:08 git:clone
      The repository mirror is at /home/deploy/blog/repo
    00:08 git:update
      01 git remote set-url origin [email protected]:grackanil/blog.git
    ✔ 01 [email protected] 0.077s
      02 git remote update --prune
      02 Fetching origin
    ✔ 02 [email protected] 5.568s
    00:14 git:create_release
      01 mkdir -p /home/deploy/blog/releases/20210622112320
    ✔ 01 [email protected] 0.075s
      02 git archive master | /usr/bin/env tar -x -f - -C /home/deploy/blog/releases/20…
    ✔ 02 [email protected] 0.092s
    00:14 deploy:set_current_revision
      01 echo "ac469184b28aec29e409430ab7bdc0eb6af76e5b" > REVISION
    ✔ 01 [email protected] 0.079s
    00:14 deploy:symlink:linked_files
      01 mkdir -p /home/deploy/blog/releases/20210622112320/config
    ✔ 01 [email protected] 0.070s
      02 rm /home/deploy/blog/releases/20210622112320/config/database.yml
    ✔ 02 [email protected] 0.074s
      03 ln -s /home/deploy/blog/shared/config/database.yml /home/deploy/blog/releases/…
    ✔ 03 [email protected] 0.071s
      04 rm /home/deploy/blog/releases/20210622112320/config/secrets.yml
    ✔ 04 [email protected] 0.071s
      05 ln -s /home/deploy/blog/shared/config/secrets.yml /home/deploy/blog/releases/2…
    ✔ 05 [email protected] 0.071s
    00:15 deploy:symlink:linked_dirs
      01 mkdir -p /home/deploy/blog/releases/20210622112320 /home/deploy/blog/releases/…
    ✔ 01 [email protected] 0.070s
      02 rm -rf /home/deploy/blog/releases/20210622112320/log
    ✔ 02 [email protected] 0.070s
      03 ln -s /home/deploy/blog/shared/log /home/deploy/blog/releases/20210622112320/l…
    ✔ 03 [email protected] 0.073s
      04 ln -s /home/deploy/blog/shared/tmp/pids /home/deploy/blog/releases/20210622112…
    ✔ 04 [email protected] 0.071s
      05 ln -s /home/deploy/blog/shared/tmp/cache /home/deploy/blog/releases/2021062211…
    ✔ 05 [email protected] 0.078s
      06 ln -s /home/deploy/blog/shared/tmp/sockets /home/deploy/blog/releases/20210622…
    ✔ 06 [email protected] 0.077s
      07 ln -s /home/deploy/blog/shared/public/system /home/deploy/blog/releases/202106…
    ✔ 07 [email protected] 0.069s
      08 rm -rf /home/deploy/blog/releases/20210622112320/public/assets
    ✔ 08 [email protected] 0.078s
      09 ln -s /home/deploy/blog/shared/public/assets /home/deploy/blog/releases/202106…
    ✔ 09 [email protected] 0.072s
    00:16 bundler:config
      01 bundle config --local deployment true
      01 You are replacing the current local value of deployment, which is currently nil
    ✔ 01 [email protected] 0.241s
      02 bundle config --local path /home/deploy/blog/shared/bundle
      02 You are replacing the current local value of path, which is currently nil
    ✔ 02 [email protected] 0.317s
      03 bundle config --local without development:test
      03 You are replacing the current local value of without, which is currently nil
    ✔ 03 [email protected] 0.308s
    00:18 bundler:install
      The Gemfile's dependencies are satisfied, skipping installation
    00:18 deploy:assets:precompile
      01 bundle exec rake assets:precompile
      01 Yarn executable was not detected in the system.
      01 Download Yarn at https://yarnpkg.com/en/docs/install
    ✔ 01 [email protected] 1.870s
    00:20 deploy:assets:backup_manifest
      01 mkdir -p /home/deploy/blog/releases/20210622112320/assets_manifest_backup
    ✔ 01 [email protected] 0.073s
      02 cp /home/deploy/blog/releases/20210622112320/public/assets/.sprockets-manifest…
    ✔ 02 [email protected] 0.071s
    00:20 deploy:migrate
      [deploy:migrate] Run `rake db:migrate`
    00:20 deploy:migrating
      01 bundle exec rake db:migrate
    ✔ 01 [email protected] 1.584s
    00:21 deploy:symlink:release
      01 ln -s /home/deploy/blog/releases/20210622112320 /home/deploy/blog/releases/cur…
    ✔ 01 [email protected] 0.075s
      02 mv /home/deploy/blog/releases/current /home/deploy/blog
    ✔ 02 [email protected] 0.072s
    00:22 passenger:restart
      01 mkdir -p /home/deploy/blog/releases/20210622112320/tmp
    ✔ 01 [email protected] 0.072s
      02 touch /home/deploy/blog/releases/20210622112320/tmp/restart.txt
    ✔ 02 [email protected] 0.072s
    00:22 deploy:cleanup
      Keeping 5 of 6 deployed releases on 15x.x3x.xxx.13
      01 rm -rf /home/deploy/blog/releases/20210622073535
    ✔ 01 [email protected] 0.080s
    00:22 deploy:log_revision
      01 echo "Branch master (at ac469184b28aec29e409430ab7bdc0eb6af76e5b) deployed as …
    ✔ 01 [email protected] 0.073s
    Copy the code

    Then you just need to change the code and deploy

    git commit
    cap production deploy
    Copy the code

    Note that the current directory is generated here and will be needed later

    Set the Nginx

    With root permission, set /etc/nginx/nginx.conf to #!!

    #!!!!!! env PATH; user www-data; worker_processes auto; pid /run/nginx.pid; events { worker_connections 768; # multi_accept on; } http { #!!! passenger_show_version_in_header off; #!!!!!! server_tokens off; #!!!!!! client_max_body_size 100m; gzip on; gzip_disable "msie6"; #!!!!!! gzip_comp_level 5; gzip_min_length 256; gzip_proxied any; gzip_vary on; gzip_types application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/xml text/plain text/javascript text/x-component; #!!!!!! include /etc/nginx/passenger.conf; # down slightlyCopy the code

    Set /etc/nginx/sites-enabled/blog.conf as root

    server { listen 80; server_name 15x.x3x.xxx.13; # with your own server IP address root/home/deploy/blog/current/public; # current, passenger_enabled on; passenger_min_instances 1; location ~ ^/assets/ { expires 1y; add_header Cache-Control public; add_header ETag ""; break; }}Copy the code

    Restart the Nginx

    sudo service nginx restart
    Copy the code

    Open IP address, done, happy

Reference documentation

  • Ruby China:ruby-china.org/wiki
  • Getting Started with Rails:guides.rubyonrails.org/getting_sta…
  • Brighbox:www.brightbox.com/docs/ruby/u…
  • Capistrano:capistranorb.com/
  • Ruby on Rails:guides.rubyonrails.org/
  • Rails: ihower. Tw/Rails/Fulls…
  • Installing Passenger + Nginx www.phusionpassenger.com/library/ins…
  • Gorails:gorails.com/deploy/ubun…

Welcome to pay attention to my small public number