Рубрики
Uncategorized

Постройте JRuby на приложении Rails с нуля и докерейте его!

Как построить JRuby на приложении Rails с нуля и докерейте его

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

Обо мне

Я разработчик Ruby с несколькими годами опыта здания и поддержания приложений Ruby.

Проблема, которую я хотел решить

Я читал книгу «Развертывание с JRUBY 9K» и экспериментировав с ним, оказывается, книга полностью устарела. Но я смог выбрать некоторые вещи, которые я знал, потребуется для достижения моей цели: Создание JRuby на рельсах и сможем докерировать его.

Мой jruby на рельсы приложение

Итак, я построил jruby on Rails Application, очень простое, но функциональное приложение, которое просто отображает страницу приветствия Rails по умолчанию. Это приложение может быть выполнено в Docker, который великолепен, поскольку вы сможете развернуть его на разных облаках, таких как Digitalocean или EC2 или что-то подобное.

Tech Stack

Я использовал следующие библиотеки/инструменты: JRuby Version 9.1.15.0 (2.3.3), Rails 5.0.6, Docker 18.02.0-CE, Docker Toolbox, PostgreSQL 9, Redis 3.2.8, Java 8

Процесс построения Jruby на рельсы приложение с нуля

Сначала вы должны убедиться, что у вас есть Java 8, установленные на вашем компьютере, затем установите JRUBY и создайте новые рельсы приложения Rails New App_name_wer Отказ

Теперь у вас есть приложение Rails, но это все еще нужно много изменений. Давайте начнем с изменение драгоценных данных, замените GEM 'Activerecord-JDBCSQLite3-Adapter' С agem ‘Activeerecord-jdbcpostgresql-адаптером’, github: ‘jruby/Activeerecord-jdbc-адаптер’, филиал: ’50 -stable»»»»а, потому что мы будем использовать PostgreSQL. Добавьте этот драгоценный камень Gem 'Stack-Timeout', '~> 0,4' Отказ Далее добавьте эту линию RUBY '2.3.3', Двигатель: «JRuby», Engine_Version: '9.1.15.0' После этого блока

git_source(:github) do |repo_name|
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
  "https://github.com/#{repo_name}.git"
end

Это указывает на то, что вы хотите использовать JRuby вместо Ruby. Вам также нужно будет добавить Gem 'Dotenv-Rails' В вашей группе развития.

Давайте двигаться дальше и создать .env Файл в приложении root, затем поместите следующее внутри него:

# This is used by Docker Compose to set up prefix names for Docker images,
# containers, volumes and networks. This ensures that everything is named
# consistently regardless of your folder structure.
COMPOSE_PROJECT_NAME=app_name_here

# What Rails environment are we in?
RAILS_ENV=development

# Rails log level.
#   Accepted values: debug, info, warn, error, fatal, or unknown
LOG_LEVEL=debug

# You would typically use `rails secret` to generate a secure token. It is
# critical that you keep this value private in production.
SECRET_TOKEN=asecuretokenwouldnormallygohere

# More details about these Puma variables can be found in config/puma.rb.
# Which address should the Puma app server bind to?
BIND_ON=0.0.0.0:3000

# Puma supports multiple threads but in development mode you'll want to use 1
# thread to ensure that you can properly debug your application.
RAILS_MAX_THREADS=1

# Puma supports multiple workers but you should stick to 1 worker in dev mode.
WEB_CONCURRENCY=1

# Requests that exceed 5 seconds will be terminated and dumped to a stacktrace.
# Feel free to modify this value to fit the needs of your project, but if you
# have any request that takes more than 5 seconds you probably need to re-think
# what you are doing 99.99% of the time.
REQUEST_TIMEOUT=30

# The database name will automatically get the Rails environment appended to it
# such as: app_name_here_development or app_name_here_production.
DATABASE_URL=postgresql://app_name_here:yourpassword@postgres:5432/app_name_here?encoding=utf8&pool=5&timeout=5000

# The full Redis URL for the Redis cache. The last segment is the namespace.
REDIS_CACHE_URL=redis://:yourpassword@redis:6379/0/cache

# Action mailer (e-mail) settings.
# You will need to enable less secure apps in your Google account if you plan
# to use GMail as your e-mail SMTP server.
# You can do that here: https://www.google.com/settings/security/lesssecureapps
SMTP_ADDRESS=smtp.gmail.com
SMTP_PORT=587
SMTP_DOMAIN=gmail.com
SMTP_USERNAME=you@gmail.com
SMTP_PASSWORD=yourpassword
SMTP_AUTH=plain
SMTP_ENABLE_STARTTLS_AUTO=true

# Not running Docker natively? Replace 'localhost' with your Docker Machine IP
# address, such as: 192.168.99.100:3000
ACTION_MAILER_HOST=192.168.99.100:3000
ACTION_MAILER_DEFAULT_FROM=you@gmail.com
ACTION_MAILER_DEFAULT_TO=you@gmail.com

# Google Analytics universal ID. You should only set this in non-development
# environments. You wouldn't want to track development mode requests in GA.
# GOOGLE_ANALYTICS_UA='xxx'

