Docker Tips – Construindo seu primeiro container com PHP

Autor(a):

Docker sem Drama: ou “como fingir que subir PHP com Nginx sempre foi uma escolha tranquila”

Se você já olhou para um Dockerfile e pensou “isso aqui parece simples, então certamente vai me dar algum susto depois”, parabéns: você já entendeu metade da experiência com containers.

Neste artigo, vou descrever uma configuração de Dockerfile que prepara um ambiente com Ubuntu 24.04Nginx e PHP-FPM 8.3, criando uma base prática para rodar aplicações PHP dentro de um container. A proposta aqui é simples: deixar tudo pronto para servir a aplicação via Nginx, com o PHP processado pelo PHP-FPM, sem aquela emoção desnecessária de configurar tudo na mão toda vez.

Visão geral da configuração

Dockerfile usa como imagem base o Ubuntu 24.04, instala os pacotes essenciais do sistema, adiciona o Nginx e o PHP, copia a configuração do servidor web e define o comando responsável por iniciar os dois serviços.

Visão geral da configuração

				
					FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /workspace

RUN apt-get update && apt-get install -y --no-install-recommends \
    bash ca-certificates curl git nano unzip zip iputils-ping net-tools lsof \
    nginx \
    php-fpm php-cli \
 && rm -rf /var/lib/apt/lists/*

WORKDIR /var/www

# NGINX CONFIG
COPY nginx/default.conf /etc/nginx/sites-available/default
RUN ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

# Simple site
RUN rm -f /var/www/html/index.nginx-debian.html && \
    printf "%s\n" "<?php phpinfo(); ?>" > /var/www/html/index.php

# Expor porta
EXPOSE 80

# Rodar PHP-FPM e NGINX
CMD ["bash", "-lc", "php-fpm8.3 -D && nginx -g 'daemon off;'"]

				
			

1. Escolhendo a imagem base

Tudo começa com:

				
					FROM ubuntu:24.04

				
			

Aqui a escolha foi usar o Ubuntu 24.04 como base. Isso significa que o container parte de um sistema operacional mais completo, em vez de uma imagem minimalista. Não é a opção mais “fitness” do mundo, mas costuma ser confortável para quem quer mais previsibilidade e facilidade na instalação de pacotes.

2. Evitando perguntas existenciais do apt

Na sequência:

				
					ENV DEBIAN_FRONTEND=noninteractive

				
			

Essa variável evita que o gerenciador de pacotes tente abrir prompts interativos durante a instalação. Em outras palavras, o build não para no meio pedindo confirmação, porque Dockerfile não é exatamente o melhor lugar para debates filosóficos com o sistema.

3. Definindo diretórios de trabalho

Primeiro:

WORKDIR /workspace

Depois:

WORKDIR /var/www

WORKDIR define o diretório padrão em que os próximos comandos serão executados. Nesse caso, o container começa em /workspace e depois muda para /var/www, que é um caminho bem comum para aplicações web em PHP.

4. Instalando as dependências

A instalação principal acontece aqui:

				
					RUN apt-get update && apt-get install -y --no-install-recommends \
    bash ca-certificates curl git nano unzip zip iputils-ping net-tools lsof \
    nginx \
    php-fpm php-cli \
 && rm -rf /var/lib/apt/lists/*

				
			

Esse bloco faz três coisas importantes:

  1. Atualiza a lista de pacotes com apt-get update.
  2. Instala ferramentas úteis de sistema, além do NginxPHP-FPM e PHP CLI.
  3. Remove o cache do apt para reduzir o tamanho final da imagem.

Pacotes instalados

Alguns dos principais pacotes são:

  • nginx: servidor web responsável por receber as requisições HTTP.
  • php-fpm: processo que interpreta os scripts PHP.
  • php-cli: útil para executar comandos PHP no terminal.
  • curlgitnanozipunzip: ferramentas de apoio para desenvolvimento e manutenção.
  • net-toolslsofiputils-ping: úteis para diagnóstico, porque em algum momento alguém sempre diz “estranho, na minha máquina funciona”.

5. Copiando a configuração do Nginx

Depois da instalação, o Dockerfile copia a configuração personalizada do Nginx:

				
					COPY nginx/default.conf /etc/nginx/sites-available/default
RUN ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

				
			

Isso substitui a configuração padrão por uma versão própria do projeto. O link simbólico garante que o site fique habilitado no Nginx.

O conteúdo do arquivo nginx/default.conf é este:

				
					server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;
    root /var/www/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $document_root;
    }
}

				
			

6. Entendendo a configuração do Nginx

Essa configuração prepara o Nginx para servir uma aplicação PHP moderna.

Ponto de entrada da aplicação

				
					root /var/www/public;
index index.php index.html;
				
			

Aqui o servidor procura os arquivos dentro de /var/www/public. Isso é bastante comum em frameworks PHP, porque a pasta public costuma ser a porta de entrada da aplicação.

Fallback para index.php

				
					location / {
    try_files $uri $uri/ /index.php?$query_string;
}

				
			

Esse trecho tenta localizar o arquivo solicitado diretamente. Se não encontrar, redireciona a requisição para o index.php, mantendo a query string. Esse comportamento é essencial para rotas amigáveis em muitos projetos PHP.

Processamento de arquivos PHP

				
					location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;

    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param DOCUMENT_ROOT $document_root;
}

				
			

Aqui o Nginx envia os arquivos .php para o PHP-FPM, usando o socket:

/run/php/php8.3-fpm.sock

Ou seja, o Nginx não executa PHP sozinho. Ele apenas entrega a requisição ao PHP-FPM, que faz o trabalho pesado. Cada um no seu papel, como deveria ser em um mundo minimamente civilizado.

7. Criando uma página PHP simples

Dockerfile também remove a página padrão do Nginx e cria um arquivo PHP básico:

				
					RUN rm -f /var/www/html/index.nginx-debian.html && \
    printf "%s\n" "<?php phpinfo(); ?>" > /var/www/html/index.php

				
			

Esse passo é útil para testes iniciais, porque gera uma página com phpinfo(), que mostra se o PHP está funcionando corretamente.

O código criado é:

<?php phpinfo(); ?>

8. Atenção a um detalhe importante

Existe um ponto que merece destaque: o Dockerfile cria o arquivo de teste em:

/var/www/html/index.php

Mas o Nginx está configurado para usar como raiz:

/var/www/public

Ou seja, se não existir uma pasta public com um index.php, o servidor pode não exibir o arquivo criado em /var/www/html. É aquele tipo de detalhe pequeno, elegante e discretamente irritante, muito apreciado por configurações feitas às pressas às 18h de uma sexta-feira.

Se a intenção for usar a pasta public, o ideal é garantir que a aplicação esteja realmente nesse caminho. Se a ideia for testar rapidamente com o phpinfo(), então o mais coerente seria alinhar ambos os caminhos.

9. Expondo a porta da aplicação

A instrução:

EXPOSE 80

indica que o container disponibiliza a porta 80, padrão para tráfego HTTP.

Isso não publica a porta automaticamente no host, mas documenta a intenção da imagem e facilita o mapeamento na hora de subir o container.

10. Inicializando os serviços

Por fim, o container é iniciado com:

				
					CMD ["bash", "-lc", "php-fpm8.3 -D && nginx -g 'daemon off;'"]

				
			

Esse comando faz o seguinte:

  • inicia o php-fpm8.3 em segundo plano com -D;
  • mantém o nginx em primeiro plano com daemon off;.

Esse detalhe é importante porque o Docker espera que o processo principal continue ativo. Se tudo rodasse em background, o container encerraria imediatamente, numa demonstração bastante objetiva de desapego.

Conclusão

Essa configuração monta um ambiente funcional para aplicações PHP com Nginx e PHP-FPM dentro de um container Docker. A estrutura é simples, direta e útil para desenvolvimento ou testes iniciais, especialmente quando se quer uma base rápida sem depender de imagens muito específicas.

Ao mesmo tempo, vale observar o alinhamento entre o caminho configurado no Nginx e o local onde os arquivos da aplicação são criados. Quando esses detalhes estão consistentes, o ambiente tende a subir de forma limpa. Quando não estão, o Docker continua funcionando normalmente, apenas com aquele charme clássico de te fazer questionar sua sanidade por alguns minutos.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *