Conteúdo

Primeiro contêiner Docker: tutorial de docker run

Nesta seção, vamos executar um servidor web nginx e aprender a consultar, acessar, parar e excluir contêineres. Cada etapa inclui o resultado real da execução.

Inicie o nginx

docker run -d -p 8080:80 --name web nginx:1.30
$ docker run -d -p 8080:80 --name web nginx:1.30
Unable to find image 'nginx:1.30' locally
1.30: Pulling from library/nginx
ecc510c1e359: Pull complete
f4616bb1be1c: Pull complete
f1a6a629b824: Pull complete
3d774efa34e3: Pull complete
cb44c3fe542b: Pull complete
121907e00c1c: Pull complete
220a6ac36368: Pull complete
Digest: sha256:9bf97bd7714f5e24c1ccd545ecb9eb5435cb6d109c97cebb15e7e455e0239edb
Status: Downloaded newer image for nginx:1.30
b470f4d4563701824e59040cdfcd2154b4bbcca581e6d2d75cae5f2c23dbcfda

O que aconteceu, em ordem:

  1. A imagem nginx:1.30 não estava no computador local (Unable to find image ... locally), então o Docker a baixou do Docker Hub.
  2. A imagem é composta por várias camadas. Cada linha Pull complete indica que uma camada terminou de ser baixada.
  3. Depois do download, o Docker usou essa imagem para criar um contêiner, com o nome web.
  4. -d faz o contêiner ser executado em segundo plano, então o comando termina imediatamente e exibe apenas o ID do contêiner (uma longa sequência de caracteres hexadecimais).

Explicação dos parâmetros

ParâmetroSignificado
-ddetached, executa em segundo plano
-p 8080:80mapeia a porta 8080 do host para a porta 80 do contêiner
--name webdá ao contêiner o nome web, que você pode usar para operá-lo depois
nginx:1.30nome e versão (tag) da imagem

Abra no navegador

Abra o navegador e digite http://localhost:8080:

Página de boas-vindas padrão do nginx
Abra http://localhost:8080 no navegador para ver a página de boas-vindas do nginx

O tráfego segue este caminho: navegador → porta 8080 do host → Docker encaminha para a porta 80 do contêiner → nginx dentro do contêiner.

Você também pode testar com curl no terminal:

$ curl -s http://localhost:8080 | head -n 4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

Consulte os contêineres em execução: docker ps

$ docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS         PORTS                                     NAMES
b470f4d45637   nginx:1.30   "/docker-entrypoint.…"   7 seconds ago   Up 7 seconds   0.0.0.0:8080->80/tcp, [::]:8080->80/tcp   web
CampoSignificado
CONTAINER IDos 12 primeiros caracteres do ID do contêiner; você pode usá-los nos comandos no lugar do nome
IMAGEimagem usada
COMMANDcomando executado ao iniciar o contêiner
CREATED / STATUShorário de criação e estado atual (Up indica que está em execução)
PORTSmapeamento de portas; 0.0.0.0:8080->80/tcp corresponde ao -p 8080:80 usado antes
NAMESnome do contêiner

Consulte os logs: docker logs

O nginx registra cada solicitação nos logs. Há pouco, fizemos uma conexão pelo navegador e outra com curl:

$ docker logs web
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2026/10/12 14:38:25 [notice] 1#1: using the "epoll" event method
2026/10/12 14:38:25 [notice] 1#1: nginx/1.30.5
2026/10/12 14:38:25 [notice] 1#1: built by gcc 14.2.0 (Debian 14.2.0-19)
2026/10/12 14:38:25 [notice] 1#1: OS: Linux 5.4.0-216-generic
2026/10/12 14:38:25 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2026/10/12 14:38:25 [notice] 1#1: start worker processes
2026/10/12 14:38:25 [notice] 1#1: start worker process 28
172.17.0.1 - - [12/Oct/2026:14:38:29 +0000] "GET / HTTP/1.1" 200 896 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/130.0.6723.31 Safari/537.36" "-"
172.18.0.1 - - [12/Oct/2026:14:38:31 +0000] "GET / HTTP/1.1" 200 896 "-" "curl/8.22.0" "-"

As primeiras linhas são mensagens do nginx durante a inicialização. Você pode ver que a versão é nginx/1.30.5. As duas últimas linhas registram as solicitações que acabamos de fazer: uma veio do navegador (o User-Agent é o navegador) e a outra, do curl. Adicione -f para acompanhar os novos logs continuamente (pressione Ctrl + C para sair):

docker logs -f web

Entrar em um contêiner: docker exec

docker exec executa um comando dentro de um contêiner em execução:

$ docker exec web nginx -v
nginx version: nginx/1.30.5

$ docker exec web ls /usr/share/nginx/html
50x.html
index.html

Adicione -it para abrir um shell interativo e explorar o contêiner:

$ docker exec -it web bash
root@b470f4d45637:/# cat /etc/os-release | head -n 2
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
NAME="Debian GNU/Linux"
root@b470f4d45637:/# ls /etc/nginx
conf.d
fastcgi_params
mime.types
modules
nginx.conf
scgi_params
uwsgi_params
root@b470f4d45637:/# ps aux
bash: line 1: ps: command not found
root@b470f4d45637:/# exit
exit

A saída mostra algumas coisas:

  • A imagem oficial do nginx é baseada no Debian 13 (trixie).
  • b470f4d45637, no prompt, é o nome do host do contêiner, que por padrão é o ID do contêiner.
  • O contêiner não tem o comando ps. A imagem oficial inclui apenas o necessário para executar o nginx; muitas ferramentas comuns foram removidas. Isso é normal. Quando precisar de ferramentas de depuração, você pode instalá-las temporariamente (apt-get update && apt-get install -y procps) ou usar docker top para consultar de fora.

Digite exit para sair. O contêiner continuará em execução.

Alterar o conteúdo da página

Altere a página inicial dentro do contêiner e atualize o navegador:

$ docker exec web sh -c 'echo "<h1>Hello from my first container</h1>" > /usr/share/nginx/html/index.html'

$ curl -s http://localhost:8080
<h1>Hello from my first container</h1>
Página inicial do nginx após a alteração
Depois de alterar index.html dentro do contêiner, o navegador mostra o novo conteúdo imediatamente

Alterar arquivos diretamente dentro do contêiner serve apenas para testes temporários. Quando o contêiner é removido, as alterações desaparecem. O jeito correto é montar os arquivos da página no contêiner (veja Volume) ou incluí-los no Dockerfile.

Parar, iniciar e remover

$ docker stop web
web

$ docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED              STATUS                              PORTS     NAMES
b470f4d45637   nginx:1.30    "/docker-entrypoint.…"   12 seconds ago       Exited (0) Less than a second ago             web
786dd898c04b   hello-world   "/hello"                 About a minute ago   Exited (0) About a minute ago                 frosty_shirley

$ docker start web
web

$ curl -s http://localhost:8080
<h1>Hello from my first container</h1>

$ docker rm web
Error response from daemon: cannot remove container "web": container is running: stop the container before removing or force remove

$ docker rm -f web
web

$ docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED              STATUS                          PORTS     NAMES
786dd898c04b   hello-world   "/hello"   About a minute ago   Exited (0) About a minute ago             frosty_shirley
  • docker stop: para o contêiner. Ele continua existindo, aparece em docker ps -a e tem o status Exited.
  • docker start: inicia novamente um contêiner existente; a página inicial alterada também continua lá.
  • docker rm: remove um contêiner parado. Se você usar o comando em um contêiner em execução, verá o erro container is running acima. Primeiro execute docker stop ou adicione -f para forçar a remoção.

A lista de docker ps -a também mostra o contêiner hello-world executado na seção anterior: ele terminou após a execução (Exited (0)), mas não foi removido. Contêineres iniciados sem --name recebem um nome aleatório, como frosty_shirley.

Depois que o contêiner é removido, a página inicial alterada também desaparece. Se você iniciar um novo contêiner com a mesma imagem, verá a página de boas-vindas original do nginx.

Executar um comando único

Nem todos os contêineres precisam ficar em execução por muito tempo. O contêiner abaixo executa um único comando e termina. --rm faz com que ele seja removido automaticamente ao terminar:

$ docker run --rm ubuntu:26.04 cat /etc/os-release
Unable to find image 'ubuntu:26.04' locally
26.04: Pulling from library/ubuntu
06ad70e463aa: Pull complete
4e07a0f12b2c: Pull complete
Digest: sha256:f144425ff09be612d6d9ad965196e9cdc23dae1f42110a8a11a3e9a8198759f7
Status: Downloaded newer image for ubuntu:26.04
PRETTY_NAME="Ubuntu 26.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="26.04"
VERSION="26.04.1 LTS (Resolute Raccoon)"
VERSION_CODENAME=resolute
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=resolute
LOGO=ubuntu-logo

Esse contêiner Ubuntu tem apenas os arquivos de espaço de usuário do Ubuntu, sem processo de inicialização e sem área de trabalho. Do início ao fim, tudo acontece em um instante.

Usar a interface gráfica do Docker Desktop

No Windows e no macOS, você também pode realizar cada uma das etapas acima com o mouse no Docker Desktop.

Buscar e baixar uma imagem

Digite o nome da imagem na caixa de busca na parte superior, escolha a versão (Tag) desejada e clique em Pull para baixar, ou clique diretamente em Run:

Buscar uma imagem no Docker Desktop
Busque uma imagem no Docker Desktop. À direita, você pode escolher a Tag e clicar em Pull ou Run. Imagem: documentação oficial do Docker (Apache-2.0)

Configurar e executar um contêiner

Depois de clicar em Run, expanda Optional settings para configurar o nome do contêiner, a porta, o Volume e as variáveis de ambiente, que correspondem a --name, -p, -v e -e de docker run:

