Como utilizar a plataforma Heroku para deploy de aplicações

Como utilizar a plataforma Heroku para deploy de aplicações

Heroku é atualmente uma das melhores opções PaaS ( Plataform as a Service ) para desenvolvedores fazerem o deploy de suas aplicações. Essa plataforma é muito utilizada nas startups porque facilita muito o gerenciamento de infraestrutura, monitoração de disco, cpu, memória e entre outros.

Nesse post vou mostrar como utilizo essa plataforma para fazer o deploy dos meus projetos pessoais em ambientes production-like.

A preparação

O código fonte da aplicação está publicado no link abaixo:

https://github.com/Responsus/TerminusNG

Essa aplicação é uma versão um pouco melhorada do meu tcc da faculdade, que foi um sistema para gerenciamento de projetos. Inicialmente esse sistema foi escrito com um framework chamado Pyramid e nessa nova versão foi escrita com o microframework Flask.

O Heroku possui vários planos que podem ser usados, eu uso o plano free, que disponibiliza um container com apenas 1 Worker e desliga após 30 minutos de inatividade, que é o suficiente para testar aplicações em ambientes não produção.

Todos os planos estão disponíveis no link abaixo:

https://www.heroku.com/pricing

Crie sua primeira aplicação

Agora, o primeiro passo é criar uma conta no Heroku.

https://signup.heroku.com/login

Após a sua conta criada, crie um novo app, clicando no botão New no topo da página conforme a imagem abaixo:

Heroku

Ao criar o novo app, dê um nome único a ele.

Heroku

Após a criação do seu app, você será redirecionado para uma outra página e nela clique em Settings, logo abaixo você encontrará um link para o seu repositório no Heroku, salve esse link que será usado mais a frente.

Instalação do client Heroku

Agora é necessário instalar o heroku-cli na máquina para publicar o projeto.

Nesse link temos todos os links para download em vários sistemas operacionais.

https://devcenter.heroku.com/articles/heroku-cli

Eu instalei a versão para windows, então os exemplos que vou usar em diante serão digitados usando o Windows Powershell.

Abaixo uma lista dos comandos disponíveis para o Heroku-cli.

01PS C:\Users\1511 MXTI\Documents> heroku --help
02Usage: heroku COMMAND
03 
04Help topics, type heroku help TOPIC for more details:
05 
06 access          manage user access to apps
07 addons          tools and services for developing, extending, and operating your app
08 apps            manage apps
09 auth            heroku authentication
10 authorizations  OAuth authorizations
11 buildpacks      manage the buildpacks for an app
12 certs           a topic for the ssl plugin
13 ci              run an application test suite on Heroku
14 clients         OAuth clients on the platform
15 config          manage app config vars
16 container       Use containers to build and deploy Heroku apps
17 domains         manage the domains for an app
18 drains          list all log drains
19 features        manage optional features
20 git             manage local git repository for app
21 keys            manage ssh keys
22 labs            experimental features
23 local           run heroku app locally
24 logs            display recent log output
25 maintenance     manage maintenance mode for an app
26 members         manage organization members
27 notifications   display notifications
28 orgs            manage organizations
29 pg              manage postgresql databases
30 pipelines       manage collections of apps in pipelines
31 plugins         manage plugins
32 ps              manage dynos (dynos, workers)
33 redis           manage heroku redis instances
34 regions         list available regions
35 releases        manage app releases
36 run             run a one-off process inside a Heroku dyno
37 sessions        OAuth sessions
38 spaces          manage heroku private spaces
39 status          status of the Heroku platform
40 teams           manage teams
41 update          update CLI
42 webhooks        setup HTTP notifications of app activity

Primeiro vou fazer o git clone da aplicação.

1PS C:\Users\1511 MXTI> git clone https://github.com/Responsus/TerminusNG.git
2Cloning into 'TerminusNG'...
3remote: Counting objects: 816, done.
4remote: Compressing objects: 100% (23/23), done.
5remote: Total 816 (delta 14), reused 21 (delta 10), pack-reused 783
6Receiving objects: 100% (816/816), 4.21 MiB | 422.00 KiB/s, done.
7Resolving deltas: 100% (130/130), done.
8PS C:\Users\1511 MXTI>

Com a aplicação já clonada, entrei no diretório e fiz o login do heroku:

