目录
运行第一个 Docker 容器:docker run 教程
本节将运行一个 nginx 网页服务器,并学习如何查看、进入、停止和删除容器。每一步都附有实际运行结果。
启动 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
依次发生了以下事情:
- 本机没有
nginx:1.30镜像(Unable to find image ... locally),因此先从 Docker Hub 下载。 - 镜像由多个层组成,每一行
Pull complete都表示一层下载完成。 - 下载完成后,Docker 使用这个镜像创建一个新容器,并将其命名为
web。 -d让容器在后台运行,因此命令会立即结束,只打印出容器 ID(一长串十六进制字符)。
参数说明
| 参数 | 含义 |
|---|---|
-d | detached,在后台运行 |
-p 8080:80 | 将主机的 8080 端口映射到容器的 80 端口 |
--name web | 将容器命名为 web,之后可以用这个名称操作它 |
nginx:1.30 | 镜像名称和版本(tag) |
用浏览器打开
打开浏览器,输入 http://localhost:8080:

流量路径为:浏览器 → 主机的 8080 端口 → Docker 转发到容器的 80 端口 → 容器中的 nginx。
也可以在终端中用 curl 测试:
$ curl -s http://localhost:8080 | head -n 4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
查看正在运行的容器: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
| 字段 | 含义 |
|---|---|
| CONTAINER ID | 容器 ID 的前 12 位,可以在命令中用它代替名称 |
| IMAGE | 使用的镜像 |
| COMMAND | 容器启动时运行的命令 |
| CREATED / STATUS | 创建时间、当前状态(Up 表示正在运行) |
| PORTS | 端口映射,0.0.0.0:8080->80/tcp 就是刚才的 -p 8080:80 |
| NAMES | 容器名称 |
查看日志:docker logs
nginx 会将每个请求记录在日志中。刚才通过浏览器和 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" "-"
前面是 nginx 启动时的消息,可以看到版本为 nginx/1.30.5。最后两行是刚才的请求记录:一行来自浏览器(User-Agent 是浏览器),另一行来自 curl。加上 -f 可以持续跟踪新日志(按 Ctrl + C 退出):
docker logs -f web
进入容器:docker exec
docker exec 可以在正在运行的容器中执行命令:
$ docker exec web nginx -v
nginx version: nginx/1.30.5
$ docker exec web ls /usr/share/nginx/html
50x.html
index.html
加上 -it 可以打开交互式 shell,进入容器四处看看:
$ 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
从输出可以看到几件事:
- nginx 官方镜像基于 Debian 13(trixie)。
- 提示符中的
b470f4d45637是容器的主机名,默认就是容器 ID。 - 容器里没有
ps命令。官方镜像只包含运行 nginx 所需的内容,许多常见工具都被移除了,这是正常的。需要调试工具时,可以临时安装(apt-get update && apt-get install -y procps),也可以使用 docker top 从外部查看。
输入 exit 退出,容器仍会继续运行。
修改网页内容
在容器中修改首页,然后刷新浏览器:
$ 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>

直接修改容器中的文件只适合临时测试。删除容器后,修改内容也会消失。正确做法是将网页文件挂载到容器中(参见 Volume),或写入 Dockerfile。
停止、启动和删除
$ 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:停止容器,容器仍然存在,可以通过docker ps -a查看,状态为Exited。docker start:重新启动已有容器,刚才修改的首页也还在。docker rm:删除已停止的容器。对正在运行的容器执行此命令会出现上面的错误container is running,需要先运行docker stop,或加上-f强制删除。
在 docker ps -a 的列表中,还能看到上一节运行过的 hello-world 容器:它运行完就退出了(Exited (0)),但没有被删除。未指定 --name 的容器会获得一个随机名称,例如 frosty_shirley。
删除容器后,刚才修改的首页也会一起消失。使用同一个镜像再启动一个新容器,看到的将是原来的 nginx 欢迎页面。
运行一次性命令
并非所有容器都需要长期运行。下面这个容器只运行一条命令就会退出,--rm 会让它退出后自动删除:
$ 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
这个 Ubuntu 容器只有 Ubuntu 的用户空间文件,没有启动进程,也没有桌面,从启动到结束只需一瞬间。
使用 Docker Desktop 图形界面操作
在 Windows 和 macOS 上,也可以在 Docker Desktop 中用鼠标完成上述每一步。
搜索并下载镜像
在顶部的搜索框中输入镜像名称,选择所需版本(Tag),点击 Pull 下载,或直接点击 Run:

