No post anterior foi mostrada a importância de se colocar o projeto num servidor de controle de versões, mesmo logo após a sua criação. Algumas preocupações puderam ser rapidamente testadas e solucionadas, por exemplo o setup em máquinas de outros desenvolvedores.
Ainda nesta fase tão precoce, podemos ir mais além: testar o deploy da aplicação num ambiente production-like. Desta forma, cria-se uma cultura de, em cada iteração, testar de ponta-a-ponta o processo de desenvolvimento.
Um dos objetivos é antecipar questões e riscos que tradicionalmente só seriam atacados ao final do projeto. Caso surjam problemas de integração, ou dificuldades técnicas que possam colocar em risco a subida do sistema para produção, as causas podem ser prontamente diagnosticadas e tratadas o mais cedo possível antes que possam comprometer o sucesso do projeto.
Setup do Heroku
O Heroku é uma opção muito popular para o deploy de aplicações Rails, que consiste simplesmente em executar:
git push heroku master
ou seja, pushando o projeto para um repositório Git remoto no Heroku.
A preparação é semelhante a da criação de uma conta no Github. É necessário criar uma conta no Heroku, e fazer o upload de uma chave pública para administração da conta via terminal.
Instalação
O primeiro passo é instalar a gem do heroku:
gem install heroku
Chave pública
Em seguida, fazer o upload da chave pública:
Caso o heroku não encontre uma chave pública em ~/.ssh/id_rsa.pub, e também não exista a chave privada ~/.ssh/id_rsa correspondente, o próprio heroku é capaz de gerar estas chaves para nós (como mostrado no trecho acima).
Podemos também aproveitar a chave pública do github, bastando que ela esteja presente em ~/.ssh/id_rsa.pub para ser upada para o heroku.
Caso mais de uma chave esteja presente no diretório .ssh, o heroku pergunta qual deve ser usada:
Criação da aplicação no Heroku
Resolvida a questão das chaves, podemos criar a aplicação no heroku: Este comando cria um ambiente no Heroku e o adiciona automaticamente como um repositório Git remoto do projeto, o que pode ser confirmado: Note também que, após deployada, a aplicação responderá inicialmente no endereço http://afternoon-robot-3025.heroku.com.
Deploy de uma aplicação Rails no Heroku
Dispensa comentários:
Até mesmo para abrir o navegador, o heroku ajuda:
heroku open
Rackfile e Procfile
O Heroku consegue fazer o deploy de aplicações Rails devido à presença do arquivo config.ru na raiz do projeto. Trata-se de um arquivo Rack, que instrui ao Heroku a forma como a aplicação é iniciada:
Procfile e Foreman
Uma alternativa ao Rack é criar um arquivo Procfile na raiz do projeto. Trata-se de um mecanismo de declarar quais comandos devem ser executados ao deployar na plataforma Heroku. Ele consiste de um conjunto de pares informando o tipo de processo e o comando para executar um determinado processo:
Apesar de opcional em aplicações Rails, seu uso é recomendado pois proporciona maior controle e flexibilidade para a aplicação. Além disso, o Heroku provê o comando heroku scale
para ajustar como escalar a aplicação, baseados no Procfile.
Para executar localmente aplicações baseadas no Procfile, é necessário instalar o Foreman.
gem install foreman
Ao iniciar a aplicação com o foreman, ele inicia cada um dos processos declarados no Procfile:
Django e Heroku
Conforme anunciado neste post,
o Heroku também oferece suporte a Python, no stack* Cedar, baseado no Ubuntu 10.04.
* o Heroku oferece diferentes stacks - ambientes completos de deploy, incluindo o sistema operacional e bibliotecas associadas.
Para criar um ambiente no stack cedar, é necessário executar o comando:
heroku create --stack cedar
e o deploy também é feito via git push:
Porém, como se vê acima, o push é rejeitado, informando que o Heroku não consegue detectar nenhuma aplicação Rails/Rack. Alguns ajustes são necessários para conseguir realizar o deploy da aplicação Django no Heroku.
Procfile para rodar aplicações Django no Heroku
Aplicações que NÃO são baseadas no Rack podem ser deployadas no Heroku usando o Procfile. No caso de uma aplicação Django, basta criar um Procfile com o seguinte conteúdo:
web: python manage.py runserver
que a aplicação passa a ser inicializável via foreman:
Agora que está tudo rodando localmente, basta apenas fazer o deploy e correr pro abraço, vai dar até pra sair mais cedo e pegar um cineminha: Oooops... Agora, através do Procfile, o Heroku já é capaz de reconhecer que se trata de uma aplicação Python, porém continua rejeitando o deploy, com uma enigmática mensagem "Django app must be in a subdirectory".
Ainda bem que o Google e o Stack Overflow existem, e alguém já havia postado a solução para este problema: http://stackoverflow.com/questions/7974902/deploying-existing-django-app-on-heroku.
Para deployar a aplicação Django no Heroku, ela precisa estar organizada de tal forma que o Procfile e o requirements.txt fiquem na raiz do repositório, e o projeto Django deve ser um subdiretório a partir da raiz do repositório.
Com esta nova organização, é importante assegurar que o arquivo settings.py esteja com o valor correto para a propriedade ROOT_URLCONF:
ROOT_URLCONF = 'urls'
Ajustada a estrutura do projeto, aí sim, esperamos que o deploy seja bem sucedido.
Basta agora um heroku open
e ver se o navegador abre a página e... Ooops. Nada acontece:
A essas alturas, cineminha já era... Neste caso, nem com ajuda de Google e Stack Overflow surgiu alguma pista. Recorrendo ao comando
heroku logs
é possível visualizar o log da subida da aplicação no Heroku, tentando procurar alguma pista sobre o que está faltando:
Voilá, nos logs surge a pista: a aplicação crasheou durante a subida, devido à ausência do módulo psycopg2.
Googleando um pouco mais, surge este blog, com instruções simples para instalar localmente este módulo:
- Pré-requisito:
sudo apt-get install libpq-dev python-dev
- Instalação: adicionar ao requirements.txt a linha
psycopg2==2.4.2
- Executar
pip install -r requirements.txt
Após nova subida, é cruzar os dedos e... nada! Eis o novo log:
Ao que o erro indica, o Heroku não faz o binding na porta 8000, e sugere pesquisar a variável de ambiente PORT. Um tanto enigmático. Recorrendo mais uma vez ao Google, eis uma pista melhor, nos comentários deste blog:
"Creating a Procfile and adding: "web: play run --http.port=$PORT $PLAY_OPTS" fixed the problem." (Ivar Abrahamsen)
o que nos conduz a alterar o Procfile para:
web: python manage.py runserver 0.0.0.0:$PORT
E finalmente:
Deploy de aplicação Django no Heroku - Resumo
- O projeto Django deve ser um subdiretório a partir da raiz que é comitada no Git
- Alterar o settings.py, fazendo
ROOT_URLCONF = 'url'
- Adicionar um Procfile na raiz do projeto contendo:
web: python manage.py runserver 0.0.0.0:$PORT
-
Instalar o psycopg2
- Para deployar no Heroku é suficiente adicionar ao requirements.txt:
psycopg2==2.4.2
- Para instalar localmente, é necessário:
- Instalar pré-requisitos
sudo apt-get install libpq-dev python-dev
- Invocar o PIP pra instalar o pycopg2
pip install -r requirements.txt
- Instalar pré-requisitos
- Para deployar no Heroku é suficiente adicionar ao requirements.txt:
- Deploy:
git push heroku master
Considerações Finais
As tentativas que envidamos para conseguir subir a aplicação Django no Heroku reforçam a tese da importância de testar o processo de desenvolvimento de ponta-a-ponta. Em cada iteração, é importante incluir o deploy para um ambiente production-like, para identificar dificuldades e riscos iterativamente, à medida que a aplicação é desenvolvida.
Nenhum comentário:
Postar um comentário