Conteúdo

docker init: gere automaticamente Dockerfile e compose.yaml

Para quem está começando, a parte mais difícil de escrever um Dockerfile é não saber por onde começar. docker init detecta a linguagem do projeto, faz algumas perguntas e gera um conjunto de arquivos Docker que você pode executar imediatamente. Nesta seção, vamos testar todo o processo com um projeto Express de aplicativo Node.js e examinar linha por linha o que ele gera.

docker init é um plug-in incluído no Docker Desktop. Hosts Linux com apenas o Docker Engine instalado não têm esse comando, mas os arquivos gerados podem ser usados em qualquer lugar.

Prepare o projeto

A pasta init-demo contém apenas três arquivos e ainda não tem nenhum arquivo relacionado ao Docker:

init-demo/
├── package.json
├── package-lock.json
└── server.js

server.js é um aplicativo Express que escuta na porta 3000, com o mesmo conteúdo do aplicativo Node.js.

Execute docker init

Execute na pasta do projeto:

$ docker init

Welcome to the Docker Init CLI!

This utility will walk you through creating the following files with sensible defaults for your project:
  - .dockerignore
  - Dockerfile
  - compose.yaml
  - README.Docker.md

Let's get started!

? What application platform does your project use?  [Use arrows to move, type to filter]
> Node - (detected) suitable for a Node server application
  Go - suitable for a Go server application
  Python - suitable for a Python server application
  Rust - suitable for a Rust server application
  ASP.NET Core - suitable for an ASP.NET Core application
  PHP with Apache - suitable for a PHP web application
  Java - suitable for a Java application that uses Maven and packages as an uber jar
  Other - general purpose starting point for containerizing your application
  Don't see something you need? Let us know!
  Quit

docker init encontrou package.json, marcou automaticamente Node como (detected) e o selecionou. Use as setas para escolher e pressione Enter para confirmar. Em seguida, ele fará estas perguntas, na ordem:

? What application platform does your project use? Node
? What version of Node do you want to use? 24
? Which package manager do you want to use? npm
? What command do you want to use to start the app? npm start
? What port does your server listen on? 3000

✔ Created → .dockerignore
✔ Created → Dockerfile
✔ Created → compose.yaml
✔ Created → README.Docker.md

→ Your Docker files are ready!
  Review your Docker files and tailor them to your application.
  Consult README.Docker.md for information about using the generated files.

What's next?
  Start your application by running → docker compose up --build
  Your application will be available at http://localhost:3000
PerguntaResposta neste exemploExplicação
application platformNodepackage.json foi detectado; basta pressionar Enter
version of Node24Não há valor padrão; é obrigatório informar, caso contrário aparece Value is required
package managernpmpackage-lock.json foi detectado; npm é o padrão
command to start the appnpm startO valor padrão vem de scripts.start em package.json
port3000Porta em que o aplicativo escuta; não há valor padrão

Se você pressionar Enter sem informar a versão do Node, verá:

? What application platform does your project use? Node
X Sorry, your reply was invalid: Value is required
? What version of Node do you want to use?

Se o projeto tiver .nvmrc ou engines.node em package.json, docker init usará esses valores como padrão.

Por fim, são gerados quatro arquivos: .dockerignore, Dockerfile, compose.yaml e README.Docker.md.

Dockerfile gerado

Conteúdo sem os comentários explicativos (o arquivo original tem comentários em inglês em cada seção):

# syntax=docker/dockerfile:1

ARG NODE_VERSION=24

FROM node:${NODE_VERSION}-alpine

# Use production node environment by default.
ENV NODE_ENV production

WORKDIR /usr/src/app

RUN --mount=type=bind,source=package.json,target=package.json \
    --mount=type=bind,source=package-lock.json,target=package-lock.json \
    --mount=type=cache,target=/root/.npm \
    npm ci --omit=dev

USER node

COPY . .

EXPOSE 3000

CMD npm start
SintaxeFunção
# syntax=docker/dockerfile:1Usa a versão mais recente da sintaxe do Dockerfile (durante o build, docker/dockerfile:1 será baixada primeiro)
ARG NODE_VERSION=24A versão é definida como variável e pode ser alterada com --build-arg NODE_VERSION=22
--mount=type=bind,source=package.jsonEm vez de usar COPY, monta package.json diretamente durante o build e evita uma camada na imagem
--mount=type=cache,target=/root/.npmCompartilha o cache de downloads do npm entre builds, sem incluí-lo na imagem
npm ci --omit=devInstala apenas as dependências de produção
USER nodeExecuta como usuário não root

