Analisador de boas práticas Dockerfile com linhas
Este analisador de boas práticas para Dockerfile verifica três problemas comuns antes de uma imagem chegar ao sistema de build.
Executar grátis
Ele aponta a ausência de WORKDIR, imagens base com a tag mutável latest e instruções RUN consecutivas que podem criar camadas desnecessárias. Cada ocorrência traz a linha de origem, um tipo estável e uma explicação direta, servindo tanto para sua revisão manual quanto para uma etapa automatizada de integração contínua.
Obtenha um relatório curto e acionável do Dockerfile
Cole todo o conteúdo do Dockerfile no campo de texto e execute a verificação. A resposta informa se o arquivo passou, apresenta o total de ocorrências e lista cada problema com numeração de linha iniciada em um, tipo estável para automação e mensagem objetiva. O analisador se concentra em três riscos frequentes de manutenção e não tenta substituir uma suíte completa de segurança de contêineres. A falta de WORKDIR aparece na linha 1 porque se aplica ao arquivo inteiro. Uma instrução FROM é marcada em sua própria linha quando usa latest explicitamente ou omite a tag e, portanto, resolve para latest. Quando dois RUN são consecutivos, o segundo é apontado com referência à linha anterior. Comentários e linhas vazias não escondem essa relação. Um arquivo limpo devolve findings vazio, facilitando o uso de valid como condição de aprovação. Continuações com barra invertida formam uma única instrução lógica, mas a posição informada continua sendo a primeira linha física, igual à exibida no editor.
Entenda a importância dessas três práticas
WORKDIR torna explícito o contexto do sistema de arquivos usado por RUN, COPY, CMD e ENTRYPOINT posteriores. Sem essa instrução, o build herda silenciosamente um diretório definido pela imagem base, que pode mudar em uma atualização. Fixar a imagem de FROM com uma tag versionada ou um digest imutável melhora a reprodução dos builds. Uma referência sem tag e uma referência latest podem mudar de conteúdo mesmo que o Dockerfile permaneça idêntico. Além disso, cada RUN normalmente cria uma camada do sistema de arquivos. Etapas consecutivas de instalação, limpeza ou configuração muitas vezes pertencem à mesma operação de shell, permitindo remover arquivos temporários na própria camada e manter o histórico mais claro. A ocorrência é uma recomendação, pois RUN separados podem ser intencionais quando os limites de cache beneficiam um fluxo consolidado. A ferramenta não reescreve comandos nem presume que toda combinação seja segura. A decisão cabe a quem conhece o build, sua estratégia de cache e o comportamento dos comandos quando ocorre uma falha.
Faça a verificação antes do build mais caro
Use o analisador em uma ação do editor, antes do commit ou no começo da integração contínua, antes de baixar imagens base e compilar a aplicação. Envie o texto-fonte original, e não uma representação processada, para preservar as linhas físicas e as continuações. O algoritmo é determinístico: entradas iguais geram saídas iguais, sem rede, relógio, aleatoriedade, daemon do Docker ou estado dependente do ambiente. Assim, ele também é adequado para Dockerfiles gerados. Trate o relatório como um sinal básico de manutenção, não como prova de segurança ou de que a imagem pode ser construída. A ferramenta não executa shell, não resolve variáveis em nomes de imagem, não inspeciona pacotes, não valida origens de COPY, não exige USER sem privilégios e não procura vulnerabilidades. Combine esta análise rápida com um build real, varredura da imagem, políticas e testes do processo final. Se a entrada tiver apenas espaços ou comentários, a solicitação falha porque não existem instruções Dockerfile para avaliar.
Casos de uso
Revise um Dockerfile antes do commit
Encontre referências mutáveis e diretórios de trabalho incertos enquanto você ainda edita as linhas relacionadas.
Controle definições de contêiner geradas
Verifique templates antes que o pipeline gaste tempo construindo e publicando uma imagem.
Avalie um repositório de contêineres
Gere ocorrências consistentes com linhas para priorizar ajustes simples em vários serviços.
Perguntas frequentes
Quanto custa uma solicitação de análise?
Cada solicitação à API custa US$ 0,002. Você também pode usar a versão do navegador diretamente nesta página.
Uma imagem sem tag conta como latest?
Sim. O Docker interpreta a tag omitida como latest, por isso o analisador recomenda uma versão explícita ou digest.
A ferramenta combina RUN automaticamente?
Não. Ela informa RUN consecutivos, mas não reescreve comandos, pois limites de cache separados podem ser intencionais.
Por que WORKDIR ausente aparece na linha 1?
A omissão afeta o arquivo inteiro e não possui linha própria; a linha 1 representa essa localização global.
Esta ferramenta valida sintaxe ou segurança?
Não. Ela executa três verificações básicas e deve ser combinada com build, políticas e varredura de vulnerabilidades.
Para desenvolvedores — acesso via API
Tudo nesta página está disponível via API. Esta seção é para equipes que querem integrar a ferramenta aos próprios sistemas; quem não precisa disso pode simplesmente usar a ferramenta acima.
Endpoint
Autenticação por token Bearer. Um único POST coloca a tarefa na fila; o resultado chega por webhook ou link assinado.
Chame do seu código
curl -X POST https://api.kit.forhosting.com/dev2/dockerfile-lint-basic \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"}'const res = await fetch("https://api.kit.forhosting.com/dev2/dockerfile-lint-basic", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev2/dockerfile-lint-basic",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev2/dockerfile-lint-basic", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"FROM node:20-alpine\\nWORKDIR /app\\nCOPY package*.json ./\\nRUN npm ci && npm cache clean --force\\nCOPY . .\\nCMD [\\"node\\", \\"server.js\\"]"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev2/dockerfile-lint-basic", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Exemplo de requisição
{
"text": "FROM node:20-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci && npm cache clean --force\nCOPY . .\nCMD [\"node\", \"server.js\"]"
}Exemplo de resposta
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev2.dockerfile_lint_basic",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}A API é assíncrona: cada chamada devolve um task_id na hora. Se preferir polling, consulte o status a até 1 requisição por segundo.
Preço
Preço publicado, sem tokens nem créditos escondidos. Tarefa que falha não é cobrada.
Erros
| HTTP | Código | O que significa |
|---|---|---|
401 | unauthorized | Token ausente ou inválido. Confira o header Authorization. |
402 | insufficient_balance | Saldo insuficiente para esta tarefa. Faça uma recarga e tente de novo. |
404 | unknown_type | Esse tipo de tarefa não existe. Confira o campo type no catálogo. |
429 | rate_limited | Muitas requisições em pouco tempo. Espere um instante e tente de novo. |