我的 Docker 入门复盘:从“这是什么”到“原来如此”

刚学完 Docker,脑子有点涨,赶紧复盘一下重点,怕忘了。感觉这东西说白了,就是一种更轻便、更高效的“虚拟机”(当然它底层不是虚拟机,是个被隔离的进程)。

基础概念:模具和糕点

首先得理清几个核心概念,不然命令根本记不住。

  • 容器: 就是最终跑起来的那个东西,好比用模具做出来的糕点
  • 镜像: 是一个模板或者叫模具。里面包含了运行所需的一切:代码、环境、依赖。
  • Docker 仓库: 就像个模具商店(比如 Docker Hub),大家把自己做好的模具放上去,需要用的时候直接拉下来。
  • 虚拟机的区别:虚拟机是模拟一整台电脑,特别重。Docker 容器直接共用宿主机的内核,只是用技术把它隔离开,所以特别轻快。它是一种 Linux 的容器化技术

常用命令:和 Docker 对话

安装好之后,就在命令行里敲命令了。

  • 先看看版本对不对:docker -version 或者 docker -v
  • docker pull nginx:从仓库拉取(下载)镜像。默认是从官方 library 命名空间拉。如果想指定版本,就加 :标签,比如 nginx:1.2
    • b站“技术爬爬虾”的视频里举了个例子 docker pull docker/n8n.io/n8n,格式是 私有仓库/命名空间/镜像名。不过刚开始我们主要用官方的。
    • 因为网络问题,有时候需要配个镜像站
  • sudo docker images:列出你本地所有的镜像。这个好记,就是镜像的英文。
  • sudo docker rmi <镜像ID>:删除本地镜像。rmi 就是 remove image。
  • sudo docker run nginx:用模具(镜像)启动一个容器(糕点)。如果本地没有这个镜像,它会自动先帮你 pull
  • sudo docker ps:查看正在运行的容器。想看所有(包括已停止的)就加 -a 参数。
  • sudo docker run -d nginx:这个 -d 参数很重要,表示 detached,让容器在后台运行,这样日志不会打印在控制台,不会阻塞你继续操作。

网络与端口映射:给容器开个窗

容器有自己的小网络,和宿主机是隔离的。比如你在容器里跑了个 Nginx(它默认在80端口监听),你直接在宿主机是访问不了的。

所以需要端口映射,用 -p 参数把宿主机的端口和容器的端口“绑”在一起。

比如:docker run -d -p 80:80 nginx
意思是:访问宿主机的 80 端口,就直接转到容器内部的 80 端口。这样你浏览器打开 localhost:80 就能看到 Nginx 的欢迎页面了。

挂载卷:让数据持久化

容器一旦被删除,它里面产生的所有数据也都没了。这不行,所以需要挂载卷,用 -v 参数把宿主机的一个目录(或一个由 Docker 管理的卷)和容器内的目录“绑定”起来。这样数据就存在宿主机上,容器删了,数据还在。

绑定挂载

直接指定宿主机目录。

docker run -d -p 80:80 -v /website/html:/user/share/nginx/html nginx

但这样一运行,访问 localhost:80 可能会报 403错误。因为宿主机目录会覆盖容器目录,如果 /website/html 是空的,那容器里 Nginx 原来的网页文件就没了。

解决办法是:

  1. cd /website/html
  2. sudo vi index.html,然后写上点内容,比如 <h1>Hello from Volume!</h1>
  3. 再刷新浏览器,就能看到你的内容了。

命名卷

让 Docker 帮你管理宿主机目录在哪,你只需要给这个“存储空间”起个名字。

  1. 先创建一个卷:sudo docker volume create nginx_html
  2. 运行容器时使用它:
    sudo docker run -d -p 80:80 -v nginx_html:/user/share/nginx/html nginx
    
  3. 想知道这个卷到底存在哪了:sudo docker volume inspect nginx_html,命令会输出一个 Mountpoint,就是它在宿主机上的真实路径。
  4. 要进去修改文件,得切换 root 用户:sudo -i,然后 cd 进那个路径,再用 vi 编辑。

管理卷的命令:

  • sudo docker volume ls:列出所有卷。
  • sudo docker volume rm nginx_html:删除指定卷。
  • sudo docker volume prune -a清除所有没在用的卷,清理空间时有用。

其他有用的 run 参数

  • sudo docker run -d --name my_nginx nginx:给容器起个名字,不然 Docker 会随机分配一个名字,不好管理。
  • sudo docker run -it --rm alpine
    • -i:交互式。
    • -t:分配一个伪终端。
    • --rm:容器退出后自动删除它
    • 这三个一般一起用,用来做临时测试非常方便。进去后可以 ls 看看,然后 exit 退出,容器自己也删了,很干净。
  • sudo docker run -d --restart always nginx--restart unless-stopped
    • always:不管啥原因挂了,都自动重启。
    • unless-stopped:除非你手动停了它,否则都重启。
    • 这个对保证服务稳定很有用,always 一般用在生产环境。