No geral, ele já segue as práticas recomendadas apresentadas no aplicativo Node.js.

Verifique com docker build --check

docker build --check verifica apenas a sintaxe do Dockerfile, sem fazer o build de verdade. Execute o comando no Dockerfile gerado:

$ docker build --check .
#0 building with "default" instance using docker driver

#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 1.20kB done
#1 DONE 0.0s

#2 resolve image config for docker-image://docker.io/docker/dockerfile:1
#2 DONE 0.2s

#3 docker-image://docker.io/docker/dockerfile:1@sha256:4edf897a3ffa55b89f906fc8cc78afdb3f1834cc9c7083565e611a8a7d5fe99e
#3 resolve docker.io/docker/dockerfile:1@sha256:4edf897a3ffa55b89f906fc8cc78afdb3f1834cc9c7083565e611a8a7d5fe99e done
#3 CACHED

#4 [internal] load metadata for docker.io/library/node:24-alpine
#4 DONE 0.2s

#5 [internal] load .dockerignore
#5 transferring context: 663B done
#5 DONE 0.0s
Check complete, 2 warnings have been found!

WARNING: LegacyKeyValueFormat - https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/
"ENV key=value" should be used instead of legacy "ENV key value" format
Dockerfile:14
--------------------
  12 |
  13 |     # Use production node environment by default.
  14 | >>> ENV NODE_ENV production
  15 |
  16 |
--------------------

WARNING: JSONArgsRecommended - https://docs.docker.com/go/dockerfile/rule/json-args-recommended/
JSON arguments recommended for CMD to prevent unintended behavior related to OS signals
Dockerfile:38
--------------------
  36 |
  37 |     # Run the application.
  38 | >>> CMD npm start
  39 |
--------------------

O modelo tem dois avisos:

  1. LegacyKeyValueFormat: ENV NODE_ENV production usa a sintaxe antiga. O correto é ENV NODE_ENV=production.
  2. JSONArgsRecommended: CMD npm start usa o formato shell. Recomenda-se o formato de matriz JSON, caso contrário, o encaminhamento dos sinais de encerramento pode ser afetado. Veja Instruções do Dockerfile.

Altere estas duas linhas:

ENV NODE_ENV=production
CMD ["node", "server.js"]

O CMD também passa a executar node diretamente, eliminando um processo do npm. Veja os testes em Aplicação Node.js. docker build --check é uma boa opção para incluir no fluxo de CI, detectando sintaxe problemática antes do build.

compose.yaml gerado

Sem os comentários, restam apenas algumas linhas:

services:
  server:
    build:
      context: .
    environment:
      NODE_ENV: production
    ports:
      - 3000:3000

A metade inferior do arquivo original contém um exemplo de PostgreSQL inteiro comentado. Se você for descomentar e usar o exemplo, preste atenção a dois problemas:

#   db:
#     image: postgres
#     ...
#     volumes:
#       - db-data:/var/lib/postgresql/data
#     ...
#     healthcheck:
#       test: [ "CMD", "pg_isready" ]
  • image: postgres não especifica uma versão, então atualmente será baixada a versão 18. O volume da versão 18 deve ser montado em /var/lib/postgresql. Se for montado em /var/lib/postgresql/data, o contêiner falhará ao iniciar. Veja PostgreSQL.
  • pg_isready não inclui -h 127.0.0.1, então o banco de dados será considerado healthy antes de terminar a inicialização.

.dockerignore e README.Docker.md

O .dockerignore gerado exclui arquivos comuns desnecessários, incluindo **/node_modules, **/.env, **/.git, **/Dockerfile*, **/compose.y*ml e outros. Ele é mais completo que a versão escrita manualmente anteriormente neste tutorial e pode ser usado diretamente.

README.Docker.md contém instruções breves em inglês sobre como iniciar com docker compose up --build e um lembrete sobre o build para diferentes arquiteturas de CPU (veja Imagens multiplataforma).

Iniciar

Siga as instruções e execute docker compose up --build. Aqui, adicionamos -d para executar em segundo plano e confirmar o resultado:

$ docker compose up -d --build

