Automatizando a criação de um ambiente de desenvolvimento com Docker + Bash Script + Portainer
Thiago Moraes
Posted on August 29, 2020
Introdução
Facilidade, automatização e velocidade são coisas que nós, desenvolvedores, amamos. Eu trabalho em muitos projetos, com diversas ferramentas, como MongoDb, MySQL, RabbitMQ, Redis, dentre outras e muitas vezes fica difícil gerenciar tudo isso (ao migrar de máquina, por exemplo). A ideia hoje é mostrar uma forma simples e eficiente de ter todas suas ferramentas centralizadas e organizadas utilizando Docker e Bash Script (quem me conhece sabe que eu amo Bash Script <3) e também o gerenciamento das mesmas através do Portainer, uma interface gráfica para o Docker. Lembrando que deixarei todos os exemplos no github ao final do artigo. E como a ideia é ser ágil, esse tutorial vai passar na velocidade da luz. Então vamos nessa!
Pré-requisitos
- Docker
- Docker Compose
Criando nossos serviços
Primeiramente, criaremos um arquivo do Docker Compose, que irá conter a descrição de todos os nossos serviços. Aqui utilizarei os serviços citados no inicio (Mysql, MongoDb, RabbitMQ e Redis), além do Portainer, que vai nos dar uma visão e gerenciamento de todos os serviços. Você também pode adicionar os serviços da sua preferência.
Esse será nosso arquivo de configuração:
#docker-compose.yml
version: '3.4'
x-logging:
&default-logging
options:
max-size: '10m'
max-file: '1'
driver: json-file
services:
portainer:
image: portainer/portainer
container_name: portainer
restart: on-failure
ports:
- "9000:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${VOLUMES_DIR}/portainer:/data
logging: *default-logging
mysql:
image: mysql:5.7
command: mysqld --sql_mode='NO_ENGINE_SUBSTITUTION'
restart: on-failure
environment:
- MYSQL_ROOT_PASSWORD=toor
- DEFAULT_TIME_ZONE=America/Sao_Paulo
- TZ=America/Sao_Paulo
volumes:
- ${VOLUMES_DIR}/mysql:/var/lib/mysql
container_name: mysql
ports:
- 3306:3306
logging: *default-logging
redis:
image: redis:latest
container_name: redis
ports:
- "6379:6379"
logging: *default-logging
mongo:
image: mongo:latest
volumes:
- ${VOLUMES_DIR}/mongodb:/data/db
container_name: mongo
ports:
- 27017:27017
logging: *default-logging
rabbitmq:
image: rabbitmq:3-management
container_name: rabbitmq
ports:
- "15672:15672"
- "5672:5672"
volumes:
- ${VOLUMES_DIR}/rabbitmq:/var/lib/rabbitmq
environment:
- RABBITMQ_ERLANG_COOKIE=cookie
- RABBITMQ_DEFAULT_USER=root
- RABBITMQ_DEFAULT_PASS=toor
logging: *default-logging
Aqui vale destacar dois pontos importantes. O primeiro é que mapeamos os volumes dos serviços utilizando uma variável que vai definir onde os dados persistentes dos containers serão armazenados na máquina host. Essa configuração só é necessária se você desejar persistir a informação, caso contrário, cada vez que você refizer o build ou remover a imagem, você perderá todos os dados contidos nelas.
O segundo é a utilização de uma política para definir o tamanho máximo do armazenamento de logs em cada container. É importante caso ocorra alguma situação inesperada, como um erro de algum container que fica acumulando logs, podendo levar você até mesmo a ficar sem storage na máquina.
Rodando os serviços
Agora que já temos o nosso arquivo de configuração dos serviços, vamos automatizar as ações que iremos utilizar com Bash Script, fazendo uma pequena abstração de alguns comandos. Nosso script ficará dessa forma:
#script.sh
export VOLUMES_DIR=/var/volumes/docker
up() {
docker-compose up --build -d $1
}
logs() {
docker-compose logs -f $1
}
down() {
docker-compose down
}
stop() {
docker-compose stop $1
}
rmi() {
docker rmi $(docker images -f dangling=true -q) --force
}
$*
Rodando todos os serviços:
bash script.sh up
Rodando um serviços específico
bash script.sh up <service name>
Parando todos os serviços:
bash script.sh down
Parando um serviço específico:
bash script.sh stop <service name>
Acessando os logs de todos os serviços:
bash script.sh logs
Acessando os logs de um serviço específico:
bash script.sh logs <service name>
Adicionei um comando extra muito útil também que remove todas as imagens não utilizadas (se você usa Docker no dia-a-dia e nunca fez uma limpeza, ficará surpreso com o quanto de storage será liberado ao rodar esse comando):
bash script.sh rmi
Gerenciando os serviços
Bom, levando em consideração que subimos todos os serviços rodando o primeiro comando, vamos explorar um pouco o Portainer como um meio de gerenciar nossos serviços. O Portainer é uma interface gráfica para o Docker que permite ver containers, volumes, rodar imagens e muito mais. De acordo com nosso arquivo de instalação, ele deve estar disponível na porta 9000. Acessando 'http://localhost:9000' teremos acesso a interface do mesmo. No primeiro acesso, você deve criar uma senha para administrador.
Em seguida escolha a opção Local e clique em connect, para que o portainer possa se conectar aos seus containers locais.
Acessando o nosso endpoint criado, no menu Containers, temos acesso aos nossos serviços (os que estão rodando e os que estão parados também).
Clicando em um Container, teremos um menu com algumas opções, como logs, stats (que mostra dados sobre uso de cpu, memória, etc) e até mesmo acesso ao terminal dentro do container. É possível acessar algumas dessas opções através do menu rápido na propria tela que lista os containers.
Outra opção interessante é a App Templates, onde você tem uma variedade enorme de serviços e é possível fazer deploy com apenas um clique.
Como prometi que seria um artigo rápido, vamos ficar por aqui, mas vale muito a pena explorar outras opções, a interface é muito rica e intuitiva (merecia um artigo só pra ele). Todos os exemplos citados acima estão no github:
https://github.com/thiagomr/docker-utils
Conclusão
Hoje vimos como é simples e rápido ter um ambiente de desenvolvimento rodando apenas um comando e também uma forma visual de gerenciar o mesmo. Se você curtiu essa dica, dá um like, star no github e me segue no twitter para novidades e deixe aqui seu comentário. Feedbacks são mais que bem-vindos.
Grande abraço e até a próxima!
Posted on August 29, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.