# The Redis URL.
REDIS_URL=redis://:yourpassword@redis:6379/0

# The full Redis URL for Active Job.
ACTIVE_JOB_URL=redis://:yourpassword@redis:6379/0

# The queue prefix for all Active Jobs. The Rails environment will
# automatically be added to this value.
ACTIVE_JOB_QUEUE_PREFIX=app_name_here:jobs

# The full Redis URL for Action Cable's back-end.
ACTION_CABLE_BACKEND_URL=redis://:yourpassword@redis:6379/0

# The full WebSocket URL for Action Cable's front-end.
# Not running Docker natively? Replace 'localhost' with your Docker Machine IP
# address, such as: ws://192.168.99.100:28080
ACTION_CABLE_FRONTEND_URL=ws://192.168.99.100:28080

# Comma separated list of RegExp origins to allow connections from.
# These values will be converted into a proper RegExp, so omit the / /.
#
# Examples:
#   http:\/\/localhost*
#   http:\/\/example.*,https:\/\/example.*
#
# Not running Docker natively? Replace 'localhost' with your Docker Machine IP
# address, such as: http:\/\/192.168.99.100*
ACTION_CABLE_ALLOWED_REQUEST_ORIGINS=http:\/\/192.168.99.100*

Docker прочитает все эти переменные среды из этого файла.

Далее, давайте создадим Docker-Compose.yml.yml.yml

version: '2'

services:
  postgres:
    image: 'postgres:9.6-alpine'
    environment:
      POSTGRES_USER: 'app_name_here'
      POSTGRES_PASSWORD: 'yourpassword'
    ports:
      - '5432:5432'
    volumes:
      - 'postgres:/var/lib/postgresql/data'

  redis:
    image: 'redis:3.2-alpine'
    command: redis-server --requirepass yourpassword
    ports:
      - '6379:6379'
    volumes:
      - 'redis:/data'

  website:
    depends_on:
      - 'postgres'
      - 'redis'
    build: .
    ports:
      - '3000:3000'
    volumes:
      - '.:/app'
    env_file:
      - '.env'

  sidekiq:
    depends_on:
      - 'postgres'
      - 'redis'
    build: .
    command: sidekiq -C config/sidekiq.yml.erb
    volumes:
      - '.:/app'
    env_file:
      - '.env'

  cable:
    depends_on:
      - 'redis'
    build: .
    command: puma -p 28080 cable/config.ru
    ports:
      - '28080:28080'
    volumes:
      - '.:/app'
    env_file:
      - '.env'

volumes:
  redis:
  postgres:

Docker будет использовать этот файл для настройки таких услуг, как POSTRESQL, вы замечаете, что у него также есть env_file который использует .env файл, который мы создали ранее.

Хорошо, теперь мы продолжим с Dockerfile.

FROM jruby:9.1.15-alpine

RUN apk update && apk add build-base nodejs postgresql-dev redis git

RUN mkdir /app
WORKDIR /app

COPY Gemfile Gemfile.lock ./
RUN bundle install --binstubs

COPY . .

CMD puma -C config/puma.rb

Это для меня самая важная часть, поскольку это то, что должен создать приложение Docker.

Мы еще не можем построить эту вещь, поскольку приложение Rails необходимо изменить первым …

Давайте начнем с папки конфигурации …

Модифицировал application.rb со следующим кодом

  ...
    # Initialize configuration defaults for originally generated Rails version.
    # config.load_defaults 5.1

    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Set up logging to be the same in all environments but control the level
    # through an environment variable.
    config.log_level = ENV['LOG_LEVEL']

    # Log to STDOUT because Docker expects all processes to log here. You could
    # then redirect logs to a third party service on your own such as systemd,
    # or a third party host such as Loggly, etc..
    logger           = ActiveSupport::Logger.new(STDOUT)
    logger.formatter = config.log_formatter
    config.log_tags  = %i[subdomain uuid]
    config.logger    = ActiveSupport::TaggedLogging.new(logger)

    # Action mailer settings.
    config.action_mailer.delivery_method = :smtp
    config.action_mailer.smtp_settings = {
      address:              ENV['SMTP_ADDRESS'],
      port:                 ENV['SMTP_PORT'].to_i,
      domain:               ENV['SMTP_DOMAIN'],
      user_name:            ENV['SMTP_USERNAME'],
      password:             ENV['SMTP_PASSWORD'],
      authentication:       ENV['SMTP_AUTH'],
      enable_starttls_auto: ENV['SMTP_ENABLE_STARTTLS_AUTO'] == 'true'
    }

    config.action_mailer.default_url_options = {
      host: ENV['ACTION_MAILER_HOST']
    }
    config.action_mailer.default_options = {
      from: ENV['ACTION_MAILER_DEFAULT_FROM']
    }

    # Set Redis as the back-end for the cache.
    config.cache_store = :redis_store, ENV['REDIS_CACHE_URL']

    # Set Sidekiq as the back-end for Active Job.
    config.active_job.queue_adapter = :sidekiq
    config.active_job.queue_name_prefix =
      "#{ENV['ACTIVE_JOB_QUEUE_PREFIX']}_#{Rails.env}"

    # Action Cable setting to de-couple it from the main Rails process.
    config.action_cable.url = ENV['ACTION_CABLE_FRONTEND_URL']

    # Action Cable setting to allow connections from these domains.
    # origins = ENV['ACTION_CABLE_ALLOWED_REQUEST_ORIGINS'].split(',')
    # origins.map! { |url| /#{url}/ }
    # config.action_cable.allowed_request_origins = origins
  ...