[+] Building 15.1s (13/13) FINISHED
 => [internal] load local bake definitions                                                                                                       0.0s
 => => reading from stdin 486B                                                                                                                   0.0s
 => [internal] load build definition from Dockerfile                                                                                             0.0s
 => => transferring dockerfile: 1.20kB                                                                                                           0.0s
 => resolve image config for docker-image://docker.io/docker/dockerfile:1                                                                        1.1s
 => docker-image://docker.io/docker/dockerfile:1@sha256:4edf897a3ffa55b89f906fc8cc78afdb3f1834cc9c7083565e611a8a7d5fe99e                         3.9s
 => => resolve docker.io/docker/dockerfile:1@sha256:4edf897a3ffa55b89f906fc8cc78afdb3f1834cc9c7083565e611a8a7d5fe99e                             0.0s
 => => sha256:9d2b4f57f9e20f33279375ce25c6ff14f30f64270ed5c7b613b2b30256754f62 14.28MB / 14.28MB                                                 3.5s
 => => extracting sha256:9d2b4f57f9e20f33279375ce25c6ff14f30f64270ed5c7b613b2b30256754f62                                                        0.4s
 => [internal] load metadata for docker.io/library/node:24-alpine                                                                                0.9s
 => [internal] load .dockerignore                                                                                                                0.0s
 => => transferring context: 663B                                                                                                                0.0s
 => [stage-0 1/4] FROM docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1                  3.2s
 => => resolve docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1                          0.0s
 => => extracting sha256:e2de96513ba9eb53b431787ec8a65cdde380ac4772a3e4c4b714dcfde2a102b5                                                        0.2s
 => => sha256:02f40d53b06f6b91fec0cd6a6719656da99270bff8ee54ed8dcdf4c157763fc1 1.26MB / 1.26MB                                                   0.8s
 => => sha256:7ce7dcbafb7f750cf0c6be3c30e34372b06dd1182fa67f6ae30782c8150c5444 444B / 444B                                                       0.2s
 => => sha256:3c504d5a797be28f9de43147d49cd8ecb2eea46dfaf7beb8715db695d5f0a7f0 56.52MB / 56.52MB                                                 1.1s
 => => extracting sha256:3c504d5a797be28f9de43147d49cd8ecb2eea46dfaf7beb8715db695d5f0a7f0                                                        1.9s
 => => extracting sha256:02f40d53b06f6b91fec0cd6a6719656da99270bff8ee54ed8dcdf4c157763fc1                                                        0.1s
 => => extracting sha256:7ce7dcbafb7f750cf0c6be3c30e34372b06dd1182fa67f6ae30782c8150c5444                                                        0.0s
 => [internal] load build context                                                                                                                0.0s
 => => transferring context: 31.23kB                                                                                                             0.0s
 => [stage-0 2/4] WORKDIR /usr/src/app                                                                                                           0.1s
 => [stage-0 3/4] RUN --mount=type=bind,source=package.json,target=package.json     --mount=type=bind,source=package-lock.json,target=package-l  2.6s
 => [stage-0 4/4] COPY . .                                                                                                                       0.0s
 => exporting to image                                                                                                                           2.7s
 => => exporting layers                                                                                                                          0.3s
 => => exporting manifest sha256:1278071dc9c5842ea834d9abc8c01262b999118ef6903ed4998b8cc8ccc5aaba                                                0.0s
 => => exporting config sha256:879a23594d9f079707b7b35c022fb427cebaaa18db9701eb78b1fbaf82efed06                                                  0.0s
 => => exporting attestation manifest sha256:012342031ad01079856bb6ebf257f096c2d8f9ff12d448ed86a58a645d64bb5d                                    0.0s
 => => exporting manifest list sha256:19aee69cf5d970c251d176f2f533bb918f9e72edf675b109b569ae2ff25cb4f3                                           0.0s
 => => naming to docker.io/library/init-demo-server:latest                                                                                       0.0s
 => => unpacking to docker.io/library/init-demo-server:latest                                                                                    2.3s
 => resolving provenance for metadata file                                                                                                       0.0s
[+] up 3/3
 ✔ Image init-demo-server       Built                                                                                                            15.2s
 ✔ Network init-demo_default    Created                                                                                                           0.0s
 ✔ Container init-demo-server-1 Started                                                                                                           0.4s

$ curl -s http://localhost:3000
{"message":"Hello from Express","node":"v24.21.0"}

$ docker compose exec server ps
PID   USER     TIME  COMMAND
    1 node      0:00 npm start
   18 node      0:00 {MainThread} node server.js
   25 node      0:00 ps

