O Docker Compose é uma ferramenta desenvolvida para facilitar e agilizar a utilização do Docker, com ele podemos criar e executar aplicações com múltiplos containers de forma fácil. É necessário ter o Docker para utilizarmos o Compose, ele está disponível em versões para Linux, Windows e MacOS.
Para manipular o Compose iremos manipular um arquivo YAML, que é um formato de serialização de dados de fácil visualização. Neste arquivo configuramos os serviços que queremos na nossa aplicação. Após a definição deste arquivo de configuração, utilizamos o Docker Compose para baixar as imagens, criar e iniciar todos os serviços descritos.
O Docker Compose é uma ótima ferramenta para os desenvolvedores. Pois, temos liberdade para decidir quais aplicativos vamos utilizar e mesmo em ambientes complexos com vários serviços, podemos criar e iniciá-los em questão de segundos. Assim, o desenvolvimento de software torna-se mais fácil e mais eficaz.
O Docker Compose tem diversos comandos para gerenciar todos as etapas da aplicação:
➡ Iniciar, parar e reconstruir serviços;
➡ Ver os status dos serviços em execução;
➡ Transmitir a saída de logs para monitorar;
➡ Executar comandos num serviço;
Benefícios:
➡ Você monta e sobe todo o seu ambiente com um único comando;
➡ Executando os serviços pelo Compose, você não precisa manter diversos softwares na máquina local;
➡ Todo ambiente pode ser recriado e replicado facilmente, ajudando na colaboração de um projeto com outras pessoas;
➡ É fácil de compreender e manipular;
Vamos fazer a instalação no Linux, assim com os passos abaixo, iremos instalar o Docker Compose de acordo com a versão do seu Sistema, lembrando que precisa do Docker instalado para funcionar:
# curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# chmod 755 /usr/local/bin/docker-compose
Podemos verificar se está instalado corretamente executando o comando abaixo para visualizar a versão:
# docker-compose --version
Para utilizarmos o autocompletar dos comandos, temos que adicionar o script no bash com o comando:
# curl -L https://raw.githubusercontent.com/docker/compose/1.17.0/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
Vamos iniciar a criação do nosso arquivo YAML com um exemplo simples, devemos seguir alguns passos para montar nosso ambiente:
➡ Definir os serviços e a relação entre eles;
➡ Criar um arquivo docker-compose.yml com as definições dos serviços;
➡ Iniciar todos os serviços com um único comando;
Para organizar e facilitar a manutenção de nossos ambientes, vamos criar um diretório para armazenar nossos projetos:
# mkdir compose && cd compose
Dentro do diretório compose criaremos outro diretório que será o nosso primeiro ambiente:
# mkdir compose-nginx-php && cd compose-nginx-php
Obs.: Todos os arquivos criados estão disponíveis no GitHub: Linux Web Compose.
Todos os serviços da nossa aplicação serão definidos dentro de um arquivo chamado “docker-compose.yml“, também vamos criar alguns arquivos de configuração para o bom funcionamento do nosso exemplo.
Vamos criar nosso arquivo docker-compose.yml, com 2 serviços distintos:
web: Será um container com o servidor web Nginx.
php: Será um container com o serviço PHP-FPM.
Lembrando que o Nginx não possui módulo do PHP (como o Apache), ele faz uso de FastCGI (API), por isso vamos utilizar o PHP-FPM que é independente do servidor web. Abaixo temos o script completo:
# vim docker-compose.yml
web:
image: nginx:latest
ports:
- "8000:80"
volumes:
- ./www:/var/www/html
- ./default.conf:/etc/nginx/conf.d/default.conf
links:
- php
php:
image: php:7-fpm
volumes:
- ./www:/var/www/html
Explicando o arquivo docker-compose.yml:
web: e php:
Definimos os nomes dos serviços pelos quais serão conhecidos dentro do nosso ambiente;
image:
Definimos quais imagens devem utilizar na criação dos containers;
ports:
Definimos a porta redirecionada do host com a porta exposta do container;
volumes:
Mapeamos volumes para uma pasta local, assim podemos adicionar arquivos ao nosso projeto, evitando a perda na reconstrução do ambiente.
No caso do serviço web, criamos uma pasta chamada www, dentro da pasta do projeto, que será mapeada com a pasta /var/www/html do Nginx. Assim, podemos adicionar nossos scripts (html, php, etc…) que serão interpretados pelo webserver. Também mapeamos o arquivo de configuração default.conf do Nginx.
No caso do serviço php, também mapeamos a pasta www, pois ele precisará ter acesso para interpretar os scripts PHP.
links:
Faz a ligação (/etc/hosts) entre os dois serviços, para que eles possam se comunicar.
Para finalizar, vamos precisar habilitar o PHP no Nginx, para isso vamos criar na raiz o arquivo default.conf que contém as configurações necessárias para o funcionamento. A linha & fastcgi_pass php:9000, indica ao Nginx que ele deve utilizar como interpretador PHP o serviço chamado php na porta 9000 (padrão da imagem php:7-fpm):
# vim default.conf
server {
listen 80;
index index.php index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
Pronto, já podemos executar nosso ambiente! Para iniciar o processo de criação utilizamos o comando abaixo:
# docker-compose up
Este comando irá verificar a sintaxe do arquivo e se encarregará de baixar as imagens e criar todos os serviços da forma que definimos. Ao término do processo ele irá mostrar no console os logs dos serviços em execução. Para interromper o ambiente, tecle Ctrl + C.
Caso queira deixar o console livre, podemos executar o comando em segundo plano, para isso use o parâmetro -d:
# docker-compose up -d
No console podemos verificar o status dos serviços que acabamos de criar executando o comando:
Na imagem podemos ver algumas informações:
Name: Nome do container. Como não definimos no arquivo ele é escolhido pelo Compose.
Command: Comando executado dentro do container.
State: Estado do serviço, Up indica que está em execução, quando interrompido exibe Exit.
Ports: Exibe portas expostas nos containers e porta redirecionadas.
Agora já podemos acessar o servidor, pelo browser. Você poderá acessar pelo localhost ou IP da máquina onde está configurado o Docker Compose, na porta 8000. No caso utilizo o nome do servidor num DNS.
Se tentarmos acessar, iremos receber uma mensagem “403 Forbidden” do Nginx.
Isso ocorre, pois não criamos nenhuma página index dentro da pasta www do nosso ambiente. Para podermos testar melhor, vamos criar um arquivo index.php e acessar no browser novamente, para criar execute no terminal:
Pronto, nosso ambiente está funcionando. Todos os scripts da pasta www serão mantidos, mesmo se você derrubar os containers do Docker Compose.
Se quisermos derrubar nossos serviços, executamos o comando:
# docker-compose down
Se quiser interromper todos os serviços que estão em execução, use:
# docker-compose stop
Para iniciar os serviços que estão parados usamos o comando:
# docker-compose start
Caso seja preciso reiniciar todos eles, podemos executar o comando:
# docker-compose restart
Para visualizar a saída dos logs dos containers, podemos executar:
# docker-compose logs -f
Vamos criar um ambiente mais completo, contendo além do que já foi criado no exemplo anterior (Nginx e PHP), também vamos adicionar o banco MySql e phpMyAdmin para administrá-lo.
Para isso vamos criar no diretório compose uma pasta que conterá o nosso segundo ambiente:
# mkdir compose-nginx-php-mysql && cd compose-nginx-php-mysql
Vamos criar nosso arquivo docker-compose.yml, com os 4 serviços:
web: Container com o servidor web Nginx.
php: Container com o serviço PHP-FPM.
db: Container com o banco de dados MySql.
admin: Container com o phpMyAdmin.
# vim docker-compose.yml
version: '3.4'
services:
web:
image: nginx:latest
container_name: web
depends_on:
- php
ports:
- "8000:80"
volumes:
- ./www:/var/www/html
- ./default.conf:/etc/nginx/conf.d/default.conf
php:
build:
context: .
dockerfile: Dockerfile
image: php-mysql
container_name: php
volumes:
- ./www:/var/www/html
db:
image: mysql:5.7
container_name: db
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mysql
volumes:
- ./data:/var/lib/mysql
admin:
image: phpmyadmin/phpmyadmin
container_name: admin
depends_on:
- db
environment:
- PMA_HOST = db
ports:
- 8080:80
Explicando o docker-compose.yml:
A partir da versão 2 do Docker Compose, foram adicionadas novas funcionalidades, uma delas foi a opção services, que permite que todos os serviços se enxerguem dentro da aplicação, sem a necessidade de utilizar a opção links. No nosso exemplo deixamos o arquivo com version 3.4.
Serviço web:
O serviço web não tem muita diferença em relação ao exemplo anterior. Apenas adicionamos a opção container_name que permite definir um nome para o container e a opção depends_on que inicia um serviço em ordem de dependência, no nosso caso, o serviço php será iniciado antes do web.
Podemos copiar o arquivo default.conf do exemplo anterior para a pasta desse ambiente, pois não precisamos fazer nenhuma alteração.
Serviço php:
No serviço php iremos criar uma imagem personalizada utilizando um (Dockerfile)[https://www.linuxnaweb.com/docker-gerenciamento-avancado-de-recursos/] para adicionar o pacote pdo_mysql para acessar o banco de dados MySql.
A opção build indica que iremos criar uma imagem, a opção context indica o diretório que se encontra o arquivo e a opção dockerfile diz qual é o nome do arquivo. Para finalizar a opção image indica o nome que terá a imagem, no caso php-mysql.
O arquivo Dockerfile terá como base a imagem do php:7.2-fpm e adicionaremos o pdo_mysql com a linha RUN. Veja como fica o arquivo:
# vim Dockerfile
FROM php:7.2-fpm
Maintainer Cesar Gaspar <rasec.rapsag@gmail.com>
RUN apt-get update && \
apt-get install -y --no-install-recommends && \
docker-php-ext-install pdo_mysql && \
apt-get clean
Serviço db:
No serviço db estamos criando um container com a imagem do mysql na versão 5.7. Expomos a porta 3306 para que possamos acessar por qualquer interface (console ou gráfica).
Definimos as variáveis de ambiente MYSQL_ROOT_PASSWORD para senha usuário root e MYSQL_DATABASE para o nome do banco.
Para preservar os dados, mapeamos uma pasta chamada data no diretório do projeto, assim podemos recriar o serviço de banco de dados sem perder as informações já armazenadas.
Serviço admin:
No serviço admin estamos criando um container com a imagem do phpmyadmin que já tem as configurações necessárias para acessarmos a interface web do phpMyAdmin. Expomos a porta 8080 para acesso pelo browser.
Definimos a variável de ambiente PMA_HOST com o nome do serviço com o mysql. E com o depends_on informamos que o serviço deverá iniciar após o db.
Pronto, contudo configurado podemos iniciar nosso ambiente com o comando:
# docker-compose up -d
Verificando o status dos serviços que criamos para nosso projeto:
# docker-compose ps
Perceba que os nomes dos serviços aparecem como foram definidos pela opção container_name.
Agora a estrutura de pastas e arquivos ficou assim:
Temos a pasta www, onde adicionamos nossos scripts php e a pasta data onde ficam os arquivos do banco de dados MySql.
Como fizemos o direcionamento da porta do serviço do MySql, podemos acessar pelo console através do cliente do MySql:
# apt -y install mysql-client
# mysql -h 127.0.0.1 -u root -p
Também podemos acessar o banco pelo phpMyAdmin através da porta 8080, perceba que o banco criado no console já aparece:
Lembrando que o usuário e senha para acesso ao MySql é root e 123456, respectivamente, como foi definido no arquivo docker-compose.yml.
Para acessar o webserver usamos a porta 8000, como não criamos nenhuma página na pasta www, irá aparecer a mensagem de acesso proibido:
Podemos verificar os erros gerados pelo webserver pelo console:
# docker-compose logs -f web
Agora, para testar a conexão do MySql num script PHP, vamos primeiramente criar uma tabela chamada usuários no banco teste, inserindo alguns registros:
Criamos um pequeno script PHP para conectar no banco e trazer os registros:
# vim www/index.php
<?php
try {
$conn = new PDO( 'mysql:host=db;dbname=teste', 'root', '123456');
$sql = 'SELECT * FROM usuarios';
foreach( $conn->query( $sql ) as $row ) {
echo '<li>' . $row['nome'] . '</li>';
}
$conn = null;
} catch (PDOException $e) {
echo "Erro!: " . $e->getMessage() . "<br/>";
die();
}
?>
Acessando no browser temos:
Pronto! Ambiente está funcionando perfeitamente. Os arquivos desse artigo se encontram no GitHub Linux Web Compose
Como podemos ver o Docker Compose é uma forma ágil de criar um ambiente de desenvolvimento. Para mais informações e opções de configuração você pode acessar o site: https://docs.docker.com/compose/.
Boa sorte!!!
Se una com os assinantes de nossa Newsletter, sempre que tiver postagem nova você será notificado.