Статьи

Три рейк-задания DevOps, которые я использую ежедневно на Heroku с MongoDB

образ

Heroku и MongoDB обеспечивают рабочий процесс без трений devops, которого хочет каждая зрелая организация программного обеспечения, и тратят кучу денег. Он начинается с установки для одного разработчика, в которой я могу получить исходный код и быть готовым начать разработку после установки пакета, и продолжить с помощью git push в промежуточную среду Heroku, которая развертывает приложение для тестирования интеграции в последнюю минуту и, наконец, , производство. Каждый отдельный экземпляр Heroku имеет свою конфигурацию и ресурсы. Мой код также нуждается в разумных настройках по умолчанию для разработки. Например, mongoid.yml перечисляет localhost: 27017 в качестве хоста базы данных разработки и ENV [‘MONGOHQ_HOST_LIST’] для производства.

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

  1. Выполните задачу Rake с изменениями локального кода и настройкой производственной среды.
  2. Откройте оболочку для основного узла MongoDB в моей среде разработки Heroku.
  3. Перед тем как сделать что-то страшное, создайте дамп отдельной таблицы из производственной базы данных.

Мы выполним вышесказанное с помощью двух новых драгоценных камней: mongoid-shell и heroku-commander . Добавьте их в свой Gemfile в разделе : development .

И, пожалуйста, помните, что с большой силой (и словом «производство» во многих из последующих) приходит большая ответственность.

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

Это стало возможным благодаря героку-командиру . Библиотека обернет CLI Heroku (введение здесь ) и запустит конфигурацию heroku . Теперь легко получить доступ к приложению Heroku и получить его конфигурацию программно, не беспокоясь о ключах API (по умолчанию оно будет использовать приложение Heroku, определенное с помощью пульта GIT «heroku»). Нам также понадобится немного кода, чтобы применить соглашение об именах нашего приложения. Это позволяет мне изменить среду выполнения на среду удаленного приложения Heroku в Ruby.

    module Heroku
      class Config < Hash
        def self.set_env_from!(env)
          app = case env.to_sym
            when :heroku, :development then nil
            else "app-#{env}"
          end
          require 'heroku-commander'
          config = Heroku::Commander.new({ :app => app }).config
          config.each do |k, v|
            ENV[k] = v
          end
        end
      end
    end

Итак, как мне запустить задачу локально, но настроить как производственную ? Со следующей задачей Rake.

    namespace :heroku do
      desc "Load environment vars from Heroku config into ENV."
      task :config_from_env do
        env = ENV['RAILS_ENV'] || Rails.env
        raise "RAILS_ENV or Rails.env must be specified" unless env
        Heroku::Config.set_env_from! env
      end
    end

Запустите RAILS_ENV = производственные грабли герою: config_from_env my: task .

Откройте оболочку для основного узла MongoDB в моей среде разработки Heroku.

Сначала выясните конфигурацию удаленного MongoDB, затем выполните команду оболочки mongo . Важно знать, что встроенная системная команда не вызывает ошибку, когда процесс возвращает ненулевой код состояния. Давайте добавим систему! функция, которая исправляет это.

    def system!(cmdline)
      logger.info("[#{Time.now}] #{cmdline}")
      rc = system(cmdline)
      fail "failed with exit code #{$?.exitstatus}" if (rc.nil? || ! rc || $?.exitstatus != 0)
    end

Вместо того, чтобы создавать командные строки MongoDB вручную, я использовал новый гем под названием mongoid-shell (введение здесь ).

    namespace :db do
      [ :staging, :production, :heroku ].each do |env|
        namespace env do
          task :shell do
            require 'mongoid-shell'
            Heroku::Config.set_env_from!(env)
            config = File.join(Rails.root, "config/mongoid.yml")
            Mongoid.load! config, env
            system! Mongoid::Shell::Commands::Mongo.new.to_s
          end
        end
      end
    end

Запустите грабли db: production: shell .

Перед тем как сделать что-то страшное, создайте дамп отдельной таблицы из производственной базы данных.

Мы все делаем резервные копии и другие важные вещи, ежедневно. Но при манипулировании производственными данными я хочу иметь последнюю защиту с самыми свежими данными из коллекции, которую я собираюсь

случайно удалить
. Дамп коллекции MongoDB локально.

    namespace :db do
      [ :production, :staging, :heroku ].each do |env|
        namespace env do
          task :dump, [ :collections ] => :environment do |t, args|
            require 'mongoid-shell'
            Heroku::Config.set_env_from!(env)
            config = File.join(Rails.root, "config/mongoid.yml")
            Mongoid.load! config, env
            collections = args[:collections].split(/[\s|,]+/)
            collections.each do |collection|
              system! Mongoid::Shell::Commands::Mongodump.new({ collection: collection }).to_s
            end
          end
        end
      end
    end

Точки

Спасибо @joeyAghion и @fancyremarker , которые отвечают за многие из основных концепций, описанных выше.