Variáveis de ambiente: o que pode estar no .env e o que nunca
Há uma ideia generalizada de que pôr um valor numa variável de ambiente é pô-lo em segurança. Não é — é só tirá-lo do código. São coisas diferentes, e a diferença dá disgostos.
1. O caso que mais custa: o que é lido na construção
Este site tem duas variáveis que parecem iguais a todas as outras e não são:
ARG NEXT_PUBLIC_SITE_URL
ENV NEXT_PUBLIC_SITE_URL=$NEXT_PUBLIC_SITE_URLO prefixo NEXT_PUBLIC_ diz ao Next para substituir aquele valor no momento da construção, dentro do JavaScript que vai ser servido ao browser. Deixa de ser uma variável e passa a ser texto dentro de um ficheiro público.
Daí saem duas consequências que apanham toda a gente uma vez:
Pôr essa variável no
.envdo servidor não faz nada. O valor já está compilado; mudá-lo exige reconstruir a imagem.Pôr lá um segredo é publicá-lo. Qualquer pessoa o lê com o botão direito.
A regra que daí sai vale para qualquer ferramenta com este mecanismo: se o prefixo diz «público», é porque é.
2. O que pode estar no .env
Em desenvolvimento, praticamente tudo — é um ficheiro na máquina de quem programa, com credenciais de uma base que só existe ali.
As duas condições são: nunca é comitado, e nunca entra numa imagem. A primeira é uma linha no .gitignore; a segunda é uma linha no .dockerignore, e a razão está no artigo sobre o contexto de construção — um ficheiro que entre numa camada fica lá para sempre, mesmo que seja apagado a seguir.
O que se comita é o exemplo, com as chaves e sem os valores:
# .env.example — este sim, vai para o repositório
DATABASE_URL=postgres://utilizador:senha@localhost:5432/base
AUTH_SECRET=
AUTH_AUTHENTIK_ID=Serve de documentação e evita a pergunta «o que é que eu tenho de preencher» a cada pessoa nova.
3. Em produção, o ficheiro não é o sítio ideal
É aceitável, e é o que este site faz: um .env ao lado do compose, lido por env_file, com permissões restritas. Para um servidor pessoal chega bem.
O que convém saber é o que isso tem contra si. Um valor passado como variável de ambiente é legível por quem conseguir ler o processo:
cat /proc/1234/environ | tr '\0' '\n'E acaba em sítios onde ninguém pensa: no resultado de um docker inspect, no relatório de um erro enviado para uma ferramenta de monitorização, no dump de uma falha. Um cofre a sério — ou os segredos do próprio orquestrador, que chegam como ficheiros e não como variáveis — fecha essa porta.
4. Validar à entrada
Uma variável em falta devolve undefined, e o programa segue com ela. O erro aparece muito depois, longe da causa — uma ligação a undefined, uma assinatura com a palavra undefined.
function obrigatoria(nome) {
const valor = process.env[nome];
if (!valor) throw new Error(`Falta a variável ${nome}`);
return valor;
}
export const BASE = obrigatoria('DATABASE_URL');Falhar no arranque é muito melhor do que falhar às três da manhã com uma mensagem que não diz nada. Neste site é o que o cliente da base faz: sem DATABASE_URL, rebenta à primeira utilização e diz porquê.
O resumo
Variável de ambiente serve para tirar valores do código e para os mudar sem recompilar. Não é um cofre. O que for lido na construção não é segredo nenhum, o que estiver no ambiente do processo é legível por quem lá chegar, e o que faltar deve impedir o arranque em vez de aparecer como undefined horas depois.