Compondo uma aplicação com o Docker Compose

(Last Updated On: 14 de dezembro de 2017)

Estou com um container com uma aplicação PHP que se comunica com um banco de dados para efetuar alguns testes antes de ir para produção. Então, fui rodar o container, porém quando realizei o login me deparei com os seguintes erros:

A aplicação precisa de um banco de dados para rodar, como estamos utilizando o Docker, o jeito mais simples é subir outro container para representar o banco de dados. Mas por que não consigo fazer esses dois containers se comunicarem?

Conhecendo o Docker Compose

Para realizar a comunicação entre os containers, podemos utilizar uma ferramenta do próprio Docker chamada de Docker Compose. Com o Docker Compose podemos criar um arquivo e especificar as propriedades de cada container, como comandos, variáveis de ambiente,…

O Docker Compose já vem instalado por padrão quando instalamos o Docker no Windows ou no Mac, porém no Linux, precisamos realizar sua instalação.

Com o docker composer instalado, podemos dizer como queremos subir esses dois containers.

O arquivo YAML

Queremos falar para o Docker Compose como ele deve subir nosso containers, para isso, temos que criar um arquivo com a extensão YAML, neste caso, vou chamar de aplicacao.yaml.

A primeira coisa que devemos informar no arquivo é a versão do Docker Compose que estamos utilizando. Nesse caso, vou utilizar a versão 3.4 que é a mais recente.


version: '3.4'

Já dissemos qual versão estamos utilizando, agora precisamos indicar quais containers vamos criar, ou seja, quais serão os serviços (services) que o Compose vai subir.

Temos dois serviços que queremos subir, o banco de dados e a aplicação web. Então vamos começar especificando o serviço da nossa aplicação.

Neste caso, vou nomeá-la como app.


version: '3.4'
services:
    app:

Nossa aplicação está baseada na imagem (image) yuri/web, e podemos dar o nome (container_name) de app por exemplo:


version: '3.4'
services:
    app:
    image: yuri/web
    container_name: app

Nós precisamos também mapear as portas (ports) que nosso container vai usar. Neste caso, vou mapear a porta 8080 do nosso host, para a porta 80 do nosso container:


version: '3.4'
services:
    app:
        image: yuri/web
        container_name: app
        ports:
          - 8080:80

Bom, nosso container depende (depends_on) de um banco de dados, então vamos falar isso em nosso arquivo do Compose. Neste caso, vou falar que ele depende do serviço db:


version: '3.4'
services:
    app:
        image: yuri/web
        container_name: app
        ports:
          - 8080:80
        depends_on:
          - db

Mas o que é esse db?

db é o nome do nosso serviço de banco de dados. Ele nada mais é do que outro container, logo, podemos especificar no mesmo arquivo .yaml do serviço de aplicação.


version: '3.4'
services:
    app:
        image: yuri/web
        container_name: app
        ports:
          - 8080:80
        depends_on:
          - db
    db:

Se ele também é um container, então é igualmente baseado em uma imagem. Neste caso, nosso banco de dados será baseado na imagem do MySQL. E vou nomeá-lo de db


#Restante da configuração
db:
    image: mysql
    container_name: db

Mas como conseguiremos acessar nosso banco de dados? Ele precisa de um usuário, correto?

Quando a imagem do MySQL está subindo como um container, ela lê algumas variáveis de ambiente (environment). Essas variáveis definem algumas informações como usuário, senha, entre outras. Podemos especificar essas variáveis no próprio arquivo do Compose.

Neste caso, por se tratar de um teste, vou utilizar o usuário **root **(MYSQL_USER=root) e não vou alocar nenhuma senha (MYSQL_ALLOW_EMPTY_PASSWORD=yes). Mas lembrando, nunca devemos usar isso em produção por motivos de segurança:


#Restante da configuração
db:
    image: mysql
    container_name: db
    environment:
      - MYSQL_USER=root
      - MYSQL_ALLOW_EMPTY_PASSWORD=yes

Também podemos falar para o Compose criar o banco de dados automaticamente quando ele subir o container. Neste caso, vou criar o banco de dados loja:


#Restante da configuração
db:
    image: mysql
    container_name: db
    environment:
      - MYSQL_USER=root
      - MYSQL_ALLOW_EMPTY_PASSWORD=yes
      - MYSQL_DATABASE=loja

Pronto! Configurações terminadas. E agora como conseguimos fazer o Docker subir esses dois containers?

No terminal conseguimos falar para o docker-compose baseado no arquivo (-f, file) aplicacao.yaml, subir (up) os containers especificados:

Aplicação rodando! Vamos tentar fazer login e ver se obtemos sucesso:

Hum… não obtemos sucesso. 🙁 Será que o Docker Compose não criou nosso banco de dados?

Na verdade ele criou! Porém, como não existem tabelas, a aplicação não funcionou.

Para resolver esse problema basta falar para o docker executar (exec) um terminal (-t) interativo (-i) com o nosso container, db no caso. Mas qual terminal vamos executar?

Neste caso, podemos executar o bash:

docker exec -it db bash

Agora, basta executar o mysql com o usuário (-u) root que teremos acesso ao banco de dados.

Nele, nós podemos criar nossas tabelas.

Agora se tentarmos logar em nossa aplicação, obteremos sucesso:

Para saber mais

Neste caso, as informações contidas no container do banco de dados não são persistidas, ou seja, caso o container pare de funcionar, essas informações serão perdidas.

Caso for necessário persistir essas informações, podemos criar um volume entre nossa máquina local e o container. Dessa forma, todas as informações salvas no container serão salvas na nossa máquina local.

Neste caso utilizamos o Docker Compose para subir nossos dois containers e realizar a comunicação entre eles.

Porém nós podíamos utilizar o próprio Docker para isso. Basta criar uma rede (network) e atribuir nossos container a ela. Contudo, com o Docker Compose, temos mais facilidade para a orquestração desses containers.

Aqui na Alura temos um curso sobre Docker que nos mostra como utilizar o Docker Compose, como criar nossas imagens, entre muitas outras coisas.

Ah, é! Não deixe de compartilhar conosco o que achou do Docker Compose nos comentários. 🙂

FIQUE POR DENTRO

Próximo ArtigoQuando usar carrossel em um site?