Quando modelamos uma imagem Docker podemos nos deparar com a necessidade de gerenciar serviços internos necessários à nossa aplicação ou mesmo modelá-la como serviço. Nosso reflexo inicial seria usar o systemd, porém para tanto precisaríamos executar o container em modo privilegiado além de montar uma série de volumes de sistema (detalhes). Como alternativa, é uma prática bem comum usar o supervisord
pois ele é bastante simples e eficaz para a grande maioria dos casos sobretudo para containerização. Neste post eu vou te mostrar como configurar uma aplicação para execução como serviço dentro de um container Docker usando o supervisord.
Supervisord
Primeiro vamos configurar nossa aplicação myapp para funcionar como um serviço do supervisord. Isso é feito por meio de um arquivo de configuração no formato INI que salvaremos com o nome myapp.conf. Segue abaixo seu conteúdo e a explicação de cada opção:
[program:myapp]
command=/usr/bin/myapp
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
redirect_stderr=true
[program:myapp] -> seção de configuração do serviço. No nosso caso, se trata de uma aplicação (program) com nome myapp.
command=/usr/bin/myapp -> informa o comando que representa o serviço/aplicação (usado para iniciar, parar, monitorar etc)
autostart/autorestart -> configura o início e reinício automático do nosso aplicativo.
stdout_logfile=/dev/stdout -> configura a saída padrão da aplicação para o /dev/stdout. Dessa forma, o Docker irá capturar toda a saída do nosso serviço.
stdout_logfile_maxbytes=0 -> desabilita o log rotate do arquivo de saída (como usamos o stdout e o docker para tratar o log, necessitamos desabilitar para evitar problemas)
redirect_stderr=true -> redireciona a saída de erro para a saída padrão. Equivalente a fazer um “2>&1” no bash.
Docker
A modelagem da imagem Docker é bem particular pois pode ser feita de várias maneiras diferentes. No nosso exemplo, para facilitar, usamos a imagem ubuntu padrão. Segue abaixo o Dockerfile:
FROM ubuntu
RUN apt-get update && apt-get install supervisor -y
COPY myapp.conf /etc/supervisor/conf.d
COPY myapp /usr/bin/myapp
ENTRYPOINT ["supervisord", "--nodaemon"]
Basicamente, instalamos o supervisord que já vem no repositório padrão (RUN). Logo após copiamos o arquivo myapp.conf criado na seção anterior para o local padrão /etc/supervisor/conf.d (COPY). Por fim, definimos o supervisord como o entrypoint do container (ENTRYPOINT). O parâmetro --nodaemon
serve para executá-lo em foreground, ou seja, não em segundo plano.
Conclusão
Usar o supervisord em conjunto com o Docker traz várias vantagens. Por exemplo, podemos reiniciar a aplicação ou seus componentes sem necessariamente reiniciar o container Docker. Bastaria executar, por exemplo, supervisorctl restart myapp
no container. Isso agiliza enormemente o desenvolvimento da aplicação e debugagem em produção. Além disso, o supervisord pode reiniciar a aplicação automaticamente em caso de falhas.
Espero que tenham gostado da dica. Fique à vontade para tirar suas dúvidas nos nossos comentários. Até a próxima.