Это будет настроить регистратор, действие действий, активную работу и кабель действий и кабель действий с переменными среды от .env.env. Благодаря GEM Дотенв-рельсы Отказ

Тогда давайте изменим `Cable.yml`

---

development: &default
  adapter: redis
  url: <%= ENV['ACTION_CABLE_BACKEND_URL'] %>

test:
  <<: *default

staging:
  <<: *default

production:
  <<: *default

Это устанавливает конфигурацию кабеля действий.

Тогда давайте изменим База данных

---

development:
  url: <%= ENV['DATABASE_URL'].gsub('?', '_development?') %>

test:
  url: <%= ENV['DATABASE_URL'].gsub('?', '_test?') %>

staging:
  url: <%= ENV['DATABASE_URL'].gsub('?', '_staging?') %>

production:
  url: <%= ENV['DATABASE_URL'].gsub('?', '_production?') %>

Это также использует .env Чтобы прочитать URL базы данных.

Тогда давайте создадим конфиг для Sidekig.yml.erb.

---

:queues:
  - <%= ENV['ACTIVE_JOB_QUEUE_PREFIX'] %>_<%= ENV['RAILS_ENV'] %>_default
  - <%= ENV['ACTIVE_JOB_QUEUE_PREFIX'] %>_<%= ENV['RAILS_ENV'] %>_mailers

Это настраивает названия очередей Sidekiq.

Вам должно быть комфортно с такими изменениями на /config папка. Итак, давайте продолжать делать больше изменений, в инициализаторы

Добавить новый файл sidekiq.rb.

Sidekiq.configure_server do |config|
  config.redis = { url: ENV['REDIS_URL'] }
end

Sidekiq.configure_client do |config|
  config.redis = { url: ENV['REDIS_URL'] }
end

Эта настройка Sidekiq Redis URL, если вы этого не делаете, Sidekiq не будет работать.

Тогда давайте создадим новый файл Timeout.rb.

Rack::Timeout.timeout = ENV.fetch('REQUEST_TIMEOUT') { 5 }.to_i

Я боролся без этого кода … Так что не забудьте добавить его.

Тогда давайте добавим новый файл База данных_connection.rb.

Rails.application.config.after_initialize do
  ActiveRecord::Base.connection_pool.disconnect!

  ActiveSupport.on_load(:active_record) do
    config = ActiveRecord::Base.configurations[Rails.env] ||
             Rails.application.config.database_configuration[Rails.env]
    config['pool'] = ENV['RAILS_MAX_THREADS'] || 16
    ActiveRecord::Base.establish_connection(config)
  end
end

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

Наконец, мы готовы построить приложение, запустите команду Docker-Compose Up --Build Отказ Будьте терпеливы, поскольку эта команда скажет многие libs, необходимые для работы виртуальной машины.

После этого визит 192.168.99.100:3000 И вы должны увидеть страницу приветствия Rails!

Проблемы я столкнулся

Я борелся с проведением всех кусочков вместе, мне потребовалось некоторое время, чтобы расследовать и отлаживать много проблем, которые я имел, создав этот проект. Например: версия рельсов 5.1.x. Не работает с версией адаптера PostgreSQL JDBC 51 поэтому я использовал рельсы версии 5.0.6 и версия адаптера PostgreSQL JDBC 50-стабильный Отказ Другая проблема была в конфигурации PUMA, я не смог установить конфигурацию работников, и я до сих пор не о том, как его использовать, не нарушая приложение, поэтому я прокомментировал его.

Назначение ключей

Если вы можете создать приложение JRUBY на Rails, которое работает на Docker, это означает, что вы находитесь на новом уровне, так как ваше приложение может масштабировать намного лучше, чем типичное приложение ROR + Heroku …

Советы и советы

Пожалуйста, проверьте мой полностью функциональный jruby на приложение Rails под названием Twitalytics здесь: https://github.com/victorhazbun/twitalytics. , вы можете скачать его или надого и играть с ним!

Окончательные мысли и следующие шаги

В будущих уроках мы будем работать с приложением Twitalytics, добавляя содержимое к нему и, включая мощные функции, такие как: развертывание JRuby на предприятии, управление приложением JRUBY, настраивая приложение JRUBY, мониторинг JRUBY в производстве, используя непрерывный интеграционный сервер.

Надеюсь, вам понравился этот пост, и если это так, пожалуйста, поддержите его, повторно его успешно!

Оригинал: «https://www.codementor.io/@victor_hazbun/build-a-jruby-on-rails-application-from-scratch-and-dockerize-it-gvjxh1xie»