sudo apt-get update sudo apt-get upgrade
sudo apt-get install git-core nodejs
demo
user and add it to the sudo
group. sudo adduser demo sudo adduser demo sudo
demo
user.sudoers
: sudo nano / etc / sudoers file. # : %sudo ALL=(ALL:ALL) ALL # : %sudo ALL=(ALL) NOPASSWD:ALL
ssh-keygen -t rsa -b 2048
~/.ssh/id_rsa.pub
on the local computer) and add it to the ~/.ssh/authorized_keys
file on the server. After this simple manipulation with SSH, you can connect to the server without a password. If not, check the server permissions: 700 for ~/.ssh
and 600 for ~/.ssh/*
. ssh-keygen -t rsa -b 2048
~/.ssh/id_rsa.pub
need to be added to the list of deployment keys (in Github, you can find them in the settings of each repository). # Nginx official repository deb http://nginx.org/packages/ubuntu/ trusty nginx deb-src http://nginx.org/packages/ubuntu/ trusty nginx
wget http://nginx.org/keys/nginx_signing.key sudo apt-key add nginx_signing.key
sudo apt-get update sudo apt-get install nginx
/etc/nginx/conf.d
. (Of course, do not try to do it if you are not working on a “clean” server.) We will create a virtual host for the application in the next chapter. sudo rm /etc/nginx/conf.d/* sudo service nginx restart
\curl -sSL https://get.rvm.io | bash -s stable source ~/.rvm/scripts/rvm
rvm requirements
rvm install 2.1.3 rvm --default use 2.1.3
libmysqlclient-dev
package.repo
, releases
and shared
. The first is a copy of the repository, the second is the releases, the third is the common files needed by the application and not dependent on the release. Also present at the root is the symlink current
, which refers to the current release version and the Deployed log file.releases
directory). The current version of the code is shifted there and a number of tests are also performed there.bundle install
, rake db:migrate
, rake assets:precompile
, constantly checking for conflicts and errors. We missed the semicolon in default.scss
, did not commit the current Gemfile.lock
, connected Paperclip, but forgot to install on the Imagemagic server? In all these cases, Capistrano will show an error and stop the installation without affecting the current running release. If the deployment was successful, but the result did not suit you, with the help of Capistrano, you can rollback
to the previous release.config
and run
folders. In the config
put up the secrets.yml
database.yml
and secrets.yml
. (Personally, I prefer to move these two files from the config on the local computer, and then create links to them.) mv ./config/database.yml ./shared/config ln -fs ./shared/config/database.yml ./config/database.yml mv ./config/secrets.yml ./shared/config ln -fs ./shared/config/secrets.yml ./config/secrets.yml
shared/config
, - we will create a config for Nginx shared/config/nginx.conf
. In its basic form, it consists of two small parts: an upstream and a typical virtual host. Be especially careful with the paths (in this and all further) in configuration files. 90% of the errors that occurred during the delay were related to them. upstream unicorn { server unix:/home/demo/application/shared/run/unicorn.sock fail_timeout=0; } server { listen 80 default; root /home/demo/application/current/public; try_files $uri/index.html $uri.html $uri @app; location ^~ /assets/ { expires max; add_header Cache-Control public; } location @app { proxy_pass http://unicorn; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; } error_page 500 502 503 504 /500.html; location = /500.html { root /home/demo/application/current/public; } }
Gemfile
. Do not forget that the addition of new gems must be accompanied by the implementation of bundle install and the commit to the repository. If we forget about git push, then the old version of the code will be uploaded to the server, which, due to the absence of the specified gems, will cause errors during the delay. group :production do gem 'unicorn', '~> 4.8.3' end
shared/config
directory, create a file unicorn.rb
. For the most part in it, we must point the way to the component parts of our application. For convenience, this can be done using variables. # root = '/home/demo/application' rails_root = "#{root}/current" # , Unicorn- pidfile = "#{root}/shared/run/unicorn.pid" pidfile_old = pidfile + '.oldbin' pid pidfile # worker_processes 1 preload_app true timeout 30 # listen "#{root}/shared/run/unicorn.sock", :backlog => 1024 # - stderr_path "#{rails_root}/log/unicorn_error.log" stdout_path "#{rails_root}/log/unicorn.log" # GC.copy_on_write_friendly = true if GC.respond_to?(:copy_on_write_friendly=) # , before_exec do |server| ENV["BUNDLE_GEMFILE"] = "#{rails_root}/Gemfile" end # before_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! if File.exists?(pidfile_old) && server.pid != pidfile_old begin Process.kill("QUIT", File.read(pidfile_old).to_i) rescue Errno::ENOENT, Errno::ESRCH end end end after_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection end
worker_processes
, - each of which uses a certain amount of memory (how much it depends on the application) and timeout
(usually from 15 to 30 seconds). Many people also mention preload_app
(the value of which false
can shorten the start time of the worker); let's look at true
, and then you decide for yourself.Gemfile
you need to add Capistrano and a series of gems that implement its connection to RVM, Bundler and Rails. group :development do gem 'capistrano', '~> 3.2.1' gem 'capistrano-rvm', '~> 0.1.1' gem 'capistrano-bundler', '~> 1.1.3' gem 'capistrano-rails', '~> 1.1.2' end
Capfile
, config/deploy.rb
and config/deploy/production.rb
. (In config/deploy
Capistrano creates default staging.rb
and production.rb
files. We will only configure the combat server using production.rb
.)Capfile
updateCapfile
created in the root. Take a look at the default file and uncomment the necessary lines or use the following content: require 'capistrano/setup' require 'capistrano/deploy' require 'capistrano/rvm' require 'capistrano/bundler' require 'capistrano/rails' Dir.glob('lib/capistrano/tasks/*.rb').each { |r| import r }
config/deploy/production.rb
and carefully look at its contents. It will help you understand the format and customization options. In general, if you use authentication with an SSH key, you will not have to write any exotics; just one line: server '178.62.252.46', user: 'demo', roles: %w{web app}
config/deploy.rb
. It is he who describes the parameters, procedures and scenario of the upcoming deployment. I will describe each block of the file, but if you want to look at it in its final form, use the repository. lock '3.2.1'
# set :repo_url, 'git@github.com:eboyko/deneb.git' # set :rails_env, 'production'
deploy_to
parameter, which determines the path for deploying the application on the server. Above, we have already said that we mean commercial interest, so we will make the script file more universal using variables and set the missing parameter: # set :username, 'demo' # set :application, 'application' # set :deploy_to, "/home/#{fetch(:username)}/#{fetch(:application)}"
log_level
parameter (default value :debug
makes Capistrano too talkative): set :log_level, :info
shared_path
) can be used directly; set with set
- via fetch
method.public/upload
. To connect them to each new release, in config/deploy.rb
you can set the parameter :linked_dirs
: set :linked_dirs, %w{public/upload}
public/upload
link will be replaced by a symlink leading to the shared/public/upload
directory, where data accumulated during previous releases. Similarly, with :linked_files
, separate files are linked: set :linked_files, %w{config/secrets.yml config/database.yml}
:linked_files
specified files ( config/secrets.yml
and config/database.yml
) is mandatory. Otherwise, the deployment will fail with an error due to the lack of connection to the database.:deploy
already exists, it can only be supplemented; all the procedures included in it for the production
server can be called with the cap production deploy commandshared
directory, in which, among other things, the configuration files ( shared/config
) are located. The logical first step is to upload them to the server. To do this, all in the same config/deploy.rb
, in the namespace :setup
, we will write the procedure: namespace :setup do desc ' ' task :upload_config do on roles :all do execute :mkdir, "-p #{shared_path}" ['shared/config', 'shared/run'].each do |f| upload!(f, shared_path, recursive: true) end end end end
shared_path
(because there is no structure on the server yet) and loading the local shared/config
directory there. You can execute it with the cap production setup: upload_config commandsudo
rights). namespace :nginx do desc ' /etc/nginx/conf.d nginx.conf ' task :append_config do on roles :all do sudo :ln, "-fs #{shared_path}/config/nginx.conf /etc/nginx/conf.d/#{fetch(:application)}.conf" end end desc ' nginx' task :reload do on roles :all do sudo :service, :nginx, :reload end end desc ' nginx' task :restart do on roles :all do sudo :service, :nginx, :restart end end after :append_config, :restart end
set :unicorn_config, "#{shared_path}/config/unicorn.rb" set :unicorn_pid, "#{shared_path}/run/unicorn.pid" namespace :application do desc ' Unicorn' task :start do on roles(:app) do execute "cd #{release_path} && ~/.rvm/bin/rvm default do bundle exec unicorn_rails -c #{fetch(:unicorn_config)} -E #{fetch(:rails_env)} -D" end end desc ' Unicorn' task :stop do on roles(:app) do execute "if [ -f #{fetch(:unicorn_pid)} ] && [ -e /proc/$(cat #{fetch(:unicorn_pid)}) ]; then kill -9 `cat #{fetch(:unicorn_pid)}`; fi" end end end
:unicorn_config
and :unicorn_pid
.:deploy
will look something like this: namespace :deploy do after :finishing, 'application:stop' after :finishing, 'application:start' after :finishing, :cleanup end
deploy.rb
, written procedures can (and maybe need) be moved beyond its limits. In Capfile
last line is responsible for importing such tasks from the lib/capistrano/tasks
directory, this is the place to move this part of the logic.staging
server, deploy to which to perform cap staging deploy.Source: https://habr.com/ru/post/240025/
All Articles