28 Ноя

Настройка Nginx + Puma для Rails

Просто, чтоб не забыть.
Создаем или редактируем файл /path_to_your_rails_app/config/puma.rb (всякие пути и названия нужно указать свои, само собой):

threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 
threads threads_count, threads_count
port        ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/tmp"
#ниже вместо your_socket.sock пишете название своего файла сокета
bind "unix://#{shared_dir}/your_sock.sock"
#перенаправляем stdout в файлы логов
stdout_redirect "#{app_dir}/log/puma.stdout.log", "#{app_dir}/log/puma.stderr.log", true
# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart

После этого в /etc/nginx/nginx.conf (или /etc/nginx/sites_enabled/your_conf_file):

upstream your_upstream {
  server unix:///var/www/your_app/tmp/your_sock.sock;
}

server {
 #       listen   443;
        listen   80;
        server_name  your_domain.ru;
        root /var/www/your_app/public;
        client_max_body_size 32m;

#        настройки для HTTPS
#        ssl    on;
#        ssl_certificate   /etc/letsencrypt/live/your_domain.ru/fullchain.pem;
#        ssl_certificate_key    /etc/letsencrypt/live/your_domain.ru/privkey.pem;


        location / {
          proxy_pass http://your_upstream; # match the name of upstream directive which is defined above
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# настройки ниже нужны, если используется Action Cable
#        location /cable {
#          proxy_pass http://your_upstream;
#          proxy_http_version 1.1;
#          proxy_set_header Upgrade $http_upgrade;
#          proxy_set_header Connection "upgrade";
#        }

#эти четыре настройки ниже нужны, если используете SSL
#          proxy_set_header  X-Forwarded-Proto $scheme;
#          proxy_set_header  X-Forwarded-Ssl on; # Optional
#          proxy_set_header  X-Forwarded-Port $server_port;
#          proxy_set_header  X-Forwarded-Host $host;
        }
        location ~* ^/assets/ {
          # Per RFC2616 - 1 year maximum expiry
          expires 1y;
          add_header Cache-Control public;
          add_header Last-Modified "";
          add_header ETag "";
          break;
        }

}

#для автоматического перенаправления на https (если используется): 
server {
        listen       80;
        server_name your_domain.ru;
        rewrite     ^   https://$server_name$request_uri? permanent;
}

После этого могут возникнуть только проблемы с правами доступа к файлу сокета. По логам выяснять и решать.

19 Июн

Неприятная проблема с миграциями в MySQL

Столкнулся с такой очень неприятной штукой на днях.
Дорабатывал я приложение у себя на локальном компе, соответственно, с development-базой на SQLite. Сделал миграцию, настроил, проверил. Всё хорошо.
Запушил на production-сервер. Пытаюсь применить миграцию (production-база на MySQL), а мне выдает следующую ошибку:
#:/var/www/project# RAILS_ENV=production rails db:migrate
/usr/local/rvm/rubies/ruby-2.4.0/bin/ruby: warning: shebang line ends with \r may cause a problem
== 20170617124016 CreateDashboards: migrating =================================
-- create_table(:dashboards)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Table 'dashboards' doesn't exist: SHOW FULL FIELDS FROM `dashboards`
/usr/local/rvm/gems/ruby-2.4.0/gems/mysql2-0.4.6/lib/mysql2/client.rb:120:in `_query'
/usr/local/rvm/gems/ruby-2.4.0/gems/mysql2-0.4.6/lib/mysql2/client.rb:120:in `block in query'
. . .
Ну и так далее ошибок на экрана четыре.
Что ж, гуглим. Сначала ничего непонятно, какая-то фигня вообще. С наскока решить не получилось.
Спустя полчаса гугления оказалось следующее. В этой таблице dashboards у меня был референс на другую таблицу (которая была создана пару месяцев назад). И проблема в том, что тип поля этого референса не совпадал с типом поля id в родительской таблице. Тип поля референса был bigint, в то время как тип родительского поля был int.
Произошло это, скорей всего, из-за того, что пару недель назад переехал с Rails 5.0.1 на Rails 5.1.0 (ну и версию Ruby пришлось поднять с 2.3.1 до 2.4.0). А в новой версии рельс, судя по всему, для id и для референсов используется bigint вместо int.
В итоге исправил проблему ручным прописыванием в миграции для создания таблицы dashboards типа референса примерно так:
 class CreateDashboards < ActiveRecord::Migration[5.1]
  def change
    create_table :dashboards do |t|
      t.references :hosp, type: :integer, foreign_key: true
      t.integer :day_count
. . .
Такие дела.
15 Янв

Проблема с bootstrap в продакшене RoR

После установки на рельсы bootstrap из вот этого репозитория столкнулся с проблемой, что не подгружаются ассеты при развертывании приложения в продакшен. То есть css и js просто не подгружаются. Совсем.
Версия руби: ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]

Версия рельс: Rails 4.2.5

В итоге наткнулся на stackoverflow на тему с такой же проблемой, где советуют сделать прописать следующие параметры в файле %rails_app%/config/environments/production.rb

config.assets.compile = true
config.assets.precompile = ['*.js', '*.css', '*.css.erb']

Ну я и прописал. Но, как обычно, ничего никогда не проходит гладко. Поэтому после этого у меня выскочила ошибка:
Undefined variable: "$alert-padding".
Немного погуглив, нашел решение, что строку

config.assets.precompile = ['*.js', '*.css', '*.css.erb']

всё же лучше убрать, оставив только

config.assets.compile = true

Ну и после этого всё нормально заработало (пока что). Впрочем, сейчас всё равно пока переключусь на development.

12 Ноя

Подключение к БД MSSQL через ActiveRecord

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

В общем, сначала я столкнулся с проблемой несостыковки кодировок в MySQL. Если заношу данные в базу (и считываю их потом оттуда) на английском языке — то всё нормич, а вот как только дело доходит до русского — приложение Sinatra сразу вылетает с ошибкой. Текст ошибки я сейчас уже не помню, но гугление помогло мне и в итоге я нашел инфу, что для подключения к MySQL необходим адаптер не mysql, как могло сначала показаться, а mysql2. Да не просто mysql2, а ещё и определенной версии. В общем, в моём приложении Gemfile стал выглядеть вот так:

 gem "sinatra"
 gem 'mysql2', '~> 0.3.18'
 gem "activerecord"
 gem "sinatra-activerecord"
 gem "sinatra-contrib"

Далее передо мной возникла проблема подключения к базе MSSQL, в общем, с горем пополам тоже нашел инфу, что для подключения к MSSQL нужны ещё два гема. В итоге Gemfile пополнился ещё двумя строчками:

gem 'tiny_tds'
gem 'activerecord-sqlserver-adapter', '~> 4.2.0'

Читать далее