Janela de configuração para executar um novo contêiner no Docker Desktop
Definir Host port como 8080 equivale a docker run -p 8080:80. Imagem: documentação oficial do Docker (Apache-2.0)

Visualizar e gerenciar contêineres

O menu lateral Containers lista todos os contêineres, o equivalente a docker ps -a. Clique no link na coluna Port(s) para abrir diretamente no navegador. Os botões à direita permitem parar, reiniciar e excluir:

Lista de contêineres no Docker Desktop
Tela Containers: status, portas e botões de ação. Imagem: documentação oficial do Docker (Apache-2.0)

Ao abrir um contêiner, você verá abas como Logs (equivalente a docker logs), Exec (equivalente a docker exec) e Files (para navegar pelos arquivos dentro do contêiner):

Aba Files de um contêiner no Docker Desktop
A aba Files permite navegar e editar diretamente os arquivos dentro do contêiner. Imagem: documentação oficial do Docker (Apache-2.0)

A interface gráfica facilita a consulta do status, mas, na prática, você ainda vai usar principalmente comandos: eles podem ser incluídos em documentos e scripts, e em servidores Linux só é possível operar por comandos.

Diferenças na sintaxe de comandos para usuários do Windows

Os comandos deste tutorial usam bash, como no Linux/macOS. No Windows, os comandos do Docker são exatamente os mesmos, mas a sintaxe do terminal (shell) é diferente:

FormaLinux / macOS (bash)Windows PowerShellWindows CMD
Pasta atual$(pwd)${PWD}%cd%
Quebra de linha em comandos\ no fim da linha` no fim da linha^ no fim da linha
Variável de ambiente$HOME$env:USERPROFILE%USERPROFILE%
Entrada de arquivo com <SimNão é compatívelSim

Os comandos deste tutorial que exigem uma sintaxe diferente incluem três abas: Linux / macOS, Windows PowerShell e Windows CMD. Ao selecionar uma delas, a página inteira muda para essa mesma sintaxe. Por exemplo, para montar a pasta site atual no nginx:

docker run -d -p 8080:80 -v "$(pwd)/site:/usr/share/nginx/html:ro" nginx:1.30
docker run -d -p 8080:80 -v "${PWD}/site:/usr/share/nginx/html:ro" nginx:1.30
docker run -d -p 8080:80 -v "%cd%/site:/usr/share/nginx/html:ro" nginx:1.30

Alguns problemas comuns (veja as mensagens de erro reais em Mensagens de erro comuns):

  • No PowerShell, escrever "$PWD:/app" causa um erro. Você precisa escrever "${PWD}:/app".
  • O PowerShell não é compatível com <. Para restaurar um banco de dados, use docker cp; os capítulos sobre cada banco de dados incluem a sintaxe.
  • Se um script de shell editado no Windows usar quebras de linha CRLF, executá-lo dentro do contêiner causará o erro no such file or directory.

Você também pode usar o Docker Desktop pelo terminal do WSL (por exemplo, Ubuntu). Nesse caso, use diretamente os comandos para Linux deste tutorial.

Resumo

  • docker run -d -p porta-host:porta-contêiner --name nome imagem inicia um contêiner em segundo plano e mapeia as portas.
  • docker ps mostra os contêineres em execução; -a inclui os que foram parados.
  • docker logs mostra a saída; docker exec -it contêiner sh abre um shell dentro do contêiner.
  • docker stop / start / rm -f controlam e removem contêineres. Alterar arquivos diretamente dentro do contêiner é adequado apenas para testes temporários.

Exercícios

  1. Inicie outro nginx, mapeando a porta 8081 do host: docker run -d -p 8081:80 --name web2 nginx:1.30, e abra http://localhost:8081 para confirmar.
  2. Use docker ps para confirmar que os dois contêineres estão em execução ao mesmo tempo e mapeiam portas diferentes do host.
  3. Remova os dois contêineres: docker rm -f web web2.

Na próxima seção, você vai conhecer melhor as imagens: as regras de nomes e tags, como baixá-las, consultá-las e removê-las.

Perguntas frequentes

Não consegue abrir http://localhost:8080?

Primeiro, use docker ps para confirmar que o contêiner está em execução e que a coluna PORTS contém 0.0.0.0:8080->80/tcp. Se outro programa estiver usando a porta 8080, docker run exibirá port is already allocated; use -p 8081:80.

Por que não há comandos como ps e vim dentro do contêiner?

As imagens oficiais incluem apenas o necessário para executar o serviço, mantendo a imagem pequena e com menos vulnerabilidades. Para depurar, use docker exec para executar as ferramentas disponíveis na imagem ou inicie outro contêiner que tenha essas ferramentas.

Posso usar o ID e o nome do contêiner de forma intercambiável?

Sim. Nos comandos, você pode usar o nome ou os primeiros caracteres do ID, desde que não se repitam em outro contêiner.

Atualizado 14 de outubro de 2026