Docker 入门:从零跑起第一个 Nginx 容器
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 会报名字冲突。
小结
跑通第一个容器只需要三行命令,真正有价值的是三个认知:
-p是宿主机在前、容器在后,别写反- 容器里的 localhost 是容器自己,不是宿主机
- 静态文件挂载改完即生效,配置文件挂载改完要
nginx -t+reload
把这三条搞明白,后面上 Docker Compose、写 Dockerfile 都是顺的。
- 点赞
- 收藏
- 关注作者
评论(0)