Seguindo a lista do modelo 12factor, temos “Serviços de Apoio” como quarta boa prática – para contextualizar, serviços de apoio é qualquer aplicação que seu código consome para operar corretamente. Por exemplo, banco de dados, serviço de mensagens e afins.
Com objetivo de evitar que seu código seja demasiadamente dependente de uma determinada infraestrutura, essa boa prática indica que você, no momento da escrita do software, não faça distinção se o serviço é interno ou externo; ou seja, seu aplicativo deve estar pronto para receber parâmetros que farão a configuração do serviço correto e, assim, possibilitem o consumo de aplicações necessárias da solução proposta.
A aplicação exemplo sofreu algumas modificações para suportar essa boa prática:
from flask import Flask from redis import Redis import os host_run=os.environ.get('HOST_RUN', '0.0.0.0') debug=os.environ.get('DEBUG', 'True') host_redis=os.environ.get('HOST_REDIS', 'redis') port_redis=os.environ.get('PORT_REDIS', '6379') app = Flask(__name__) redis = Redis(host=host_redis, port=port_redis) @app.route('/') def hello(): redis.incr('hits') return 'Hello World! %s times.' % redis.get('hits') if __name__ == "__main__": app.run(host=host_run, debug=True)
Como você pode perceber no código acima, sua aplicação agora pode receber variáveis de ambiente para configurar o hostname e porta do serviço Redis, ou seja, nesse caso é possível configurar um host e porta da redis que você deseja conectar. E tudo isso pode, e deve, ser especificado no docker-compose.yml, que também passou por uma mudança para se adequar a essa nova boa prática:
version: "2" services: web: build: . ports: - "5000:5000" volumes: - .:/code labels: - 'app.environment=${ENV_APP}' environment: - HOST_RUN=${HOST_RUN} - DEBUG=${DEBUG} - PORT_REDIS=6379 - HOST_REDIS=redis redis: image: redis:3.2.1 volumes: - dados:/data labels: - 'app.environment=${ENV_APP}' volumes: dados: external: false
Como podemos observar nos códigos já explicados, a grande vantagem de se utilizar dessa boa prática é o fato da possibilidade de mudança de comportamento sem a necessidade de mudança do código. Mais uma vez é possível viabilizar que o mesmo código que foi construído em um momento, possa ser reutilizado de forma semelhante tanto no notebook do desenvolvedor, como no servidor de produção.
Fique atento para o armazenamento de segredos dentro do docker-compose.yml, pois esse arquivo será enviado para o repositório de controle de versão, ou seja, é importante pensar em outra estratégia de manutenção de segredos.
Uma estratégia possível é a manutenção de variáveis de ambiente no docker host e dessa forma você precisaria usar variáveis do tipo ${variavel} dentro do docker-compose.yml pra pode repassar essa configuração ou utilizar outro recurso mais avançado de gerenciamento de segredos.