Como colocar um aplicativo PHP em um contêiner Docker com segurança
James Olaogun
2 de agosto de 2023
0 minutos de leituraNota do editor: 10 de agosto de 2023
Esta publicação foi atualizada para incluir uma versão mais recente do PHP no tutorial.
Imagine que você criou um aplicativo PHP, mas quer separá-lo da infraestrutura de suporte de um jeito que mantenha tudo leve, portátil e ainda bastante seguro. Você quer que outros desenvolvedores possam trabalhar nele sem precisar recriar ambientes inteiros. Em resumo, o que você quer fazer é colocá-lo em um contêiner — empacotando o aplicativo e suas dependências em contêineres que podem ser compartilhados facilmente entre ambientes.
A solução de conteinerização mais popular atualmente é o Docker, uma plataforma de código aberto lançada em 2013. Desde então, ela se tornou uma tecnologia amplamente adotada no desenvolvimento de software para isolar aplicativos, criar componentes reutilizáveis de CI/CD e permitir implantações rápidas.
Neste tutorial, você vai aprender passo a passo como colocar com segurança um aplicativo PHP em um contêiner — ou, mais especificamente, “Dockerizá-lo”. Você também vai usar o Snyk, uma plataforma de segurança para desenvolvedores com ferramentas que ajudam a identificar vulnerabilidades em aplicativos modernos e automatizar suas correções.
Pré-requisitos e recomendações
Antes de começar o tutorial, reserve um momento para garantir que você tem as seguintes ferramentas:
O Docker instalado na sua máquina. Você vai usá-lo para executar e gerenciar o contêiner PHP.
Uma conta gratuita do Snyk. As ferramentas de análise de segurança do Snyk vão identificar e corrigir vulnerabilidades nos contêineres.
NPM ou Yarn para instalar e executar a Snyk CLI.
Um aplicativo PHP básico. Neste tutorial, usamos um projeto Laravel recém-criado.
Depois de confirmar que você atende a esses requisitos, considere as dicas a seguir antes de continuar. Estas recomendações devem ajudar você a Dockerizar seu aplicativo PHP com segurança e sem complicações.
Use uma versão específica da imagem como base das compilações
Sempre use uma versão específica da imagem Docker ao compilar seu aplicativo. Por exemplo, em vez de baixar PHP-FPM, você pode especificar a versão da imagem e baixar PHP:8.0-fpm. Lembre-se de que a imagem base usada dependerá dos requisitos de versão do seu aplicativo.
Assim, você garante que seu aplicativo seja compilado com base em uma versão conhecida, testada e estável. Além disso, você saberá que a versão da imagem pode usar a mesma plataforma e as mesmas dependências subjacentes em diferentes ambientes, o que melhora a reprodutibilidade e a consistência.
Não use ADD para dependências remotas
O comando ADD pode baixar arquivos de URLs arbitrárias, o que pode introduzir vulnerabilidades de segurança no seu aplicativo Dockerizado. Por isso, recomendo evitar o comando `ADD` nos Dockerfiles para incluir dependências remotas.
Em vez disso, use o comando COPY para copiar arquivos do sistema de arquivos local. O comando COPY garante que apenas os arquivos necessários para o aplicativo sejam incluídos na imagem Docker. Mais uma vez, isso ajuda a reduzir o risco de vulnerabilidades.
Use um arquivo YAML do Docker Compose
O Docker Compose permite gerenciar e orquestrar seus contêineres Docker definindo o aplicativo Docker em um arquivo YAML e especificando como ele deve ser compilado e executado. Entre os benefícios do Docker Compose estão:
Separação dos componentes do aplicativo. O Docker Compose permite separar os componentes do aplicativo em diferentes contêineres. Isso limita a superfície de ataque de cada contêiner e reduz o risco de um único ponto de falha.
Uso de variáveis de ambiente. O Docker Compose permite usar variáveis de ambiente para configurar seu aplicativo, o que pode ajudar você a gerenciar informações confidenciais com segurança, como senhas de banco de dados.
Gerenciamento de conexões de rede. O Docker Compose permite gerenciar as conexões de rede entre seus contêineres. Assim, eles só podem se comunicar entre si por um canal seguro.
Se você instalou o Docker Desktop para Windows, Mac ou Linux, o Docker Compose já está disponível.
Use PHP-FPM, não mod_php
PHP-FPM e mod_php são soluções para executar aplicativos PHP em servidores web, mas funcionam de maneiras diferentes. Enquanto mod_php é um módulo do Apache que permite ao servidor web Apache processar arquivos PHP, PHP-FPM é um gerenciador de processos PHP compatível com vários servidores web, incluindo NGINX e Apache.
Em geral, o PHP-FPM é considerado uma maneira mais eficiente e escalável de executar aplicativos PHP, especialmente em ambientes com alto tráfego.
Use compilações em várias etapas
A compilação em várias etapas é uma técnica do Docker para criar imagens menores e mais seguras. Ao criar várias etapas em um Dockerfile, cada uma com seu próprio conjunto de instruções, você não precisa recompilar a imagem inteira do zero a cada alteração. Com isso, o processo de compilação do Docker fica mais rápido e eficiente.
Sempre teste a segurança do seu aplicativo Dockerizado
Testes de segurança frequentes são fundamentais para garantir e melhorar a segurança do seu aplicativo. Embora o Docker ofereça um ambiente isolado para executar o aplicativo, isso não significa que ele seja seguro. Faça verificações de segurança regularmente para identificar e corrigir possíveis vulnerabilidades antes que invasores possam explorá-las.
Cinco etapas para colocar seu aplicativo PHP em um contêiner Docker com segurança
Agora vamos à parte prática! Neste tutorial, você vai aprender cinco etapas para Dockerizar com segurança um aplicativo PHP com Laravel, usando algumas das dicas que acabamos de apresentar.
1. Configure o Dockerfile usando o Apache
Crie um novo projeto Laravel, caso ainda não tenha um, e use cd para acessar o diretório do projeto. Por exemplo, no comando a seguir, substitua {{laravel-application-directory}} pelo nome do diretório do seu aplicativo Laravel.
Crie um arquivo chamado Dockerfile no diretório raiz do seu aplicativo Laravel:
Copie e cole o código a seguir no Dockerfile recém-criado:
Embora o PHP-FPM seja a melhor opção para criar uma solução escalável, como mencionado acima, este tutorial usa mod_php porque o aplicativo é pequeno.
Observe também que o conteúdo do Dockerfile acima usa a compilação em várias etapas. Na primeira etapa, a imagem oficial do Composer instala as dependências do aplicativo e cria o autoloader. Na segunda, a imagem oficial do PHP/Apache executa o aplicativo. Observe que usamos o comando COPY para copiar os arquivos de compilação do Composer do sistema de arquivos local, e não o comando ADD.
Crie um arquivo chamado docker-compose.yml no diretório raiz do seu aplicativo Laravel:
Copie e cole o código a seguir no arquivo docker-compose.yml recém-criado:
No código acima, o serviço snykdemoapp é o contêiner do aplicativo PHP. Além disso, a seção networks define a rede app-network, que o Docker Compose usará para a comunicação.
2. Adicione um contêiner de banco de dados MySQL ao docker-compose.yml
Vamos adicionar um contêiner MySQL ao seu arquivo docker-compose.yml. Esse contêiner hospedará o banco de dados do seu aplicativo Laravel.
Crie um novo serviço para o contêiner MySQL adicionando o código a seguir como um novo serviço ao arquivo docker-compose.yml criado na primeira etapa:
No bloco de código acima:
app_dbé o nome do serviço de banco de dados criado com a imagem da versão 5.7 do MySQL. Você pode escolher outro nome, mas lembre-se de alterá-lo também nos outros serviços que o referenciam.{{database_name}}é o nome de banco de dados que você preferir.{{database_user}}é o nome de usuário do banco de dados que você preferir.{{dbuser_password}}é a senha que você preferir para o usuário do banco de dados.
Pronto: você adicionou um contêiner MySQL à sua configuração do Docker.
3. Adicione um contêiner PHPMyAdmin ao docker-compose.yml
Agora vamos adicionar um contêiner PHPMyAdmin para desenvolvimento e testes locais, junto aos contêineres Laravel e MySQL. O PHPMyAdmin é uma ferramenta de administração gratuita e de código aberto para MySQL e MariaDB. Ele oferece uma interface web para gerenciar seus bancos de dados. Recomendamos usar o PHPMyAdmin apenas em desenvolvimento, não em produção.
Crie um novo serviço para o contêiner PHPMyAdmin adicionando o trecho de código abaixo como um novo serviço ao arquivo docker-compose.yml.
No bloco de código acima, phpmyadmin é o nome do serviço PHPMyAdmin criado com a imagem phpmyadmin/phpmyadmin. A seção environment define a variável PMA_HOST como app_db, que é o nome do serviço MySQL no mesmo arquivo docker-compose.yml.
Agora você tem um contêiner PHPMyAdmin configurado para funcionar com seus contêineres Laravel e MySQL. Lembre-se de que a imagem PHPMyAdmin deve ser usada apenas para desenvolvimento. Usá-la em produção representa um risco de segurança para seu aplicativo.
4. Compile e execute o aplicativo PHP com Laravel no Docker
Agora que você configurou o Dockerfile e o arquivo docker-compose.yml, inicie o serviço Docker e verifique se ele está em execução. Em seguida, você pode compilar e executar o aplicativo PHP com Laravel usando os comandos a seguir:
docker-compose build: compila a imagem Docker.docker-compose up -d: inicia os contêineres.docker ps: verifica o status do contêiner.
Se todos os comandos acima forem executados com sucesso, abra o navegador e acesse http://localhost:8000/ para visitar a página inicial do seu aplicativo Laravel.

