docker 作者: typecho 时间: 2026-05-22 分类: 默认分类 评论 # Docker 视频教程学习讲义 本讲义根据项目文件夹 `ed_videos/` 下的 Docker 视频教程整理,顺序对应本地视频文件: ```text 01 课程简介 Docker 02 基础 Docker 架构与容器化 05 基础 安装 Docker 06 命令 镜像操作 07 命令 容器操作 08 命令 run 细节 09 命令 保存镜像 10 命令 分享镜像 11 命令 实验小结 12 存储 目录挂载 13 存储 卷映射 14 网络 自定义网络 15 网络 Redis 主从集群 16 最佳实践 17 Docker Compose 安装 WordPress 18 Docker Compose 语法 19 Docker Compose 其他 20 Dockerfile 制作镜像 21 Dockerfile 镜像分层机制 22 一键启动所有中间件 23 访问测试全部通过 24 销毁实例 25 结束语 ``` 这套视频不是在讲“云原生全家桶”,而是在讲你当前路线最需要的能力: > 能用 Docker 把服务快速部署起来,能管理镜像、容器、端口、数据和网络。 > 能用 Docker Compose 一键启动多个中间件,也能写 Dockerfile 制作自己的应用镜像。 --- ## 0. 学 Docker 前先明确目标 你现在学 Docker,不是为了背命令,也不是为了马上搞 Kubernetes。你的目标应该是: - 会安装 Docker。 - 会拉取镜像。 - 会启动、停止、删除容器。 - 会把容器端口映射到宿主机。 - 会把宿主机目录挂载到容器。 - 会创建自定义网络,让容器之间用名字互相访问。 - 会用 Docker Compose 管理多个服务。 - 会写 Dockerfile,把自己的项目打成镜像。 - 会用日志和端口命令排查容器服务为什么访问不了。 结合你的学习路线,Docker 最终要服务于这些项目: - 个人 Web 服务部署。 - Nginx 反向代理。 - FastAPI 数据分析平台。 - WordPress 或博客系统部署。 - Redis/MySQL/MinIO 等中间件部署。 - Ollama + OpenWebUI 私有化部署。 - 射频测试数据自动化分析平台部署。 --- ## 1. 课程简介:Docker 到底解决什么问题 对应视频:`01.课程简介_Docker` Docker 解决的核心问题是: > 让应用和它的运行环境一起打包、一起交付、一起启动。 以前部署一个项目,经常会遇到这些问题: - 开发电脑能跑,服务器跑不起来。 - Python、Java、Node 版本不一致。 - 依赖库版本冲突。 - 安装 MySQL、Redis、Nginx 很麻烦。 - 换一台服务器要重新搭环境。 - 多个服务部署步骤难以复现。 Docker 的思路是: - 把应用运行所需环境做成镜像。 - 用镜像启动容器。 - 容器之间相互隔离。 - 容器可以快速创建、删除、迁移和重启。 - 配合 Compose 可以一键启动一组服务。 你可以这样理解: ```text 镜像 image = 软件安装包 + 运行环境模板 容器 container = 镜像运行起来后的实例 仓库 registry = 存放镜像的地方 Dockerfile = 制作镜像的说明书 Compose = 一键启动多容器项目的配置文件 ``` 工程上你最常说的一句话是: > 我用 Docker Compose 把 Nginx、后端服务、数据库和 Redis 统一编排起来,部署时只需要执行 `docker compose up -d`。 --- ## 2. Docker 架构与容器化 对应视频:`02.基础_Docker架构与容器化` ### 2.1 Docker 的基本架构 Docker 主要由几部分组成: ```text Docker Client -> Docker Daemon -> Images / Containers / Networks / Volumes | v Docker Registry ``` 常见组件: - Docker Client:你在命令行输入的 `docker` 命令。 - Docker Daemon:后台服务,真正负责创建容器、拉镜像、管理网络和存储。 - Image:镜像,是只读模板。 - Container:容器,是镜像运行后的实例。 - Registry:镜像仓库,如 Docker Hub、阿里云镜像仓库、私有仓库。 - Volume:Docker 管理的数据卷。 - Network:Docker 管理的容器网络。 当你执行: ```bash docker run nginx ``` 背后发生的事情大致是: 1. Docker Client 把命令发给 Docker Daemon。 2. Daemon 检查本地有没有 `nginx` 镜像。 3. 如果没有,就从镜像仓库拉取。 4. 用镜像创建容器。 5. 给容器分配文件系统、网络、进程空间。 6. 启动容器里的 Nginx 主进程。 ### 2.2 容器不是虚拟机 虚拟机通常包含完整操作系统: ```text 物理机 -> 宿主机操作系统 -> 虚拟化软件 -> 虚拟机操作系统 -> 应用 ``` 容器共享宿主机内核: ```text 物理机 -> 宿主机操作系统 -> Docker -> 容器 -> 应用 ``` 所以容器通常更轻: - 启动快。 - 占用资源少。 - 适合快速部署服务。 - 适合统一环境。 但容器也不是万能的: - 它不是完整虚拟机。 - 它依赖宿主机内核。 - 数据默认不应该只放在容器内部。 - 安全隔离不等于绝对隔离。 ### 2.3 镜像和容器的关系 镜像像“类”,容器像“对象”。 ```text nginx 镜像 -> nginx 容器 A -> nginx 容器 B -> nginx 容器 C ``` 同一个镜像可以启动多个容器。每个容器有自己的进程、网络、文件系统变化层。 --- ## 3. 安装 Docker 对应视频:`05.基础_安装Docker` ### 3.1 Linux 上安装 Docker Ubuntu 常见安装方式: ```bash sudo apt update sudo apt install -y ca-certificates curl gnupg ``` 如果使用官方仓库,通常还会添加 GPG key 和 Docker 软件源。学习阶段也可以直接使用发行版仓库: ```bash sudo apt install -y docker.io docker-compose-plugin ``` 启动 Docker: ```bash sudo systemctl start docker sudo systemctl enable docker ``` 查看状态: ```bash systemctl status docker ``` 检查版本: ```bash docker version docker compose version ``` 运行测试容器: ```bash sudo docker run hello-world ``` ### 3.2 让普通用户执行 docker 如果每次都要 `sudo docker`,可以把当前用户加入 docker 组: ```bash sudo usermod -aG docker $USER ``` 然后退出 SSH,重新登录。 验证: ```bash docker ps ``` 注意: > 加入 docker 组后,这个用户基本拥有接近 root 的能力。自己的学习服务器可以这样做,生产环境要按公司规范来。 ### 3.3 常见安装问题 #### Docker 服务没启动 现象: ```text Cannot connect to the Docker daemon ``` 排查: ```bash systemctl status docker sudo systemctl start docker ``` #### 权限不足 现象: ```text permission denied while trying to connect to the Docker daemon socket ``` 处理: ```bash sudo usermod -aG docker $USER ``` 重新登录后再试。 #### 拉镜像很慢 可能是网络或镜像源问题。可以配置国内镜像加速器,或者使用云服务器所在厂商提供的加速地址。 --- ## 4. 镜像操作 对应视频:`06.命令_镜像操作` 镜像是启动容器的模板。你要先会找镜像、拉镜像、看镜像、删镜像。 ### 4.1 搜索镜像 ```bash docker search nginx docker search redis docker search mysql ``` 学习时可以搜索,实际部署更建议去 Docker Hub 或官方文档确认镜像名和版本。 ### 4.2 拉取镜像 ```bash docker pull nginx docker pull redis docker pull mysql:8.0 docker pull python:3.11-slim ``` 镜像名后面的 `:8.0`、`:3.11-slim` 是 tag。 如果不写 tag,默认是: ```text latest ``` 不建议正式项目长期使用 `latest`,因为它会变化。更推荐固定版本: ```bash docker pull redis:7.2 docker pull nginx:1.25 ``` ### 4.3 查看本地镜像 ```bash docker images ``` 或: ```bash docker image ls ``` 你会看到: ```text REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest xxxxxxxx ... ... ``` 字段含义: - REPOSITORY:镜像仓库名。 - TAG:版本标签。 - IMAGE ID:镜像 ID。 - SIZE:镜像大小。 ### 4.4 删除镜像 ```bash docker rmi nginx docker rmi nginx:latest docker rmi 镜像ID ``` 如果镜像正在被容器使用,删除会失败。要先删除相关容器。 查看所有容器: ```bash docker ps -a ``` 删除容器: ```bash docker rm 容器名或容器ID ``` 再删镜像。 ### 4.5 查看镜像详情 ```bash docker inspect nginx docker history nginx ``` `docker inspect` 看完整元数据。 `docker history` 看镜像分层历史,这在 Dockerfile 和镜像分层机制里会用到。 --- ## 5. 容器操作 对应视频:`07.命令_容器操作` 容器是镜像运行起来后的实例。 ### 5.1 启动一个容器 最简单: ```bash docker run nginx ``` 这会占住当前终端。更常用后台启动: ```bash docker run -d nginx ``` `-d` 表示 detached,后台运行。 ### 5.2 查看运行中的容器 ```bash docker ps ``` 查看所有容器,包括已经停止的: ```bash docker ps -a ``` 常见字段: - CONTAINER ID:容器 ID。 - IMAGE:使用的镜像。 - COMMAND:容器启动命令。 - STATUS:运行状态。 - PORTS:端口映射。 - NAMES:容器名称。 ### 5.3 停止、启动、重启容器 ```bash docker stop 容器名 docker start 容器名 docker restart 容器名 ``` 例如: ```bash docker stop my-nginx docker start my-nginx docker restart my-nginx ``` ### 5.4 删除容器 删除已经停止的容器: ```bash docker rm 容器名 ``` 强制删除运行中的容器: ```bash docker rm -f 容器名 ``` 学习环境可以用 `-f`,正式环境先确认容器是否承载重要服务。 ### 5.5 查看日志 ```bash docker logs 容器名 docker logs -f 容器名 docker logs --tail 100 容器名 ``` 常用组合: ```bash docker logs -f --tail 100 my-nginx ``` ### 5.6 进入容器 ```bash docker exec -it 容器名 bash ``` 如果容器里没有 bash: ```bash docker exec -it 容器名 sh ``` 参数含义: - `exec`:在运行中的容器里执行命令。 - `-i`:保持输入。 - `-t`:分配终端。 ### 5.7 查看容器资源 ```bash docker stats ``` 可以看到 CPU、内存、网络、磁盘 IO 等。 --- ## 6. docker run 细节 对应视频:`08.命令_run细节` `docker run` 是最核心的命令之一。它不是单纯“启动”,而是: ```text 拉镜像,如果本地没有 -> 创建容器 -> 设置名称、端口、环境变量、挂载、网络等参数 -> 启动容器 ``` ### 6.1 给容器命名 ```bash docker run -d --name my-nginx nginx ``` 好处: - 后续不用记容器 ID。 - 日志、停止、删除更方便。 ```bash docker logs my-nginx docker stop my-nginx docker rm my-nginx ``` ### 6.2 端口映射 容器里的 Nginx 默认监听 80,但外部不能直接访问容器内部端口。需要映射到宿主机。 ```bash docker run -d --name my-nginx -p 8080:80 nginx ``` 含义: ```text 宿主机 8080 -> 容器 80 ``` 访问: ```bash curl http://127.0.0.1:8080 ``` 如果云服务器要让外网访问,还要放行安全组端口。 ### 6.3 后台运行 ```bash docker run -d nginx ``` 如果不加 `-d`,容器前台输出会占住终端。 ### 6.4 容器自动删除 ```bash docker run --rm hello-world ``` 容器退出后自动删除。适合临时测试,不适合有状态服务。 ### 6.5 环境变量 ```bash docker run -d --name mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ mysql:8.0 ``` 很多官方镜像都用环境变量做初始化配置,比如 MySQL 密码、Redis 配置、应用运行模式。 ### 6.6 重启策略 ```bash docker run -d --restart always --name my-nginx nginx ``` 常见策略: - `no`:默认,不自动重启。 - `always`:总是自动重启。 - `unless-stopped`:除非手动停止,否则自动重启。 - `on-failure`:异常退出时重启。 服务器部署常用: ```bash --restart unless-stopped ``` ### 6.7 一个完整 run 示例 ```bash docker run -d \ --name my-nginx \ --restart unless-stopped \ -p 8080:80 \ nginx:1.25 ``` 检查: ```bash docker ps docker logs --tail 50 my-nginx curl -I http://127.0.0.1:8080 ``` --- ## 7. 保存镜像 对应视频:`09.命令_保存镜像` 保存镜像常见有两类含义: - 把本地镜像导出成文件,方便离线传输。 - 基于容器当前状态提交成新镜像。 ### 7.1 docker save:导出镜像 导出镜像: ```bash docker save nginx:1.25 -o nginx-1.25.tar ``` 导入镜像: ```bash docker load -i nginx-1.25.tar ``` 适用场景: - 服务器不能访问外网。 - 需要把镜像拷贝到另一台机器。 - 内网部署交付。 ### 7.2 docker commit:从容器提交镜像 假设你进入容器改了一些内容: ```bash docker exec -it my-nginx bash ``` 然后可以提交成镜像: ```bash docker commit my-nginx my-nginx-custom:1.0 ``` 查看: ```bash docker images ``` 但是注意: > 正式项目不推荐依赖 `docker commit` 制作镜像。更推荐写 Dockerfile,因为 Dockerfile 可复现、可维护、可交给别人重新构建。 `docker commit` 适合学习、临时保存实验结果。 --- ## 8. 分享镜像 对应视频:`10.命令_分享镜像` 分享镜像主要有两种方式: - 文件方式:`docker save` + `docker load`。 - 仓库方式:`docker tag` + `docker push`。 ### 8.1 文件分享 导出: ```bash docker save my-app:1.0 -o my-app-1.0.tar ``` 传到服务器: ```bash scp my-app-1.0.tar 用户名@服务器IP:/opt/ ``` 服务器导入: ```bash docker load -i /opt/my-app-1.0.tar ``` 启动: ```bash docker run -d --name my-app -p 8000:8000 my-app:1.0 ``` ### 8.2 推送到镜像仓库 登录: ```bash docker login ``` 给镜像打标签: ```bash docker tag my-app:1.0 用户名/my-app:1.0 ``` 推送: ```bash docker push 用户名/my-app:1.0 ``` 别人拉取: ```bash docker pull 用户名/my-app:1.0 ``` ### 8.3 版本命名建议 不要只用: ```text latest ``` 建议: ```text my-app:1.0.0 my-app:2026-05-19 my-app:dev my-app:prod ``` 项目交付时写清楚镜像版本,避免“昨天能跑,今天拉了 latest 跑不起来”。 --- ## 9. 命令实验小结 对应视频:`11.命令_实验小结` 这一阶段你要把 Docker 的基础命令串起来。 ### 9.1 镜像命令 ```bash docker search nginx docker pull nginx:1.25 docker images docker inspect nginx:1.25 docker history nginx:1.25 docker rmi nginx:1.25 ``` ### 9.2 容器命令 ```bash docker run -d --name my-nginx -p 8080:80 nginx:1.25 docker ps docker ps -a docker logs my-nginx docker exec -it my-nginx sh docker stop my-nginx docker start my-nginx docker restart my-nginx docker rm -f my-nginx ``` ### 9.3 排障命令 ```bash docker logs --tail 100 容器名 docker inspect 容器名 docker stats ss -tunlp | grep 端口 curl -v http://127.0.0.1:端口 ``` 如果一个容器服务访问不了,先问四个问题: 1. 容器是否正在运行? 2. 容器内部服务是否启动成功? 3. 端口是否映射正确? 4. 宿主机防火墙或云安全组是否放行? --- ## 10. 存储:目录挂载 对应视频:`12.存储_目录挂载` 容器默认是临时的。容器删除后,容器内部新增的数据也可能随之消失。 所以正式部署必须考虑数据持久化。 目录挂载的意思是: ```text 宿主机目录 <-> 容器内部目录 ``` ### 10.1 Nginx 静态目录挂载 创建宿主机目录: ```bash mkdir -p /opt/nginx-demo/html ``` 写一个页面: ```bash echo "hello docker nginx" > /opt/nginx-demo/html/index.html ``` 启动容器: ```bash docker run -d \ --name nginx-demo \ -p 8080:80 \ -v /opt/nginx-demo/html:/usr/share/nginx/html \ nginx:1.25 ``` 访问: ```bash curl http://127.0.0.1:8080 ``` 你改宿主机的 `/opt/nginx-demo/html/index.html`,容器里看到的内容也会变化。 ### 10.2 挂载配置文件 例如挂载 Nginx 配置: ```bash docker run -d \ --name nginx-conf-demo \ -p 8080:80 \ -v /opt/nginx-demo/nginx.conf:/etc/nginx/nginx.conf:ro \ nginx:1.25 ``` 末尾 `:ro` 表示只读挂载。 ### 10.3 目录挂载常见问题 #### 宿主机目录不存在 Docker 可能会自动创建目录,但不一定符合你的预期。建议先手动创建。 ```bash mkdir -p /opt/project/data ``` #### 权限不足 容器内进程可能无法写宿主机目录。 排查: ```bash ls -ld /opt/project/data docker logs 容器名 ``` #### 路径写错 挂载路径写错会导致容器内看不到期望文件。 检查: ```bash docker inspect 容器名 docker exec -it 容器名 sh ``` --- ## 11. 存储:卷映射 对应视频:`13.存储_卷映射` Docker Volume 是 Docker 自己管理的数据卷。 目录挂载由你指定宿主机路径: ```bash -v /opt/mysql-data:/var/lib/mysql ``` Volume 由 Docker 管理: ```bash -v mysql-data:/var/lib/mysql ``` ### 11.1 创建卷 ```bash docker volume create mysql-data docker volume ls docker volume inspect mysql-data ``` ### 11.2 使用卷 ```bash docker run -d \ --name mysql-demo \ -e MYSQL_ROOT_PASSWORD=123456 \ -v mysql-data:/var/lib/mysql \ mysql:8.0 ``` 删除容器后,卷还在: ```bash docker rm -f mysql-demo docker volume ls ``` 重新启动一个 MySQL 容器,仍可复用这个数据卷。 ### 11.3 删除卷 ```bash docker volume rm mysql-data ``` 清理未使用卷: ```bash docker volume prune ``` 注意: > 删除卷可能意味着删除数据库数据。不要在不确认的情况下执行 `docker volume prune`。 ### 11.4 目录挂载和卷的选择 适合目录挂载: - 你需要直接编辑配置文件。 - 你需要清楚知道数据在宿主机哪个目录。 - 项目 README 要写明确路径。 适合 volume: - 数据由 Docker 管理即可。 - 不想关心宿主机具体路径。 - 数据库类服务。 学习和交付项目里,推荐你把重要数据目录写清楚,例如: ```text /opt/rf-platform/data /opt/rf-platform/uploads /opt/rf-platform/logs ``` 这样更容易排障和备份。 --- ## 12. 网络:自定义网络 对应视频:`14.网络_自定义网络` 容器之间通信,最推荐使用自定义网络。 ### 12.1 查看网络 ```bash docker network ls ``` 常见默认网络: - bridge - host - none 大多数普通容器默认使用 bridge。 ### 12.2 创建自定义网络 ```bash docker network create app-net ``` 查看: ```bash docker network ls docker network inspect app-net ``` ### 12.3 在同一网络启动两个容器 启动 Redis: ```bash docker run -d \ --name redis \ --network app-net \ redis:7.2 ``` 启动一个临时容器测试: ```bash docker run --rm -it \ --network app-net \ redis:7.2 \ redis-cli -h redis ping ``` 如果返回: ```text PONG ``` 说明容器可以通过名字 `redis` 访问 Redis 容器。 ### 12.4 为什么不要依赖容器 IP 容器 IP 可能变化。容器删除重建后,IP 不一定相同。 自定义网络里可以用容器名当域名: ```text redis mysql backend nginx ``` 这就是 Compose 里服务名互通的基础。 --- ## 13. 网络:Redis 主从集群 对应视频:`15.网络_Redis主从集群` 这一集的重点不是让你成为 Redis 专家,而是通过 Redis 主从理解: > 多个容器如何在同一个 Docker 网络里互相访问,并通过容器名组成一个小型服务集群。 ### 13.1 创建网络 ```bash docker network create redis-net ``` ### 13.2 启动 Redis 主节点 ```bash docker run -d \ --name redis-master \ --network redis-net \ redis:7.2 ``` ### 13.3 启动 Redis 从节点 ```bash docker run -d \ --name redis-slave-1 \ --network redis-net \ redis:7.2 \ redis-server --replicaof redis-master 6379 ``` 再启动一个: ```bash docker run -d \ --name redis-slave-2 \ --network redis-net \ redis:7.2 \ redis-server --replicaof redis-master 6379 ``` ### 13.4 验证主从 进入主节点: ```bash docker exec -it redis-master redis-cli ``` 写入: ```redis set name docker ``` 进入从节点: ```bash docker exec -it redis-slave-1 redis-cli ``` 读取: ```redis get name ``` 查看复制信息: ```redis info replication ``` ### 13.5 你真正要掌握的点 - 容器名可以作为网络地址。 - 多个容器要放到同一个自定义网络。 - 数据库、中间件、后端服务之间不一定要暴露到宿主机。 - 对外访问通常只暴露 Nginx 或网关。 --- ## 14. Docker 最佳实践 对应视频:`16.最佳实践` ### 14.1 不要把重要数据只放容器里 错误做法: ```bash docker run -d --name mysql mysql:8.0 ``` 容器删了,数据很容易一起没了。 更好的做法: ```bash docker run -d \ --name mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ -v mysql-data:/var/lib/mysql \ mysql:8.0 ``` 或挂载宿主机目录: ```bash -v /opt/mysql-data:/var/lib/mysql ``` ### 14.2 不要乱用 latest 建议固定版本: ```yaml image: mysql:8.0 image: redis:7.2 image: nginx:1.25 ``` ### 14.3 容器要有清晰命名 ```bash --name rf-platform-api --name rf-platform-nginx --name rf-platform-redis ``` ### 14.4 配置和数据分开 推荐目录: ```text /opt/rf-platform/ docker-compose.yml .env nginx/ data/ logs/ uploads/ ``` ### 14.5 对外只暴露必要端口 推荐: ```text 外部 -> Nginx 80/443 Nginx -> API 8000 API -> Redis/MySQL ``` 数据库和 Redis 不一定要对外暴露。 ### 14.6 先看日志再猜问题 ```bash docker logs --tail 100 服务名 docker compose logs -f 服务名 ``` 日志是排障第一证据。 --- ## 15. Docker Compose 安装 WordPress 对应视频:`17.DockerCompose_安装wordpress` Compose 用一个 YAML 文件描述多个容器。 WordPress 需要: - WordPress 应用容器。 - MySQL 数据库容器。 - 数据卷保存数据库。 - 端口映射访问 WordPress。 - 网络让 WordPress 访问 MySQL。 ### 15.1 创建目录 ```bash mkdir -p /opt/wordpress-demo cd /opt/wordpress-demo ``` ### 15.2 编写 docker-compose.yml ```yaml services: db: image: mysql:8.0 container_name: wordpress-db restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpresspass volumes: - db_data:/var/lib/mysql wordpress: image: wordpress:latest container_name: wordpress-web restart: unless-stopped depends_on: - db ports: - "8080:80" environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpresspass WORDPRESS_DB_NAME: wordpress volumes: - wordpress_data:/var/www/html volumes: db_data: wordpress_data: ``` ### 15.3 启动 ```bash docker compose up -d ``` 查看: ```bash docker compose ps docker compose logs -f ``` 访问: ```bash curl -I http://127.0.0.1:8080 ``` 浏览器打开: ```text http://服务器IP:8080 ``` ### 15.4 停止和删除 停止: ```bash docker compose stop ``` 启动: ```bash docker compose start ``` 删除容器和网络: ```bash docker compose down ``` 连数据卷一起删除: ```bash docker compose down -v ``` 注意: > `down -v` 会删除数据库数据。学习环境可以用,真实项目要小心。 --- ## 16. Docker Compose 语法 对应视频:`18.DockerCompose_语法` Compose 的核心是 `services`。 ### 16.1 最小结构 ```yaml services: nginx: image: nginx:1.25 ports: - "8080:80" ``` 启动: ```bash docker compose up -d ``` ### 16.2 image 直接使用现成镜像: ```yaml services: redis: image: redis:7.2 ``` ### 16.3 build 使用 Dockerfile 构建镜像: ```yaml services: api: build: . image: rf-platform-api:1.0 ``` ### 16.4 container_name ```yaml container_name: rf-platform-api ``` 学习环境方便查看。但大型项目里有时不建议固定 container_name,因为可能影响扩容。 ### 16.5 ports ```yaml ports: - "8080:80" ``` 含义: ```text 宿主机端口:容器端口 ``` 如果只给内部服务用,可以不写 `ports`,只用 `expose` 或默认网络通信。 ### 16.6 environment ```yaml environment: MYSQL_ROOT_PASSWORD: 123456 MYSQL_DATABASE: app ``` 也可以使用 `.env` 文件: ```yaml environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} ``` `.env`: ```env MYSQL_ROOT_PASSWORD=123456 ``` ### 16.7 volumes 目录挂载: ```yaml volumes: - ./html:/usr/share/nginx/html ``` 命名卷: ```yaml volumes: - db_data:/var/lib/mysql volumes: db_data: ``` ### 16.8 networks ```yaml services: api: networks: - app-net redis: networks: - app-net networks: app-net: ``` 同一 Compose 项目默认会创建网络,很多简单项目不用手写 networks。 ### 16.9 depends_on ```yaml depends_on: - db ``` 含义是启动顺序依赖,不等于数据库已经完全可用。应用还应该有重试机制。 ### 16.10 restart ```yaml restart: unless-stopped ``` 服务器部署建议加上。 ### 16.11 常用 Compose 命令 ```bash docker compose up -d docker compose down docker compose ps docker compose logs -f docker compose logs --tail 100 api docker compose restart docker compose pull docker compose build docker compose up -d --build ``` --- ## 17. Docker Compose 其他 对应视频:`19.DockerCompose_其他` ### 17.1 查看项目状态 ```bash docker compose ps ``` ### 17.2 查看日志 全部服务: ```bash docker compose logs -f ``` 单个服务: ```bash docker compose logs -f api ``` 最近 100 行: ```bash docker compose logs --tail 100 api ``` ### 17.3 进入服务容器 ```bash docker compose exec api sh docker compose exec db mysql -uroot -p docker compose exec redis redis-cli ``` ### 17.4 重建服务 ```bash docker compose up -d --build ``` 适合 Dockerfile 或代码变化后重新构建。 ### 17.5 清理项目 ```bash docker compose down ``` 如果要删除数据卷: ```bash docker compose down -v ``` 再次提醒:`-v` 会删除 Compose 创建的命名卷,数据库数据可能消失。 --- ## 18. Dockerfile 制作镜像 对应视频:`20.Dockerfile_制作镜像` Dockerfile 是制作镜像的说明书。 ### 18.1 一个最小 Python FastAPI Dockerfile 项目结构: ```text rf-platform/ app/ main.py requirements.txt Dockerfile ``` `requirements.txt`: ```text fastapi uvicorn[standard] pandas matplotlib ``` `Dockerfile`: ```dockerfile FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY app/ ./app/ EXPOSE 8000 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] ``` 构建: ```bash docker build -t rf-platform-api:1.0 . ``` 运行: ```bash docker run -d \ --name rf-platform-api \ -p 8000:8000 \ rf-platform-api:1.0 ``` 测试: ```bash curl -v http://127.0.0.1:8000 ``` ### 18.2 常用 Dockerfile 指令 ```dockerfile FROM WORKDIR COPY RUN ENV EXPOSE CMD ENTRYPOINT ``` 解释: - `FROM`:基础镜像。 - `WORKDIR`:工作目录。 - `COPY`:复制文件到镜像。 - `RUN`:构建镜像时执行命令。 - `ENV`:设置环境变量。 - `EXPOSE`:声明容器内服务端口。 - `CMD`:容器启动时默认执行的命令。 - `ENTRYPOINT`:容器入口命令。 ### 18.3 CMD 和 RUN 的区别 `RUN` 是构建镜像时执行: ```dockerfile RUN pip install -r requirements.txt ``` `CMD` 是容器启动时执行: ```dockerfile CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] ``` ### 18.4 .dockerignore 不要把无关文件复制进镜像。 `.dockerignore`: ```text .git __pycache__ .venv *.log data uploads outputs ``` 好处: - 构建更快。 - 镜像更小。 - 避免把本地数据、日志、密钥打进镜像。 --- ## 19. 镜像分层机制 对应视频:`21.Dockerfile_镜像分层机制` Docker 镜像是分层的。Dockerfile 里的很多指令都会产生层。 例如: ```dockerfile FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY app/ ./app/ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] ``` 可以看历史: ```bash docker history rf-platform-api:1.0 ``` ### 19.1 为什么先 COPY requirements.txt 推荐: ```dockerfile COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY app/ ./app/ ``` 不要一开始就: ```dockerfile COPY . . RUN pip install --no-cache-dir -r requirements.txt ``` 原因: - Docker 构建有缓存。 - 依赖文件不变时,安装依赖这一层可以复用。 - 代码变化时,只重新复制代码层。 - 构建速度更快。 ### 19.2 减小镜像体积 建议: - 使用 `python:3.11-slim` 而不是完整大镜像。 - 使用 `.dockerignore`。 - 安装依赖时加 `--no-cache-dir`。 - 不把数据、日志、临时文件复制进镜像。 ### 19.3 镜像不是数据仓库 不要把上传文件、数据库数据、分析结果写死进镜像。镜像应该保存程序和运行环境,数据应该用 volume 或目录挂载。 --- ## 20. 一键启动所有中间件 对应视频:`22.超酷_一键启动所有中间件` 这一集的核心是: > 用 Docker Compose 把一组常用中间件一次性启动起来。 中间件可以包括: - MySQL - Redis - Nginx - MinIO - PostgreSQL - RabbitMQ - Elasticsearch 你不一定都要学深入,但要会用 Compose 管理。 ### 20.1 示例:MySQL + Redis + Nginx ```yaml services: mysql: image: mysql:8.0 container_name: demo-mysql restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: demo volumes: - mysql_data:/var/lib/mysql redis: image: redis:7.2 container_name: demo-redis restart: unless-stopped volumes: - redis_data:/data nginx: image: nginx:1.25 container_name: demo-nginx restart: unless-stopped ports: - "8080:80" volumes: - ./nginx/html:/usr/share/nginx/html:ro volumes: mysql_data: redis_data: ``` 启动: ```bash docker compose up -d ``` 查看: ```bash docker compose ps ``` 日志: ```bash docker compose logs -f ``` ### 20.2 为什么这很重要 以后你做项目时,不应该手动一条条 `docker run` 启动一堆服务。 更好的方式是: ```text docker-compose.yml -> 记录服务、版本、端口、环境变量、挂载、网络 -> 一条命令启动 -> 一条命令停止 -> README 可复现 ``` --- ## 21. 访问测试全部通过 对应视频:`23.超酷_访问测试全部通过` 启动一组服务后,不等于部署成功。你要会测试。 ### 21.1 看容器是否运行 ```bash docker compose ps ``` 关注: - STATUS 是否 Up。 - PORTS 是否有映射。 - 是否反复 Restarting。 ### 21.2 看日志是否报错 ```bash docker compose logs --tail 100 docker compose logs -f mysql docker compose logs -f redis docker compose logs -f nginx ``` ### 21.3 测试端口 宿主机查看端口: ```bash ss -tunlp ``` 测试 HTTP: ```bash curl -I http://127.0.0.1:8080 ``` 测试 Redis: ```bash docker compose exec redis redis-cli ping ``` 测试 MySQL: ```bash docker compose exec mysql mysql -uroot -p ``` ### 21.4 排查访问失败 如果浏览器打不开: ```bash docker compose ps docker compose logs --tail 100 nginx ss -tunlp | grep 8080 curl -v http://127.0.0.1:8080 ``` 如果容器内服务访问不了另一个服务: ```bash docker compose exec api sh ping redis ``` 有些镜像没有 `ping`,可以用对应客户端测试,例如 `redis-cli`、`mysql`、`curl`。 --- ## 22. 销毁实例 对应视频:`24.销毁实例` 学习和实验结束后,要会清理。 ### 22.1 停止项目 ```bash docker compose stop ``` 只是停止,不删除容器。 ### 22.2 删除项目容器和网络 ```bash docker compose down ``` 会删除 Compose 创建的容器和网络,但默认不删除命名卷。 ### 22.3 连数据卷一起删 ```bash docker compose down -v ``` 这会删除数据卷。数据库、上传文件等可能丢失。 ### 22.4 删除镜像 ```bash docker rmi 镜像名:标签 ``` ### 22.5 清理未使用资源 查看占用: ```bash docker system df ``` 清理停止容器: ```bash docker container prune ``` 清理无用镜像: ```bash docker image prune ``` 清理无用卷: ```bash docker volume prune ``` 清理全部未使用资源: ```bash docker system prune ``` 谨慎使用: ```bash docker system prune -a ``` 它会清理更多未使用镜像,可能导致下次重新拉取很慢。 --- ## 23. 结束语:你应该学到什么程度 对应视频:`25.结束语` 你不需要现在就学 Kubernetes。先把 Docker 基础练扎实。 最低验收标准: - 能用 Docker 部署 Nginx。 - 能用 Docker 部署 Redis/MySQL。 - 能用 `docker logs` 看日志。 - 能用 `-p` 映射端口。 - 能用 `-v` 挂载目录或 volume。 - 能创建自定义网络。 - 能用 Compose 启动 WordPress 或一组中间件。 - 能写 Dockerfile 打包自己的 FastAPI 项目。 - 能解释镜像、容器、仓库、网络、卷的区别。 --- ## 24. 按视频顺序的练习任务 ### 任务 1:跑通 Nginx ```bash docker pull nginx:1.25 docker run -d --name nginx-demo -p 8080:80 nginx:1.25 docker ps curl -I http://127.0.0.1:8080 docker logs nginx-demo ``` 验收: - `docker ps` 能看到 nginx-demo。 - `curl` 返回 HTTP 响应头。 - 浏览器能访问 8080。 ### 任务 2:目录挂载 ```bash mkdir -p /opt/nginx-demo/html echo "hello docker" > /opt/nginx-demo/html/index.html docker rm -f nginx-demo docker run -d --name nginx-demo -p 8080:80 \ -v /opt/nginx-demo/html:/usr/share/nginx/html \ nginx:1.25 curl http://127.0.0.1:8080 ``` 验收: - 修改宿主机 `index.html` 后,访问内容同步变化。 ### 任务 3:Redis 自定义网络 ```bash docker network create app-net docker run -d --name redis --network app-net redis:7.2 docker run --rm -it --network app-net redis:7.2 redis-cli -h redis ping ``` 验收: ```text PONG ``` ### 任务 4:Compose 部署 WordPress 创建 `docker-compose.yml`,使用 WordPress + MySQL,然后: ```bash docker compose up -d docker compose ps docker compose logs --tail 100 curl -I http://127.0.0.1:8080 ``` 验收: - WordPress 初始化页面能打开。 - MySQL 数据使用 volume 保存。 ### 任务 5:Dockerfile 打包 FastAPI 构建: ```bash docker build -t rf-platform-api:1.0 . ``` 运行: ```bash docker run -d --name rf-platform-api -p 8000:8000 rf-platform-api:1.0 ``` 测试: ```bash curl -v http://127.0.0.1:8000 ``` 验收: - 能解释 Dockerfile 每一行。 - 能通过日志排查启动失败原因。 --- ## 25. Docker 常见问题排查表 ### 容器启动后马上退出 查看: ```bash docker ps -a docker logs 容器名 ``` 常见原因: - 启动命令错。 - 配置文件错。 - 环境变量缺失。 - 应用启动时报错。 ### 端口访问不了 查看: ```bash docker ps ss -tunlp | grep 端口 curl -v http://127.0.0.1:端口 ``` 常见原因: - `-p` 没写。 - 端口写反。 - 容器内服务没监听。 - 云安全组没放行。 端口映射别写反: ```text -p 宿主机端口:容器端口 ``` ### 数据丢失 常见原因: - 数据写在容器内部。 - 删除容器后没有 volume。 - 执行了 `docker compose down -v`。 解决: - 使用 volume。 - 使用宿主机目录挂载。 - 写清楚备份目录。 ### 容器之间互相访问失败 查看: ```bash docker network ls docker network inspect 网络名 docker inspect 容器名 ``` 解决: - 放到同一个自定义网络。 - 用容器名或 Compose 服务名访问。 - 不依赖容器 IP。 ### 镜像构建很慢 优化: - 使用 `.dockerignore`。 - 先复制依赖文件,再安装依赖。 - 固定基础镜像版本。 - 复用构建缓存。 --- ## 26. 你可以写进简历的 Docker 表达 技能栏: ```text Docker:熟悉镜像、容器、端口映射、目录挂载、数据卷、自定义网络、Dockerfile 与 Docker Compose,能够完成 Web 服务和常用中间件的容器化部署与日志排障。 ``` 项目描述: ```text 使用 Docker Compose 编排 Nginx、FastAPI、Redis/MySQL 等服务,配置端口映射、数据卷持久化和自定义网络;通过 docker logs、docker compose logs、ss、curl 等命令排查容器启动失败、端口不通和服务访问异常问题。 ``` 结合射频测试平台: ```text 将射频测试数据分析平台容器化,编写 Dockerfile 构建 FastAPI 应用镜像,使用 Docker Compose 管理后端服务、Nginx 反向代理和数据目录挂载,实现服务器一键部署与快速恢复。 ``` --- ## 27. 进阶:把 Docker 用到真实项目里 前面的视频内容已经够你入门。进阶阶段要从“能启动容器”升级到“能稳定部署项目”。 真实项目里 Docker 要解决这些问题: - 服务如何自动重启。 - 配置如何管理。 - 数据如何持久化和备份。 - 日志如何查看和限制大小。 - 服务之间如何通信。 - 镜像如何构建得更小更快。 - 部署失败后如何定位。 - 更新版本时如何减少中断。 你可以用下面这条主线学习进阶 Docker: ```text Dockerfile 优化 -> Compose 工程化 -> 数据卷和备份 -> 网络隔离 -> 健康检查 -> 日志和资源限制 -> Nginx 反向代理 -> 项目部署与回滚 ``` --- ## 28. 进阶 Dockerfile:写得像工程项目 基础 Dockerfile 能跑就行,进阶 Dockerfile 要考虑: - 构建速度。 - 镜像大小。 - 安全性。 - 可维护性。 - 缓存利用。 ### 28.1 更完整的 FastAPI Dockerfile ```dockerfile FROM python:3.11-slim ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 WORKDIR /app RUN apt-get update \ && apt-get install -y --no-install-recommends curl \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY app/ ./app/ RUN useradd -m appuser USER appuser EXPOSE 8000 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] ``` 这里比基础版多了几个点: - `PYTHONDONTWRITEBYTECODE=1`:不生成 `.pyc` 文件。 - `PYTHONUNBUFFERED=1`:日志更及时输出到控制台。 - `--no-install-recommends`:减少不必要系统包。 - `rm -rf /var/lib/apt/lists/*`:清理 apt 缓存,减小镜像。 - `USER appuser`:不用 root 运行应用,安全性更好。 ### 28.2 构建缓存技巧 推荐顺序: ```dockerfile COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY app/ ./app/ ``` 原因: - 依赖文件没变时,`pip install` 那一层可以复用。 - 只改业务代码时,构建速度会快很多。 ### 28.3 不要把密钥写进镜像 错误示例: ```dockerfile ENV MYSQL_PASSWORD=123456 COPY id_rsa /root/.ssh/id_rsa ``` 正确思路: - 密码放 `.env`,不要提交到公开仓库。 - 生产密钥用服务器环境变量、CI/CD Secret 或专门的密钥管理。 - 镜像只保存程序和运行环境。 ### 28.4 镜像构建常用命令 ```bash docker build -t rf-platform-api:1.0 . docker build --no-cache -t rf-platform-api:1.0 . docker history rf-platform-api:1.0 docker image inspect rf-platform-api:1.0 ``` `--no-cache` 适合排查缓存导致的构建异常,但平时不要滥用。 --- ## 29. 进阶:多阶段构建 多阶段构建适合前端、Go、Java 等需要先编译再运行的项目。核心思想是: > 构建阶段用完整工具链,运行阶段只保留运行所需文件。 ### 29.1 前端项目多阶段构建示例 ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM nginx:1.25-alpine COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] ``` 优点: - 最终镜像不包含 Node 构建工具。 - 镜像更小。 - 运行环境更干净。 ### 29.2 Go 项目多阶段构建示例 ```dockerfile FROM golang:1.22-alpine AS builder WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go build -o app ./cmd/server FROM alpine:3.20 WORKDIR /app COPY --from=builder /src/app /app/app EXPOSE 8080 CMD ["/app/app"] ``` 你现在主要学 Python/FastAPI,多阶段构建不是必须,但理解它会让你看懂更多真实项目的 Dockerfile。 --- ## 30. 进阶 Compose:生产感更强的写法 基础 Compose 只要能启动。进阶 Compose 要考虑: - `.env` 管理配置。 - 健康检查。 - 日志大小限制。 - 资源限制。 - 网络隔离。 - 数据卷明确。 - 服务依赖和重启策略。 ### 30.1 一个更完整的项目结构 ```text rf-platform/ docker-compose.yml .env Dockerfile app/ nginx/ default.conf data/ uploads/ logs/ ``` ### 30.2 .env 示例 ```env APP_PORT=8000 NGINX_PORT=80 MYSQL_ROOT_PASSWORD=change-me MYSQL_DATABASE=rf_platform MYSQL_USER=rf_user MYSQL_PASSWORD=rf_pass ``` 注意: - `.env` 可以放学习项目里。 - 真正公开仓库不要提交真实密码。 - 可以提交 `.env.example`,让别人照着复制。 ### 30.3 Compose 示例:Nginx + API + MySQL + Redis ```yaml services: api: build: . image: rf-platform-api:1.0 container_name: rf-platform-api restart: unless-stopped env_file: - .env volumes: - ./uploads:/app/uploads - ./logs:/app/logs expose: - "8000" depends_on: - mysql - redis networks: - backend healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/health"] interval: 30s timeout: 5s retries: 3 start_period: 20s logging: driver: json-file options: max-size: "10m" max-file: "3" nginx: image: nginx:1.25 container_name: rf-platform-nginx restart: unless-stopped ports: - "${NGINX_PORT}:80" volumes: - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - api networks: - frontend - backend mysql: image: mysql:8.0 container_name: rf-platform-mysql restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} volumes: - mysql_data:/var/lib/mysql networks: - backend logging: driver: json-file options: max-size: "10m" max-file: "3" redis: image: redis:7.2 container_name: rf-platform-redis restart: unless-stopped volumes: - redis_data:/data networks: - backend networks: frontend: backend: volumes: mysql_data: redis_data: ``` 这个例子体现了真实部署思路: - 只有 Nginx 对外暴露端口。 - API、MySQL、Redis 都在后端网络里。 - 数据库使用 volume 持久化。 - API 上传文件和日志挂载到宿主机目录。 - 日志做大小限制。 - API 增加健康检查。 --- ## 31. 健康检查 healthcheck 健康检查用于判断容器内服务是否真的可用。 容器运行中,不代表应用可用。比如: - 进程还在,但接口卡死。 - Web 服务启动了,但数据库连不上。 - 服务端口监听了,但返回 500。 ### 31.1 Dockerfile 里写健康检查 ```dockerfile HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ CMD curl -f http://127.0.0.1:8000/health || exit 1 ``` ### 31.2 Compose 里写健康检查 ```yaml healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/health"] interval: 30s timeout: 5s retries: 3 start_period: 20s ``` 查看健康状态: ```bash docker ps docker inspect 容器名 ``` 建议你的 FastAPI 项目提供一个接口: ```python @app.get("/health") def health(): return {"status": "ok"} ``` --- ## 32. 日志管理:别让 Docker 日志撑爆磁盘 Docker 默认使用 `json-file` 保存容器日志。如果不限制大小,长期运行可能撑爆磁盘。 查看 Docker 占用: ```bash docker system df du -sh /var/lib/docker ``` Compose 中限制日志: ```yaml logging: driver: json-file options: max-size: "10m" max-file: "3" ``` 含义: - 单个日志文件最大 10MB。 - 最多保留 3 个文件。 查看日志仍然用: ```bash docker logs --tail 100 容器名 docker compose logs -f api ``` 项目建议: - 应用日志输出到标准输出,方便 `docker logs` 查看。 - 关键业务日志也可以挂载到 `./logs`。 - Compose 里限制 Docker 日志大小。 --- ## 33. 资源限制:防止一个容器拖垮服务器 学习阶段通常不用限制资源,但真实服务器上建议知道这些参数。 ### 33.1 docker run 限制资源 限制内存: ```bash docker run -d --name api --memory 512m rf-platform-api:1.0 ``` 限制 CPU: ```bash docker run -d --name api --cpus 1.0 rf-platform-api:1.0 ``` ### 33.2 Compose 限制资源 普通 Compose 可以写: ```yaml services: api: image: rf-platform-api:1.0 mem_limit: 512m cpus: 1.0 ``` 查看实时资源: ```bash docker stats ``` 如果服务器只有 2C2G,不要一口气启动太多中间件。MySQL、Elasticsearch、OpenWebUI、Ollama 都可能吃资源。 --- ## 34. Compose profiles:按需启动服务 有些服务不是每次都要启动,比如管理后台、调试工具、一次性任务。 可以用 profiles: ```yaml services: api: image: rf-platform-api:1.0 redis: image: redis:7.2 adminer: image: adminer ports: - "8081:8080" profiles: - tools ``` 默认启动: ```bash docker compose up -d ``` 不会启动 `adminer`。 启动 tools: ```bash docker compose --profile tools up -d ``` 适合: - 数据库管理工具。 - 临时调试服务。 - 本地开发辅助容器。 --- ## 35. Nginx + Docker 的反向代理写法 你路线里 Docker 经常要和 Nginx 一起用。 ### 35.1 Nginx 在宿主机上 如果 Nginx 装在宿主机,后端容器映射到本机端口: ```yaml services: api: image: rf-platform-api:1.0 ports: - "127.0.0.1:8000:8000" ``` Nginx 配置: ```nginx server { listen 80; server_name example.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } ``` 优点: - 宿主机 Nginx 管理多个项目方便。 - 后端端口只绑定 `127.0.0.1`,外部不能直接访问。 ### 35.2 Nginx 也在容器里 Compose: ```yaml services: nginx: image: nginx:1.25 ports: - "80:80" volumes: - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - api api: image: rf-platform-api:1.0 expose: - "8000" ``` Nginx 配置: ```nginx server { listen 80; location / { proxy_pass http://api:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } ``` 注意: > Nginx 容器代理 API 容器时,地址用 Compose 服务名 `api`,不是 `127.0.0.1`。 这是很多 Docker 新手最容易错的地方。 --- ## 36. 部署更新和回滚 真实项目会不断更新。你要会更新,也要会回滚。 ### 36.1 更新镜像版本 假设当前: ```yaml image: rf-platform-api:1.0 ``` 更新为: ```yaml image: rf-platform-api:1.1 ``` 执行: ```bash docker compose pull docker compose up -d docker compose ps docker compose logs --tail 100 api ``` 如果是本地构建: ```bash docker compose build api docker compose up -d api ``` ### 36.2 回滚 把 Compose 里的版本改回: ```yaml image: rf-platform-api:1.0 ``` 执行: ```bash docker compose up -d api docker compose logs --tail 100 api ``` 所以镜像版本一定要固定,不要只写 `latest`。 ### 36.3 更新前备份 数据库类服务更新前先备份。 MySQL 备份示例: ```bash docker compose exec mysql \ mysqldump -uroot -p${MYSQL_ROOT_PASSWORD} rf_platform > backup.sql ``` 也可以进入容器执行,或写专门的备份脚本。 --- ## 37. Docker 安全基础 你现在不需要学很深,但这些底线要知道。 ### 37.1 不要随便暴露数据库端口 不推荐: ```yaml mysql: ports: - "3306:3306" ``` 除非你明确需要外部访问数据库。更推荐只在 Docker 网络内部访问。 ### 37.2 不要把密码写进公开仓库 不要提交真实 `.env`。 可以提交: ```text .env.example ``` 内容: ```env MYSQL_ROOT_PASSWORD=please-change-me MYSQL_DATABASE=rf_platform MYSQL_USER=rf_user MYSQL_PASSWORD=please-change-me ``` ### 37.3 不要长期用 root 跑应用 Dockerfile 里尽量: ```dockerfile RUN useradd -m appuser USER appuser ``` ### 37.4 不要滥用 privileged 危险参数: ```bash --privileged ``` 它会给容器很高权限。除非你明确知道为什么需要,否则不要用。 ### 37.5 镜像来源要可靠 优先使用: - 官方镜像。 - 大厂维护镜像。 - 自己构建的镜像。 不要随便拉不明来源镜像跑在服务器上。 --- ## 38. 面向你的进阶实战项目 你可以做一个完整项目: > 射频测试数据分析平台 Docker 化部署 ### 38.1 项目功能 - 上传 `.csv` 或 `.s2p` 文件。 - FastAPI 解析文件。 - pandas 处理数据。 - matplotlib 生成曲线图。 - 页面展示 S11/S21 曲线。 - Redis 缓存任务状态。 - MySQL 保存上传记录。 - Nginx 对外提供访问。 ### 38.2 推荐架构 ```text 浏览器 -> Nginx 容器 80/443 -> FastAPI 容器 8000 -> Redis 容器 -> MySQL 容器 -> uploads/logs 挂载目录 ``` ### 38.3 你要交付的文件 ```text Dockerfile docker-compose.yml .env.example nginx/default.conf README.md ``` README 要包含: - 环境要求。 - 启动命令。 - 停止命令。 - 日志查看。 - 数据目录。 - 常见问题排查。 ### 38.4 面试时的讲法 ```text 我将 FastAPI 射频测试数据分析平台容器化,使用 Dockerfile 构建应用镜像,并通过 Docker Compose 编排 Nginx、API、Redis 和 MySQL。部署中我配置了数据卷持久化、容器自定义网络、日志大小限制和健康检查;排障时主要使用 docker compose ps、docker compose logs、ss、curl 等命令定位容器状态、端口映射、服务健康和反向代理问题。 ``` 这比单纯说“我学过 Docker”强很多。 --- ## 39. 进阶排障清单 当 Docker 项目访问不了时,按这个顺序查。 ### 39.1 看容器状态 ```bash docker compose ps docker ps -a ``` 重点看: - 是否 Up。 - 是否 Restarting。 - 是否 Exited。 - 端口是否映射。 ### 39.2 看日志 ```bash docker compose logs --tail 100 docker compose logs -f api docker compose logs -f nginx ``` 重点搜: - error - failed - permission denied - connection refused - no such file or directory - address already in use ### 39.3 看端口 ```bash ss -tunlp | grep 80 ss -tunlp | grep 8000 curl -v http://127.0.0.1 curl -v http://127.0.0.1:8000 ``` 如果 API 没有映射到宿主机,只能从同一 Docker 网络或 Nginx 容器里访问。 ### 39.4 进容器内部查 ```bash docker compose exec api sh docker compose exec nginx sh ``` 在 Nginx 容器里测试 API: ```bash curl -v http://api:8000/health ``` 如果这里不通,说明 Docker 网络、服务名、API 监听地址或 API 本身有问题。 ### 39.5 查挂载 ```bash docker inspect 容器名 ls -la ./uploads ls -la ./logs ``` 重点看: - 宿主机目录是否存在。 - 容器内路径是否正确。 - 权限是否允许写入。 ### 39.6 查 Docker 资源 ```bash docker system df docker stats df -h free -h ``` 磁盘满、内存不足都会让容器异常。 --- ## 40. 最终总结 这套视频的主线可以浓缩成一条工程链路: ```text 理解 Docker 架构 -> 安装 Docker -> 操作镜像 -> 操作容器 -> 掌握 docker run 参数 -> 保存和分享镜像 -> 做数据持久化 -> 建自定义网络 -> 用 Compose 编排多服务 -> 用 Dockerfile 制作自己的镜像 -> 一键启动中间件 -> 测试访问 -> 销毁和清理资源 ``` 你学完后最应该具备的能力不是“我看过 Docker 视频”,而是: > 给我一台 Linux 服务器和一个项目,我能用 Docker/Compose 把它部署起来,并且能定位端口、日志、挂载、网络和镜像构建相关的问题。 这正好对应你的路线:Linux 是服务器基础,Docker 是部署能力核心,Nginx 是对外入口,Python/FastAPI 是你的项目载体,射频测试数据平台是你的差异化方向。
linux学习 作者: typecho 时间: 2026-05-18 分类: 默认分类 评论 # Linux 工程够用版学习讲义 基于项目中的学习路线整理。你的 Linux 学习目标不是成为“纯运维”,而是把 Linux 作为工程工具,用来支撑服务器部署、系统联调、测试平台搭建、Docker/Nginx 部署、日志排障和交付现场问题处理。 一句话定位: > 你要学的是“能把服务稳定跑起来、出问题能定位、能写进项目和简历”的 Linux,而不是内核、驱动、编译器、进程调度那种底层路线。 --- ## 1. 这条路线里 Linux 的位置 项目路线的主线是: > 通信/射频背景 + Linux/Docker/Nginx 部署能力 + Python 数据处理/测试平台能力 所以 Linux 在这里有三个作用。 第一,它是服务器操作环境。你以后做 Docker 部署、Nginx 反向代理、FastAPI 平台、Ollama/OpenWebUI 私有化部署,基本都会落到 Linux 服务器上。 第二,它是排障工具箱。服务访问不了、端口被占用、磁盘满了、权限不对、进程挂了、日志报错、Nginx 502、HTTPS 证书异常,这些都要靠 Linux 命令定位。 第三,它是面试和项目表达能力。你不需要说“精通 Linux 内核”,但要能说清楚“我如何在服务器上部署服务、查看日志、定位端口、处理权限、设置开机自启、排查资源占用”。 你应该避免的误区: - 不要一开始钻 Linux 内核源码。 - 不要把 Shell 高级编程当主线。 - 不要花太多时间背冷门命令。 - 不要只看视频不操作服务器。 - 不要把目标定成低端运维,而要定成“工程交付 + 部署排障 + 测试平台落地”。 你应该建立的能力: - 会连接服务器。 - 会管理文件和目录。 - 会理解权限。 - 会安装软件和管理服务。 - 会看进程、端口、磁盘、内存。 - 会看日志。 - 会排查一个 Web 服务为什么访问不了。 - 会为 Docker、Nginx、Python Web 服务提供 Linux 基础环境。 --- ## 2. 推荐学习顺序 不要按“Linux 大百科”的顺序学。建议按工程场景学。 ### 阶段 1:先会登录服务器和安全操作 目标: - 能用 SSH 登录服务器。 - 能用 SCP/SFTP 传文件。 - 知道自己当前在哪个目录。 - 知道哪些命令危险。 - 知道 root 用户和普通用户的区别。 必须掌握: ```bash ssh scp pwd whoami hostname date clear exit sudo ``` ### 阶段 2:文件和目录操作 目标: - 能在服务器上找到文件。 - 能创建、复制、移动、删除文件。 - 能查看配置文件和日志文件。 - 能编辑简单配置。 必须掌握: ```bash ls cd mkdir touch cp mv rm cat less head tail find du vim nano ``` ### 阶段 3:权限和用户 目标: - 知道为什么脚本不能执行。 - 知道为什么 Nginx 访问文件时报 403。 - 知道为什么 Docker 或服务没有权限写目录。 必须掌握: ```bash chmod chown id groups useradd passwd su sudo ``` ### 阶段 4:进程、资源和端口 目标: - 能判断服务有没有启动。 - 能找到占用端口的程序。 - 能看 CPU、内存、磁盘是否异常。 - 能停止异常进程。 必须掌握: ```bash ps top htop free -h df -h du -sh ss -tunlp lsof kill ``` ### 阶段 5:服务管理和日志 目标: - 能启动、停止、重启服务。 - 能设置服务开机自启。 - 能实时看日志。 - 能根据日志判断服务失败原因。 必须掌握: ```bash systemctl journalctl tail -f grep ``` ### 阶段 6:网络连通性和 Web 排障 目标: - 能判断域名是否解析正确。 - 能判断服务器是否能访问外网。 - 能判断本机服务是否正常响应。 - 能初步排查 Nginx 502/403/404。 必须掌握: ```bash ping curl ip addr ip route ss -tunlp dig nslookup traceroute ``` ### 阶段 7:和 Docker/Nginx/Python 项目结合 目标: - 会给项目创建目录。 - 会保存配置文件。 - 会查看容器日志和宿主机日志。 - 会判断问题是在 Linux、Docker、Nginx 还是应用代码。 必须掌握的工程动作: - 创建项目目录:`/opt/project-name` - 保存数据目录:`/data/project-name` - 保存日志目录:`/var/log/project-name` - 用 `systemctl` 管理 Nginx。 - 用 `journalctl` 和 `docker logs` 找错误。 - 用 `ss -tunlp` 看端口。 - 用 `curl` 本机自测接口。 --- ## 3. Linux 文件系统:先理解这些目录 你不需要背所有目录,但要知道常见目录的意义。 ```text / 根目录,所有路径从这里开始 /home 普通用户家目录 /root root 用户家目录 /etc 系统和服务配置文件 /var/log 日志目录 /var/www 常见网站文件目录 /opt 第三方项目或自部署项目目录 /usr/bin 常用命令程序 /usr/local 用户自己安装的软件常放这里 /tmp 临时文件目录 /data 常见自定义数据目录,不是所有系统默认都有 /proc 进程和系统状态的虚拟文件系统 ``` 工程上你最常接触的是: - `/etc/nginx/`:Nginx 配置。 - `/var/log/nginx/`:Nginx 访问日志和错误日志。 - `/opt/`:部署项目。 - `/home/用户名/`:普通用户文件。 - `/root/`:root 用户文件。 - `/tmp/`:临时测试文件。 路径有两种写法。 绝对路径: ```bash /etc/nginx/nginx.conf /opt/rf-platform/docker-compose.yml ``` 相对路径: ```bash ./docker-compose.yml ../logs/app.log ``` 建议你在服务器上操作配置文件时,尽量用绝对路径,减少“我到底在哪个目录”的混乱。 --- ## 4. SSH:连接服务器的第一步 SSH 是远程登录 Linux 服务器的基础。 基本登录: ```bash ssh 用户名@服务器IP ``` 指定端口: ```bash ssh -p 22 用户名@服务器IP ``` 使用密钥登录: ```bash ssh -i ~/.ssh/id_rsa 用户名@服务器IP ``` 第一次登录时会看到类似提示: ```text Are you sure you want to continue connecting? ``` 输入 `yes` 即可。它的意思是把这台服务器的指纹加入本机信任列表。 常见问题: ### 连接超时 可能原因: - 服务器没开机。 - IP 写错。 - 安全组没有开放 22 端口。 - 服务器防火墙阻止了 SSH。 - 本地网络访问不到服务器。 排查: ```bash ping 服务器IP ``` 如果 ping 不通,不一定代表服务器坏了,有些云服务器默认禁 ping。继续看端口是否能连。 ```bash ssh -v 用户名@服务器IP ``` `-v` 会输出更详细的连接过程。 ### Permission denied 可能原因: - 用户名错。 - 密码错。 - 密钥错。 - 服务器禁用了密码登录。 - 密钥权限太宽。 密钥权限可以这样修: ```bash chmod 600 ~/.ssh/id_rsa ``` ### 连接上以后第一件事 建议执行: ```bash whoami pwd hostname ip addr df -h free -h ``` 你要知道: - 我是谁。 - 我在哪。 - 我连的是哪台机器。 - 这台机器的 IP 是什么。 - 磁盘是否快满。 - 内存是否够用。 --- ## 5. SCP:在本地和服务器之间传文件 从本地传到服务器: ```bash scp ./app.py 用户名@服务器IP:/opt/rf-platform/ ``` 从服务器下载到本地: ```bash scp 用户名@服务器IP:/var/log/nginx/error.log ./ ``` 传目录要加 `-r`: ```bash scp -r ./rf-platform 用户名@服务器IP:/opt/ ``` 指定 SSH 端口: ```bash scp -P 2222 ./file.txt 用户名@服务器IP:/tmp/ ``` 注意:`ssh` 指定端口是小写 `-p`,`scp` 指定端口是大写 `-P`。 项目里常见用途: - 上传 `docker-compose.yml`。 - 上传 Nginx 配置。 - 下载日志给别人分析。 - 上传测试数据文件,比如 `.csv`、`.s2p`。 --- ## 6. 文件查看:别一上来就 vim 看文件内容: ```bash cat 文件名 ``` 适合小文件。不适合大日志。 分页看文件: ```bash less 文件名 ``` 常用操作: - `Space` 下一页。 - `b` 上一页。 - `/关键词` 搜索。 - `n` 下一个匹配。 - `q` 退出。 看前几行: ```bash head 文件名 head -n 50 文件名 ``` 看后几行: ```bash tail 文件名 tail -n 100 文件名 ``` 实时看日志: ```bash tail -f /var/log/nginx/error.log ``` 实时看最近 200 行再持续追踪: ```bash tail -n 200 -f /var/log/nginx/error.log ``` 工程建议: 排查服务时不要盲目改配置。先看日志,再改配置,再重启服务,再继续看日志。 --- ## 7. 文件操作:创建、复制、移动、删除 查看当前目录: ```bash pwd ``` 列出文件: ```bash ls ls -l ls -la lh -lh ``` 如果你输入 `lh -lh` 报错,说明系统没有 `lh` 这个别名。标准命令是: ```bash ls -lh ``` `ls -lh` 的意思: - `-l`:长格式显示。 - `-h`:human readable,用 KB/MB/GB 显示大小。 进入目录: ```bash cd /opt cd .. cd ~ cd - ``` 创建目录: ```bash mkdir logs mkdir -p /opt/rf-platform/logs ``` `-p` 表示父目录不存在也一起创建。 创建空文件: ```bash touch app.log ``` 复制文件: ```bash cp nginx.conf nginx.conf.bak ``` 复制目录: ```bash cp -r rf-platform rf-platform-bak ``` 移动或重命名: ```bash mv old.conf new.conf mv app.py /opt/rf-platform/ ``` 删除文件: ```bash rm app.log ``` 删除目录: ```bash rm -r logs ``` 特别谨慎: ```bash rm -rf / rm -rf * rm -rf /opt/* ``` `rm -rf` 没有回收站。你现在阶段只在明确知道路径时使用。 安全习惯: 删除前先 `pwd` 和 `ls`。 ```bash pwd ls -la rm -r ./logs-old ``` --- ## 8. 查找文件和内容 按文件名查找: ```bash find /opt -name "docker-compose.yml" find /etc -name "*nginx*" ``` 按目录大小排查磁盘占用: ```bash du -sh /var/log du -sh /opt/* ``` 查找文件内容: ```bash grep "error" app.log grep -i "error" app.log grep -n "listen" /etc/nginx/nginx.conf grep -r "server_name" /etc/nginx/ ``` 参数含义: - `-i`:忽略大小写。 - `-n`:显示行号。 - `-r`:递归查找目录。 日志中过滤错误: ```bash grep -i "error" /var/log/nginx/error.log grep -i "permission denied" /var/log/nginx/error.log ``` 实时日志中筛选关键词: ```bash tail -f app.log | grep --line-buffered "ERROR" ``` 如果你只记一个思路: > 文件找不到用 `find`,内容找不到用 `grep`,日志太长用 `tail` 和 `less`。 --- ## 9. Vim:只掌握够改配置的部分 你不需要一开始学成 Vim 高手。够用就行。 打开文件: ```bash vim /etc/nginx/nginx.conf ``` 进入编辑模式: ```text i ``` 保存退出: ```text Esc :wq Enter ``` 不保存退出: ```text Esc :q! Enter ``` 只保存: ```text Esc :w Enter ``` 搜索: ```text /server_name ``` 跳到下一处: ```text n ``` 显示行号: ```text :set nu ``` 工程建议: 改配置前先备份: ```bash cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak ``` 改完先检查配置: ```bash nginx -t ``` 再重启: ```bash systemctl reload nginx ``` --- ## 10. 用户、root 和 sudo Linux 里常见两类用户: - root:最高权限用户。 - 普通用户:日常登录用户。 查看当前用户: ```bash whoami ``` 查看用户 ID 和所属组: ```bash id ``` 临时用管理员权限执行命令: ```bash sudo systemctl restart nginx ``` 切换到 root: ```bash su - ``` 或者: ```bash sudo -i ``` 不建议长期用 root 乱操作。工程现场常见事故很多来自 root 下误删文件、误改权限。 如果普通用户没有 sudo 权限,会看到类似: ```text user is not in the sudoers file ``` 这说明当前用户不能执行管理员操作,需要 root 或管理员配置权限。 --- ## 11. 权限:理解 rwx 就够用一大半 查看权限: ```bash ls -l ``` 你会看到类似: ```text -rw-r--r-- 1 root root 1024 May 18 app.conf drwxr-xr-x 2 www www 4096 May 18 static ``` 第一列含义: ```text -rw-r--r-- ``` 第一个字符: - `-`:普通文件。 - `d`:目录。 - `l`:软链接。 后面 9 个字符分三组: ```text rw- r-- r-- 用户 组 其他人 ``` 权限含义: - `r`:read,读。 - `w`:write,写。 - `x`:execute,执行。 常见权限数字: - `7 = rwx` - `6 = rw-` - `5 = r-x` - `4 = r--` 常用命令: ```bash chmod +x deploy.sh chmod 644 app.conf chmod 755 /opt/rf-platform chown -R www-data:www-data /var/www/html ``` 常见场景: ### 脚本不能执行 现象: ```text Permission denied ``` 处理: ```bash chmod +x deploy.sh ./deploy.sh ``` ### Nginx 403 可能原因: - 文件不存在。 - Nginx 用户没有读取权限。 - 目录没有执行权限。 - 配置的 root/alias 路径不对。 排查: ```bash ls -ld /var/www ls -ld /var/www/html ls -l /var/www/html tail -n 100 /var/log/nginx/error.log ``` ### 服务无法写日志 可能原因: - 日志目录不存在。 - 服务运行用户没有写权限。 处理思路: ```bash mkdir -p /var/log/rf-platform chown -R appuser:appuser /var/log/rf-platform ``` 不要一遇到权限问题就 `chmod 777`。这会让所有人可读、可写、可执行,安全性很差。学习阶段可以临时验证,但正式项目不要这样写进文档。 --- ## 12. 软件安装:知道不同发行版的包管理器 Ubuntu/Debian 常用: ```bash apt update apt install nginx apt remove nginx ``` CentOS/RHEL/Rocky 常用: ```bash yum install nginx dnf install nginx ``` 查看系统版本: ```bash cat /etc/os-release ``` 更新软件源: ```bash sudo apt update ``` 安装常用工具: ```bash sudo apt install -y curl wget vim git unzip htop nginx ``` 注意: - `apt update` 是更新软件列表。 - `apt upgrade` 是升级已安装软件。 - 服务器生产环境不要随手全量升级,先确认影响。 --- ## 13. 进程:服务到底有没有在跑 查看进程: ```bash ps aux ``` 筛选进程: ```bash ps aux | grep nginx ps aux | grep python ``` 动态查看资源: ```bash top ``` 如果有 `htop`,更好用: ```bash htop ``` 看某个进程的 PID: ```bash ps aux | grep uvicorn ``` 结束进程: ```bash kill PID ``` 强制结束: ```bash kill -9 PID ``` 不要一开始就 `kill -9`。普通 `kill` 会给程序一个正常退出机会,`kill -9` 是强制终止,可能导致文件未写完、状态异常。 工程场景: FastAPI 项目访问不了,你可以先看进程: ```bash ps aux | grep uvicorn ``` 如果没有进程,再看启动脚本或 systemd 服务日志。 --- ## 14. CPU、内存和磁盘 查看内存: ```bash free -h ``` 关注: - `total`:总内存。 - `used`:已使用。 - `available`:可用。 Linux 会用一部分内存做缓存,所以不要只看 `used`,更要看 `available`。 查看磁盘: ```bash df -h ``` 关注: - `/` 根分区是否快满。 - `/var` 或 `/data` 是否快满。 查看目录占用: ```bash du -sh /var/log du -sh /var/lib/docker du -sh /opt/* ``` 常见磁盘满原因: - Docker 镜像和容器日志过多。 - Nginx 日志长期不清理。 - 应用上传文件没有限制。 - 数据库备份堆积。 初步排查: ```bash df -h du -sh /var/* du -sh /var/log/* du -sh /var/lib/docker/* ``` 注意: 不要随便删除 `/var/lib/docker`。这可能破坏 Docker 数据。先用 Docker 自己的命令查看和清理。 --- ## 15. 端口:服务是否在监听 查看监听端口: ```bash ss -tunlp ``` 参数含义: - `-t`:TCP。 - `-u`:UDP。 - `-n`:不解析成域名,直接显示数字。 - `-l`:只看监听状态。 - `-p`:显示进程信息。 查看 80 端口: ```bash ss -tunlp | grep ':80' ``` 查看 443 端口: ```bash ss -tunlp | grep ':443' ``` 查看 FastAPI 常用 8000 端口: ```bash ss -tunlp | grep ':8000' ``` 如果没有 `ss`,可尝试: ```bash netstat -tunlp ``` 但新系统更推荐 `ss`。 端口排障思路: 1. 服务是否启动。 2. 服务是否监听正确端口。 3. 服务监听的是 `127.0.0.1` 还是 `0.0.0.0`。 4. 防火墙或安全组是否放行。 5. Nginx 是否代理到正确端口。 `127.0.0.1:8000` 表示只允许本机访问。 `0.0.0.0:8000` 表示监听所有网卡,外部也可能访问,前提是防火墙和安全组允许。 --- ## 16. curl:服务器自测神器 `curl` 用来从命令行发 HTTP 请求。 访问首页: ```bash curl http://127.0.0.1:8000 ``` 查看响应头: ```bash curl -I http://example.com ``` 显示详细连接过程: ```bash curl -v http://127.0.0.1:8000 ``` 测试 POST 接口: ```bash curl -X POST http://127.0.0.1:8000/api/analyze ``` 带 JSON: ```bash curl -X POST http://127.0.0.1:8000/api/analyze \ -H "Content-Type: application/json" \ -d '{"file":"test.csv"}' ``` 常见判断: - `Connection refused`:端口没有服务监听,或服务没启动。 - `Connection timed out`:网络不通、防火墙、安全组或服务无响应。 - `404`:服务通了,但路径不对。 - `502`:Nginx 通了,但后端服务异常或代理地址错。 - `403`:权限或访问规则问题。 项目排障中非常推荐本机先测: ```bash curl -v http://127.0.0.1:8000 ``` 如果本机都不通,先别怀疑域名和 HTTPS,先把应用服务跑起来。 --- ## 17. systemctl:服务管理核心 查看服务状态: ```bash systemctl status nginx ``` 启动服务: ```bash sudo systemctl start nginx ``` 停止服务: ```bash sudo systemctl stop nginx ``` 重启服务: ```bash sudo systemctl restart nginx ``` 重新加载配置: ```bash sudo systemctl reload nginx ``` 设置开机自启: ```bash sudo systemctl enable nginx ``` 取消开机自启: ```bash sudo systemctl disable nginx ``` 看是否开机自启: ```bash systemctl is-enabled nginx ``` 看是否正在运行: ```bash systemctl is-active nginx ``` 常见服务: ```bash systemctl status nginx systemctl status docker systemctl status ssh ``` `reload` 和 `restart` 区别: - `reload`:重新加载配置,尽量不中断服务。 - `restart`:停止后重新启动,可能有短暂中断。 Nginx 改配置后常用: ```bash sudo nginx -t sudo systemctl reload nginx ``` 先 `nginx -t` 检查配置,再 reload。 --- ## 18. journalctl:看 systemd 服务日志 查看某个服务日志: ```bash journalctl -u nginx ``` 看最近 100 行: ```bash journalctl -u nginx -n 100 ``` 实时追踪: ```bash journalctl -u nginx -f ``` 看今天日志: ```bash journalctl -u nginx --since today ``` 看指定时间: ```bash journalctl -u nginx --since "2026-05-18 10:00:00" ``` 如果服务启动失败: ```bash systemctl status 服务名 journalctl -u 服务名 -n 100 ``` 重点看: - 配置文件路径是否错误。 - 端口是否被占用。 - 权限是否不足。 - 环境变量是否缺失。 - 可执行文件路径是否不存在。 --- ## 19. 日志思维:问题不是猜出来的 工程上排障最重要的习惯: > 先拿证据,再做判断。 常见日志位置: ```text /var/log/nginx/access.log /var/log/nginx/error.log /var/log/syslog /var/log/messages /var/log/auth.log ``` Ubuntu 常见系统日志: ```bash tail -f /var/log/syslog ``` CentOS/RHEL 常见系统日志: ```bash tail -f /var/log/messages ``` Nginx 错误日志: ```bash tail -f /var/log/nginx/error.log ``` Nginx 访问日志: ```bash tail -f /var/log/nginx/access.log ``` 日志里你要关注: - `error` - `failed` - `permission denied` - `connection refused` - `no such file or directory` - `address already in use` - `upstream timed out` - `connect() failed` 排障模板: ```bash systemctl status nginx journalctl -u nginx -n 100 tail -n 100 /var/log/nginx/error.log ss -tunlp | grep ':80' curl -I http://127.0.0.1 ``` --- ## 20. 网络基础:够部署排障即可 查看 IP: ```bash ip addr ``` 查看路由: ```bash ip route ``` 测试网络连通: ```bash ping 8.8.8.8 ping baidu.com ``` 如果 IP 能 ping 通,域名 ping 不通,可能是 DNS 问题。 查看 DNS 解析: ```bash nslookup example.com dig example.com ``` 跟踪路由: ```bash traceroute example.com ``` 如果没有 `traceroute`,Ubuntu 可安装: ```bash sudo apt install traceroute ``` Web 服务访问链路: ```text 浏览器 -> 域名 DNS -> 云服务器公网 IP -> 安全组/防火墙 -> Nginx 80/443 -> 后端服务 8000/其他端口 -> 应用代码 -> 数据文件/数据库 ``` 排查时要一层层确认。 --- ## 21. 防火墙和云安全组 很多初学者会忽略:服务器内部开放端口,不代表外网能访问。 需要同时满足: - 服务监听了端口。 - Linux 防火墙放行。 - 云厂商安全组放行。 - Nginx 配置正确。 - 域名解析正确。 Ubuntu 常见防火墙 UFW: ```bash sudo ufw status sudo ufw allow 80 sudo ufw allow 443 sudo ufw allow 22 ``` CentOS/RHEL 常见 firewalld: ```bash sudo firewall-cmd --state sudo firewall-cmd --list-all sudo firewall-cmd --add-service=http --permanent sudo firewall-cmd --add-service=https --permanent sudo firewall-cmd --reload ``` 云服务器还要去控制台安全组开放: - SSH:22 - HTTP:80 - HTTPS:443 - 测试服务端口:如 8000,建议只临时开放 正式项目建议: - 外部只开放 80/443。 - 后端 8000 只监听本机 `127.0.0.1`。 - 由 Nginx 反向代理到后端。 --- ## 22. Nginx 相关 Linux 基础 虽然 Nginx 是下一阶段重点,但 Linux 部分要先会这些。 配置目录常见位置: ```text /etc/nginx/nginx.conf /etc/nginx/conf.d/ /etc/nginx/sites-available/ /etc/nginx/sites-enabled/ ``` 日志目录: ```text /var/log/nginx/access.log /var/log/nginx/error.log ``` 检查配置: ```bash sudo nginx -t ``` 重新加载: ```bash sudo systemctl reload nginx ``` 查看状态: ```bash systemctl status nginx ``` 常见 502 排查: ```bash tail -n 100 /var/log/nginx/error.log ss -tunlp | grep ':8000' curl -v http://127.0.0.1:8000 ``` 如果日志里有: ```text connect() failed (111: Connection refused) while connecting to upstream ``` 通常说明后端端口没有服务在监听,或者 Nginx 代理地址写错。 常见 403 排查: ```bash tail -n 100 /var/log/nginx/error.log ls -ld /var/www/html ls -l /var/www/html ``` 常见 404 排查: ```bash grep -n "root" /etc/nginx/nginx.conf grep -n "location" /etc/nginx/nginx.conf ``` --- ## 23. Docker 相关 Linux 基础 Docker 本身是下一阶段,但 Linux 要先帮你理解几个点。 Docker 数据常见位置: ```text /var/lib/docker ``` Docker 服务: ```bash systemctl status docker sudo systemctl start docker sudo systemctl enable docker ``` 普通用户执行 docker 报权限问题: ```text permission denied while trying to connect to the Docker daemon socket ``` 常见处理: ```bash sudo usermod -aG docker 当前用户名 ``` 然后重新登录 SSH。 不要直接乱改 `/var/run/docker.sock` 权限。 查看 Docker 占用磁盘: ```bash du -sh /var/lib/docker ``` 清理前先看: ```bash docker system df ``` 项目目录建议: ```text /opt/rf-platform/docker-compose.yml /opt/rf-platform/.env /opt/rf-platform/nginx/ /opt/rf-platform/data/ /opt/rf-platform/logs/ ``` Linux 要负责把这些目录权限、路径、磁盘空间管理好。 --- ## 24. 环境变量和 PATH 查看环境变量: ```bash env ``` 查看某个变量: ```bash echo $PATH ``` `PATH` 是系统查找命令的位置列表。 比如你输入: ```bash python3 ``` 系统会到 `PATH` 里的目录挨个找有没有 `python3`。 临时设置变量: ```bash export APP_ENV=production ``` 当前终端关闭后失效。 写入 shell 配置: ```bash vim ~/.bashrc ``` 或: ```bash vim ~/.zshrc ``` 让配置生效: ```bash source ~/.bashrc ``` systemd 服务里的环境变量要单独配置,不能只依赖你当前终端里的 `export`。 --- ## 25. 压缩和解压 常见压缩包: ```text .zip .tar .tar.gz .tgz ``` 解压 zip: ```bash unzip file.zip ``` 打包目录: ```bash tar -czvf project.tar.gz project/ ``` 解压: ```bash tar -xzvf project.tar.gz ``` 只查看压缩包内容: ```bash tar -tzf project.tar.gz ``` 项目用途: - 打包部署文件。 - 备份配置和日志。 - 上传测试数据。 备份 Nginx 配置: ```bash tar -czvf nginx-conf-backup.tar.gz /etc/nginx ``` --- ## 26. 软链接:Nginx 配置常见 软链接类似快捷方式。 创建软链接: ```bash ln -s /etc/nginx/sites-available/rf-platform.conf /etc/nginx/sites-enabled/rf-platform.conf ``` 查看软链接: ```bash ls -l /etc/nginx/sites-enabled/ ``` 会看到: ```text rf-platform.conf -> /etc/nginx/sites-available/rf-platform.conf ``` 删除软链接: ```bash rm /etc/nginx/sites-enabled/rf-platform.conf ``` 这通常不会删除原文件,只删除链接。 --- ## 27. 时间、时区和定时任务 查看时间: ```bash date ``` 查看时区: ```bash timedatectl ``` 设置时区为上海: ```bash sudo timedatectl set-timezone Asia/Shanghai ``` 定时任务用 cron。 编辑当前用户定时任务: ```bash crontab -e ``` 查看: ```bash crontab -l ``` 例子:每天凌晨 2 点执行备份脚本。 ```cron 0 2 * * * /opt/rf-platform/scripts/backup.sh ``` cron 常见坑: - PATH 很短,脚本里最好写绝对路径。 - 工作目录不一定是项目目录。 - 日志要重定向出来。 推荐写法: ```cron 0 2 * * * cd /opt/rf-platform && /bin/bash scripts/backup.sh >> /var/log/rf-platform/backup.log 2>&1 ``` --- ## 28. 一个标准 Web 服务排障流程 场景:你部署了 FastAPI 服务,浏览器访问不了。 ### 第一步:确认机器 ```bash hostname ip addr pwd ``` 确认自己没有连错服务器。 ### 第二步:确认磁盘和内存 ```bash df -h free -h ``` 磁盘满了,很多服务会异常。 ### 第三步:确认进程 ```bash ps aux | grep uvicorn ``` 如果进程不存在,服务没启动。 ### 第四步:确认端口 ```bash ss -tunlp | grep ':8000' ``` 如果没有监听,应用没有正常启动。 ### 第五步:本机 curl ```bash curl -v http://127.0.0.1:8000 ``` 本机不通,先查应用。 ### 第六步:查应用日志 ```bash journalctl -u rf-platform -n 100 tail -n 100 /opt/rf-platform/logs/app.log ``` 看是否缺依赖、路径错误、端口占用、权限不足。 ### 第七步:查 Nginx ```bash nginx -t systemctl status nginx tail -n 100 /var/log/nginx/error.log ``` 看是否代理错端口。 ### 第八步:查防火墙和安全组 ```bash sudo ufw status ``` 再去云厂商控制台看安全组。 这个流程可以写进项目 README,面试时也能讲。 --- ## 29. Nginx 502 的完整判断 502 的意思通常是:Nginx 找不到或连不上后端。 排查命令: ```bash tail -n 100 /var/log/nginx/error.log ss -tunlp | grep ':8000' curl -v http://127.0.0.1:8000 systemctl status nginx ``` 常见原因: - 后端服务没启动。 - 后端端口写错。 - 后端只监听了错误地址。 - Docker 端口映射错。 - Nginx 配置里的 upstream 写错。 - 后端启动慢或超时。 如果 Nginx 配置是: ```nginx proxy_pass http://127.0.0.1:8000; ``` 你就必须确认: ```bash curl -v http://127.0.0.1:8000 ``` 能在服务器本机访问。 如果后端在 Docker Compose 网络里,Nginx 也在容器里,代理地址可能应该是服务名,而不是 `127.0.0.1`。 --- ## 30. 权限问题的完整判断 场景:应用启动了,但上传文件失败。 可能报错: ```text Permission denied: '/opt/rf-platform/uploads/test.csv' ``` 排查: ```bash ls -ld /opt/rf-platform ls -ld /opt/rf-platform/uploads ps aux | grep uvicorn ``` 你要确认: - 应用以哪个用户运行。 - 上传目录属于谁。 - 目录是否有写权限。 处理: ```bash sudo mkdir -p /opt/rf-platform/uploads sudo chown -R appuser:appuser /opt/rf-platform/uploads sudo chmod 755 /opt/rf-platform/uploads ``` 如果是 Docker 容器,还要看 volume 映射后的宿主机目录权限。 --- ## 31. 端口冲突的完整判断 现象: ```text Address already in use ``` 排查: ```bash ss -tunlp | grep ':8000' ``` 假设输出显示 PID 是 1234。 查看进程: ```bash ps -p 1234 -f ``` 处理方式: - 改你的服务端口。 - 停掉占用端口的旧服务。 - 检查是否重复启动了同一个服务。 停止旧进程: ```bash kill 1234 ``` 如果是 systemd 服务: ```bash sudo systemctl stop 服务名 ``` 不要只 kill 进程而不查它是不是由 systemd 或 Docker 自动拉起,否则它可能马上又起来。 --- ## 32. 磁盘满的完整判断 现象: - 服务无法写日志。 - 数据上传失败。 - Docker 容器异常退出。 - 数据库报错。 排查: ```bash df -h du -sh /var/* du -sh /var/log/* du -sh /opt/* du -sh /var/lib/docker ``` 如果 `/var/log` 很大: ```bash ls -lh /var/log ``` 如果 Docker 很大: ```bash docker system df ``` 谨慎清理: ```bash docker image prune docker container prune ``` 更激进的: ```bash docker system prune ``` 执行前要确认不会删除仍需要的镜像、停止容器、缓存。 长期方案: - 配置日志轮转。 - 限制 Docker 日志大小。 - 项目上传目录设置清理策略。 - 数据库和文件备份分开存储。 --- ## 33. systemd 自定义服务:把 Python 项目管起来 如果你不用 Docker,也可以用 systemd 管理 FastAPI。 示例服务文件: ```ini [Unit] Description=RF Test Data Platform After=network.target [Service] User=appuser WorkingDirectory=/opt/rf-platform ExecStart=/opt/rf-platform/.venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000 Restart=always RestartSec=5 [Install] WantedBy=multi-user.target ``` 保存为: ```text /etc/systemd/system/rf-platform.service ``` 加载配置: ```bash sudo systemctl daemon-reload ``` 启动: ```bash sudo systemctl start rf-platform ``` 开机自启: ```bash sudo systemctl enable rf-platform ``` 看状态: ```bash systemctl status rf-platform ``` 看日志: ```bash journalctl -u rf-platform -f ``` 面试表达: > 我将 FastAPI 服务配置为 systemd service,指定运行用户、工作目录、启动命令和自动重启策略,通过 journalctl 查看服务日志,配合 Nginx 反向代理对外提供 HTTPS 访问。 --- ## 34. 和射频测试平台项目怎么结合 你的差异化项目可以是: > 射频测试数据自动化分析与可视化平台 Linux 在项目里负责: - 创建部署目录。 - 管理上传数据目录。 - 管理日志目录。 - 启动 Python/FastAPI 服务。 - 配置 Nginx 反向代理。 - 查看端口和服务状态。 - 排查用户上传失败、页面打不开、服务异常退出等问题。 建议目录: ```text /opt/rf-platform/ app/ data/ uploads/ outputs/ logs/ docker-compose.yml README.md ``` 常用检查命令: ```bash cd /opt/rf-platform ls -la df -h free -h ss -tunlp curl -v http://127.0.0.1:8000 tail -n 100 logs/app.log ``` 项目 README 可以写: ```text 部署环境:Ubuntu Server 服务管理:Docker Compose / systemd 反向代理:Nginx 日志排查:journalctl、tail、docker logs 端口检查:ss -tunlp 资源检查:df -h、free -h、top ``` 这会比只写“熟悉 Linux”更有说服力。 --- ## 35. Linux 学习路线的 14 天安排 ### 第 1-2 天:SSH 和文件系统 练习: - 登录服务器。 - 查看系统版本。 - 熟悉 `/etc`、`/var/log`、`/opt`、`/home`。 - 用 `scp` 上传下载文件。 验收: ```bash ssh 用户名@服务器IP cat /etc/os-release pwd ls -la /var/log scp ./test.txt 用户名@服务器IP:/tmp/ ``` ### 第 3-4 天:文件操作和 vim 练习: - 创建项目目录。 - 复制、移动、删除测试文件。 - 用 vim 修改配置。 - 改配置前备份。 验收: ```bash mkdir -p /opt/demo/logs cp demo.conf demo.conf.bak vim demo.conf ``` ### 第 5-6 天:权限 练习: - 看懂 `ls -l`。 - 修改脚本执行权限。 - 修改目录所属用户。 - 模拟上传目录不可写问题。 验收: ```bash chmod +x deploy.sh chown -R appuser:appuser /opt/demo/uploads ls -ld /opt/demo/uploads ``` ### 第 7-8 天:进程、端口、资源 练习: - 启动一个 Python HTTP 服务。 - 查看进程。 - 查看端口。 - 用 curl 测试。 验收: ```bash python3 -m http.server 8000 ps aux | grep python ss -tunlp | grep ':8000' curl -I http://127.0.0.1:8000 ``` ### 第 9-10 天:systemctl 和 journalctl 练习: - 安装 Nginx。 - 启动、停止、重载 Nginx。 - 查看 Nginx 日志。 验收: ```bash systemctl status nginx sudo nginx -t sudo systemctl reload nginx journalctl -u nginx -n 50 ``` ### 第 11-12 天:网络和 Web 排障 练习: - 用 curl 判断服务是否正常。 - 用 ss 查端口。 - 制造一个端口不通问题并排查。 - 看 Nginx 访问日志和错误日志。 验收: ```bash curl -v http://127.0.0.1 tail -n 50 /var/log/nginx/access.log tail -n 50 /var/log/nginx/error.log ``` ### 第 13-14 天:小项目部署复盘 练习: - 部署一个最小 Web 服务。 - 用 Nginx 代理。 - 写部署 README。 - 写排障记录。 验收: - README 里有部署步骤。 - README 里有常见问题排查。 - 能解释每条命令为什么用。 --- ## 36. 必背命令清单 连接和身份: ```bash ssh 用户名@服务器IP scp 本地文件 用户名@服务器IP:/远程路径 whoami pwd hostname sudo 命令 ``` 文件目录: ```bash ls -la cd /path mkdir -p /path cp 源 目标 mv 源 目标 rm 文件 cat 文件 less 文件 tail -n 100 文件 tail -f 文件 find /path -name "文件名" grep -r "关键词" /path ``` 权限: ```bash ls -l chmod +x script.sh chmod 755 dir chmod 644 file chown -R user:group dir ``` 资源: ```bash ps aux top free -h df -h du -sh /path ``` 端口和网络: ```bash ss -tunlp curl -v http://127.0.0.1:8000 ping IP或域名 ip addr ip route ``` 服务和日志: ```bash systemctl status 服务名 systemctl start 服务名 systemctl stop 服务名 systemctl restart 服务名 systemctl reload 服务名 systemctl enable 服务名 journalctl -u 服务名 -n 100 journalctl -u 服务名 -f ``` --- ## 37. 面试怎么讲 Linux 不要说: > 我熟悉 Linux。 这句话太空。 可以说: > 我主要掌握 Linux 服务器部署和排障相关能力,包括 SSH 登录、文件和权限管理、systemd 服务管理、journalctl 日志查看、端口监听排查、磁盘和内存检查,以及 Nginx/Docker 部署中常见的 502、403、端口冲突、权限不足等问题定位。 如果面试官问:“服务访问不了你怎么排查?” 可以答: > 我会先确认是否连对服务器,然后检查资源状态,比如 `df -h` 和 `free -h`。接着用 `ps aux` 或 `systemctl status` 看服务是否运行,用 `ss -tunlp` 看端口是否监听,再用 `curl -v http://127.0.0.1:端口` 在服务器本机测试。如果本机服务正常,再看 Nginx 配置和错误日志,比如 `nginx -t`、`tail -n 100 /var/log/nginx/error.log`。最后再确认防火墙和云安全组是否开放。 如果面试官问:“Nginx 502 怎么查?” 可以答: > 502 通常是 Nginx 连不上后端。我会先看 `/var/log/nginx/error.log`,再确认 upstream 配置的端口是否有服务监听,用 `ss -tunlp | grep 端口`,然后用 `curl` 直接访问后端。如果后端没起来,就看应用日志或 `journalctl -u 服务名`。如果后端在 Docker 里,还要确认端口映射和容器网络。 如果面试官问:“权限问题怎么查?” 可以答: > 我会用 `ls -l` 和 `ls -ld` 看文件及父目录权限,确认服务运行用户是谁,再判断是否有读写执行权限。比如 Nginx 403 可能不是文件没有读权限,而是父目录没有执行权限。处理时我会优先用 `chown` 调整属主和 `chmod 755/644` 设置合理权限,不会直接用 `chmod 777` 作为正式方案。 --- ## 38. 简历怎么写 Linux 技能栏可以写: ```text Linux:熟悉服务器常用命令、文件/权限管理、systemd 服务管理、journalctl 日志排查、端口与资源监控,能够完成 Web 服务部署和常见故障定位。 ``` 项目里可以写: ```text 在 Ubuntu Server 上完成 FastAPI 服务部署,使用 systemd/Docker Compose 管理服务进程,结合 Nginx 反向代理对外提供访问;通过 ss、curl、journalctl、tail 等命令排查端口占用、502、权限不足和日志异常问题。 ``` 更贴合你的路线可以写: ```text 面向射频测试数据分析平台,搭建 Linux 服务器运行环境,规划上传数据、分析结果和日志目录,配置服务自启动和反向代理,并编写部署与故障排查文档。 ``` --- ## 39. 不需要优先学的内容 这些不是不能学,而是你现在不该优先投入大量时间: - Linux 内核源码。 - 驱动开发。 - 进程调度算法。 - 高级 Shell 编程。 - awk/sed 特别复杂的写法。 - iptables 深度规则。 - Kubernetes 大规模集群。 - Prometheus/Grafana 全套监控体系。 - 高可用数据库运维。 等你完成 Linux + Docker + Nginx + Python 测试平台项目以后,再按岗位需要补。 --- ## 40. 最小实战任务 完成下面这个任务,你的 Linux 入门就不是纸上谈兵。 任务:在 Linux 服务器上部署一个最小 Web 服务。 要求: 1. 用 SSH 登录服务器。 2. 创建 `/opt/linux-demo`。 3. 上传一个简单 HTML 或 Python Web 服务。 4. 启动服务监听 8000。 5. 用 `ss -tunlp` 确认端口。 6. 用 `curl` 本机访问。 7. 配 Nginx 反向代理到 8000。 8. 用 `nginx -t` 检查配置。 9. 用 `systemctl reload nginx` 生效。 10. 查看访问日志和错误日志。 11. 故意制造一个错误端口,观察 502。 12. 写下排障过程。 你最终要能输出一份 README: ```text 部署环境 部署步骤 常用命令 日志位置 常见故障 排查流程 ``` 这份 README 就是你从“看过 Linux”变成“用过 Linux 做工程”的证明。 --- ## 41. 最后总结 你在这条路线里学 Linux,核心不是命令数量,而是工程闭环: ```text 连接服务器 -> 上传项目 -> 配置目录和权限 -> 启动服务 -> 检查端口 -> 配置 Nginx -> 查看日志 -> 定位故障 -> 写成部署文档 ``` 只要你能把这套流程做熟,再接 Docker、Nginx、Python/FastAPI、射频测试数据平台,就会形成一条很清晰的能力线: > 我懂通信/射频业务,也能把测试数据平台部署到 Linux 服务器。 > 我也能排查服务运行中的常见问题。 这就是项目路线里 Linux 最应该学成的样子。