Рубрики
Uncategorized

Развертывание приложения Ruby с помощью Anisible

В наше время вы можете получить свой собственный выделенный сервер вверх и запускаете в секундах. Как только вы получите это, вам действительно нужно провести несколько часов на настройке его для ваших потребностей приложений? Вы действительно хотите повторить одни и те же шаги с каждым новым сервером? В этой статье вы узнаете, как автоматизировать этот процесс с помощью Anisible.

Автор оригинала: Vyacheslav.

Вступление

В наше время вы можете получить свой собственный выделенный сервер вверх и запускаете в секундах. Как только вы получите это, вам действительно нужно провести несколько часов на настройке его для потребностей вашего приложения? Вы действительно хотите повторить одни и те же шаги с каждым новым сервером? В этой статье я дам вам представление об автоматизированной установке с помощью Anbible, простой IT-инструмента «Автоматизатор» и Ubuntu 14.04 LTS Server в качестве вашего Box OS.

Фон

Вам понадобится базовое понимание неизменного файлового синтаксиса. Если вы еще не играли с Anbible, я бы порекомендовал вам просмотреть некоторые вступительные статьи, такие как http://docs.ansable.com/ansable/intro.html Или, возможно, один из слайдшаров, таких как http://www.slidehare.net/robertreiz/ansable-40167296 ?

Готовка

Нам нужно будет развернуть следующие компоненты: Ruby, веб-сервер с пассажиром и сам вашу приложение. Для целей этой демонстрации мы установим известное стартовое устройство https://github.com/RailsApps/rails-devise.git

Ruby Switcher Chruby.

Раньше я выбрал RMV, но недавно я фанат хруби — Легкий, быстро понимать и просто работает — это доступно в Github https://github.com/postmodern/chruby.

При изучении инструкций по установке мы можем автоматизировать ручные шаги установки с помощью Anbible и получите бонус: повторно используемый рецепт для установки Ch_Ruby Отказ

---
  - name: Ruby | Check if chruby is present
    shell: test -x /usr/local/bin/chruby-exec
    when: ansible_system == "Linux"
    ignore_errors: yes
    register: chruby_present
    tags: ruby

  - name: Ruby | Download chruby distribution
    get_url: chruby_version }}.tar.gz"
             chruby_version }}.tar.gz"
    when: chruby_present|failed
    tags: ruby

  - name: Ruby | unpack chruby
    command: tar xf "/tmp/chruby-{{ chruby_version }}.tar.gz"
             when: chruby_present|failed
    tags: ruby

  - name: Ruby | chruby install target
    command: make install
             chruby_version }}"
    become: yes
    when: chruby_present|failed
    tags: ruby

  - name: Ruby | autoload script
    template: dest=/etc/profile.d/chruby.sh
    become: yes
    tags: ruby

Ruby install

Ruby-install это второй инструментарий от одного и того же автора. В настоящий момент этот подход — выбор № 1 для меня, когда мне нужно установить определенную версию Ruby. Этот инструмент доступен в Github под адресом https://github.com/postmodern/ruby-install

Как только мы изучаем ruby-install Настройка Примечания, мы можем автоматизировать эти шаги с помощью серии Anisible шагов:

---
  - name: Ruby | Check if ruby install is present
    shell: test -x /usr/local/bin/ruby-install
    when: ansible_system == "Linux"
    ignore_errors: yes
    register: rubyinstall_present
    tags: ruby

  - name: Ruby | Ruby install | package dependencies
    apt: pkg={{ item }} state=present update_cache="yes"
    when: ansible_system == "Linux"
    with_items:
      - build-essential
      - libffi-dev
      - libgdbm-dev
      - libncurses5-dev
      - libreadline-dev
      - libreadline6-dev
      - libtinfo-dev
      - libyaml-dev
    become: yes
    tags: ruby

  - name: Ruby | Download rubyinstall
    get_url: url=http://github.com/postmodern/ruby-install/archive/v{{ ruby_install_version }}.tar.gz
           dest=/tmp/ruby-install-{{ ruby_install_version }}.tar.gz
    when: rubyinstall_present | failed
    tags: ruby

  - name: Ruby | Unpack ruby-install
    command: tar xf /tmp/ruby-install-{{ ruby_install_version }}.tar.gz
             chdir=/tmp
    when: rubyinstall_present | failed
    tags: ruby

  - name: Ruby | Run ruby-install install target
    command: make install
           chdir=/tmp/ruby-install-{{ ruby_install_version }}
    when: rubyinstall_present | failed
    become: yes
    tags: ruby

  - name: Ruby | Download list of rubies available
    command: ruby-install
    when: rubyinstall_present | failed
    become: yes
    tags: ruby

