Recentemente, a nossa equipe participou do Circuito das Estações Adidas. E como não poderia deixar de ser, eu estava lá. A questão é que eu esperava ter um desempenho muito melhor na corrida, mas o que aconteceu foi que eu vi que correr no asfalto é bem diferente de correr na esteira. E o que isso tem a ver com liberar uma versão em produção? Vamos chegar lá.
A maioria das pessoas quando quer ter um bom desempenho em uma corrida de rua, treina em uma academia. Nesse ambiente, você corre em uma esteira onde é possível controlar a velocidade que deseja correr, e em algumas é possível até controlar a inclinação do terreno. Depois de um período de treinamento, você já é capaz de saber como seu corpo responde ao esforço realizado. Sabe se pode correr mais rápido ou mais devagar e tudo isso é controlado por você através do visor da esteira. Quando passamos para o asfalto, todo esse controle some. Você não sabe se o terreno é liso ou não. Você não sabe a velocidade exata em que está correndo e pode ser que esses fatores atrapalhem o seu desempenho e ele seja bem pior do que aquele que você tem na academia.
O mesmo acontece com sistemas quando estão no ambiente de desenvolvimento e passam para o ambiente de produção – ou homologação. Os desenvolvedores constroem as funcionalidades de um sistema no ambiente de desenvolvimento. Elas estão acostumadas a funcionar ali e todos os problemas que foram possíveis de serem encontrados, já foram resolvidos. O sistema está adaptado para rodar ali e o ambiente está sempre configurado de acordo com a última versão do sistema, já que é nele que as evoluções acontecem.
Quando chega a hora de liberar versão em produção, a história muda. Essa versão, que está funcionando perfeitamente no seu ambiente local, será transferida para um outro ambiente e será acessada por outros usuários. Isso pode e gerará situações inesperadas que terão de ser contornadas de forma rápida e eficiente, para que os usuários não tenham seu acesso ao sistema prejudicado. E por que isso acontece? Justamente por se tratar de um ambiente diferente, em um servidor diferente, com configurações e infraestrutura diferentes. Você não tem conhecimento suficiente desse ambiente, e de seus usuários, para saber que comportamento esperar do sistema quando a nova versão estiver lá. Por isso, o que podemos fazer é nos prevenir para evitar que problemas ocorram e, caso ocorram, seja possível se recuperar da forma mais rápida e melhor possível. Para isso, seguem algumas dicas:
- Simule o ambiente de produção no seu computador local: antes de liberar uma versão em outro ambiente, simule-o no seu computador de desenvolvimento. Tenha um servidor de aplicação, um banco de dados e qualquer outra infraestrutura necessária para o seu projeto separados, com as mesmas configurações e estruturas que existem no ambiente de produção. Muitas vezes, ao lançar uma nova versão, é preciso alterar uma configuração ou uma tabela do banco de dados. E, muitas vezes também, a gente esquece de realizar essa alteração no ambiente de destino. Testar a nova versão nesse ambiente simulado pode prevenir que problemas aconteçam no ambiente de produção.
- Mantenha um backup da versão que estava em produção: fazer um backup da versão que está atualmente em produção, antes de liberar a nova versão, é altamente recomendado. Essa estratégia evita problemas, como deixar o sistema fora do ar porque a nova versão teve erros na liberação e você não tem como recuperar o estado anterior rapidamente. Nesses casos, quando se tem um backup, retira-se rapidamente a nova versão do servidor e coloca-se a versão anterior novamente até que o problema ocorrido seja resolvido. Nunca pense que isso nunca acontecerá com você. Como dito acima, o ambiente de produção é um ambiente diferente e situações inesperadas podem ocorrer.
- Crie tags da versão que será liberada no controle de versão: por estar em um ambiente diferente e com usuários diferentes, é possível que bugs apareçam e dependendo da gravidade dos mesmos, talvez seja necessário corrigí-los para ontem. Se você criou uma tag da versão que acabou de ser liberada, será possível corrigí-la e liberá-la novamente sem enviar código relacionado a funcionalidades que ainda não estão prontas. No entanto, não se esqueça de replicar essa alteração no código de desenvolvimento. Se isso não for feito, novas versões voltarão a apresentar o mesmo problema e isso gerará retrabalho para a equipe.
- Mantenha um arquivo com os scripts das alterações realizadas no banco de dados: não é sempre, mas às vezes é necessário alterar a estrutura do banco de dados ao fazer uma alteração ou desenvolver uma nova funcionalidade. Se for de costume da equipe manter um arquivo com os scripts de alteração dessa estrutura, identificando que alteração corresponde a que versão, fica mais fácil identificar o que deve ser alterado no banco utilizado em produção. Uma boa prática é fazer com que os scripts desse arquivo estejam genéricos, ou seja, as consultas não devem ser feitas considerando valores específicos. Lembrem-se que mesmo que os dados dos dois bancos sejam iguais, é possível que os ids, por exemplo, não sejam correspondentes. E, se no script as consultas dependerem deles, isso gerará um problemão. Além disso, essa prática ajuda nos casos em que se cria um novo banco de dados a partir do schema_create do início do projeto e é preciso ajustar sua estrutura para o estado atual do projeto.
- Mantenha um histórico das atualizações realizadas na configuração do ambiente: similar ao item acima, é sempre bom manter um histórico das atualizações realizadas na configuração do ambiente. Isso permite que seja criado uma espécie de tutorial para ajudar na configuração de um novo ambiente.
Essas são dicas simples, porém muito eficazes. Assim como quando corremos no asfalto, não temos como prever exatamente qual será o comportamento do sistema quando ele estiver em um ambiente no qual ele não está acostumado a funcionar. Adicionar esses passos ao seu processo de deploy pode ajudar, e muito, a evitar problemas inesperados.
Olá Eduardo,
Muito bom realmente esse ponto que você levantou. De fato, se você consegue integrar ao seu projeto uma ferramenta que faça isso automaticamente, facilita muito o processo e diminui drasticamente a possiblidade de algum passo ser esquecido. De qualquer forma, acredito que esses 5 passos, mesmo feitos manualmente, podem ajudar aqueles que ainda não possuem essa infraestrutura. O Rodrigo, no comentário dele, citou algumas ferramentas que podem ajudar nesse processo de automatização. Você conhece alguma para nos indicar?
Como disse o Eduardo, com certeza ferramentas de automatização são muito importantes. Acho que integração contínua já ajuda bastante em parte desse processo, outra seria o gerenciamento de atualizações do banco de dados, que existem algumas ferramentas interessantes baseadas nas Migrations do Ruby on Rails, como migrate4j e flyway.
Resumindo, use uma estrutura que forneça tudo isso automaticamente, porque se não você vai esquecer de algum desses passos.