$ time docker compose stop
 Container init-demo-server-1 Stopping
 Container init-demo-server-1 Stopped
real	0m 0.21s
user	0m 0.04s
sys	0m 0.02s

$ docker compose logs server
server-1  |
server-1  | > express-app@1.0.0 start
server-1  | > node server.js
server-1  |
server-1  | Listening on port 3000
server-1  | SIGTERM received, closing server
server-1  | npm notice
server-1  | npm notice New major version of npm available! 11.19.0 -> 12.2.0
server-1  | npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0
server-1  | npm notice To update run: npm install -g npm@12.2.0
server-1  | npm notice
  • A primeira etapa do build é baixar docker/dockerfile:1, efeito da linha # syntax=.
  • O nome do serviço é server, e o site responde normalmente.
  • ps mostra que o PID 1 é npm start, e o node é seu processo filho. docker compose stop termina em 0,21 segundo, e o npm encaminha o sinal de parada para o node.

Quando usar o docker init

  • Projeto novo, sem familiaridade com Dockerfile: use-o para gerar um ponto de partida e, em seguida, compare com este tutorial para entender e modificar cada linha.
  • Projeto que já tem Dockerfile: você pode gerar um em outra pasta e usar como referência de escrita (por exemplo, para montagem de cache).
  • O que ele não faz: não cuida de migrações de banco de dados, variáveis de ambiente, HTTPS nem dos detalhes de builds em vários estágios. Os arquivos gerados são apenas um começo.

Resumo

  • docker init detecta a linguagem do projeto e, após fazer algumas perguntas, gera Dockerfile, compose.yaml, .dockerignore e README.Docker.md.
  • A versão do Node e a porta não têm valores padrão; você precisa informá-los.
  • O Dockerfile gerado usa as montagens bind e cache do BuildKit. A abordagem é boa, mas ainda há avisos sobre sintaxe antiga.
  • Use docker build --check para verificar qualquer Dockerfile.
  • O exemplo de PostgreSQL comentado no modelo precisa ser modificado para funcionar com postgres:18.

Exercícios

Exercício 1: execute docker build --check . em um Dockerfile que você mesmo escreveu (por exemplo, o exemplo de introdução ao Dockerfile) e veja se há avisos.

Dica

Quando não há problemas, é exibido Check complete, no warnings found.. Os avisos mais comuns são JSONArgsRecommended (CMD e ENTRYPOINT usam o formato shell) e LegacyKeyValueFormat (ENV não usa =).

Exercício 2: modifique o Dockerfile gerado para alterar a versão do Node para 22 sem modificar o conteúdo do arquivo.

Resposta

NODE_VERSION é um ARG; basta informá-lo durante o build:

docker build --build-arg NODE_VERSION=22 -t init-demo:node22 .

No Compose, defina-o em build.args:

services:
  server:
    build:
      context: .
      args:
        NODE_VERSION: "22"

Exercício 3: corrija as duas linhas ENV e CMD conforme as instruções deste capítulo e execute docker build --check . novamente para confirmar que os avisos desapareceram.

Perguntas frequentes

Posso usar docker init no Docker Engine para Linux?

docker init é um plug-in de CLI incluído no Docker Desktop (disponível no Docker Desktop para Windows, macOS e Linux). Por padrão, hosts Linux com apenas o Docker Engine instalado não têm esse comando, e a execução mostra docker: unknown command: docker init.

Posso executar docker init em um projeto que já tem um Dockerfile?

Sim, mas ele perguntará se você quer substituir os arquivos existentes. Recomendamos fazer primeiro um commit no Git ou testá-lo em outra pasta, comparar o conteúdo gerado e então decidir se quer adotá-lo.

Quais linguagens docker init suporta?

Na versão v1.4.0 testada, o menu oferece Node, Go, Python, Rust, ASP.NET Core, PHP with Apache, Java e a opção genérica Other. Ele detecta arquivos no projeto (como package.json) e seleciona automaticamente os valores padrão.

Posso usar os arquivos gerados diretamente em produção?

Eles podem servir como ponto de partida, mas você precisa revisá-los. Por exemplo, o modelo testado neste capítulo usa a sintaxe antiga ENV key value e um CMD no formato shell, que geram avisos em docker build --check; o exemplo PostgreSQL comentado no modelo também não funciona com postgres:18.

Atualizado 13 de outubro de 2026