Туторіал з налаштування Rails-додатків на Amazon EC2 з Chef. Частина 3
Усім привіт! Ця стаття завершує цикл туторіалів із розгортання Rails-додатків за допомогою платформи автоматизації Chef та Amazon EC2. Скориставшись знаннями, отриманими у попередніх частинах нашого циклу, ми закінчимо писати cookbooks і захистимо наш сервер. Ми також пройдемо весь цикл розгортання нашого Spree-додатка.
Попередні випуски циклу: частина 1, частина 2.
Налаштування безпеки
Щоб захистити додаток, вам необхідно встановити й налаштувати OpenSSH на цьому етапі.
OpenSSH
Щоб увімкнути автентифікацію за допомогою SSH, встановіть OpenSSH за допомогою openssh cookbook.
Додайте необхідні залежності в Berksfile.
cookbook 'openssh', '~> 2.6.1'
Створіть cookbook.
mkdir site-cookbooks/app-openssh
Встановіть метадані для cookbook.
touch site-cookbooks/app-openssh/metadata.rb
# site-cookbooks/app-openssh/metadata.rb name 'app-openssh' version '0.1.0' depends 'openssh'
Створіть атрибути за стандартним cookbook налаштуванням.
mkdir site-cookbooks/app-openssh/attributes touch site-cookbooks/app-openssh/attributes/default.rb
Скасуйте автентифікацію за допомогою пароля через атрибут password_authentication та відключіть print_motd, який визначить, чи потрібно логувати SSH daemon, коли користувач входить до сервера у файл /etc/motd.
# site-cookbooks/app-openssh/attributes/default.rb default['openssh']['server']['password_authentication'] = 'no' default['openssh']['server']['print_motd'] = 'no'
Створіть recipe для cookbook за стандартним налаштуванням.
mkdir site-cookbooks/app-openssh/recipes touch site-cookbooks/app-openssh/recipes/default.rb
Потім вам потрібно підключити зовнішній cookbook для встановлення Redis.
# site-cookbooks/app-openssh/recipes/default.rb include_recipe 'openssh'
І нарешті, додайте всі cookbooks до security role.
touch roles/security.rb
У roles/security.rb
name 'security' description 'Security setup' run_list 'recipe[app-openssh]'
Також додайте security role до списку запуску YOUR_IP_ADDRESS.json node.
... "run_list": [ "role[setup]", "role[database]", "role[web]", "role[security]" ], ...
Управління та моніторинг системних процесів
На цьому етапі налаштуємо процес моніторингу за станом процесів такого програмного забезпечення:- PostgreSQL;
- Redis;
- Nginx;
- Puma.
Для моніторингу стану цих процесів будемо використовувати Monit. Щоб установити й налаштувати Monit, будемо використовувати chef-monit.
Також додайте необхідні залежності в Berksfile.
cookbook 'monit', '~> 1.0.0'
Створіть cookbook.
mkdir site-cookbooks/app-monit
Встановіть метадані для cookbook.
touch site-cookbooks/app-monit/metadata.rb
# site-cookbooks/app-monit/metadata.rb name 'app-monit' version '0.1.0' depends 'app-attributes' depends 'app-postgresql' depends 'app-deploy' depends 'monit'
Щоб у майбутньому було зручно підтримувати атрибути додатка, перемістіть Monit атрибути username та password до app-atributes.
# site-cookbooks/app-attributes/attributes/default.rb # Monit ----------------------------------------------------------- override['monit']['username'] = 'USERNAME' override['monit']['password'] = 'PASSWORD'
Замініть USERNAME і PASSWORD своїми значеннями. Далі (у частині розгортання програми) ми покажемо вам, як більш надійно зберігати таку інформацію, використовуючи encrypted_data_bags.
Тепер створіть атрибути для cookbook за стандартним налаштуванням.
mkdir site-cookbooks/app-monit/attributes touch site-cookbooks/app-monit/attributes/default.rb
Визначте наступні атрибути:
# site-cookbooks/app-monit/attributes/default.rb default['monit']['poll_period'] = 5 # Interval in seconds to check all Monit services at default['monit']['port'] = 2812 # Port to listen on for Monit's HTTPD interface default['monit']['address'] = '0.0.0.0' # Local address to bind to for Monit's HTTPD interface default['monit']['logfile'] = '/var/log/monit.log' # Path to log messages to
Тепер ви можете написати recipes і шаблони конфігурації Monit для зазначеного вище програмного забезпечення.
mkdir -p site-cookbooks/app-monit/{recipes,templates}
PostgreSQL
Створіть recipe для підключення Monit до PostgreSQL.touch site-cookbooks/app-monit/recipes/postgresql.rb
З’єднайте зовнішній cookbook і шаблон PostgreSQL з конфігураціями.
include_recipe 'monit' monit_config 'postgresql' do source 'postgresql.conf.erb' variables( version: node['postgresql']['defaults']['server']['version'] ) end
Потім створіть сам шаблон.
touch site-cookbooks/app-monit/templates/postgresql.conf.erb
Напишіть конфигурацію для відстежування PostgreSQL-процесу:
# site-cookbooks/app-monit/templates/postgresql.conf.erb check process postgresql with pidfile /var/run/postgresql/<%= @version %>-main.pid group database start program = "/etc/init.d/postgresql start" stop program = "/etc/init.d/postgresql stop" if failed unixsocket /var/run/postgresql/.s.PGSQL.5432 protocol pgsql then restart if failed host 127.0.0.1 port 5432 protocol pgsql then restart
Потім оновіть перелік запусків для database role .
# roles/database.rb run_list 'recipe[app-postgresql]', 'recipe[app-monit::postgresql]'
Redis
Створіть recipe для підключення Monit до Redis.touch site-cookbooks/app-monit/recipes/redis.rb
Вам потрібно підключити зовнішній cookbook і шаблон Redis до ваших конфігурацій.
# site-cookbooks/app-monit/recipes/redis.rb include_recipe 'monit' monit_config 'redis' do source 'redis.conf.erb' end
Створіть шаблон.
touch site-cookbooks/app-monit/templates/redis.conf.erb
Напишіть конфігурацію для відстежування Redis-процесу:
# site-cookbooks/app-monit/templates/redis.conf.erb check process redis with pidfile /var/run/redis/redis-server.pid start program = "/etc/init.d/redis-server start" stop program = "/etc/init.d/redis-server stop"
Тепер додайте цей recipe до web role.
# roles/web.rb run_list 'recipe[app-redis]', 'recipe[app-ruby]', 'recipe[app-nodejs]', 'recipe[app-imagemagick]', 'recipe[app-nginx]', 'recipe[app-monit::redis]'
Nginx
Створіть recipe для інтеграції Monit з Nginx.
touch site-cookbooks/app-monit/recipes/nginx.rb
З’єднайте зовнішній cookbook та інтегруйте шаблон Nginx з конфігураціями.
# site-cookbooks/app-monit/recipes/nginx.rb include_recipe 'monit' monit_config 'nginx' do source 'nginx.conf.erb' end
Тепер створіть шаблон.
touch site-cookbooks/app-monit/templates/nginx.conf.erb
Напишіть конфігурацію для відстежування Nginx-процесу:
# site-cookbooks/app-monit/templates/nginx.conf.erb check process nginx with pidfile /var/run/nginx.pid start program = "/etc/init.d/nginx start" stop program = "/etc/init.d/nginx stop"
Вам також потрібно додати recipe, який уже був доданий у web role.
# roles/web.rb run_list 'recipe[app-redis]', 'recipe[app-ruby]', 'recipe[app-nodejs]', 'recipe[app-imagemagick]', 'recipe[app-nginx]', 'recipe[app-monit::redis]', 'recipe[app-monit::nginx]'
Puma
Створіть recipe для інтеграції Monit з Puma.touch site-cookbooks/app-monit/recipes/puma.rb
Далі вам необхідно підключити зовнішній cookbook та інтегрувати шаблон Puma з конфігураціями.
# site-cookbooks/app-monit/recipes/puma.rb include_recipe 'monit' user = node['project']['user'] project_root = node['project']['root'] rvm = File.join('/', 'home', user, '.rvm', 'scripts', 'rvm') monit_config 'puma' do source 'puma.conf.erb' variables( user: user, project_root: project_root, rvm: rvm ) end
Створіть шаблон.
touch site-cookbooks/app-monit/templates/puma.conf.erb
Напишіть конфігурацію для відстежування Puma-процесу:
# site-cookbooks/app-monit/templates/puma.conf.erb check process puma with pidfile <%= @project_root %>/shared/tmp/pids/puma.pid start program = "/bin/su - <%= @user %> -s /bin/bash -c 'source <%= @rvm %> && cd <%= @project_root %>/current && bundle exec puma -C <%= @project_root %>/shared/puma.rb -e <%= node.environment %> --daemon'" with timeout 30 seconds stop program = "/bin/su - <%= @user %> -s /bin/bash -c 'source <%= @rvm %> && cd <%= @project_root %>/current && bundle exec pumactl -P <%= @project_root %>/shared/tmp/pids/puma.pid stop'" with timeout 30 seconds
Нарешті, додайте цей recipe до web role.
# roles/web.rb run_list 'recipe[app-redis]', 'recipe[app-ruby]', 'recipe[app-nodejs]', 'recipe[app-imagemagick]', 'recipe[app-nginx]', 'recipe[app-monit::redis]', 'recipe[app-monit::nginx]', 'recipe[app-monit::puma]'
Розгортання додатка
Setup
У цьому розділі нашого туторіалу ми розглянемо, як можна розгорнути додаток, використовуючи Chef.Основи
Почнемо зі створення app-deploy cookbook, де буде описаний recipe розгортання додатків.Спочатку додайте залежності до метаданих.
# site-cookbooks/app-deploy/metadata.rb name 'app-deploy' version '0.1.0' depends 'app-attributes' depends 'app-users'
Використовуйте encrypted_data_bags для збереження конфіденційної інформації про проект: пароль бази даних або ключі від зовнішніх служб (AWS та ін.).
Чому ми використовуємо encrypted_data_bags
Головна причина — безпека. За допомогою encrypted_data_bags усі дані зберігаються у зашифрованому вигляді. Таким чином, навіть якщо зловмисник отримає доступ до сховища зі скриптами, він не зможе використати конфіденційну інформацію.
Щоб мати змогу використовувати зашифровані data bags, потрібно створити файл, у якому зберігатимуться ключі шифрування й дешифрування. Використовуйте OpenSSL для створення приватного ключа й помістіть його у файл encrypted_data_bag_secret.
Зауважте! Якщо ви перезапишете існуючий файл encrypted_data_bag_secret або видалите його, ви не зможете розшифрувати дані, зашифровані раніше.
Щоб створити ключ, запустіть у терміналі цю команду:
openssl rand -base64 512 | tr -d '\\r\\n' > encrypted_data_bag_secret
Зауважте! Варто не зберігати у репозиторії створений файл, а поділитися ним з членами вашої команди. Для цього потрібно додати його до .gitignore.
# .gitignore encrypted_data_bag_secret
Далі вкажіть додатковий елемент encrypted_data_bag_secret для knife solo.
# .chef/knife.rb ... encrypted_data_bag_secret 'encrypted_data_bag_secret'
Використовуючи knife solo, створіть файл конфігурації для середовища Dev за допомогою приватного ключа.
knife solo data bag create configs dev --secret-file encrypted_data_bag_secret
У текстовий редактор, відкритий у терміналі, введіть database credentials, секретні ключі додатка та Monit credentials.
# data_bags/configs/dev.json { "id": "dev", "database": { "name": "NAME", "user": "USER", "password": "PASSWORD" }, "application": { "AWS_ACCESS_KEY_ID": "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY": "AWS_SECRET_ACCESS_KEY", "S3_BUCKET_NAME": "S3_BUCKET_NAME", "S3_REGION": "S3_REGION", "S3_HOST_NAME": "S3_HOST_NAME", "DEVISE_SECRET_KEY": "DEVISE_SECRET_KEY", "SECRET_KEY_BASE": "SECRET_KEY_BASE" }, "monit": { "username": "USER_NAME", "password": "PASSWORD" } }
Після того, як ви збережете свої дані до /data_bags/configs/dev.json, ви побачите, що вони тепер зашифровані.
Замініть значення, встановлені у пунктах 5.2 та 5.5, за допомогою тих, що були встановлені під час 5.2 Database setup та 5.5 Monit setup.
Ви можете редагувати дані із зашифрованих data bags за допомогою наступної команди:
knife solo data bag edit configs dev
Ви також можете читати ці дані за допомогою цієї команди:
knife solo data bag show configs dev
Оскільки ваші ключі та credentials тепер зберігаються в encrypted_data_bag, ви можете видалити явне визначення Monit credentials з app-attributes.
# site-cookbooks/app-attributes/attributes/default.rb # Monit ----------------------------------------------------------- monit_configs = Chef::EncryptedDataBagItem.load('configs', node.environment)['monit'] override['monit']['username'] = monit_configs['username'] override['monit']['password'] = monit_configs['password']
Set up SSH
Додаток знаходиться у приватному репозиторії. Тому для стиснення проекту використовуйте обгортку SSH. Для цього вам потрібні ключі SSH, які ви додасте до cookbook.
Якщо у вас немає ключа SSH, ви можете створити його за допомогою наведеної нижче команди. Не потрібно встановлювати пароль private key, оскільки він блокує chef-client під час запуску сценаріїв розгортання. Вам також потрібно буде вказати свою адресу електронної пошти замість Данный адрес e-mail защищен от спам-ботов, Вам необходимо включить Javascript для его просмотра. .
ssh-keygen -t rsa -b 4096 -C " Данный адрес e-mail защищен от спам-ботов, Вам необходимо включить Javascript для его просмотра. "
Потім створіть каталог — site-cookbooks/app-deploy/files — де ви розмістите приватні та публічні ключі.
mkdir site-cookbooks/app-deploy/files mkdir site-cookbooks/app-deploy/files/default touch site-cookbooks/app-deploy/files/default/key touch site-cookbooks/app-deploy/files/default/key.pub
Додайте ключі у створений файл.
cp ~/.ssh/id_rsa site-cookbooks/app-deploy/files/default/key cp ~/.ssh/id_rsa.pub site-cookbooks/app-deploy/files/default/key.pub
Зауважте! Додайте site-cookbooks/app-deploy/files/default каталог до .gitignore, оскільки ніхто не повинен знати ваш приватний ключ.
# .gitignore site-cookbooks/app-deploy/files/default
Далі створіть recipe за стандартним налаштуванням, де ви докладно розпишете процес розгортання.
mkdir site-cookbooks/app-deploy/recipes touch site-cookbooks/app-deploy/recipes/default.rb
У верхній частині цього файлу визначте змінні, з якими ви будете працювати у recipe:
# site-cookbooks/app-deploy/recipes/default.rb encrypted_data = Chef::EncryptedDataBagItem.load('configs', node.environment) config = node['project'] deployer = config['user'] deployer_group = config['group'] root_path = config['root'] home_path = File.join('/', 'home', deployer) shared_path = File.join(root_path, 'shared') bundle_path = File.join(shared_path, 'vendor', 'bundle') config_path = File.join(shared_path, 'config') ssh_path = File.join(shared_path, '.ssh') puma_state_file = File.join(shared_path, 'tmp', 'pids', 'puma.state') sidekiq_state_file = File.join(shared_path, 'tmp', 'pids', 'sidekiq.pid') maintenance_file = File.join(shared_path, 'tmp', 'maintenance')
Тепер ми можемо почати описувати recipe розгортання додатка. Recipe складається з декількох етапів:
- Використання SSH ключів;
- Створення спільних каталогів;
- Створення бази даних і конфігурації Puma.
Використання SSH ключів
Перш за все, ми опишемо використання SSH ключів:# site-cookbooks/app-deploy/recipes/default.rb # SSH ------------------------------------------------------------------------------------------------- ssh_key_file = File.join(ssh_path, deployer) ssh_wrapper_file = File.join(ssh_path, 'wrap-ssh4git.sh') directory ssh_path do owner deployer group deployer_group recursive true end cookbook_file ssh_key_file do source 'key' owner deployer group deployer_group mode 0o600 end file ssh_wrapper_file do content "#!/bin/bash\n/usr/bin/env ssh -o \"StrictHostKeyChecking=no\" -i \"#{ssh_key_file}\" $1 $2" owner deployer group deployer_group mode 0o755 end
Створення спільних каталогів
# site-cookbooks/app-deploy/recipes/default.rb # DIRECTORIES --------------------------------------------------------------------------------------------------------- %w[config log public/system public/uploads public/assets repo tmp/cache tmp/pids tmp/sockets].each do |dir| directory File.join(shared_path, dir) do owner deployer group deployer_group mode 0o755 recursive true end end
Створення бази даних і конфігурації Puma
1. Конфігурація бази даних
Опишемо використання шаблону з конфігурацією для доступу до бази даних.
# site-cookbooks/app-deploy/recipes/default.rb template File.join(config_path, 'database.yml') do source File.join(node.environment, 'database.yml.erb') variables( environment: node.environment, database: encrypted_data['database']['name'], user: encrypted_data['database']['user'], password: encrypted_data['database']['password'] ) sensitive true owner deployer group deployer_group mode 0o644 end
Далі створимо шаблон:
# site-cookbooks/app-deploy/templates/dev/database.yml.erb --- <%= @environment %>: adapter: postgresql encoding: unicode database: <%= @database %> user: <%= @user %> password: <%= @password %> pool: 20
mkdir site-cookbooks/app-deploy/templates mkdir site-cookbooks/app-deploy/templates/dev touch site-cookbooks/app-deploy/templates/dev/database.yml.erb
2. Конфігурація додатка
Тут ви маєте описати генерацію файлу application.yml, де ви будете зберігати змінні проекту.
# site-cookbooks/app-deploy/recipes/default.rb file File.join(config_path, 'application.yml') do content Hash[node.environment, encrypted_data['application']].to_yaml sensitive true owner deployer group deployer_group mode 0o644 end
3. Puma
Тепер вам потрібно описати, як використовувати шаблон з конфігураціями:
# site-cookbooks/app-deploy/recipes/default.rb template File.join(shared_path, 'puma.rb') do source File.join(node.environment, 'puma.rb.erb') variables( environment: node.environment, project_root: root_path ) owner deployer group deployer_group mode 0o644 end
Вам також потрібно створити шаблон з конфігурацією:
touch site-cookbooks/app-deploy/templates/dev/puma.rb.erb
# site-cookbooks/app-deploy/templates/dev/puma.rb.erb #!/usr/bin/env puma directory '<%= @project_root %>/current' rackup '<%= @project_root %>/current/config.ru' environment '<%= @environment %>' pidfile '<%= @project_root %>/shared/tmp/pids/puma.pid' state_path '<%= @project_root %>/shared/tmp/pids/puma.state' stdout_redirect '<%= @project_root %>/shared/log/puma.error.log', '<%= @project_root %>/shared/log/puma.access.log', true threads 4, 16 bind 'unix://<%= @project_root %>/shared/tmp/sockets/puma.sock' workers 0 preload_app! on_restart do puts 'Refreshing Gemfile' ENV['BUNDLE_GEMFILE'] = '<%= @project_root %>/current/Gemfile' end on_worker_boot do ActiveSupport.on_load(:active_record) do ActiveRecord::Base.establish_connection end end
4. Конфігурація Sidekiq
Спочатку опишіть, як створити шаблон з конфігурацією Sidekiq:
# site-cookbooks/app-deploy/recipes/default.rb template File.join(config_path, 'sidekiq.yml') do source File.join(node.environment, 'sidekiq.yml.erb') variables( environment: node.environment ) sensitive true owner deployer group deployer_group mode 0o644 end
Потім створіть шаблон з конфігурацією:
touch site-cookbooks/app-deploy/templates/dev/sidekiq.yml.erb --- <%= @environment %>: :verbose: true :logfile: log/sidekiq.log :concurrency: 1 :strict: false :pidfile: tmp/pids/sidekiq.pid :queues: - [default, 1]
Розгортання
Тепер перейдемо безпосередньо до розгортання додатка. Як правило, розгортання відбувається в чотири етапи:- Checkout — chef-client використовує ресурс Source Code Management (SCM) для отримання вказаної ревізії додатка й розміщення clone або checkout в субкаталозі deploy каталогу з назвою cached-copy. Потім копія додатка розміщується в цьому субкаталозі.
- Migrate — якщо процес міграції буде запущено, chef-client символічно пов’язує файл конфігурації бази даних з checkout (config/database.yml за замовчуванням) і запускає команду міграції. Для Ruby on Rails додатка migration_command зазвичай встановлюється в rack db: migrate.
- Symlink — каталог для загальних і тимчасових файлів, які видаляються з checkout (log, tmp / pids і public / system за замовчуванням). Після цього вам потрібно створити будь-які необхідні каталоги (tmp, public і config за замовчуванням), якщо їх не існує. Наприкінці цього кроку ви посилаєтеся на спільні каталоги в поточний release, public / system, tmp / pids та log каталоги, а потім — на release у current.
- Restart — перезапустіть додаток, використовуючи команду restart у recipe.
Ось детальна інструкція розгортання додатків:
# site-cookbooks/app-deploy/recipes/default.rb # DEPLOYMENT ---------------------------------------------------------------------------------------------------------- timestamped_deploy node['domain'] do ssh_wrapper ssh_wrapper_file repository config['repository'] branch config['branch'] repository_cache 'repo' deploy_to config['root'] user deployer group deployer_group # Set global environments environment( 'HOME' => home_path, 'RAILS_ENV' => node.environment ) # Before you start to run the migration, create tmp and public directories. create_dirs_before_symlink %w[tmp public] # Map files in a shared directory to their paths in the current release directory. symlinks( 'config/application.yml' => 'config/application.yml', 'config/database.yml' => 'config/database.yml', 'config/newrelic.yml' => 'config/newrelic.yml', 'config/sidekiq.yml' => 'config/sidekiq.yml', 'log' => 'log', 'public/system' => 'public/system', 'public/uploads' => 'public/uploads', 'public/assets' => 'public/assets', 'tmp/cache' => 'tmp/cache', 'tmp/pids' => 'tmp/pids', 'tmp/sockets' => 'tmp/sockets' ) # Map files in a shared directory to the current release directory. symlink_before_migrate( 'config/application.yml' => 'config/application.yml', 'config/database.yml' => 'config/database.yml' ) # Run this code before the migration starts before_migrate do file maintenance_file do owner deployer group deployer_group action :create end # Install bundler gem execute 'install bundler' do command "/bin/bash -lc 'source $HOME/.rvm/scripts/rvm && gem install bundler'" cwd release_path user deployer group deployer_group environment( 'HOME' => home_path ) end # Install other gems execute 'bundle install' do command "/bin/bash -lc 'source $HOME/.rvm/scripts/rvm && bundle install --without development test --deployment --path #{bundle_path}'" cwd release_path user deployer group deployer_group environment( 'HOME' => home_path ) end end migration_command "/bin/bash -lc 'source $HOME/.rvm/scripts/rvm && bundle exec rails db:migrate --trace'" migrate true restart_command do # If PUMA is running ‒ restart it if File.exist? puma_state_file execute 'pumactl restart' do command "/bin/bash -lc 'source $HOME/.rvm/scripts/rvm && bundle exec pumactl -S #{puma_state_file} restart'" cwd release_path user deployer group deployer_group environment( 'HOME' => home_path ) end end # If Sidekiq is running ‒ restart it if File.exist? sidekiq_state_file execute 'sidekiqctl stop' do command "/bin/bash -lc 'source $HOME/.rvm/scripts/rvm && bundle exec sidekiqctl stop #{sidekiq_state_file}'" cwd release_path user deployer group deployer_group environment( 'HOME' => home_path ) end end end # Run the following tasks before app restart commands before_restart do execute 'db:seed' do command "/bin/bash -lc 'source $HOME/.rvm/scripts/rvm && bundle exec rake db:seed'" cwd release_path user 'root' group 'root' environment( 'HOME' => home_path, 'RAILS_ENV' => node.environment ) end execute 'assets:precompile' do command "/bin/bash -lc 'source $HOME/.rvm/scripts/rvm && bundle exec rake assets:precompile'" cwd release_path user 'root' group 'root' environment( 'HOME' => home_path, 'RAILS_ENV' => node.environment ) end end # Once you've restarted the app, remove the maintenance file after_restart do file maintenance_file do action :delete end end action :deploy end
Застосування конфігурацій
Тепер вам потрібно додати app-deploy cookbook до deploy role, щоб використовувати цей cookbook далі в node.touch roles/deploy.rb
Опишемо базову інформацію про цю role та її run list.
# roles/deploy.rb name 'deploy' description 'Deployment' run_list 'recipe[app-deploy]'
Далі додайте цю role до загального списку nodes/ YOUR_IP_ADDRESS.json node.
// nodes/YOUR_IP_ADDRESS.json ... "run_list": [ "role[setup]", "role[database]", "role[web]", "role[security]", "role[deploy]" ], ...
Тепер ви можете застосувати скрипти, які ви написали, щоб запустити додаток на сервері.
Встановіть Chef і застосуйте всі конфігурації за допомогою такої команди:
knife solo bootstrap ubuntu@YOUR_IP_ADDRESS -i spree_dev.pem
Після завершення розгортання Spree-додаток буде доступний через публічний DNS. У нашому прикладі — адреса ec2-18-221-230-71.us-east-2.compute.amazonaws.com.
Тепер ви можете увійти на сервер через SSH як deployer-користувач:
ssh deployer@YOUR_IP_ADDRESS
У майбутньому ви зможете розгорнути додаток на віддаленому комп’ютері за допомогою такої команди:
knife solo cook deployer@YOUR_IP_ADDRESS -o "'recipe[app-deploy]'"
Підбиваємо підсумки
Коли я створював цей туторіал, то мав на меті показати надзвичайну гнучкість Chef та його можливості розгортання проектів будь-якої складності. Також зауважу, що туторіал буде цікавий у першу чергу для новачків, адже в ньому детально розібрані компоненти, необхідні для коректної роботи Spree-додатка та показані всі етапи розгортання додатка.
Сподіваюсь, що туторіал був для вас корисним. Запрошую вас поділитися своїм досвідом використання Chef нижче у коментарях.
Дякую команді RubyGarage за допомогу у підготовці матеріалу.