Рубин

Теперь пришло время установить Ruby. Небольшой комментарий Здесь: если вы развернули на общий сервер, вы, скорее всего, хотели бы иметь возможность иметь несколько версий Ruby и переключаться между ними. С другой стороны, если вы развернуте свое приложение к выделенному хосту, обычно я также заменил систему по умолчанию Ruby с той же версией Ruby.

С приведенными выше инструментами ваш рецепт установки Ruby будет Compact & Clear:

---
  - name: Ruby | Find out if ruby_version is already installed
    stat: path={{rubies_location}}/ruby-{{ruby_version}}
    register: ruby_version_present
    tags: ruby

  - name: Ruby | Install ruby_version if necessary
    command: '/usr/local/bin/ruby-install ruby {{ruby_version}}'
    when: not ruby_version_present.stat.exists
    become: yes
    tags: ruby

  - debug: - name: Ruby | Update SYSTEM ruby_version if necessary
    command: '/usr/local/bin/ruby-install --system ruby {{ruby_version}}'
    when: option_ruby_install_setsystem
    become: yes
    tags: ruby

WebServer & Passenger

Благодаря пассажирской команде Phance, которая проделала отличную работу, чтобы предоставить предварительно созданные двоичные файлы для большинства популярных платформ и конфигураций в https://oss-binaries.phusionpassenngase.com/ , мы можем пропустить этапы компиляции пассажиров Phance из источника, перекомпиляции, веб-сервера и т. Д. и использовать их предварительно построенный двоичный вместо этого.

Исторически я предпочитаю Nginx над классическим выбором Apache, поэтому мы установим предварительно построенный Nginx с пассажиром:

---
  - name: Nginx | Check if is present
    command: test -x /usr/sbin/nginx
    when: ansible_os_family == "Debian"
    ignore_errors: yes
    register: nginx_present
    tags: nginx

  - name: Passenger | Add GPG key to apt keyring
    apt_key: keyserver=keyserver.ubuntu.com id=561F9B9CAC40B2F7
    when: ansible_os_family == "Debian" and nginx_present|failed
    tags: passenger
    become: yes

  - name: Passenger | Install needed packages
    apt: state=present with_items:
     - apt-transport-https
     - ca-certificates
    when: ansible_os_family == "Debian" and nginx_present|failed
    become: yes
    tags: passenger

  - name: Passenger | Add nginx extras repository
    apt_repository: https://oss-binaries.phusionpassenger.com/apt/passenger trusty main" state=present
    when: ansible_os_family == "Debian" and nginx_present|failed
    tags: passenger
    become: yes

  - name: Ruby | Install Nginx extra and Phusion Passenger
    apt: state=present update_cache=yes when: ansible_os_family == "Debian" and nginx_present|failed
    with_items:
     - nginx-extras
     - passenger
    become: yes
    tags: passenger

  - name: Nginx | Create sites available/enabled directories
    file: path={{item}} state=directory mode=0755
    with_items:
      - /etc/nginx/sites-available
      - /etc/nginx/sites-enabled
    when: ansible_os_family == "Debian" and nginx_present|failed
    tags:
      - nginx
      - passenger
    become: yes

  - name: Nginx | Configure include sites-enabled
    lineinfile: dest=/etc/nginx/nginx.conf line="    include /etc/nginx/sites-enabled/*;" state=present
    tags:
      - nginx
      - passenger
    when: ansible_os_family == "Debian" and nginx_present|failed
    become: yes

  - name: Nginx | Disable default site
    file: path=/etc/nginx/sites-enabled/default state=absent
    tags:
      - nginx
      - passenger
    when: ansible_os_family == "Debian" and nginx_present|failed
    become: yes

  - name: Nginx | Uncomment server_names_hash_bucket_size
    lineinfile: dest=/etc/nginx/nginx.conf line="\1server_names_hash_bucket_size 64;" backrefs=yes
    become: yes
    when: ansible_os_family == "Debian" and nginx_present|failed
    tags:
      - nginx
      - passenger

  - name: Nginx | Set ruby to system one
    lineinfile: dest=/etc/nginx/nginx.conf line="passenger_ruby /usr/local/bin/ruby;" backrefs=yes
    become: yes
    when: ansible_os_family == "Debian" and nginx_present|failed
    tags:
      - nginx
      - passenger

  - name: Nginx | Set ruby to system one
    lineinfile: dest=/etc/nginx/nginx.conf line="passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;" backrefs=yes
    become: yes
    when: ansible_os_family == "Debian" and nginx_present|failed
    tags:
      - nginx
      - passenger

  - name: Nginx | Reload
    service: name=nginx state=reloaded
    when: ansible_os_family == "Debian" and nginx_present|failed
    tags:
      - nginx
      - passenger
    become: yes

