Automatizando a criação de um ambiente de desenvolvimento com Docker + Bash Script + Portainer

thiagomr

Thiago Moraes

Posted on August 29, 2020

Automatizando a criação de um ambiente de desenvolvimento com Docker + Bash Script + Portainer

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.

login

Em seguida escolha a opção Local e clique em connect, para que o portainer possa se conectar aos seus containers locais.

connect

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).

containers

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.

detail

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.

templates

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!

💖 💪 🙅 🚩
thiagomr
Thiago Moraes

Posted on August 29, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related