1PS C:\Users\1511 MXTI> cd .\TerminusNG\
2PS C:\Users\1511 MXTI\TerminusNG> heroku login
3Enter your Heroku credentials:
4Email: alisson.copyleft@gmail.com
5Password: *****************
6Logged in as alisson.copyleft@gmail.com
7PS C:\Users\1511 MXTI\TerminusNG>

Agora adicione o repositório copiado do heroku nos passos anteriores.

1PS C:\Users\1511 MXTI\TerminusNG> git remote add heroku https://git.heroku.com/alissonmachado.git
2PS C:\Users\1511 MXTI\TerminusNG>

Após adicionado o heroku como remote, foi feito um push para esse repositório:

01PS C:\Users\1511 MXTI\TerminusNG> git add --all
02PS C:\Users\1511 MXTI\TerminusNG> git commit -m "deploy heroku"
03On branch master
04Your branch is up to date with 'origin/master'.
05 
06nothing to commit, working tree clean
07PS C:\Users\1511 MXTI\TerminusNG> git push heroku
08Counting objects: 816, done.
09Delta compression using up to 8 threads.
10Compressing objects: 100% (645/645), done.
11Writing objects: 100% (816/816), 4.21 MiB | 59.00 KiB/s, done.
12Total 816 (delta 130), reused 816 (delta 130)

A saida do comando será parecida com essa:

