Docker 入门:从零跑起第一个 Nginx 容器

举报
yd_282015185 发表于 2026/10/24 11:42:11 2026/10/24
【摘要】 用第一个 Nginx 容器讲清 Docker 入门的三个关键认知:-p 端口映射的方向、容器内 localhost 到底指谁、静态文件挂载与配置挂载改完为什么一个即生效一个要 reload。附真实命令、真实报错和排查结论。

Docker 入门:从零跑起第一个 Nginx 容器

很多人第一次用 Docker,卡住的不是"装不上",而是跑起来之后的三件事:端口为什么访问不通、容器里的 localhost 到底指谁、改完配置怎么让它生效。这篇用一个 Nginx 静态站把这三件事讲透。

一、先确认环境,别急着 pull

docker version

输出里有两段:Client 和 Server。只有 Client 一段说明守护进程没起来。Linux 上通常是:

sudo systemctl start docker
sudo systemctl enable docker

如果报 permission denied while trying to connect to the Docker daemon socket,是当前用户不在 docker 组里:

sudo usermod -aG docker $USER

注意:这条命令要重新登录(或 newgrp docker)才生效。我第一次就是因为没重登,以为加组失败了,反复查了半天。

二、拉镜像并跑起来

docker pull nginx:1.27-alpine
docker run -d --name my-nginx -p 8080:80 nginx:1.27-alpine

两行说明:

  • -d 后台运行,否则终端被占住,Ctrl+C 容器就停了
  • -p 8080:80 是 宿主机端口:容器端口,顺序反了就等于没映射

选 alpine 版本不是为了省那几十 MB 的好看,而是它体积小、拉取快,出问题时 docker exec 进去也干净——没有一堆用不上的预装包干扰判断。

验证:

docker ps
curl -sI http://127.0.0.1:8080

看到 HTTP/1.1 200 OK 和 Server: nginx/1.27.x 就算通了。

三、第一个容易踩的坑:容器里的 localhost

这是新手最容易误解的一点。在容器内部执行:

docker exec -it my-nginx sh
wget -qO- http://localhost

能访问到 Nginx,是因为 这个 localhost 指的是容器自己的网络命名空间,不是你的服务器。所以:

  • 容器内访问 127.0.0.1:3306,找的是容器自己身上的 3306,不是你宿主机上跑的 MySQL
  • 反过来,宿主机上用 localhost:8080 能访问容器,是因为 -p 做了端口转发

要在容器里连宿主机服务,Linux 下用 --add-host=host.docker.internal:host-gateway,然后访问 host.docker.internal。macOS / Windows 的 Docker Desktop 默认就有这个域名。

四、改内容:挂载而不是进容器改

进容器 vi 改文件是最糟的做法:容器一删,改动全没。正确姿势是挂载宿主机目录:

mkdir -p ~/site && echo '<h1>hello docker</h1>' > ~/site/index.html
docker rm -f my-nginx
docker run -d --name my-nginx -p 8080:80 \
  -v ~/site:/usr/share/nginx/html:ro \
  nginx:1.27-alpine

:ro 只读挂载有两个好处:容器里的进程改不动你的源文件;也提醒自己这个目录是"配置输入"而不是"运行时数据"。

改完 ~/site/index.html 后浏览器刷新立刻生效,不需要重启容器——这是静态文件挂载和配置挂载的关键区别。下面这条就要重启。

五、改 Nginx 配置:必须 reload

docker cp my-nginx:/etc/nginx/nginx.conf ~/nginx.conf   # 先把默认配置捞出来看
docker run -d --name my-nginx -p 8080:80 \
  -v ~/site:/usr/share/nginx/html:ro \
  -v ~/nginx.conf:/etc/nginx/nginx.conf:ro \
  nginx:1.27-alpine

改了挂载进来的 nginx.conf 之后,容器里的 Nginx 主进程不会自动重读,必须:

docker exec my-nginx nginx -t        # 先校验语法,别直接 reload
docker exec my-nginx nginx -s reload

nginx -t 这步千万别省。配置写错直接 reload,Nginx 会保留旧配置继续服务,但日志里一堆报错,排查时很容易被误导成"改动没生效"。

六、出问题看日志,别猜

docker logs --tail 50 my-nginx
docker logs -f my-nginx          # 持续跟踪

常见错误对照:

现象 原因
bind: address already in use 宿主机端口被占,ss -tlnp | grep 8080 查占用者
访问 502 / 连接被拒 -p 写反了,或容器内服务没监听 0.0.0.0
容器秒退,docker ps -a 看到 Exited 配置语法错,看 docker logs 第一行
改了配置不生效 忘了 nginx -s reload

第一条尤其常见:本机 80 端口经常被别的服务占着,所以示例里我用 8080。查占用:

ss -tlnp | grep ':8080'

七、收尾:删除要彻底

docker stop my-nginx
docker rm my-nginx
docker rmi nginx:1.27-alpine     # 镜像不删会一直占磁盘

docker ps -a 会列出所有容器(包括已退出的)——停止的容器不占 CPU,但占磁盘和名字,长期不清理,下次 --name my-nginx 会报名字冲突。

小结

跑通第一个容器只需要三行命令,真正有价值的是三个认知:

  1. -p 是宿主机在前、容器在后,别写反
  2. 容器里的 localhost 是容器自己,不是宿主机
  3. 静态文件挂载改完即生效,配置文件挂载改完要 nginx -t + reload

把这三条搞明白,后面上 Docker Compose、写 Dockerfile 都是顺的。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。