调节容器:管理它的状态

  • sudo docker stop <容器ID或名字>:停止容器。
  • sudo docker start <容器ID或名字>:启动已停止的容器。
  • sudo docker inspect <容器ID>查看容器的详细信息,包括配置、网络、挂载卷等等,相当于它的“体检报告”。
  • sudo docker create -p 80:80 nginx只创建容器,但不启动。和 run 的区别就在这里,run 是创建并立即启动。
  • sudo docker logs <容器ID>查看容器日志,排障神器。

Docker 原理:它为啥能工作?

Docker 不是魔法,它利用了 Linux 的两大原生功能:

  1. Cgroups:负责限制和隔离进程的资源(CPU、内存、网络带宽等)。给你这个容器分 1G 内存,它就不能用超,防止一个容器吃光所有资源。
  2. Namespaces:负责隔离进程的视图。让容器只能看到自己内部的进程 ID、网络、文件系统,感觉就像自己独占了一个系统。

所以,容器本质上就是一个被严格限制和隔离了的特殊进程。每个容器都表现得像一个独立的 Linux 系统,但底层共享着同一个内核。

进入容器内部看看

  • sudo docker exec <容器ID> ps -ef:在正在运行的容器里执行一条命令,这里是在看它的进程列表。
  • sudo docker exec -it <容器ID> /bin/sh进入容器的交互式 Shell,这样就可以在里面随便操作了,就像 SSH 进去一样。

Dockerfile:自己制作模具

总不能一直用别人的镜像,得学会自己打包。Dockerfile 就是一个图纸,告诉 Docker 如何一步步构建镜像。

比如在 VSCode 里创建一个 Dockerfile 文件:

# 1. 从哪个基础镜像开始构建
FROM python:3.9

# 2. 设置工作目录
WORKDIR /app

# 3. 把当前目录的所有文件,复制到容器的 /app 目录
COPY . .

# 4. 运行命令来安装依赖
RUN pip install -r requirements.txt

# 5. 声明这个容器运行时需要暴露的端口
EXPOSE 8000

# 6. 容器启动时执行的命令
CMD ["python3", "main.py"]

然后构建镜像:

docker build -t docker_test .
  • -t 是给镜像打个标签(起个名字)。
  • 最后那个点 . 表示在当前目录找 Dockerfile

构建成功后,就可以运行了:docker run -d -p 8000:8000 docker_test,然后在浏览器访问就能看到效果了。

推送到 DockerHub

想分享自己的镜像?

  1. docker login 先登录。
  2. 重新构建,但名字要改成你的用户名:docker build -t username/docker_test .
  3. docker push username/docker_test 推上去。

Docker 网络:容器之间怎么通信?

默认是桥接模式,容器会得到一个 172.17.x.x 这类地址。

可以自己创建网络:docker network create network1。好处是:

  • 容器间可以互相通信
  • 隔离网络环境

同一子网下的容器,可以通过容器名直接通信,因为 Docker 内置了 DNS 机制。

Host 模式

还有一种 host 模式:sudo docker run -d --network host nginx
这时容器直接使用宿主机的网络,没有自己独立的网络空间。所以不需要 -p 映射端口了,直接访问服务器 IP 的 80 端口就能访问到 Nginx。

可以进容器看看:sudo docker exec -it id /bin/sh,然后安装网络工具:

apt update
apt install iproute2
ip addr show

你会发现看到的 IP 和宿主机一模一样。

管理网络命令:

  • sudo docker network ls:列出所有网络。
  • sudo docker network rm <网络ID>:删除网络。

Docker Compose:偷懒神器

一个项目通常需要前端、后端、数据库好几个容器。一个个手动 docker run 太麻烦了,而且命令很长。

Docker Compose 就是一个轻量级容器编排工具。可以理解成,它把你需要运行的所有 docker run 命令,按照特定格式写进一个 yaml 文件里。

我们只需要把想要的 docker run 命令发给 AI,让它帮我们生成一个等价的 compose 文件就行了。

  1. 在服务器上 vi docker-compose.yaml
  2. 把 AI 生成的内容贴进去保存。
  3. 执行 sudo docker compose up -d,它就会按照文件启动所有服务。加上 -d 是后台运行。
  4. 想关掉时:
    • sudo docker compose down停止并删除所有容器。
    • sudo docker compose stop:只停止,不删除,之后还可以用 start 启动。

总结一下

Docker 学习路径挺清晰的:

  1. 先理解镜像和容器的关系(模具和糕点)。
  2. 掌握最基础的 pullrunpsstoprm 命令。
  3. 搞懂两个核心概念:端口映射 (-p)挂载卷 (-v)
  4. 学会自己写 Dockerfile 来构建镜像。
  5. 最后用 Docker Compose 来管理多个容器。

更多推荐