Hospedagem Rails Heroku por Raphael Almeida Araújo ([email protected]) Sumário Dashboard Dynos Procfile Colaboradores Databases Addons Heroku Toolbelt Build packs Deploy Nova aplicação Publicar código existente Publicando Configuração de DNS Páginas de erros Variáveis de ambiente Tags Logs Gems privadas Problemas e Soluções Deploy Apontamento para repositório do Heroku Gems Jquery Rails Tiny tds Sinatra Devise Paper clip Assets Precompilação fora do ambiente de produção Conflitos entre plugins Javascript Configurações da aplicação Dashboard Todo usuário do Heroku possui um dashboard que lista das aplicações criados por ele também aplicações criadas por outros usuários que lhe deram permissão de acesso. Imagem de um dashboard de um usuário qualquer no Heroku Cada aplicação possui um “serviço” separado das demais. As aplicações rodam através de máquinas virtuais que são chamadas de Dyno, e elams podem várias nos seguinte status: 1. Desativado (representado pelo ícone de um exagono com um sinal de menos): Quando não há nenhum Dyno alocada para a aplicação; 2. Dormindo (representado pelo ícone de um exagono com ‘zzz’ dentro): Quando há algum Dyno alocado para a aplicação mas a aplicação está inativa por falta de acesso; 3. Ativado (representado pelo ícone de um exagono sem nada dentro): Quando a aplicação está em execução; Acessando sua aplicação você terá uma página interna com informações de sua aplicação: ● Dynos ● Addons ● Tags ● Colaboradores ● Configurações Imagem interna de uma aplicação no Heroku Dynos Como comentado anteriormente, os dynos são como máquinas virtuais independentes que executam uma determinada aplicação. No Heroku uma aplicação com apenas um dyno é gratuita, oferecendo um ambiente temporário para que os desenvolvedores testem e publiquem sua aplicação. Infelizmente uma aplicação de um único dyno tende a “dormir” quando nenhuma requisição é feita a aplicação durante um interválo de 1 hora (mais informações em https://blog.heroku.com/archives/2013/6/20/app_sleeping_on_heroku) Para que uma aplicação não durma, é necessário que a mesma tenha no mínimo 2 dynos alocados. Cada dyno pode variar entre 512 mB e 1023 mB de RAM. Através do painel da aplicação você configura facilmente e instantaneamente essa demanda. No painel são apresentados dynos em 2 grupos: 1. Web 2. Worker Não obrigatoriamente sua aplicação terá os 2 grupos. “Web” e “worker” são nomes customizáveis que são definidos automaticamente quando se cria uma aplicação no Heroku. Procfile Sua aplicação pode ter mais do que apenas uma aplicação web. Tal como em alguns projetos, são utilizados background jobs que são necessários para execução de tarefas secundárias. Como no Heroku há um limite de 30 segundos de resposta para qualquer requisão, alguns projetos que possuem funcionalidades que requerem mais tempo usufruem da gem ‘delayedjobs’. Essa gem depende de um rake (rake jobs:work) que sempre está executando além da aplicação web. O conteúdo de um Procfile é formado pelos nomes dos processos que agrupam os dynos no painel da aplicação qual o comando executado por esse processo. Veja um exemplo: web: bundle exec unicorn p $PORT c ./config/unicorn.rb worker: bundle exec rake jobs:work Com base nesse arquivo Procfile, durante todos os deploys, os serviços necessários da aplicação são identificados e reiniciados para que contemplem sempre o código mais atual. Colaboradores Para que uma aplicação exista é necessário um usuário master. Mas pode haver casos que o usuário master não é o responsável técnico ou que haja a necessidade se haver mais de um usuário responsável pela aplicação. Para atender essas e outras necessidades há como se definir um mais colaboradores para uma mesma aplicação. Para ter acesso a esse cadastro faça: 1. Acesse seu dashboard 2. Acesse a aplicação em questão 3. Vá no menu ‘Access’ 4. Adicione o usuário pelo email do mesmo É realmente um processo bem simples. Se o usuário já tiver cadastro no Heroku ele apenas receberá um lembrete por email para acesso a aplicação. Se não tiver, ele receberá um convite de cadastro e assim que cadastrar já terá acesso a aplicação. Databases As base de dados das aplicação são inseridas através de Addons, mas para facilitar a adminitrção e identificação das mesmas, o Heroku ofere uma página que lista todas as suas bases. Para ter acesso vá no seu dashboard e acesse o menu ‘Databases’ Nessa página você terá acesso aos seus bancos de dados hospedados no Heroku. E como esses banco são criados e configurados automaticamente, as senhas e usuários não são definidos por você. Como isso, caso seja necessário acessar o banco por terceiros, você pode acessar essa página e verá todas as informações do banco. Detalhes de um banco Postgre no Heroku Add-ons São inúmeras as ferramentas disponibilizadas pelo Heroku para sua aplicações. Já que você não tem acesso de root para instalar aplicações de terceiros em seu servidor no Heroku, ele te oferece um leque gigante de opções de ferramentas de: ● Banco de dados ● Acompanhamento de log ● Serviços de email ● Serviços agendados ● Analise e acompanhamento dos servidores ● Cache ● Pagamentos A instalação desses completos também é bastante simplificada e imediata. Existem duas formas de se fazer isso: 1. Pelo painel da aplicação Lista de addons Versões disponíveis 2. Por linha de comando pelo toolbelt: heroku addons:add mongolab:dedicatedcluster Alguns dos addons oferecem serviços de terceiros, como é o caso do MongoHQ. O qual oferecer um painel do MongoHQ direto na aplicação do Heroku. Assim você não precisa possuir conta no MongoHQ além da conta do Heroku. Isso as vezes pode facilitar mas também pode encarecer o serviço. Heroku Toolbelt O Heroku oferece ferramentas de linha de comando para que você genrencie suas aplicações sem mesmo ter que acessar o dashboard para isso. A ferramente que o Heroku oferece é chamada Heroku Tollbet (https://toolbelt.heroku.com/). Com ela você pode: ● Criar e remover aplicações ● Iniciar, reiniciar e parar aplicações ● Habilitar, desabilitar e configurar dynos ● Instalar addons em aplicações especificas ● Consultar logs ● Acessar o bash do servidor ● Executar comandos diretamente no servidor Alguns exemplos de comandos: ● heroku ps ● heroku run bash ● heroku run rake nome_da_rake ● heroku run:detached rake nome_da_rake ● heroku logs ● heroku logs p run.3950 Para mais informações você pode acessar https://devcenter.heroku.com/articles/usingthecli Build packs Há também a possibilidade se utilizar buildpacks. Que são aplicações de terceiros que pode ser adicionada a aplicação. Por exemplo, em um projeto conhecido é necessário utilizar a ferramenta phantomjs (http://phantomjs.org), que é apenas um arquivo executável, mas que devido as restrições de acesso, você não será capas de embutir no seu código ou instalar no servidor. Para pode utilizar o phantomjs será necessário habilitar o buildpack respectivo (https://github.com/stomita/herokubuildpackphantomjs.git). Assim durante todos os deploys de sua aplicação, além do código do projeto, também será importado para a aplicação o executável do phantomjs. Para utilizar mais de um buildpack é necessário utilizar uma referência diferente da padrão (https://github.com/ddollar/herokubuildpackmulti) Deploy Como todos os procedimentos do Heroku, o deploy também é facilmente executado. Antes de tudo, é necessário um conhecimento básico de git para realizar tal tarefa. Uma dica muito útil para ter esse conhecimento, é gastar 15 minutos aprendendo um pouco sobre git em http://try.github.io. Adquirido o conhecimento em git, você deverá ter em sua máquina o Heroku toolbelt (http://toolbelt.heroku.com) instalado. Com o toolbelt instalado em sua máquina, você precisa se autenticar a sua conta no Heroku: heroku login A partir dai qualquer comando executado pelo toolbelt será gerido por esse usuário. Você poderá: 1. Criar uma nova aplicação 2. Publicar um código existente no Heroku Em tese para publicar uma aplicação no Heroku você já deve ter um código fonte definido. Até mesmo porque o deploy só irá funcionar quando o Heroku conseguir identificar a plataforma da aplicação e instalar sua dependências. Quando digo “nova aplicação” quero dizer uma nova aplicação em seu dashboard do Heroku. Página de manutenção Durante o deploy é interessante deixar a página em manutenção para que outros usuários não tenham acesso. Para ativar execute: heroku maintenance:on Para desativar: heroku maintenance:off Mas informações você pode encontrar em https://devcenter.heroku.com/articles/maintenancemode Nova aplicação Uma nova aplicação pode ser criada: ● Pelo dashboard do Heroku: ● Por linha de comando (https://devcenter.heroku.com/articles/creatingapps): heroku create Os nomes das aplicações são únicos independente de usuário. Isso fica claro quando se pensa que cada aplicação possui um subdomínio no Heroku. Criando uma nova aplicação por linha de comando todas as referências ao respositório do Heroku são automaticamente definidas. Publicar código existente Em caso de você já ter criado uma aplicação no dashboard e quere publicar um novo código, você necessitará apenas de referenciar o repositório por um comando git: git remote add heroku [email protected]:nome_aplicacao.git Apenas com essa referência, você será capas de executar os comandos no toolbelt diretamente para a aplicação referenciada pelo git. Publicando Agora que seu código está referenciando sua aplicação no Heroku. Basta um único código para se conseguir ter sua aplicação acessível externamente. O comando para publicar seu código é: git push heroku master Simples e eficas assim. Agora, é necessário saber que sua aplicação irá pegar o conteúdo do branch ‘master’ local. Então antes de realizar tal comando, você precisa ter certeza de ter um branch ‘master’ mais atual em sua máquina. Para isso vejamos uma sequência de comandos: git status # para saber a cituação do branch atual # No ramo develop # Changes not staged for commit: # (utilize "git add <arquivo>..." para atualizar o que será submetido) # (utilize "git checkout <arquivo>..." para descartar mudanças no diretório de trabalho) # … git commit am “descrição dos ajustes” git pull origin develop # para pegar a versão mais atual do github git push origin develop # para publicar os ajustes locais no github git checkout master # para alternar para o branch master git merge develop # para pegar os ajustes do develop e aplicar ao master git push origin master # para publicar os ajustes locais no github git push heroku master # para enviar os arquivos atualizados da aplicação ao Heroku e implantar a aplicação Durante o processo de deploy o Heroku se foca em 3 arquivos: 1. Gemfile.lock 2. .buildpacks 3. Procfile O ‘Gemfile.lock’ diz pro Heroku quais as gems e suas respectivas versões são necessárias para a aplicação. O .builpacks diz pro Heroku quais as dependências de terceiros são necessárias. O Procfile diz quais os processos da aplicação deverão ser reiniciados. Configuração de DNS Por padrão o Heroku não disponibiliza um servidor de DNS, mas o Registro.br sim. Então é recomendável utilizar ele para definir seus apontamentos. A adição de domínios e subdomínios pode ser feita pelo toolbelt ou pelo menu ‘Settings’ da aplicação no dashboard do usuário. Menus ‘Settings’ da aplicação Para o apontamento do Heroku no Registro.br você deve definir o willcard ‘CNAME’. Veja mais informações em http://i.ndigo.com.br/2012/04/registrobreherokuconfigurandodns/ e https://devcenter.heroku.com/articles/customdomains#wildcarddomains Páginas de erros Também no menu ‘Settings’ é possível definir as páginas apresentadas quando a aplicação não responde. Url’s de páginas de erros Variáveis de ambiente Algumas configurações da aplicação são definidas em variáveis de ambiente. Essas variavies são definidas e consultadas através do toolbelt pelos comandos: heroku config:get NOME_DA_VARIAVEL heroku config:set NOME_DA_VARIAVEL=”valor” A variável de banco de dados que é a “DATABASE_URL” é setada automaticamente durante a instalação de um banco de dados para uma aplicação. Mas pode ser alterada a qualquer momento pelo usuário. Algumas aplicações utilizando o Paper Clip com hospedagem de arquivos no Amazon S3 (aws.amazon.com/pt/s3/), e como é documentado em https://devcenter.heroku.com/articles/paperclips3 também utiliza variáveis de sistema para definir algumas configurações de acesso tal como em ‘config/enviroments/production.rb’: config.paperclip_defaults = { :storage => :s3, :s3_credentials => { :bucket => ENV['S3_BUCKET_NAME'], :access_key_id => ENV['AWS_ACCESS_KEY_ID'], :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'] } } Vale lembrar que além dessas variáveis de ambiente o Paper Clip necessita definir o host dos arquivos em ‘config/initializers/paperclip.rb’ também documentado na descrição do Heroku: Paperclip::Attachment.default_options[:s3_host_name] = 's3uswest2.amazonaws.com' Tags Em alguns projetos desenvolvedores utilizam a geração de tags no repositório da aplicação para definirem marcos no desenvolvimento e publicação das mesmas. No Heroku, essas tags são geradas automaticamente em seu repositório local. Apesar do Heroku dizer que o repositório git não deve ser utilizado como única fonte de repositório por questões de seguração e backup de seus arquivos. O Heroku oferece um histórico de todos deploys executados em cada aplicação. Histórico de deploys da aplicação no heroku Esse histórico auxilia muito quando há necessidade de se restaurar rapidamente alguma versão anterior. Logs Existem várias formas de se consultar o log de uma aplicação no Heroku. Através do Heroku Toolbelt você possui alguns comando interessantes como: heroku logs tail heroku logs source app ps worker Veja mais informações em https://devcenter.heroku.com/articles/logging Além do toolbet existem Addons que também oferecem formas de consultas mais simples. Um addon bastante utilizado é o Paper Trail. Assim que instalado em sua aplicação e posteriores execuções de sua aplicação ele lhe dara um registro de todos os logs e ferramentas simples de consultas. Logs de uma aplicação qualquer no Heroku Gems privadas Como o processo de deploy do Heroku é feito automaticamente pelos próprio servidor, é necessário em caso de uso de gem em repositórios privados o uso de urls com token para acesso. Quando se utiliza uma gem privada, você informa além do nome da gem no arquivo Gemfile a url para ser baixada. Veja um exemplo: gem 'proteste_generate_application', :git => 'https://abdcdefghijk:xoauth[email protected]/proteste/pafapplicati on.git' Para gerar um token de acesso a uma gem privada, você deve ter os dados de um usuário que tenha acesso ao repositório. Tendo esses dados execute: curl u 'raphox' d '{"scopes":["repo"], "app":{"url":"https://github.com/proteste/pafintegration"}}' https://api.github.com/authorizations Executando esse comando, será requistada senha para o usuário ‘raphox’. Assim que inserida o usuário receberá um JSON com o atributo ‘token’ o qual deverá ser utilizado no lugar do ‘abcdefghijk’ da url ‘https://abdcdefghijk:xoauth[email protected]/proteste/pafapplicatio n.git’ Veja mais informações na documentação oficial do github https://help.github.com/articles/creatinganoauthtokenforcommandlineuse Problemas e Soluções Deploy Apontamento para repositório do Heroku Existem passos para se criar uma aplicação no Heroku diretamente pelo console utilizando o Heroku Tollbet, mas em muitos casos o intuito é publicar uma aplicação existente. Com isso é necessário definir o apontamento do repositório em que o Heroku gera as TAGs da aplicação. Para isso você deve: 1. Acessar o seu painel de aplicações dashboard.heroku.com/apps 2. Acessar sua aplicação na listagem 3. Acessar o menu ‘Settings’ e identificar a url do repositório git 4. Tendo a url do repositório, você deve acessar o diretório da sua aplicação: $ cd /comparilhado/htdocs/minha_aplicacao 5. Executar o comando: git remote add heroku [email protected]:xxx.git Gems Jquery Rails Devido o ‘pafscaffold’ utilizar o tema ‘gebo’, é necessário fixar a versão da gem ‘jqueryrails’ para que não haja modificações nas versão do jquery e jqueryui compatível com o tema. A versão utilizada atualmente da gem é ‘2.1.4’ Tiny tds O Tiny tds é uma gem utilizada para se conectar com o Sql server. Isso quer dizer que para ser utilizada é necessário que o ambiente tenha requerimentos desse banco de dados, o que por padrão não existe. Por isso foram removidas todas referências dessa gem. Sinatra Durante a execução de processos de rake em desenvolvimento ocorreram falhas devido a versão da gem do ‘sinatra’ no projeto ‘forall’. Então foi fixado uma versão compatível com a implementação atual: gem 'sinatra', '~> 1.3.6' gem 'sinatracontrib', '~> 1.3.2' Devise A última versão da gem do ‘devise’ compatível com o ACA é: gem 'devise', "~> 3.1.2" A gem ‘pafauth’ utiliza uma funcionalidade (token_authenticatable http://blog.plataformatec.com.br/2013/08/devise31nowwithmoresecuredefaults/) do ‘devise’ que foi depreciada após essa versão. Paper clip Além de oferecer funcionalidades de upload de arquivos a gem ‘papeclip’ é capaz de gerar versões (thumbs de largura e altura configuráveis) de imagens durante o upload das mesmas. Para isso ela utiliza a ferramenta Image Magick (http://www.imagemagick.org) para tratamento dessas imagens. Assets Pre-compilação fora do ambiente de produção Conflitos entre plugins Javascript Muitos arquivos e bibliotecas de um projeto pode conter códigos inválidos (ou quase) que gere algum conflito quando o Rails tenta unificar todos eles um um único arquivo. Grande parte desses problema pode ser sanado inserindo um ‘;’ antes dos arquivos (http://stackoverflow.com/a/7145534). Mas não é necessário sair inserindo ‘;’ em todos os arquivos. Em uma das aplicações do projeto havia uma falha em uma determinada linha do arquivo geral, então identifiquei os arquivos envovidos, que eram dois, e inserir o ‘;’ apenas neles. O que resolveu o problema. Configurações da aplicação O Heroku starta a aplicação bom base na configuração do arquivo ‘config/enviroments/production.rb’. Essa arquivo contem toda a variação de configuração entre um ambiente de desenvolvimento e o de produção. Foi notado no Heroku que os assets da maioria das aplicações levava muito tempo para serem compiladas durante o deploy, com isso foi optado por compilar os assets localmente e enviar para o repositório git. Algumas das configurações importantes desse arquivo são: # Disable Rails's static asset server (Apache or nginx will already do this). config.serve_static_assets = true # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = true # Version of your assets, change this if you want to expire all your assets. config.assets.version = '1.0' # Specifies the header that your server uses for sending files. config.action_dispatch.x_sendfile_header = nil config.action_controller.asset_host = "http://xxx.herokuapp.com" config.action_mailer.asset_host = "http://forallimobiliaria.herokuapp.com/"