DEV Community

Cover image for Como criar containers com PHP, MySQL e NGINX utilizando o Docker Compose
Antonio Nunes Moreira Junior
Antonio Nunes Moreira Junior

Posted on • Edited on

54 3

Como criar containers com PHP, MySQL e NGINX utilizando o Docker Compose

Nesse post vamos aprender a subir containers com PHP 7.3, MySQL 5.7 e Nginx utilizando o Docker Compose para subir os ambientes com apenas um comando de forma clara, objetiva e padronizada.

O que é Docker?

Docker é uma plataforma Open Source escrito em Go, que é uma linguagem de programação de alto desempenho desenvolvida dentro do Google, que possibilita a criação e administração de ambientes isolados ao invés de um Sistema Operacional completo, como acontece nos ambientes de virtualização tradicionais.

Quais as vantagens de utilizar o Docker?

O Docker permite o empacotamento de um serviço ou de um ambiente inteiro dentro de um único container, com isso todo esse ambiente torna-se portável para qualquer outra máquina que tenha o Docker instalado.
Com isso é possível reduzir muito o tempo de deploy do ambiente ou aplicação, pois não há necessidade de realizar nenhum ajuste nesse ambiente para o correto funcionamento da aplicação, pois o ambiente é sempre o mesmo, após configurá-lo uma vez é possível replicá-lo quantas vezes quiser.

Mas e o Docker Compose?

Docker Compose é uma ferramenta utilizada para subir vários contêineres com somente um comando a partir de um arquivo chamado docker-compose que é semelhante ao Dockerfile, esse arquivo é escrito em YAML “YAML Ain’t Markup Language” (em português, “YAML não é linguagem de marcação”).

Passo 1: Instalando e configurando no Windows e Linux

Em Windows:

Para baixar o Docker é necessário criar um ID no docker.com e após autenticado basta acessar:

https://hub.docker.com/editions/community/docker-ce-desktop-windows

Após baixar o docker, siga o passo a passo do instalador, você irá precisar aceitar os termos de uso, autorizar a instalação e esperar o Docker carregar todos os arquivos, ao final, clique em “Finish”.

Após isso, busque por “Docker” na barra de pesquisa do Windows e aperte dê um duplo clique sobre o ícone do Docker for Windows para executá-lo.

Pronto, agora o docker já está rodando em seu computador e já podemos criar nosso primeiro container.

Em Linux:

Para instalar o Docker com o Docker Compose no Linux, basta executar o comando abaixo no terminal do seu Linux:

sudo apt install docker docker-compose -y

Passo 2: Configurando o servidor Web

Primeiro passo é definir onde vamos criar o diretório do projeto, no meu caso, criei na área de trabalho um diretório chamado “Projeto”:

Windows:

Imagem ilustrativa

Linux:

Imagem ilustrativa

Dentro desse diretório vamos criar um arquivo chamado docker-compose.yml contendo as configurações do nosso servidor web, insira as seguintes linhas nesse arquivo:



services:
 web:
  image: nginx:latest
  container_name: nginx
  restart: always
  ports:
   - "80:80"


Enter fullscreen mode Exit fullscreen mode
  • Linha 1: É o nome do serviço que vamos subir, nesse caso, o serviço é web.
  • Linha 2: É a imagem e versão que vamos utilizar, nesse caso, vamos utilizar a imagem do Nginx na sua última versão disponível.
  • Linha 3: Definimos um nome para nosso container, nesse caso, vamos chamá-lo de “nginx”.
  • Linha 4: Por padrão a política de reinicialização do Docker é “no”, ou seja, não reinicia o container em hipótese alguma, nessa linha alteramos essa política para “Always” para que o Docker reinicie o container sempre que necessário.
  • Linhas 5 e 6: Nessas duas linhas definimos as portas que vão ser utilizadas pelo nosso servidor web, primeiro a porta que vamos ouvir em nossa máquina e depois a porta que o servidor web está ouvindo no container.

Com essa configuração definida, já podemos subir nosso primeiro container utilizando o Docker Compose, para isso, basta rodar o comando abaixo através do terminal no diretório do projeto:

docker-compose up –d

Lembrando: No Linux é necessário rodar o comando com sudo no início.

Após executar esse comando no diretório do nosso projeto, caso tudo ocorra bem, será mostrada a seguinte mensagem no terminal “Creating nginx… done”.

Imagem ilustrativa

Podemos ver os containers que estão rodando e as portas utilizadas com o comando pelos respectivos containers com o seguinte comando:

docker-compose ps

Lembrando: No Linux é necessário rodar o comando com sudo no início.

Imagem ilustrativa

