)
适合课堂 / 自学整理结构Docker 基础 → 安装 → 核心概念 → 常用命令 → Dockerfile 镜像构建 → Nginx 中文乱码实战我们前面实操内容一、什么是 Docker1. 传统虚拟机 和 Docker 容器区别虚拟机完整虚拟一套硬件 独立完整操作系统体积大、启动慢、资源占用高Docker容器共享宿主机 Linux 内核只打包程序、依赖、配置没有独立内核体积小、秒级启动、资源消耗极低一句话虚拟机是 “装完整电脑”Docker 是 “打包程序运行环境”2. Docker 核心作用一次打包到处运行开发、测试、生产环境统一解决经典问题“我本地能跑线上不行”3. Docker 三大核心组件必考镜像Image只读静态模板相当于安装包包含程序、依赖、配置。镜像不能修改分层存储。容器Container镜像运行出来的实例有一层可读写临时层程序实际跑在容器里。删除容器容器内手动修改的内容默认丢失。仓库Registry存放镜像的地方官方公共仓库Docker Hub类比理解镜像 蛋糕配方容器 按照配方烤出来的蛋糕实例二、Docker 安装部署CentOS 系统我们实操环境环境CentOS7 / CentOS Stream1. 前置卸载旧版本 docker可选yum remove -y docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine2. 安装 yum 工具包yum install -y yum-utils3. 设置 docker yum 源国内推荐阿里云源速度快yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo4. 安装 Docker 引擎ce 社区免费版yum install -y docker-ce docker-ce-cli containerd.io5. 启动 Docker 设置开机自启# 启动 systemctl start docker # 开机自动启动 systemctl enable docker6. 验证是否安装成功docker --version docker info # 运行hello-world测试 docker run hello-world解释Unable to find image hello-world:latest locally# 本地电脑宿主机找不到 hello-world:latest 这个镜像latest: Pulling from library/hello-world4f55086f7dd0: Pull complete# 去 Docker Hub 公共仓库拉取 hello-world 镜像下载完成Digest: sha256:5dd0d3e6e255913fc30f90b9f2b1d359cc2cbdb48090cc4b65f1676e203243cc# 镜像的唯一校验值哈希值用来确认镜像没被篡改Status: Downloaded newer image for hello-world:latest# 状态已经下载好了最新版 hello-world 镜像Hello from Docker!This message shows that your installation appears to be working correctly.# 来自Docker的问候这条信息代表你的Docker安装正常可以使用。✅ 优化配置国内镜像加速必配否则拉镜像很慢# 创建daemon.json配置文件 cat /etc/docker/daemon.json EOF { registry-mirrors: [https://mirror.baidubce.com] } EOF # 重启docker生效 systemctl daemon-reload systemctl restart docker三、Docker 基础常用命令分类整理1. 镜像相关# 搜索镜像 docker search nginx # 拉取镜像不加tag默认latest最新版 docker pull nginx:1.27 # 查看本地镜像 docker images # 删除镜像镜像id/名字 docker rmi 镜像ID2. 容器相关高频# 创建并启动容器 # -d 后台运行 --name 自定义名字 -p 宿主机端口:容器内端口 镜像名:tag docker run -d --name nginx-test -p 8080:80 nginx:1.27 # 查看正在运行容器 docker ps # 查看所有容器包含停止的 docker ps -a # 停止容器 docker stop 容器名/容器ID # 启动已存在的容器 docker start 容器名/容器ID # 删除容器必须先停止加-f强制删除正在运行的 docker rm -f 容器名/容器ID # 进入正在运行的容器内部 docker exec -it 容器名 /bin/bash # 宿主机 和 容器之间 文件互传 # 宿主机文件 → 容器 docker cp 本地文件 容器名:容器内路径 # 容器文件 → 宿主机 docker cp 容器名:容器内路径 本地路径做端口映射的时候要用如果是在linux虚拟机上要用内网IP如果是云服务器的话就用公网IP云服务器本身自带独立公网 IP这里的公网 IP不是 Docker 单独的 IP是这台服务器整机的公网 IPDocker 只是把本机 80 端口转发到容器内部这样就可以在浏览器打开你的docker了。3. 其他辅助# 查看容器日志 docker logs 容器名四、Dockerfile 构建自定义镜像重点本次 Nginx 实战核心需求不直接用官方原始 nginx 镜像自己定制环境、文件打包成新镜像 ✅ 核心规则Dockerfile 里每一条指令都会生成镜像分层镜像只读固化常用 Dockerfile 指令表格指令作用FROM基础镜像必须第一行ENV设置环境变量COPY把宿主机文件复制进镜像内RUN构建镜像时执行命令EXPOSE声明容器要开放的端口仅声明不实际开放CMD容器启动默认执行命令nginx:1.27 镜像是 Debian 基础镜像容器内默认字符集是 POSIX不是 UTF-8Shell 不识别中文直接把中文转成八进制编码 \345\260\232...最终网页渲染出现乱码 / 繁体异常。✅ 我们实战最终 Dockerfilev2 版本固化 utf8 环境 带 meta 的 htmlFROM nginx:1.27 # 系统级UTF8编码固化在镜像不会被echo修改 ENV LANGC.UTF-8 ENV LC_ALLC.UTF-8 # 将本地写好的完整html打包进镜像 COPY index.html /usr/share/nginx/html/index.html # 声明端口 EXPOSE 80✅ 构建镜像命令# -t 镜像名:版本号 . 代表当前目录找Dockerfile docker build -t mynginx-dockerfile:v2 .五、文件重定向符号本次踩坑重点表格符号含义风险覆盖写入清空原有全部内容再写入新内容❗ 本次乱码根源追加写入保留原有内容新内容加到末尾 ✅# 覆盖危险会删掉meta标签 echo h1测试文字/h1 index.html # 追加安全 echo p新增一行/p index.html # 多行写入完整html cat index.html EOF 完整html代码 EOF六、Nginx 中文乱码实战复盘我们前面完整踩坑 解决重点两个独立 UTF-8 配置极易混淆ENV LANGC.UTF-8系统编码作用Linux 底层存储中文不乱码固化在镜像echo 修改不了缺陷不会通知浏览器编码格式meta charsetutf-8html 内标签作用告诉浏览器使用 utf8 解析页面 本质只是 html 里一段文本一旦覆盖文件直接消失 → 浏览器乱码现象复现流程基于 v2 镜像启动容器index.html 自带 meta 标签中文正常进入容器执行echo h1测试/h1 index.htmlindex.html 原有全部代码清空meta 标签消失 → 网页乱码重点系统编码依旧是 UTF8文字本身没问题只是缺少网页编码声明解决方案想要永久保留完整 html必须写入 Dockerfile 重新 build 镜像而不是容器内手动修改关键结论容器内直接修改文件 临时生效删除容器就丢失 想要永久固化配置 / 文件 → Dockerfile docker build 打包镜像七、拓展方案可选笔记方案 1安全修改页面追加内容不破坏 html 结构echo p新增文字/p /usr/share/nginx/html/index.html方案 2生产级 Nginx 全局 utf8nginx 响应头强制编码不需要 meta 标签FROM nginx:1.27 ENV LANGC.UTF-8 ENV LC_ALLC.UTF-8 RUN echo charset utf-8; /etc/nginx/conf.d/default.conf COPY index.html /usr/share/nginx/html/index.html EXPOSE 80八、一句话速记总结背诵版Docker 共享宿主机内核轻量、秒启动核心镜像、容器、仓库Dockerfile 构建镜像镜像只读固化容器可读写临时层容器内修改默认不持久覆盖清空文件追加内容ENV C.UTF-8管系统存储文字meta charset管浏览器解析网页永久修改环境 / 文件 → build 镜像临时调试 → 直接改运行容器九、保存镜像1、可以把镜像打包发给别人使用保存也加载load输出别人发给我们的镜像之后我让他继续运行run运行后给他设置名字以及端口映射然后区去浏览器看下 是不是和别人发我们镜像页面一样一样的就成功啦十、镜像分享到社区Docker Hub 就是 Docker 官方公共社区别人可以直接docker pull下载你的镜像Docker前置准备浏览器打开 https://hub.docker.com 注册账号记住你的Docker Hub 用户名全部小写网页上点Create repository创建仓库仓库名小写选择Public公开仓库名字建议mynginx和本地镜像对应。完整 4 步命令实操①给本地镜像打 tag最重要格式docker tag 本地镜像:版本 你的hub用户名/仓库名:版本示例假设你的 docker hub 用户名是atguigudemo# 本地镜像 mynginx:v1 → 改成符合hub规范名字 docker tag mynginx:v1 atguigudemo/mynginx:v1⚠️坑必须带上你的用户名不能直接写mynginx:v1push会报错。打完 tag 查看docker images | grep hub里的用户名②服务器命令行登录 Docker Hubdocker login输入你的 DockerHub 用户名密码现在推荐用网页生成的Access Token不要用账号原始密码登录。 登录成功提示Login Succeeded③push 推送上传到社区仓库docker push 用户名/mynginx:v1Docker 会分层上传镜像全部层上传完成网页 Docker Hub 仓库就能看到你的镜像。可以在你的镜像这里添加说明书显示发布的版本和最新版本④别人任意机器直接下载使用分享完成其他人不需要 tar 包一条命令拉取docker pull atguigudemo/mynginx:v1 docker run -d -p 8082:80 atguigudemo/mynginx:v1笔记两套分享方式对比表格分享方式命令特点离线分享save‑load生成 tar 文件拷贝文件给别人不能网络 pull社区公开分享 (Docker Hub)tag → login → push上传公共仓库全世界可以 pull 下载完整标准工作流无 commitDockerfile → docker build → docker tag → docker push高频踩坑❌直接 pushmynginx:v1报错denied: requested access to the resource is denied原因镜像名字缺少你的 hub 用户名命名空间必须 docker tag 重命名。镜像名全部小写不能大写字母Docker Hub 强制要求。latest标签坑尽量用明确版本号v1不要无脑用 latest版本会混乱。国内服务器访问 Docker Hub 网络慢 / 推不上去需要配置 docker 镜像加速器。退出登录可选docker logout两套分享总结内网 / 不能上网环境用docker save‑loadtar 包对外分享给所有人Docker Hubtag push常用命令注如果是云服务器的话允许哪些端口访问是要在服务器上设置的两层防护第一层云厂商安全组阿里云 / 腾讯云… 网页控制台配置⚠️这个不在 Linux 命令里面操作网页后台设置云服务器外面还有一层防火墙叫安全组。就算你 Linux 系统 firewalld 关了如果安全组没放行端口外网依旧访问不了。举例你容器 -p 8082:80宿主机用 8082 端口安全组入方向规则需要放行 8082 端口允许来源 0.0.0.0/0所有 IP。如果你用 -p 80:80就要放行 80 端口。坑只改 Linux 内部防火墙忘记云平台安全组浏览器访问超时。第二层Linux 系统内部防火墙 firewalld服务器命令行操作CentOS7/8 默认开启 firewalldbash#查看当前放行端口firewall-cmd --list-all两种处理方式练习环境选其一1、临时放行端口重启服务器失效bashfirewall-cmd --add-port80/tcp2、直接关闭防火墙学习测试环境简单粗暴bashsystemctl stop firewalldsystemctl disable firewalld完整访问判断排查顺序记笔记排错顺序浏览器访问不通按顺序排查从上往下✅容器状态docker ps 容器状态是 Up✅服务器本机内部测试curl 127.0.0.1:端口如果 curl 本机都失败 → Docker 容器 /nginx 服务本身问题✅Linux 防火墙firewalld 放行对应端口或者关闭✅云服务器安全组网页控制台放行宿主机映射出来的端口注意放行的是宿主机端口不是容器内部 80 端口。例如 -p 8082:80安全组放行 8082不是 80。举例子docker run -d -p 8082:80 mynginx:v1容器内部端口80宿主机对外端口8082安全组、firewalld都要放行 8082虚拟机你现在 CentOS 虚拟机不是云服务器你现在本地 VMware 虚拟机没有云厂商安全组只有 firewalld 一层。只需要处理系统防火墙即可。区分记忆本地虚拟机只有 Linux firewalld阿里云 / 腾讯云云服务器安全组 firewalld 两层防火墙高频踩坑安全组放行容器内部端口不放宿主机端口 → 访问失败curl 服务器内部 127.0.0.1 能通外网浏览器打不开90% 是安全组没开。安全组改完有时候十几秒才生效。简单总结一句话云服务器对外暴露服务安全组和系统防火墙都要考虑虚拟机只需要管系统防火墙。放行的是宿主机映射后的端口。