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:
- A imagem
nginx:1.30não estava no computador local (Unable to find image ... locally), então o Docker a baixou do Docker Hub. - A imagem é composta por várias camadas. Cada linha
Pull completeindica que uma camada terminou de ser baixada. - Depois do download, o Docker usou essa imagem para criar um contêiner, com o nome
web. -dfaz 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âmetro | Significado |
|---|---|
-d | detached, executa em segundo plano |
-p 8080:80 | mapeia a porta 8080 do host para a porta 80 do contêiner |
--name web | dá ao contêiner o nome web, que você pode usar para operá-lo depois |
nginx:1.30 | nome e versão (tag) da imagem |
Abra no navegador
Abra o navegador e digite http://localhost:8080:

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
| Campo | Significado |
|---|---|
| CONTAINER ID | os 12 primeiros caracteres do ID do contêiner; você pode usá-los nos comandos no lugar do nome |
| IMAGE | imagem usada |
| COMMAND | comando executado ao iniciar o contêiner |
| CREATED / STATUS | horário de criação e estado atual (Up indica que está em execução) |
| PORTS | mapeamento de portas; 0.0.0.0:8080->80/tcp corresponde ao -p 8080:80 usado antes |
| NAMES | nome 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>

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 emdocker ps -ae tem o statusExited.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 errocontainer is runningacima. Primeiro executedocker stopou adicione-fpara 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:

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:

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:

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):

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:
| Forma | Linux / macOS (bash) | Windows PowerShell | Windows 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 < | Sim | Não é compatível | Sim |
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, usedocker 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 imageminicia um contêiner em segundo plano e mapeia as portas.docker psmostra os contêineres em execução;-ainclui os que foram parados.docker logsmostra a saída;docker exec -it contêiner shabre um shell dentro do contêiner.docker stop/start/rm -fcontrolam e removem contêineres. Alterar arquivos diretamente dentro do contêiner é adequado apenas para testes temporários.
Exercícios
- Inicie outro nginx, mapeando a porta 8081 do host:
docker run -d -p 8081:80 --name web2 nginx:1.30, e abrahttp://localhost:8081para confirmar. - Use
docker pspara confirmar que os dois contêineres estão em execução ao mesmo tempo e mapeiam portas diferentes do host. - 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