01remote: Compressing source files... done.
02remote: Building source:
03remote:
04remote: -----> Python app detected
05remote: -----> Installing python-3.6.4
06remote: -----> Installing pip
07remote: -----> Installing requirements with pip
08remote:        Collecting Flask (from -r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 1))
09remote:          Downloading Flask-0.12.2-py2.py3-none-any.whl (83kB)
10remote:        Collecting Flask_SQLAlchemy (from -r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 2))
11remote:          Downloading Flask_SQLAlchemy-2.3.2-py2.py3-none-any.whl
12remote:        Collecting gunicorn (from -r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 3))
13remote:          Downloading gunicorn-19.7.1-py2.py3-none-any.whl (111kB)
14remote:        Collecting flask-security (from -r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
15remote:          Downloading Flask_Security-3.0.0-py2.py3-none-any.whl (68kB)
16remote:        Collecting flask-mongoengine (from -r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 5))
17remote:          Downloading flask-mongoengine-0.9.3.tar.gz (111kB)
18remote:        Collecting bcrypt (from -r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 6))
19remote:          Downloading bcrypt-3.1.4-cp36-cp36m-manylinux1_x86_64.whl (54kB)
20remote:        Collecting itsdangerous>=0.21 (from Flask->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 1))
21remote:          Downloading itsdangerous-0.24.tar.gz (46kB)
22remote:        Collecting click>=2.0 (from Flask->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 1))
23remote:          Downloading click-6.7-py2.py3-none-any.whl (71kB)
24remote:        Collecting Jinja2>=2.4 (from Flask->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 1))
25remote:          Downloading Jinja2-2.10-py2.py3-none-any.whl (126kB)
26remote:        Collecting Werkzeug>=0.7 (from Flask->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 1))
27remote:          Downloading Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
28remote:        Collecting SQLAlchemy>=0.8.0 (from Flask_SQLAlchemy->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 2))
29remote:          Downloading SQLAlchemy-1.2.0.tar.gz (5.5MB)
30remote:        Collecting passlib>=1.7 (from flask-security->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
31remote:          Downloading passlib-1.7.1-py2.py3-none-any.whl (498kB)
32remote:        Collecting Flask-Login>=0.3.0 (from flask-security->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
33remote:          Downloading Flask-Login-0.4.1.tar.gz
34remote:        Collecting Flask-Mail>=0.7.3 (from flask-security->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
35remote:          Downloading Flask-Mail-0.9.1.tar.gz (45kB)
36remote:        Collecting Flask-Principal>=0.3.3 (from flask-security->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
37remote:          Downloading Flask-Principal-0.4.0.tar.gz
38remote:        Collecting Flask-BabelEx>=0.9.3 (from flask-security->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
39remote:          Downloading Flask-BabelEx-0.9.3.tar.gz (41kB)
40remote:        Collecting Flask-WTF>=0.13.1 (from flask-security->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
41remote:          Downloading Flask_WTF-0.14.2-py2.py3-none-any.whl
42remote:        Collecting mongoengine>=0.8.0 (from flask-mongoengine->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 5))
43remote:          Downloading mongoengine-0.15.0.tar.gz (144kB)
44remote:        Collecting six (from flask-mongoengine->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 5))
45remote:          Downloading six-1.11.0-py2.py3-none-any.whl
46remote:        Collecting cffi>=1.1 (from bcrypt->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 6))
47remote:          Downloading cffi-1.11.3-cp36-cp36m-manylinux1_x86_64.whl (420kB)
48remote:        Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->Flask->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 1))
49remote:          Downloading MarkupSafe-1.0.tar.gz
50remote:        Collecting blinker (from Flask-Mail>=0.7.3->flask-security->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
51remote:          Downloading blinker-1.4.tar.gz (111kB)
52remote:        Collecting Babel>=1.0 (from Flask-BabelEx>=0.9.3->flask-security->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
53remote:          Downloading Babel-2.5.1-py2.py3-none-any.whl (6.8MB)
54remote:        Collecting speaklater>=1.2 (from Flask-BabelEx>=0.9.3->flask-security->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
55remote:          Downloading speaklater-1.3.tar.gz
56remote:        Collecting WTForms (from Flask-WTF>=0.13.1->flask-security->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
57remote:          Downloading WTForms-2.1.zip (553kB)
58remote:        Collecting pymongo>=2.7.1 (from mongoengine>=0.8.0->flask-mongoengine->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 5))
59remote:          Downloading pymongo-3.6.0-cp36-cp36m-manylinux1_x86_64.whl (378kB)
60remote:        Collecting pycparser (from cffi>=1.1->bcrypt->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 6))
61remote:          Downloading pycparser-2.18.tar.gz (245kB)
62remote:        Collecting pytz>=0a (from Babel>=1.0->Flask-BabelEx>=0.9.3->flask-security->-r /tmp/build_f5fec0d0c01ac466add1d2bf054ac08c/requirements.txt (line 4))
63remote:          Downloading pytz-2017.3-py2.py3-none-any.whl (511kB)
64remote:        Installing collected packages: itsdangerous, click, MarkupSafe, Jinja2, Werkzeug, Flask, SQLAlchemy, Flask-SQLAlchemy, gunicorn, passlib, Flask-Login, blinker, Flask-Mail, Flask-Principal, pytz, Babel, speaklater, Flask-BabelEx, WTForms, Flask-WTF, flask-security, pymongo, six, mongoengine, flask-mongoengine, pycparser, cffi, bcrypt
65remote:          Running setup.py install for itsdangerous: started
66remote:            Running setup.py install for itsdangerous: finished with status 'done'
67remote:          Running setup.py install for MarkupSafe: started
68remote:            Running setup.py install for MarkupSafe: finished with status 'done'
69remote:          Running setup.py install for SQLAlchemy: started
70remote:            Running setup.py install for SQLAlchemy: finished with status 'done'
71remote:          Running setup.py install for Flask-Login: started
72remote:            Running setup.py install for Flask-Login: finished with status 'done'
73remote:          Running setup.py install for blinker: started
74remote:            Running setup.py install for blinker: finished with status 'done'
75remote:          Running setup.py install for Flask-Mail: started
76remote:            Running setup.py install for Flask-Mail: finished with status 'done'
77remote:          Running setup.py install for Flask-Principal: started
78remote:            Running setup.py install for Flask-Principal: finished with status 'done'
79remote:          Running setup.py install for speaklater: started
80remote:            Running setup.py install for speaklater: finished with status 'done'
81remote:          Running setup.py install for Flask-BabelEx: started
82remote:            Running setup.py install for Flask-BabelEx: finished with status 'done'
83remote:          Running setup.py install for WTForms: started
84remote:            Running setup.py install for WTForms: finished with status 'done'
85remote:          Running setup.py install for mongoengine: started
86remote:            Running setup.py install for mongoengine: finished with status 'done'
87remote:          Running setup.py install for flask-mongoengine: started
88remote:            Running setup.py install for flask-mongoengine: finished with status 'done'
89remote:          Running setup.py install for pycparser: started
90remote:            Running setup.py install for pycparser: finished with status 'done'
91remote:        Successfully installed Babel-2.5.1 Flask-0.12.2 Flask-BabelEx-0.9.3 Flask-Login-0.4.1 Flask-Mail-0.9.1 Flask-Principal-0.4.0 Flask-SQLAlchemy-2.3.2 Flask-WTF-0.14.2 Jinja2-2.10 MarkupSafe-1.0 SQLAlchemy-1.2.0 WTForms-2.1 Werkzeug-0.14.1 bcrypt-3.1.4 blinker-1.4 cffi-1.11.3 click-6.7 flask-mongoengine-0.9.3 flask-security-3.0.0 gunicorn-19.7.1 itsdangerous-0.24 mongoengine-0.15.0 passlib-1.7.1 pycparser-2.18 pymongo-3.6.0 pytz-2017.3 six-1.11.0 speaklater-1.3
92remote:
93remote: -----> Discovering process types
94remote:        Procfile declares types -> web
95remote:
96remote: -----> Compressing...
97remote:        Done: 58.4M
98remote: -----> Launching...
99remote:        Released v3

O log acima, mostra todo o processo de instalação de dependências para que seja criado o container e seja feito o deploy da aplicação, mas o mais importante é o final do log que aparecerá similiar ao mostrado abaixo:

1remote: -----> Launching...
2remote:        Released v3
3remote:        https://alissonmachado.herokuapp.com/ deployed to Heroku
4remote:
5remote: Verifying deploy... done.

Foi retornado a seguinte url: https://alissonmachado.herokuapp.com/.

E pronto, agora é só acessar a aplicação que já estará funcionando.

Mas como foi feito o deploy?

Ao se fazer uma aplicação que será publicada no heroku, ela já deve ser construída pensada em heroku, assim como qualquer outra plataforma DevOps que faz o deploy em containers.

Dentro do repositório existe um arquivo chamado Procfile: https://github.com/Responsus/TerminusNG/blob/master/Procfile , nesse arquivo é definido qual é o processo que deve ser iniciado, que no nosso caso é o servidor Web gunicorn e ele vai iniciar p arquivo app.py que é o principal da aplicação.

Outro ponto importante é deixar o arquivo requirements.txt: https://github.com/Responsus/TerminusNG/blob/master/requirements.txt, sempre atualizado, pois ele também faz a instalação do gunicorn que é o servidor de aplicação que é usado durante o deploy.

E acho que é isso ai, qualquer coisa é só mandar um salve (=

Anterior Seja o melhor aluno e garanta sua contratação na 4Linux
Próxima Guia definitivo para aprender PHP em 2018: passo a passo para iniciantes

About author

Alisson Machado
Alisson Machado 22 posts

Alisson Menezes, atua como Gerente de T.I, 9 anos de experiência em projetos FOSS (Free and Open Source Software) e Python. Formação em Análise de Sistemas pela FMU e cursando MBA em BigData pela FIA, possui certificações LPI1, LPI2 e SUSE CLA, LPI DevOps e Exim - DevOps Professional. Autor dos cursos Python Fundamentals, Python for Sysadmins, MongoDB for Developers/DBAs, DevSecOps, Co-Autor do Infraestrutura Ágil e Docker da 4Linux e palestrantes em eventos como FISL, TDC e Python Brasil. É entusiasta das mais diversas áreas em T.I como Segurança, Bancos de dados NoSQL, DataScience mas tem como foco DevOps e Automação.

View all posts by this author →

Você pode gostar também

DevOps

Como configurar um repositório Yum local com Nexus Sonatype

Administradores de sistemas, sempre que operam em ambiente GNU/Linux,  realizam a instalação de pacotes pré-compilados localizados em repositórios remotos. Para distribuições baseadas em Red Hat, fazemos uso de repositórios Yum

DevOps

4Linux se torna A.T.O do EXIN com curso homologado para DEVOPS Master

Material didático desenvolvido pela 4Linux foi homologado pelo EXIN A 4linux acaba de se tornar um A.T.O. (Authorized Training Organization) do EXIN e simultaneamente teve o material de seu curso

DevOps

Crie sua primeira aplicação em Python: Guia passo a passo

Neste post estaremos aprendendo a criar uma aplicação simples utiliando a linguagem de programação “Python”.   Primeiramente, obviamente, será necessário ter o python instalado em nossas máquinas, podemos adquirí-lo de