Apresentação realizada no dia 13/04/2013, no 29º Guru-SP: gurusp.org/encontros/vigesimo-nono-encontro-do-guru-sp
Versão original em js: https://github.com/nuxlli/12factor-openruko
4. The Twelve-Factor Apps
Write by Adam Wiggins - CTO e Co-Founder do Heroku
Disponível para contribuição no github:
https://github.com/adamwiggins/12factor
7. 12factor - I. Codebase
Um codebase com controle de versão, vários deploys
Deploy: instância de uma aplicação.
Mesmo codebase ao longo dos deploys, mas diferentes versões em
cada instância.
8. 12factor - I. Codebase
Um codebase com controle de versão, vários deploys
✓ Diferentes desenvolvedores e instâncias pode rodar diferentes
versões do codebase.
11. 12factor - II. Dependencies
Declarar e isolar dependências explicitamente
✘ Declaração e isolamento de dependências devem ser utilizas de
forma conjunta, apenas o uso de uma não satisfaz twelve-factor.
12. 12factor - II. Dependencies
Declarar e isolar dependências explicitamente
✘ Nunca depender da existência implícita de todas as ferramentas
do sistema
Mesmo que um recurso esteja sempre presente na maior parte dos
sistemas, não existe garantia de que ele sempre vai estar presente
ou que sera compatível: vendorize
14. 12factor - III. Config
Armazenar configurações no environment
✘ Configurações nunca devem estar armazenadas na forma de
constantes no código. Isso viola o twelve-factor
Elas podem variar entre os environments (staging, production e
developer) de uma mesma aplicação, o código não vai variar com a
mesma frequência.
15. 12factor - III. Config
Armazenar configurações no environment
Melhor forma de saber se esta seguindo essa premissa é se o código
da aplicação poderia ser tornar publico a qualquer momento, sem
comprometer a segurança.
16. 12factor - III. Config
Armazenar configurações no environment
Configurações internas da aplicação não são consideradas "config",
"config/routes.rb" ou código xml de ORM são exemplos de
configuração interna.
17. 12factor - III. Config
Armazenar configurações no environment
✓ Twelve-factor apps usam variáveis de ambiente para armazenar
configurações:
Fácil de alterar entre ambientes;
Há poucas chances das configurações irem parar no codebase;
Não é preciso nenhum sistema adicional de configuração;
19. 12factor - III. Config
Armazenar configurações no environment
Modelos: Grupos nomeados (também conhecidos como
"environments") vs. Variáveis de ambiente
20. 12factor - IV. Backing Services
Tratar backing services como recursos conectados
Qualquer que seja o backing service consumido via rede e faça
parte da operação normal do sistema, exemplos:
Datastores: MySQL ou MongoDB
Messaging/Queueing: RabbitMQ ou Beanstalkd
SMTP: Postfix
Caching: Memcached ou Redis
21. 12factor - IV. Backing Services
Tratar backing services como recursos conectados
Mas não somente serviços que em geral são resposabilidade do ops
enginner, também fazem parte serviços de terceiros:
SMTP services: Postmark ou Sendgrid
Metrics-gathering services: New Relic ou Loggly
Binary asset services: Amazon S3 ou Azure Store
API's: Twitter, Google Maps ou Last.fm
22. 12factor - IV. Backing Services
Tratar backing services como recursos conectados
✓ Não é feita distinção entre backing services locais ou de terceiros
Uma vez que o resource foi anexado a aplicação, seu acesso se da
por URL ou localizador/credencias adicionados ao config.
23. 12factor - IV. Backing Services
Tratar backing services como recursos conectados
✓ Facilitar o processo de troca entre versões de resources, sem a
necessidade de alteração ou deploy de um novo código
24. 12factor - IV. Backing Services
Tratar backing services como recursos conectados
Cada backing service é um resource diferente. Por exemplo um
MySQL é um resource, dois MySQLs (usados em redundância) são
qualificados como dois resources diferentes;
25.
26. V. Build, release, run
Separar os estágios de build e execução
O codebase é transformado em deploy em três estágios:
27. V. Build, release, run
Separar os estágios de build e execução
Build stage: É um processo de transformação, que transforma
código do respositório em uma versão executável, nesta fase é feita
a busca pela versão especificada do código, vendorização das
dependências e compilação de assets.
28. V. Build, release, run
Separar os estágios de build e execução
Release stage: Nesta fase o produto da fase build é empacotado
juntamente com o as informações do config, um pacote pronto para
execução é criado
29. V. Build, release, run
Separar os estágios de build e execução
Run stage: também conhecido com runtime, nesta fase o pacote
gerado no release é executado no ambiente de execução.
31. V. Build, release, run
Separar os estágios de build e execução
Twelve-factor define uma separação estrita entre as fases: build,
release e run. Por exemplo: não é possível alterar o código da
aplicação na fase de runtime.
32. V. Build, release, run
Separar os estágios de build e execução
O processo de build é disparado pela ferramenta de deploy, que
deve ser capaz de, dentre outras coisas, executar processo de
rollback e atualização do código
Cada release deve ter um ID único, e uma vez criada não pode ser
modificada;
A fase de build tende a ser a fase mais complexa, em geral é onde
as falhas acontecem e são reportadas ao desenvolvedor
imediatamente
37. 12factor - VII. Port binding
Exportar serviços via port binding
Nenhum webserver é injetado no environment de execução, as
aplicações devem ser auto-contidas, elas devem expor o serviço http
dando binding em uma porta e aguardar por requests nesta porta.
38. 12factor - VII. Port binding
Exportar serviços via port binding
Não apenas serviços http devem ser espostos dessa forma, um
serviço com ejabberd ou redis devem fazer o mesmo
39. 12factor - VII. Port binding
Exportar serviços via port binding
Observe que um serviço assim exposto pode ser tornar um backing
service para outras aplicações
43. 12factor - IX. Disposability
Maximizar a robustez com fast startup e graceful shutdown
O processo de graceful shutdown deve ocorrer normalmente
quando o processo recebe um SIGTERM. Para processos http por
exemplo, ele deve parar de esperar por novas requisições, finalizar
as requisições atuais, fechar todos os streams em andamento e
finalizar o processo
45. 12factor - X. Dev/prod parity
Procure tornar os ambientes de development, staging e
production o mais similar possível
Evite os gaps:
Gap de time: Desenvolver código por dias, semanas ou até
mesmo por meses só depois para por em produção;
Gap pessoal: Desenvolvedor coda, ops enginners fazem deploy;
Gap de ferramentas: Desenvolve localmente com Nginx, SQLite
sobre OS X, e coloca em produção sobre: Apache, MySQL e Linux;
47. 12factor - X. Dev/prod parity
Procure tornar os ambientes de development, staging e
production o mais similar possível
Como os gaps são evitados:
Gap de time: Após desenvolver um código o dev pode fazer o
deploy depois de algumas horas ou mesmo minutos;
Gap pessoal: Quem desenvolve faz deploy, e pode observar como
o código se comportou em produção;
Gap de ferramentas: mantendo o environment de produção e
desenvolvimento tão semelhante possível;
48. 12factor - X. Dev/prod parity
Procure tornar os ambientes de development, staging e
production o mais similar possível
✘ Divergências entre backing services talvez sejam um dos
principais pivos de problemas, e um dos mais complicados de
resolver.
✓ Porém o desenvolvedor twelve-factor resiste ao máximo utilizar
diferentes backing services para a mesma função entre os
environments
50. 12factor - XI. Logs
Trate logs como stream
Logs são uma parte muito importe de uma aplicação, porém é
comum o redirecionamento e amazenamento dos mesmos em
arquivos.
✘ Isso não deve acontecer, assim como no ambiente de
desenvolvimento, em geral, logs são visualizados na forma de
stream na saída padrão, o desenvolvedor twelve-factor não se
preocupa em encaminhar ou armazenar este stream.
51. 12factor - XI. Logs
Trate logs como stream
✓ Porém como logs são importantes, o sistema de execução deve
se preocupar em capturar e encaminhar os logs para algum serviço
que o desenvolvedor possa consultar depois.
Esse processo deve ser o menos impactante possível, seja em
processamento e comunicação da máquina onde a aplicação esta
sendo executada
52. 12factor - XI. Logs
Trate logs como stream
Backing services para análise dos logs e geração de métricas podem
ser adicionados para completar o processo.
53. 12factor - XII. Admin process
Tarefas de administração e manutenção devem ser on-off
processes
Além dos processo normais de execução das aplicações, muitas
vezes o desenvolvedor pode precisar executar tarefas de
manutenção e administração, como:
Rodar migrações de banco de dados;
Acessar um console para execução de códigos aleatórios;
Rodar algum script de correção de dados;
59. Openruko - Arquitetura
Api Server - openruko/apiserver
Componente central do Openruko, feito em node.js + postgresql,
seu trabalho é divido em duas partes:
API Pública (heroku compatível): Responsável por toda interação
com o desenvolvedor, que em geral é feita por meio da
ferramenta de CLI.
API Privada: Por meio da qual todos os outros componentes
internos obtem informações sobre as fases de: build, release e
run.
60. Openruko - Arquitetura
Gitmouth - openruko/gitmouth
Desenvolvido em python com auxilio da biblioteca twisted, é
responsável pelo balanceamento de carga das chamadas ssh/git.
Alternativas em desenvolvimento:
azukiapp/plowman
Filirom1/gogit
61. Openruko - Arquitetura
Dynohost - openruko/dynohost
Serviço desenvolvido em node.js + LXC, seu trabalho se divide em
quatro partes:
62. Container constructor: Através de scripts bash constroi os
arquivos de configuração e ponto de montagem / do container
LXC Wrapper: Uma vez com arquivos de configuração e o ponto
de montagem estabelecido, gerencia a execução dos containers
LXC;
Deploy: Antes de executar um container baixa o slug a ser
executado e monta este na pasta /app, e por fim starta o
container para execução do rukorun
Dyno gestor: Constroi um canal de comunicação com o container
(dyno) por meio de sockets;
63. Openruko - Arquitetura
Rukorun - openruko/rukorun
Feito em node.js, esse é um simples script que faz a ponte do
container com o mundo, através de sockets estabelecidos pelo
Dynohost
É atráves deste script que aplicação e inicializada pelo dynohost, ou
mesmo coisas como um console podem ser estabelecidas com o
container
64. Openruko - Arquitetura
Httprouting - openruko/httprouting
Balanceador de carga para chamadas http, desenvolvido em node.js
é o responsável por tratar todas as chamadas http vindas com
destino as aplicações em execução no openruko.
Atualmente suporta websockets, e se conecta direto ao postgresql
para obter dados de resolução e dynos.
Alternativas:
dotcloud/hipache
samalba/hipache-nginx
65. Openruko - Arquitetura
Logplex - openruko/logplex
Syslog distribuído, este serviço desenvolvido em node.js é uma
simplificação compatível do serviço de mesmo nome do heroku.