Como definimos que a porta 80 do container vai ser mapeada pela 80 de nossa máquina, para testar o acesso ao nosso servidor web, basta digitar http://localhost no navegador e apertar enter, se o servidor estiver rodando corretamente, será apresentado a tela de boas-vindas do Nginx.

Imagem ilustrativa

Agora que já temos um servidor web rodando, vamos mapear uma pasta de nosso computador para ser a raiz desse nosso servidor e também mapear o arquivo de configurações desse servidor, para isso, vamos inserir as seguintes linhas no docker-compose.yml criado anteriormente:



  volumes:
   - ./www:/www
   - ./site.conf:/etc/nginx/conf.d/site.conf


Enter fullscreen mode Exit fullscreen mode
  • Linha 1: Declaração de que vamos mapear volumes nas linhas abaixo.
  • Linha 2: Nessa linha declaramos que o diretório www dentro da pasta do nosso projeto vai passar a mapear o diretório www dentro de nosso container.
  • Linha 3: Nessa linha declaramos que o arquivo site.conf vai ser passar a mapear o caminho /etc/nginx/conf.d/site.conf dentro do nosso container.

Agora no mesmo nível do docker-compose.yml, vamos criar um diretório chamado www.

Imagem ilustrativa

Ainda no diretório do nosso projeto, vamos criar o arquivo chamado site.conf que vai possuir toda a configuração do host docker.localhost de nosso servidor Nginx, nesse arquivo inclua as seguintes linhas:



server {
    index index.html index.php;
    server_name docker.localhost;
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access{% raw %}`.log;
    root /www;
}
```

- **Linha 1:** Tag de abertura da configuração do servidor Nginx.
- **Linha 2:** Nessa linha definimos os arquivos iniciais de nosso host.
- **Linha 3:** Definimos qual host vai utilizar essa configuração, nesse exemplo vamos utilizar o host docker.localhost.
- **Linha 4:** Aqui definimos o caminho onde serão salvos os logs de erro.
- **Linha 5:** Aqui definimos o caminho onde serão salvos os logs de acesso ao host.
- **Linha 6:** Nessa linha definimos o diretório raiz do nosso host, nesse caso, definimos o diretório www que foi mapeado para o diretório www do diretório de nosso projeto.

**Lembrando:** Por padrão a imagem do Nginx já possui um default.conf que ira configurar o acesso para o endereço http://localhost, por isso não podemos criar uma nova conf para esse mesmo endereço, caso deseje substituir essa configuração padrão para subir a sua aplicação em http://localhost basta criar o arquivo chamado default.conf ao invés do site.conf e montar um volume apontando para /etc/nginx/conf.d/default.conf como feito com site.conf.

![Imagem ilustrativa](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z6sdebv4obtssqwjrp7t.png)

Precisamos agora acessar o diretório www, nesse diretório vamos criar uma página bem básica para testar se a configuração do servidor web está funcionando corretamente, para isso, basta criar um arquivo chamado index.html e incluir as seguintes linhas:

```HTML
<html>
<head>
    <title>Ola</title>
</head>
<body>
    <h2>Ola Docker!<h2>
</body>
</html>
```

![Imagem ilustrativa](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ww6vdrowmk484b0touss.png)

Tudo pronto, agora vamos reiniciar o nosso container com os seguintes comandos:


**docker-compose down**
**docker-compose up -d**


**Lembrando:** No Linux é necessário rodar o comando com sudo no início.

![Imagem ilustrativa](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ysbit6sculyxhimfgj9.png)


**No Windows:**

Abra o Bloco de Notas como administrador, agora com Bloco de Notas aberto clique em Arquivo > Abrir, na sequência, vá até a seguinte pasta: C: > Windows > System32 > Drivers > etc. Ali, no lado do campo Nome, mude a opção Documentos de texto (*.txt) para Todos os arquivos (*.*), o arquivo hosts aparecerá, clique nele, com o arquivo aberto no Bloco de Notas vá até o final do arquivo e inclua a seguinte linha:

127.0.0.1 docker.localhost

Após basta salvar o arquivo indo em Arquivo > Salvar.

![Imagem ilustrativa](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19dgg9q5lh3xs0ptb5p0.png)


No Linux:

Abra o terminal do seu Linux e digite o comando abaixo:

**sudo nano /etc/hosts**

Com arquivo aberto em seu terminal, vá até o final do arquivo e inclua a seguinte linha:

127.0.0.1 docker.localhost

![Imagem ilustrativa](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1w6e15jwo3fhgwdw3b7h.png)


Após isso basta salvar a alteração teclando Ctrl + O e depois Enter, para sair da edição do arquivo pressione Ctrl + X.

Pronto, finalmente podemos testar o acesso ao endereço http://docker.localhost, caso tudo esteja correto, será apresentado um “Ola Docker!”.

![Imagem ilustrativa](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7jw5gmd54dmioq12hn9k.png)

**Passo 3: Configurando o PHP-FPM em nosso servidor Nginx**

Agora que nosso servidor web já está funcionando, vamos configurar o PHP-FPM e fazer a ligação com o serviço web, para isso, vamos abrir novamente o arquivo docker-compose.yml e incluir as seguintes linhas:


```YML
  links:
  - php
 php:
  image: php:7.3-fpm
  container_name: php-fpm
  volumes:
  - ./www:/www
```

- **Linha 1 e 2:** Nessas linhas criamos um link do php para o serviço web tenha acesso a ele.
- **Linha 3:** Definimos o nome do nosso serviço.
- **Linha 4:** Nome da imagem e versão que iremos utilizar.
- **Linha 5:** Definimos o nome do nosso container.
- **Linha 6 e 7:** Mapeamos o diretório www de nosso projeto também no container do PHP-FPM para que o mesmo também tenha acesso aos arquivos.

Após incluir a configuração do PHP-FPM e linkar o serviço PHP no serviço web, vamos incluir as seguintes linhas no site.conf, dentro da tag server:

```
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;
}
```

Vamos agora acessar o diretório www e renomear a index.html para index.php e substituir seu conteúdo por:

```PHP
<?php
echo phpinfo();
```

Antes de testar vamos rodar os comandos abaixo para encerrar todos containers que estão rodando e subi-los novamente, incluindo o do serviço php.


**docker-compose down**
**docker-compose up –d**

**Lembrando:** No Linux é necessário rodar os comandos com sudo no início.


![Imagem ilustrativa](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tp5n3zbizc5cfqr52ifb.png)

Pronto, finalmente podemos testar o acesso ao endereço http://docker.localhost.

![Imagem ilustrativa](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o5ozdr87rn740n47zc50.png)


Agora que temos o servidor rodando com PHP, vamos configurar o MySQL 5.7, para isso, vamos retornar ao arquivo docker-compose.yml e incluir as seguintes linhas no final do arquivo:

```YML
  links:
  - db
 db:
  image: mysql:5.7
  container_name: mysql
  ports:
  - "3306:3306"
  command: --default-authentication-plugin=mysql_native_password
  restart: always
  environment:
    MYSQL_ROOT_PASSWORD: root
    MYSQL_DATABASE: teste
```

- Linha 1 e 2: Nessas linhas criamos um link do serviço de Banco de Dados para que o PHP tenha acesso a ele.
- Linha 3: Aqui definimos o nome do nosso serviço.
- Linha 4: Nome da imagem e versão que vamos utilizar.
- Linha 5: Definimos o nome do nosso container.
- Linha 6 e 7: Nessas duas linhas definimos as portas que vão ser utilizadas pelo nosso servidor MySQL, primeiro a porta que queremos ouvir em nossa máquina e depois a porta que o servidor MySQL está ouvindo no container.
- Linha 8: Nessa linha definimos que vamos utilizar o método nativo de autenticação do MySQL.
- Linha 9: Definimos a política de restart do Docker para “Always” para que o Docker reinicie o container sempre que necessário.
- Linha 10: Nessa linha dizemos que abaixo vamos definir algumas variáveis de ambiente.
- Linha 11: Definimos a senha do root como “root”.
- Linha 12: Nessa linha definimos que vamos utilizar uma base chamada teste, quando subirmos o container a base em questão vai ser criada automaticamente.

Após isso, vamos rodar os comandos abaixo para encerrar todos containers e subi-los novamente:

**docker-compose down**
**docker-compose up –d**

**Lembrando:** No Linux é necessário rodar os comandos com sudo no início.

![Imagem ilustrativa](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wn7ke6nr09a5dw1x5h7u.png)


Para verificar se o servidor MySQL está rodando corretamente e possui a base “teste” criada, vamos acessar esse container via bash com o seguinte comando:

**docker-compose exec db bash**

**Lembrando:** No Linux é necessário rodar o comando com sudo no início.

Após rodar esse comando você está no bash do container onde o MySQL está rodando, agora vamos acessar o MySQL com usuário root e senha root que definimos no arquivo docker-compose.yml com o seguinte comando:

**mysql -u root –proot**

Após rodar esse comando você vai estar logado no MySQL com usuário root e pode ver as bases criadas, para isso basta executar o seguinte comando:

**show databases;**

Com isso, será mostrada todas as bases criadas, entre elas deve existir a base chamada teste. 


![Imagem ilustrativa](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7r6n38otg9lfphfbeimy.png)


Perfeito, agora temos o servidor Nginx rodando com PHP e o MySQL, já podemos criar um script em PHP para se conectar a base teste e verificar se está tudo funcionando corretamente.

Para testar a conexão, primeiro precisamos instalar a extensão PDO para MySQL no PHP pois essa não vem configurado por padrão, é possível definir a instalação dessa extensão no arquivo Dockerfile para que seja instalada já no primeiro build do serviço, como nesse post não iremos abordar o arquivo Dockerfile, vamos realizar essa instalação de forma manual com um comando, para isso vamos executar o seguinte comando no diretório de nosso projeto:

**docker exec -it php-fpm docker-php-ext-install pdo pdo_mysql**
**docker-compose restart**

**Lembrando:** No Linux é necessário rodar os comandos com sudo no início. 

Agora que já temos o driver de conexão ao MySQL instalado e configurado no PHP, vamos criar um arquivo chamado db.php dentro do diretório www com o seguinte código:

```PHP
<?php
$host = "db";
$username = "root";
$password = "root";
$db = "teste";
try {
    $conn = new PDO("mysql:host=$host;dbname=$db", $username, 
    $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, 
    PDO::ERRMODE_EXCEPTION);
echo '<h2>Conectado com sucesso.<h2>';
} catch (PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}
?>
```

Por fim, podemos acessar http://docker.localhost/db.php para testar a conexão do PHP ao nosso servidor MySQL, caso tudo funcione como esperado, você vai ver a mensagem “Conectado com sucesso.” no seu navegador.


![Imagem ilustrativa](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/25ol4cge2d699lfhg215.png)

Agora você tem um ambiente que pode ser replicado facilmente para qualquer outra máquina que possua o Docker instalado, para isso basta apenas copiar o arquivo docker-compose.yml.


**Conclusão**

Há muito mais sobre o Docker Compose do que o que foi mostrado nesse post, mas acredito que isso deve ser suficiente para começar a utilizar e aproveitar toda facilidade que o Docker Compose proporciona para realizar o deploy dos seus ambientes de desenvolvimento, teste, produção, etc.

**Meus contatos:**

E-mail: nunesjr1993@gmail.com
Linkedin: https://www.linkedin.com/in/jrnunes1993/

**Endereço do repositório do projeto no Github:**

https://github.com/jrnunes1993/Docker

**Links interessantes para estudo e usados na construção deste post:**

https://docs.docker.com/
https://nginx.org/en/docs/
https://pt.wikipedia.org/wiki/YAML
https://pt.wikipedia.org/wiki/Docker_(software) 
Enter fullscreen mode Exit fullscreen mode

Billboard image

Deploy and scale your apps on AWS and GCP with a world class developer experience

Coherence makes it easy to set up and maintain cloud infrastructure. Harness the extensibility, compliance and cost efficiency of the cloud.

Learn more

Top comments (6)

Collapse
 
einnovationline profile image
einnovationline

Parabéns, muito bom e fácil só tive um erro pois não tinha o mysql instalado.

Collapse
 
jrggroberto profile image
Roberto

Muito legal, funcionou perfeitamente.
Agora como faria para adicionar o Composer ao PHP?
Acessei o bash do php

docker exec -it php-fpm bash
Enter fullscreen mode Exit fullscreen mode

E lá realizei a instalação do Command-line installation descrito em getcomposer.org/download/

Até são gerados os arquivos mas o sistema ainda não consegue enxergar o ventor/autoload.php...

Quando descobrir coloco aqui
Obrigado pelas informações

Collapse
 
paulodebatin profile image
paulodebatin

Muito bom...
Só tive um problema de conexão do PHP com Mysql:
ERROR: SQLSTATE[HY000] [2002] No such file or directory

Alguém tem alguma ideia do que pode ser?

Collapse
 
luizglauco profile image
Glauco Luiz Espirito Santo

No meu aqui deu essa mensagem também, eu olhei e tinham uns espaços a mais ali na explicação:
$conn = new PDO(“mysql: host = $host;
dbname = $db”, $username, $password);

Corrigindo fica:

$conn = new PDO("mysql:host=$host;dbname=$db, $username, $password);

Collapse
 
jrnunes1993 profile image
Antonio Nunes Moreira Junior

Obrigado pelo comentário, irei ajustar no post esse exemplo.

Collapse
 
robsonponti profile image
Robson Ponti • Edited

No arquivo onde criou a conexão com DB, altera o hostname de "localhost" para "db" que resolve.

AWS GenAI LIVE!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️