Несколько комментариев на скрипте установки выше, что может потребовать изменений в зависимости от ваших собственных сценариев:

  1. Задача «Созданные сайты доступны/с включенными каталогами», — но следующий фактически реализует Apache-Apache «Доступные сайты/сайты». Если вы предпочитаете настройку по умолчанию, комментировать эту деталь.

  2. Указание расположения Ruby для пассажира с

lineinfile: dest=/etc/nginx/nginx.conf regexp="^(\s*)#\s*passenger_ruby" line="passenger_ruby /usr/local/bin/ruby;" backrefs=yes

Как видите, замена выше предполагает, что ваша система Ruby используется. Вы можете указать другой путь Ruby здесь.

Цель этих двух задач — это взять nginx.conf И установить два параметра: passenger_root и Passenger_Ruby. в соответствии с оригинальными инструкциями в вышеуказанном комментарии.

        ##
        # Uncomment it if you installed passenger or passenger-enterprise
        ##

passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /usr/local/bin/ruby;

Как бы вы провели, если вы установили NGINX с пассажиром правильно?

Вы можете сделать это, выполняя эти команды, чтобы подтвердить настройку:

sudo /usr/bin/passenger-config validate-install

What would you like to validate?
Use  to select.
If the menu doesn't display correctly, press '!'

 ‣ ⬢  Passenger itself
   ⬡  Apache

-------------------------------------------------------------------------

 * Checking whether this Passenger install is in PATH... ✓
 * Checking whether there are no other Passenger installations... ✓

Everything looks good. :-)

Что касается /usr/sbin/passenger-memory-stats , вы должны увидеть как Nginx & Passenger Processions.

sudo /usr/sbin/passenger-memory-stats
Version: 5.0.26
Date   : 2016-03-18 11:17:57 +0200
------------- Apache processes -------------
*** WARNING: The Apache executable cannot be found.
Please set the APXS2 environment variable to your 'apxs2' executable's filename, or set the HTTPD environment variable to your 'httpd' or 'apache2' executable's filename.

--------- Nginx processes ----------
PID   PPID  VMSize    Private  Name
------------------------------------
8768  9991  138.1 MB  1.1 MB   nginx: worker process
8769  9991  137.8 MB  0.9 MB   nginx: worker process
8770  9991  137.8 MB  0.9 MB   nginx: worker process
8771  9991  137.8 MB  0.9 MB   nginx: worker process
9991  1     137.8 MB  0.9 MB   nginx: master process /usr/sbin/nginx
### Processes: 5
### Total private dirty RSS: 4.68 MB

