Приклад деплоя app на Ruby On Rails
В даній замітці розглядається приклад деплою проетку під назвою tools на VPS-сервер Ubuntu 14.04 в каталог /home/deployer/apps/project/, код проекту знаходиться на git-сервері bitbucket.org у приватному репозиторію. Використовуємо Ruby 2.4.0 та Ruby On Rails 5
Підготовка VPS-серверу
Створюємо LXC-контейнер використавши шаблон ubuntu-14.04-standart-amd64-ROR-Nginx-Passenger-Postgres-Capistrano (опис деплоя з нуля)
Заходимо через консоль, та задаємо пароль для користувача deployer
1 |
passwd deployer |
Створюємо базу даних та користувача
1 |
sudo -u postgres psql |
1 2 3 |
create user deployer with password 'password'; alter role deployer superuser createrole createdb replication; create database MYAPP_production owner deployer; |
Генерація ssh ключів
Оскільки користувачу deployer потрібний доступ до git-серверу а репозиторій проекту у нас приватний, ми генеруємо ssh-key
1 |
ssh-keygen -t rsa -C "<your@mail>" |
та додаємо ключ на git-сервер
1 |
cat ~/.ssh/id_rsa.pub |
налаштування поштового серверу
1 |
sudo dpkg-reconfigure postfix |
Підготовка проекту на локальній машині для деплоя
Для деплоя проекту, нам потрібний ssh-доступ з докальної машини на VPS-сервер, для цього добавимо ssh-key на сервер deploy'я
1 |
ssh-copy-id deployer@<deploy-server.hostname> |
якщо у config/secrets.yml ми маємо
1 2 |
production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> |
тоді генеруємо токен
1 |
bundle exec rake secret |
та вставляємо його замість <%= ENV[“SECRET_KEY_BASE”] %>
Якщо проект в стадії розробки, варто буде в config/environments/production.rb задати
1 |
config.consider_all_requests_local = true |
щоб бачити реальні помилки замість сторінки із "we're sorry"
Capistrano
В нашому локальному проекті добавимо наступні gem'и (в Gemfile)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
group :development do # Джем, який добавляє специфічні для Rails таски, такі як прогон міграцій і компіляція ассетів gem 'capistrano-rails' gem 'capistrano-rails-console' # Джем, який добавляє можливість bundle до capistrano gem 'capistrano-bundler' # Добалвення підтримки RVM (менеджера версій для Ruby) gem 'capistrano-rvm' # Інтеграція пасажира и капістрано gem 'capistrano-passenger' gem 'capistrano-linked-files' end |
Виконуємо інсталяцію нових gem'ів та capistrano
1 2 |
bundle install cap install |
В результаті у нас з'являться наступні два нові файли
config/deploy.rb
config/deploy/production.rb
Конфігурація config/deploy.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# Назва проекту set :application, 'tools' # Шляз до tools репозиторія set :repo_url, 'git@bitbucket.org:username/tools' # Вітка за змовчанням set :branch, 'master' # Директорія для деплоя set :deploy_to, '/home/deployer/apps/project' set :default_stage, 'production' set :log_level, :info # Файли та директорії (між деплоями), об'єкти яких немає в проеті потрібно забрати set :linked_files, %w{config/database.yml} set :linked_dirs, %w{tmp/pids tmp/cache tmp/sockets vendor/bundle public/uploads} # А це рекомендують добавити для проектів, які використовують ActiveRecord set :puma_init_active_record, true namespace :deploy do desc 'Restart application' task :restart do on roles(:app), in: :sequence, wait: 5 do # Your restart mechanism here, for example: # execute :touch, release_path.join('tmp/restart.txt') end end after :restart, :clear_cache do on roles(:web), in: :groups, limit: 3, wait: 10 do # Here we can do anything such as: # within release_path do # execute :rake, 'cache:clear' # end end task :seed do on roles(:all) do within release_path do with rails_env: fetch(:rails_env) do execute :rake, "db:seed" end end end end task :precompile do on roles(:all) do within release_path do with rails_env: fetch(:rails_env) do execute :rake, "assets:precompile --trace" end end end end task :setup do before "deploy:migrate", :create_db invoke :deploy end task :create_db do on roles(:all) do within release_path do with rails_env: fetch(:rails_env) do execute :rake, "db:create" end end end end end after :finishing, 'deploy:cleanup' # Uploading both linked_files and dirs before :finishing, 'linked_files:upload' # Uploading only linked_files before :finishing, 'linked_files:upload_files' # Uploading only dirs before :finishing, 'linked_files:upload_dirs' end |
Конфігурація config/deploy/production.rb, полягає лише у втсавці ip-адресу vps-серверу
1 |
server '<ip>', user: 'deployer', roles: %w{web app db} |
Якщо ви не захотіли по якійсь причині використовувати ключі для доступу до VPS-серверу, ми можете прописати ssh-параметри доступу в цьому файлі
1 2 3 4 5 6 7 |
set :ssh_options, { forward_agent: false, auth_methods: %w(password), password: '<your_password>', user: 'deployer', } |
Конфігурація Capfile
1 2 3 4 5 6 7 8 9 10 |
require "capistrano/setup" require "capistrano/deploy" require 'capistrano/rvm' require 'capistrano/bundler' require 'capistrano/passenger' require 'capistrano/rails/assets' require 'capistrano/rails/migrations' require 'capistrano/linked_files' Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r } |
Виконуємо deploy!
1 2 3 |
cap production deploy bundle exec cap production linked_files:upload_files cap production deploy |
Можливі проблеми:
- NoMethodError: undefined method `[]' for nil:NilClass – переімуневати усі .css файли у .scss