配置并运行容器
点击 Run 后展开 Optional settings,可以设置容器名称、端口、Volume、环境变量,分别对应 docker run 的 --name、-p、-v、-e:

查看和管理容器
左侧菜单中的 Containers 会列出所有容器,相当于 docker ps -a。点击 Port(s) 列中的链接可以直接用浏览器打开,右侧按钮可用于停止、重新启动和删除容器:

点击某个容器,可以看到 Logs(相当于 docker logs)、Exec(相当于 docker exec)、Files(浏览容器中的文件)等选项卡:

图形界面便于查看状态,但实际工作中仍以命令为主:命令可以写入文档和脚本,在 Linux 服务器上也只能通过命令操作。
Windows 用户:命令写法差异
本教程中的命令以 Linux/macOS 的 bash 为准。在 Windows 上,Docker 命令本身完全相同,但终端(shell)的语法不同:
| 写法 | Linux / macOS(bash) | Windows PowerShell | Windows CMD |
|---|---|---|---|
| 当前文件夹 | $(pwd) | ${PWD} | %cd% |
| 命令换行 | 行尾 \ | 行尾 ` | 行尾 ^ |
| 环境变量 | $HOME | $env:USERPROFILE | %USERPROFILE% |
从文件输入 < | 支持 | 不支持 | 支持 |
本教程中需要使用不同写法的命令,都附有 Linux / macOS、Windows PowerShell、Windows CMD 三个选项卡,点击后整页都会切换为相应写法。例如,将当前文件夹中的 site 挂载到 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
几个常见问题(实际错误信息见常见错误信息):
- 在 PowerShell 中写
"$PWD:/app"会出错,必须写成"${PWD}:/app"。 - PowerShell 不支持
<,还原数据库时需要改用docker cp,各数据库章节都附有相应写法。 - 在 Windows 上编辑的 shell 脚本如果使用 CRLF 换行,放入容器运行时会出现
no such file or directory。
也可以在 WSL(例如 Ubuntu)的终端中使用 Docker Desktop,此时直接使用本教程中的 Linux 写法即可。
重点回顾
docker run -d -p 主机端口:容器端口 --name 名称 镜像在后台启动容器并映射端口。docker ps查看正在运行的容器,-a会包含已停止的容器。docker logs查看输出,docker exec -it 容器 sh进入容器。docker stop/start/rm -f用于控制和删除容器;直接修改容器中的文件只适合临时测试。
动手练习
- 再启动一个 nginx,并映射到主机的 8081 端口:
docker run -d -p 8081:80 --name web2 nginx:1.30,打开http://localhost:8081确认结果。 - 用
docker ps确认两个容器同时运行,并且分别映射到不同的主机端口。 - 删除这两个容器:
docker rm -f web web2。
下一节将深入介绍镜像:名称和标签的规则,以及如何下载、查看和删除镜像。
常见问题
http://localhost:8080 打不开?
先用 docker ps 确认容器正在运行,并且 PORTS 列中有 0.0.0.0:8080->80/tcp。如果 8080 被其他程序占用,docker run 会显示 port is already allocated,请改用 -p 8081:80。
为什么容器里没有 ps、vim 这些命令?
官方镜像只包含运行服务所需的内容,这样镜像更小、漏洞更少。调试时可以用 docker exec 运行镜像中已有的工具,或另外启动一个包含工具的容器。
容器 ID 和名称可以互换使用吗?
可以。命令中既可以使用名称,也可以使用 ID 的前几位(只要不与其他容器重复)。
更新于 2026年10月14日