---- Passenger processes -----
PID   VMSize    Private  Name
------------------------------
8742  436.3 MB  1.0 MB   Passenger watchdog
8745  982.9 MB  2.0 MB   Passenger core
8756  444.5 MB  1.1 MB   Passenger ust-router
8806  387.1 MB  69.3 MB  Passenger RubyApp: /var/www/public (production)
### Processes: 4
### Total private dirty RSS: 73.47 MB
slavko@ERM:/etc/nginx$

Сама установка приложений

Давайте определим параметры вашего приложения: в частности, требуемые пакеты ОС для создания драгоценных камней, секрета приложения и хэш-пароли, параметры среды приложений, данные соединения базы данных.

  app_dependencies:
    - libsqlite3-dev
    - libmysqlclient-dev
    - libpq-dev
    - git
    - nodejs
    - npm

  app_short_name: app
  app_env: production
  app_domain: domain.local
  app_secret: 82d58d3dfb91238b495a311eb8539edf5064784f1d58994679db8363ec241c745bef0b446bfe44d66cbf91a2f4e497d8f6b1ef1656e3f405b0d263a9617ac75e
  app_repository: https://github.com/RailsApps/rails-devise.git
#  app_repository_keyname: id_rsa_app
  app_base_dir: /var/www
  app_www_root: "{{app_base_dir}}/public"

  app_env_vars:
    - {name: SECRET_KEY_BASE, value: "{{app_secret}}" }
    - {name: DATABASE_URL, value: "postgres://{{app_db_user}}:{{app_db_password}}@{{app_db_host}}/{{app_db_name}}"}
    - {name: RAILS_ENV, value: "{{app_env}}" }
    - {name: DOMAIN_NAME, value: "{{app_domain}}" }

  app_db_host: localhost
  app_db_user: app_user
  app_db_password: app_password
  app_db_name: app_database    

  app_directories:
    - "{{app_base_dir}}"

Сам скрипт приложений вступит в стадии: зависимости пакетов OS пакетов, зависимости GEM (для разработки это SQLite3), проверка исходного кода, исправления драгоценного файла, чтобы версия Ruby соответствует установленным на хосте +, вводящих производственные драгоценные камни для UGLifysjs (это Это текущее приложение, специфичное приложение), установка Bundle, Patching Configuration базы данных, компиляция активов, миграция DB, генерация конфигурации сайта NGINX, перезагрузка веб-сервера.