Você também pode acessar http://localhost:8080/ para abrir a interface do PHPAdmin. Use os valores de MYSQL_USER e MYSQL_PASSWORD definidos no arquivo docker-compose.yml para fazer login.

5. Teste e proteja seu aplicativo PHP com o Snyk
Depois de compilar seu aplicativo Docker com sucesso e conseguir acessar tanto o aplicativo quanto o PHPMyAdmin pelo navegador, a próxima etapa é testar a segurança do aplicativo Dockerizado. Neste tutorial, usamos o Snyk para testar e garantir que o aplicativo Dockerizado esteja totalmente protegido.
Entre na sua conta ou crie uma nova conta do Snyk usando qualquer uma das opções de SSO listadas na página. Instale a Snyk CLI e autentique seu laptop, conforme indicado na seção de pré-requisitos deste artigo.

Depois de configurar o Snyk, use a Snyk CLI para avaliar a segurança do seu aplicativo Dockerizado. Execute o comando a seguir no diretório raiz do seu aplicativo Laravel:
Na linha acima, {{your-image}} é o nome da imagem que você quer testar. Você pode usar o comando `docker ps` para ver uma lista das imagens Docker do seu aplicativo.
Ao executar o comando acima na imagem base PHP 8.2 chamada snykdemoapp usada neste tutorial, você verá o seguinte:

O PHP 8.2 é a versão mais recente com suporte de longo prazo (LTS). Embora tenham sido encontrados 69 problemas de segurança na imagem base deste contêiner, todos são de baixa gravidade.
Se você usasse versões anteriores do PHP em aplicativos de produção, como o PHP 7.4, encontraria vulnerabilidades de segurança mais graves e urgentes que precisariam ser corrigidas. Nesse caso, o Snyk se torna ainda mais valioso, pois oferece imagens alternativas com menos vulnerabilidades.
O comando snyk container test fornece apenas um resultado pontual. Uma opção melhor é executar o comando container monitor para fazer uma análise do contêiner.
O comando container monitor envia ao Snyk as informações do teste da imagem do seu contêiner. Assim, o Snyk pode exibir essas informações no seu painel e avisar você sobre possíveis vulnerabilidades futuras na imagem.
Ao executar container monitor na imagem base PHP 7.4 chamada snykdemoapp.

Como corrigir vulnerabilidades detectadas no seu aplicativo PHP
Agora que você testou seu contêiner PHP, confira algumas dicas para corrigir as vulnerabilidades detectadas.
Reconstrua a imagem para obter as atualizações de segurança mais recentes da imagem base upstream do Docker. Assim, todas as atualizações de segurança serão incorporadas ao seu aplicativo. Depois de reconstruir a imagem, execute a verificação de segurança novamente para identificar e corrigir possíveis vulnerabilidades introduzidas pelas atualizações mais recentes da imagem base.
Confira a avaliação de vulnerabilidades fornecida pela Snyk. Essa lista pode trazer informações úteis sobre possíveis problemas de segurança nas dependências do aplicativo.
Lembre-se de que as vulnerabilidades podem ter várias origens. Elas podem estar no runtime do PHP, nas ferramentas ou nas bibliotecas instaladas na imagem base. É fundamental atualizar e monitorar regularmente todos os componentes da pilha do aplicativo para identificar e corrigir vulnerabilidades de segurança o quanto antes.
Conclusão
Seguir algumas práticas recomendadas pode ajudar você a desenvolver um aplicativo com menos vulnerabilidades. Se você acompanhou o tutorial passo a passo, já deve conseguir desenvolver com segurança um aplicativo PHP em contêiner Docker, usando a plataforma de segurança da Snyk para detectar e corrigir vulnerabilidades.
Você encontra todo o código usado no aplicativo Laravel em contêiner Docker deste tutorial no GitHub.
Segurança de contêineres que prioriza os desenvolvedores
O Snyk encontra e corrige automaticamente vulnerabilidades em imagens de contêiner e workloads do Kubernetes.