---

  - name: APP STUB | Dependencies
    apt: pkg={{ item }} state=present update_cache="yes"
    when: ansible_system == "Linux"
    with_items: "{{app_dependencies}}"
    become: yes
    tags: app_stub

  - name: APP STUB | Install gem dependencies
    shell: "gem install --no-rdoc --no-ri {{item}}"
    with_items:
      - sqlite3
    become: yes
    tags: app_stub

  - name: APP STUB | Re-create base app directory
    file: path={{app_base_dir}} state=absent
    become: yes
    tags: app_stub

  - name: APP STUB | Create directories
    file: path={{item}} state=directory mode=0755 owner={{ansible_user_id}} group={{ansible_user_id}}
    with_items: "{{app_directories}}"
    become: yes
    tags: app_stub

  - name: APP STUB | Checkout app without key
    git: dest="{{app_base_dir}}" force="yes"
    when: app_repository_keyname is not defined
    tags: app_stub

  - name: APP STUB | Install global rails gem
    shell: gem install --no-rdoc --no-ri rails
    become: yes
    tags: app_stub

  - name: APP STUB | Eliminate ruby req
    lineinfile: regexp="^(\s*)*ruby" '{{ruby_version}}'"
    tags: app_stub

  - name: APP STUB | gem therubyracer - uglifyjs
    lineinfile: dest="{{app_base_dir}}/Gemfile" 'therubyracer'" line="gem 'therubyracer', :platforms => :ruby" :production do"
    tags: app_stub

  - name: APP STUB | gem execjs - uglifyjs
    lineinfile: regexp="^(\s*)*gem 'execjs'" line="gem 'execjs'" insertafter="^group :production do"
    tags: app_stub

  - name: APP STUB | gem pg
    lineinfile: regexp="^(\s*)*gem 'pg'" line="gem 'pg'" insertafter="^group :production do"
    tags: app_stub

  - name: APP STUB | Run bundle install --path .bundle/gems --binstubs .bundle/bin
    shell: bundle install  --path .bundle/gems --binstubs .bundle/bin
    args:
      chdir: "{{app_base_dir}}"
    tags: app_stub

  - name: APP STUB | database.yml
    template: dest="{{app_base_dir}}/config/database.yml"
    become: yes
    tags: app_stub

  - name: APP STUB | Precompile assets
    shell: bundle exec rake assets:precompile
    args:
      chdir: "{{app_base_dir}}"
    environment:
      RAILS_ENV: "{{app_env}}"
      DATABASE_URL: "postgres://{{app_db_user}}:{{app_db_password}}@{{app_db_host}}/{{app_db_name}}"
      SECRET_KEY_BASE: "{{app_secret}}"
      DOMAIN_NAME: "{{app_domain}}"
    tags: app_stub

  - name: APP STUB | DB Migrate
    shell: bundle exec rake db:migrate
    args:
      chdir: "{{app_base_dir}}"
    environment:
      RAILS_ENV: "{{app_env}}"
      DATABASE_URL: "postgres://{{app_db_user}}:{{app_db_password}}@{{app_db_host}}/{{app_db_name}}"
      SECRET_KEY_BASE: "{{app_secret}}"
      DOMAIN_NAME: "{{app_domain}}"
    tags: app_stub

  - name: APP STUB | Nginx conf
    template: dest="/etc/nginx/sites-enabled/{{app_short_name}}.conf"
    become: yes
    tags: app_stub

  - name: Nginx | Reload
    service: name=nginx state=reloaded
    become: yes
    tags: app_stub

В частности, мы исправляем конфигурацию базы данных/база данных .YML с реальными деталями подключения

# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
#   DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
   production:
     url: <%= ENV['DATABASE_URL'] %>

И мы исправляем сайт NGINX App Config для предоставления переменных приложений для Ruby App с passenger_env_var инструкции.

server {
  listen 80 default_server;
  passenger_enabled on;

  {% for envvar in app_env_vars %}
  passenger_env_var {{ envvar.name }} "{{ envvar.value }}";
  {% endfor %}

  passenger_app_env {{app_env}};
  root {{app_www_root}};
}

Запуск кода

Давайте выполним предоставление и проверить его. Для целей демонстрации демонстрации мы будем использовать локальные почты в качестве нашей БД.

---
- hosts: www

  vars:
    - root_dir: ..

  roles:
     - {
         role: "sa-postgres",
         option_create_app_user: true
       }
     - {
         role: "sa-ruby",
         ruby_install_setsystem: true,
         ruby_version: 2.3.0,

         option_install_sampleapp: true,
         option_install_nginx_passenger: true
       }

После окончания процесса предоставления приложений:

TASK: [sa-ruby | Nginx | Reload] **********************************************
changed: [192.168.0.17] => {"changed": true, "name": "nginx", "state": "started"}

PLAY RECAP ********************************************************************
192.168.0.17               : ok=55   changed=46   unreachable=0    failed=0   

Play run took 23 minutes

Итак, в зависимости от скорости вашей сети вы будете установлены приложение.

Давайте проверим через IP-адрес:

Развернутое приложение

Точки интереса

Теперь вы знаете о другом способе развертывания приложений Ruby.

Сценарий демонстрации доступен на https://github.com/voronenko/devops-ruby-app-demo Рецепты упаковываются как Anisible Reurable роль, доступную в https://github.com/softasap/sa-ruby.

Оригинал: «https://www.codementor.io/@slavko/deploying-ruby-application-with-ansible-du107ozr7»